pax_global_header00006660000000000000000000000064132514545660014525gustar00rootroot0000000000000052 comment=d1b23e3c5a3582c9016dd5148438200219a05ad5 fwupd-1.0.6/000077500000000000000000000000001325145456600126565ustar00rootroot00000000000000fwupd-1.0.6/.github/000077500000000000000000000000001325145456600142165ustar00rootroot00000000000000fwupd-1.0.6/.github/ISSUE_TEMPLATE.md000066400000000000000000000020751325145456600167270ustar00rootroot00000000000000To help us pinpoint your issue, please insert the output of the following commands when ran on the system with the issue: ```shell $ fwupdmgr --version **INSERT OUTPUT HERE** ``` Note, the switch `--version` is only present since version 0.9.6. If you use an earlier version, please use the package manager to find out the package version. For example, `dpkg -l fwupd`. ```shell $ fwupdmgr get-devices **INSERT OUTPUT HERE** ``` ```shell $ efibootmgr -v **INSERT OUTPUT HERE** **This is only required if you use the UEFI plugin** ``` ```shell $ efivar -l | grep fw **INSERT OUTPUT HERE** **This is only required if you use the UEFI plugin** ``` ```shell $ tree /boot **INSERT OUTPUT HERE** **This is only required if you use the UEFI plugin** **We're looking for any `.cap` files and the location of `fwupx64.efi`** ``` Please answer the following questions: - Operating system and version: - How did you install fwupd (ex: `from source`, `pacman`, `apt-get`, etc): - Have you tried rebooting? - Are you using an NVMe disk? - Is secure boot enabled (only for the UEFI plugin)? fwupd-1.0.6/.gitignore000066400000000000000000000000151325145456600146420ustar00rootroot00000000000000/build /dist fwupd-1.0.6/.travis.yml000066400000000000000000000004471325145456600147740ustar00rootroot00000000000000language: c sudo: required dist: trusty services: - docker env: - OS=fedora - OS=debian-x86_64 - OS=arch - OS=debian-s390x - OS=debian-i386 - OS=ubuntu-x86_64 install: - ./contrib/ci/generate_docker.py script: - docker run -e CI=true -t -v `pwd`/dist:/build/dist fwupd-$OS fwupd-1.0.6/.tx/000077500000000000000000000000001325145456600133675ustar00rootroot00000000000000fwupd-1.0.6/.tx/config000066400000000000000000000002111325145456600145510ustar00rootroot00000000000000[main] host = https://www.transifex.com [fwupd.master] file_filter = po/.po source_file = po/fwupd.pot source_lang = en type = PO fwupd-1.0.6/AUTHORS000066400000000000000000000000451325145456600137250ustar00rootroot00000000000000Richard Hughes fwupd-1.0.6/CODE_OF_CONDUCT.md000066400000000000000000000062231325145456600154600ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge 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. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities 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. 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. ## Scope 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. ## Enforcement 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. 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. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ fwupd-1.0.6/CONTRIBUTING.md000066400000000000000000000025101325145456600151050ustar00rootroot00000000000000Coding Style ============ The coding style to respect in this project is very similar to most GLib projects. In particular, the following rules are largely adapted from the PackageKit Coding Style. * 8-space tabs for indentation * Prefer lines of less than <= 80 columns * 1-space between function name and braces (both calls and macro declarations) * If function signature/call fits in a single line, do not break it into multiple lines * Prefer descriptive names over abbreviations (unless well-known) and shortening of names. e.g `device` not `dev` * Single statments inside if/else should not be enclosed by '{}' * Use comments to explain why something is being done, but also avoid over-documenting the obvious. Here is an example of useless comment: // Fetch the document fetch_the_document (); * Comments should not start with a capital letter or end with a full stop and should be C-style, not C++-style, e.g. `/* this */` not `// this` * Each object should go in a separate .c file and be named according to the class * Use g_autoptr() and g_autofree whenever possible, and avoid `goto out` error handling * Failing methods should return FALSE with a suitable `GError` set * Trailing whitespace is forbidden * Pointers should be checked for NULL explicitly, e.g. `foo != NULL` not `!foo` fwupd-1.0.6/COPYING000066400000000000000000000432541325145456600137210ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. fwupd-1.0.6/MAINTAINERS000066400000000000000000000000451325145456600143520ustar00rootroot00000000000000Richard Hughes fwupd-1.0.6/NEWS000066400000000000000000001012321325145456600133540ustar00rootroot00000000000000Version 1.0.6 ~~~~~~~~~~~~~ Released: 2018-03-12 New Features: - Add bash completion for fwupdmgr (Mario Limonciello) - Add support for newest Thunderbolt chips (Andrei Emeltchenko) - Allow all functions that take device arguments to be prompted (Mario Limonciello) - Allow devices to use the runtime version when in bootloader mode (Richard Hughes) - Allow overriding ESP mount point via conf file (Mario Limonciello) - Delete any old fwupdate capsules and efivars when launching fwupd (Richard Hughes) - Generate Vala bindings (Robert Ancell) Bugfixes: - Allow ctrl-d out of the prompt for devices (Mario Limonciello) - Allow to create package out of provided binary (Andrei Emeltchenko) - Correct handling of unknown Thunderbolt devices (Yehezkel Bernat) - Correctly detect new remotes that are manually copied (Richard Hughes) - Fix a crash related to when passing device to downgrade in CLI (Mario Limonciello) - Fix running the self tests when no fwupd is installed (Richard Hughes) - Fix Unifying signature writing and parsing for Texas bootloader (Ogier Bouvier) - Only send success and failure reports to the server (Richard Hughes) - Use a CNAME to redirect to the correct CDN for metadata (Richard Hughes) - Use a longer timeout when powering back the Thunderbolt device (Richard Hughes) Version 1.0.5 ~~~~~~~~~~~~~ Released: 2018-02-14 New Features: - Offer to reboot when processing an offline update (Richard Hughes) - Report the efivar, libsmbios and fwupdate library versions (Mario Limonciello) - Report Thunderbolt safe mode and SecureBoot status (Mario Limonciello) - Show the user a URL when they report a known problem (Richard Hughes) - Support split cabinet archives as produced by Windows Update (Richard Hughes) Bugfixes: - Be more careful deleting and modifying device history (Richard Hughes) - Clarify which devices don't have upgrades (Mario Limonciello) - Ensure the Thunderbolt version is xx.yy (Richard Hughes) - Fix a daemon warning when using fwupdmgr get-results (Richard Hughes) - Fix crasher with MST flashing (Mario Limonciello) - Fix DFU detach with newer releases of libusb (Richard Hughes) - Include the device VID and PID when generating the device-id (Richard Hughes) - Set the RemoteId when using GetDetails (Richard Hughes) - Stop matching 8bitdo DS4 controller VID/PID (Mario Limonciello) - Use help2man for dfu-tool and drop docbook dependencies (Mario Limonciello) - Use ngettext for any strings with plurals (Piotr Drąg) - Use the default value if ArchiveSizeMax is unspecified (Richard Hughes) Version 1.0.4 ~~~~~~~~~~~~~ Released: 2018-01-25 New Features: - Add D-Bus methods to get and modify the history information (Richard Hughes) - Allow the user to share firmware update success or failure (Richard Hughes) - Ask the user to refresh metadata when it is very old (Richard Hughes) - Store firmware update success and failure to a local database (Richard Hughes) Bugfixes: - Add a device name for locked UEFI devices (Mario Limonciello) - Allow each plugin to opt-in to the recoldplug action (Richard Hughes) - Fix firmware downloading using gnome-software (Richard Hughes) - Fix UX capsule reference to the one specified in efivar (Mario Limonciello) - Never add two devices to the daemon with the same ID (Richard Hughes) - Rescan supported flags when refreshing metadata (Richard Hughes) Version 1.0.3 ~~~~~~~~~~~~~ Released: 2018-01-09 New Features: - Add a new plugin to add support for CSR "Driverless DFU" (Richard Hughes) - Add initial SF30/SN30 Pro support (Mario Limonciello) - Support AppStream metadata with relative URLs (Richard Hughes) Bugfixes: - Add more metadata to the user-agent string (Richard Hughes) - Block owned Dell TPM updates (Mario Limonciello) - Choose the correct component from provides matches using requirements (Richard Hughes) - Do not try to parse huge compressed archive files (Richard Hughes) - Fix a double-free bug in the Udev code (Philip Withnall) - Handle Thunderbolt "native" mode (Yehezkel Bernat) - Use the new functionality in libgcab >= 1.0 to avoid writing temp files (Richard Hughes) Version 1.0.2 ~~~~~~~~~~~~~ Released: 2017-11-28 New Features: - Add a plugin for the Nitrokey Storage device (Richard Hughes) - Add support for the original AVR DFU protocol (Richard Hughes) - Allow different plugins to claim the same device (Richard Hughes) - Allow quirks to set common USB properties (Richard Hughes) - Move a common plugin functionality out to a new shared object (Richard Hughes) - Optionally delay the device removal for better replugging (Richard Hughes) - Set environment variables to allow easy per-plugin debugging (Richard Hughes) - Use a SHA1 hash for the internal DeviceID (Richard Hughes) Bugfixes: - Add quirk for AT32UC3B1256 as used in the RubberDucky (Richard Hughes) - Disable the dell plugin if libsmbios fails (Mario Limonciello) - Don't register for USB UDev events to later ignore them (Richard Hughes) - Fix a possible buffer overflow when debugging ebitdo devices (Richard Hughes) - Fix critical warning when more than one remote fails to load (Richard Hughes) - Fix DFU attaching AVR32 devices like the XMEGA (Richard Hughes) - Ignore useless Thunderbolt device types (Mario Limonciello) - Refactor ColorHug into a much more modern plugin (Richard Hughes) - Release the Steelseries interface if getting the version failed (Richard Hughes) - Remove autoconf-isms from the meson configure options (Richard Hughes) - Show a nicer error message if the requirement fails (Richard Hughes) - Sort the output of GetUpgrades correctly (Richard Hughes) Version 1.0.1 ~~~~~~~~~~~~~ Released: 2017-11-09 New Features: - Add support for HWID requirements (Richard Hughes) - Add support for programming various AVR32 and XMEGA parts using DFU (Richard Hughes) - Add the various DFU quirks for the Jabra Speak devices (Richard Hughes) - Allow specifying the output file type for 'dfu-tool read' (Richard Hughes) - Move the database of supported devices out into runtime loaded files (Richard Hughes) - Support the IHEX record type 0x05 (Richard Hughes) - Use help2man to generate the man page at build time (Richard Hughes) - Use the new quirk infrastructure for version numbers (Richard Hughes) Bugfixes: - Catch invalid Dell dock component requests (Mario Limonciello) - Correctly output Intel HEX files with > 16bit offset addresses (Richard Hughes) - Do not try to verify the element write if upload is unsupported (Richard Hughes) - Fix a double-unref when updating any 8Bitdo device (Richard Hughes) - Fix crash when enumerating with Dell dock connected but with no UEFI (Mario Limonciello) - Fix uploading large firmware files over DFU (Richard Hughes) - Format the BCD USB revision numbers correctly (Richard Hughes) - Guess the DFU transfer size if it is not specified (Richard Hughes) - Include the reset timeout as wValue to fix some DFU bootloaders (Richard Hughes) - Make the error message clearer when sans fonts are missing (Mario Limonciello) - Support devices with truncated DFU interface data (Richard Hughes) - Use the correct remote-specified username and passord when using fwupdmgr (Richard Hughes) - Use the correct wDetachTimeOut when writing DFU firmware (Richard Hughes) - Verify devices with legacy VIDs are actually 8Bitdo controllers (Richard Hughes) Version 1.0.0 ~~~~~~~~~~~~~ Released: 2017-10-09 Notes: - This release breaks API and ABI to remove deprecated symbols - libdfu is now not installed as a shared library New Features: - Add a human-readable title for each remote (Richard Hughes) - Add a method to return a list of upgrades for a specific device (Richard Hughes) - Add an 'Summary' and 'Icons' properties to each device (Richard Hughes) - Add FuDeviceLocker to simplify device open/close lifecycles (Richard Hughes) - Add functionality to blacklist Dell HW with problems (Mario Limonciello) - Add fu_plugin_check_supported() (Richard Hughes) - Add fwupd_remote_get_checksum() to use in client programs (Richard Hughes) - Add ModifyRemote as an easy way to enable and disable remotes (Richard Hughes) - Add the plugin documentation to the main gtk-doc (Richard Hughes) - Allow plugins to depend on each other (Richard Hughes) - Disable the fallback USB plugin (Richard Hughes) - Parse the SMBIOS v2 and v3 DMI tables directly (Richard Hughes) - Support uploading the UEFI firmware splash image (Richard Hughes) - Use the intel-wmi-thunderbolt kernel module to force power (Mario Limonciello) Bugfixes: - Only run SMI to toggle host MST GPIO on Dell systems with host MST (Mario Limonciello) - Disable unifying support if no CONFIG_HIDRAW support (Richard Hughes) - Do not auto-open all USB devices at startup (Richard Hughes) - Do not fail to load the daemon if cached metadata is invalid (Richard Hughes) - Do not use system-specific infomation for UEFI PCI devices (Richard Hughes) - Fix a crash when using fu_plugin_device_add_delay() (Richard Hughes) - Fix the libdfu self test failure on s390 and ppc64 (Richard Hughes) - Fix various printing issues with the progressbar (Richard Hughes) - Generate the LD script from the GObject introspection data (Richard Hughes) - Never fallback to an offline update from client code (Richard Hughes) - Only set the Dell coldplug delay when we know we need it (Mario Limonciello) - Prefer to use HWIDs to get DMI keys and DE table (Mario Limonciello) Version 0.9.7 ~~~~~~~~~~~~~ Released: 2017-09-01 New Features: - Add a configure switch for the LVFS remotes (Richard Hughes) - Add a FirmwareBaseURI parameter to the remote config (Richard Hughes) - Add a firmware builder that uses bubblewrap (Richard Hughes) - Add a python script to create fwupd compatible cab files from Microsoft .exe files (Max Ehrlich) - Add a thunderbolt plugin for new kernel interface (Christian Kellner, Yehezkel Bernat) - Allow plugins to get DMI data from the hardware in a safe way (Richard Hughes) - Allow plugins to set metadata on devices created by other plugins (Richard Hughes, Mario Limonciello) - Optionally install the LVFS PKCS7 root certificate (Richard Hughes) - Optionally use GnuTLS to verify PKCS7 certificates (Richard Hughes) Bugfixes: - Add back options for HAVE_SYNAPTICS and HAVE_THUNDERBOLT (Mario Limonciello) - Allow configuring systemd and udev directories (Mario Limonciello) - Enable C99 support in meson.build (Philip Withnall) - Fix an incomplete cipher when using XTEA on data not in 4 byte chunks (Richard Hughes) - Fix minor const-correctness issues (Philip Withnall) - Implement thunderbolt image validation (Yehezkel Bernat, Christian Kellner) - Remove the confusing ALLOW_OFFLINE and ALLOW_ONLINE flags (Richard Hughes) - Show a bouncing progress bar if the percentage remains at zero (Richard Hughes) - Use a hwid to match supported systems for synapticsmst (Mario Limonciello) - Use the new bootloader PIDs for Unifying pico receivers (Richard Hughes) - When thunderbolt is in safe mode on a Dell recover using SMBIOS (Mario Limonciello) Version 0.9.6 ~~~~~~~~~~~~~ Released: 2017-08-03 New Features: - Add DfuPatch to support forward-only firmware patching (Richard Hughes) - Add --version option to fwupdmgr (Richard Hughes, Mario Limonciello) - Display all errors recorded by efi_error tracing (Mario Limonciello) - Make building introspection optional (Patrick Ohly) - Support embedded devices with local firmware metadata (Richard Hughes) Bugfixes: - Check all the device GUIDs against the blacklist when added (Richard Hughes) - Correct a memory leak in Dell plugin (Mario Limonciello, Richard Hughes) - Default to "en" for UEFI capsule graphics (Mario Limonciello) - Don't log a warning when an unknown unifying report is parsed (Richard Hughes) - Enable test suite via /etc/fwupd.conf (Mario Limonciello) - Fix a hang on 32 bit computers (Richard Hughes) - Fix compilation of the policy on a variety of configurations (Mario Limonciello) - Fix UEFI crash when the product name is NULL (Richard Hughes) - Make flashing ebitdo devices work with fu-ebitdo-tool (Chris Lee) - Make messages from installing capsules useful (Mario Limonciello) - Make sure the unifying percentage completion goes from 0% to 100% (Richard Hughes) - Run the plugin coldplug methods in a predictable order (Richard Hughes) - Test UEFI for kernel support during coldplug (Mario Limonciello) - Use new GUsb functionality to fix flashing Unifying devices (Richard Hughes) Version 0.9.5 ~~~~~~~~~~~~~ Released: 2017-07-04 New Features: - Add a get-remotes command to fwupdmgr (Richard Hughes) - Add a plugin to get the version of the AMT ME interface (Richard Hughes) - Add Arch Linux to CI (Bruno Pagani) - Add some installed tests flashing actual hardware (Richard Hughes) - Allow flashing Unifying devices in bootloader modes (Richard Hughes) - Allow ordering the metadata remotes (Richard Hughes) Bugfixes: - Do not check the runtime if the DFU device is in bootloader mode (Richard Hughes) - Do not unlock devices when doing VerifyUpdate (Richard Hughes) - Filter by Unifying SwId when making HID++2.0 requests (Richard Hughes) - Fix downgrades when version_lowest is set (Richard Hughes) - Fix the self tests when running on PPC64 big endian (Richard Hughes) - Move the remotes parsing from the client to the server (Richard Hughes) - Split up the Unifying HID++2.0 and HID++1.0 functionality (Richard Hughes) - Store the metadata files rather than merging to one store (Richard Hughes) - Use a longer timeout for some Unifying operations (Richard Hughes) - Use the UFY DeviceID prefix for Unifying devides (Richard Hughes) Version 0.9.4 ~~~~~~~~~~~~~ Released: 2017-06-15 New Features: - Add installed tests that use the daemon (Richard Hughes) - Add the ability to restrict firmware to specific vendors (Richard Hughes) - Enable Travis CI for Fedora and Debian (Richard Hughes, Mario Limonciello) - Export some more API for dealing with checksums (Richard Hughes) - Generate a images for status messages during system firmware update (Peter Jones) - Show progress download when refreshing metadata (Richard Hughes) Bugfixes: - Compile with newer versions of meson (Richard Hughes, Mario Limonciello) - Ensure that firmware provides are legal GUIDs (Richard Hughes) - Fix a common crash when refreshing metadata (Richard Hughes) - Use the correct type signature in the D-Bus introspection file (Richard Hughes) Version 0.9.3 ~~~~~~~~~~~~~ Released: 2017-06-07 New Features: - Add a 'downgrade' command to fwupdmgr (Richard Hughes) - Add a 'get-releases' command to fwupdmgr (Richard Hughes) - Add support for ConsoleKit2 (Eric Koegel) - Add support for Microsoft HardwareIDs (Richard Hughes) - Allow downloading metadata from more than just the LVFS (Richard Hughes) - Allow multiple checksums on devices and releases (Richard Hughes) Bugfixes: - Allow to specify bindir (Timo Gurr) - Correctly open Unifying devices with original factory firmware (Richard Hughes) - Deprecate some of the old FwupdResult API (Richard Hughes) - Do not copy the origin from the new metadata file (Richard Hughes) - Do not expect a Unifying reply when issuing a REBOOT command (Richard Hughes) - Do not re-download firmware that exists in the cache (Richard Hughes) - Fix a problem when testing for a Dell system (Mario Limonciello) - Fix flashing new firmware to 8bitdo controllers (Richard Hughes) - Increase minimum required AppStream-Glib version to 0.6.13 (Chris Mayo) - Make documentation and man pages optional (Chris Mayo) - Make systemd dependency at least version 231 (Mario Limonciello) - Only decompress the firmware after the signature check (Richard Hughes) - Remove 'lib' prefix when looking for libraries (Mirco Tischler) - Return the remote ID when getting updates about hardware (Richard Hughes) - Send the daemon the remote ID when sending firmware metadata (Richard Hughes) Version 0.9.2 ~~~~~~~~~~~~~ Released: 2017-05-22 New Features: - Add support for Unifying DFU features (Richard Hughes) Bugfixes: - Do not spew a critial warning when parsing an invalid URI (Richard Hughes) - Ensure device is closed if did not complete setup (Richard Hughes) - Ensure steelseries device is closed if it returns an invalid packet (Richard Hughes) - Fix man page installation location (Mario Limonciello) - Ignore spaces in the Unifying version prefix (Richard Hughes) - Set HAVE_POLKIT_0_114 when polkit is newer than 0.114 (Moritz Kiefer) Version 0.9.1 ~~~~~~~~~~~~~ Released: 2017-04-28 New Features: - Add a config option to allow runtime disabling plugins by name (Richard Hughes) - Add the Meson build system and remove autotools (Richard Hughes) - Support signed Intel HEX files (Richard Hughes) Bugfixes: - Add DFU quirk for OpenPICC and SIMtrace (Richard Hughes) - Create directories in /var/cache as required (Richard Hughes) - Refactor the unifying plugin now we know more about the hardware (Richard Hughes) - Set the source origin when saving metadata (Richard Hughes) - Support proxy servers in fwupdmgr (Richard Hughes) - Use a 60 second timeout on all client downloads (Richard Hughes) Version 0.8.1 ~~~~~~~~~~~~~ Released: 2017-02-27 Bugfixes: - Adjust systemd confinement restrictions (Mario Limonciello, Richard Hughes) - Do not hardcode docbook2man path (Kai Krakow) - Don't initialize libsmbios on unsupported systems (Mario Limonciello) - Fix a crash when enumerating devices on a Dell WLD15 (Richard Hughes) - Fix compiler warnings (Kai Krakow) - Fix fwupdmgr timeout with missing pending database (Richard Hughes) Version 0.8.0 ~~~~~~~~~~~~~ Released: 2017-02-08 New Features: - Add a set of vfuncs that are run before and after a device update (Richard Hughes) - Add Dell-specific functionality to allow other plugins turn on TBT/GPIO (Mario Limonciello) - Add support for Intel Thunderbolt devices (Richard Hughes, Mario Limonciello) - Add support for Logitech Unifying devices (Richard Hughes) - Add support for Synaptics MST cascades hubs (Mario Limonciello) - Add support for the Altus-Metrum ChaosKey device (Richard Hughes) - Add VerifyUpdate to update the device checksums server-side (Richard Hughes) - Allow the metadata to match a version of fwupd and the existing fw version (Richard Hughes) Bugfixes: - Add a new method for forcing a controller to flash mode (Mario Limonciello) - Always make sure we're getting a C99 compiler (Richard Hughes) - Close USB devices before error returns (Tsunghan Liu) - Don't read data from some DfuSe targets (Richard Hughes) - Include all debug messages when run with --verbose (Richard Hughes) - Return the pending UEFI update when not on AC power (Richard Hughes) - Use a heuristic for the start address if the firmware has no DfuSe footer (Richard Hughes) - Use more restrictive settings when running under systemd (Richard Hughes, Mario Limonciello) Version 0.7.5 ~~~~~~~~~~~~~ Released: 2016-10-19 New Features: - Add a 'replace-data' command to dfu-tool (Richard Hughes) - Use an animated progress bar when performing DFU operations (Richard Hughes) Bugfixes: - Add quirks for HydraBus as it does not have a DFU runtime (Richard Hughes) - Don't create the UEFI dummy device if the unlock will happen on next boot (Richard Hughes) - Enable hardening flags on more binaries (Mario Limonciello) - Fix an assert when unlocking the dummy ESRT device (Richard Hughes) - Fix writing firmware to devices using the ST reference bootloader (Richard Hughes) - Match the Dell TB16 device (Mario Limonciello) - Re-get the quirks when the DfuDevice gets a new GUsbDevice (Richard Hughes) - Show the nicely formatted target name for DfuSe devices (Richard Hughes) - Verify devices support updating in mode they are called (Mario Limonciello) Version 0.7.4 ~~~~~~~~~~~~~ Released: 2016-09-19 New Features: - Add dfu_firmware_add_symbol() (Richard Hughes) - Allow the argument to 'dfu-tool set-release' be major.minor (Richard Hughes) - Load the Altos USB descriptor from ELF files (Richard Hughes) - Support writing the IHEX symbol table (Richard Hughes) Bugfixes: - Add a fallback for older appstream-glib releases (Richard Hughes) - Fix a possible crash when uploading firmware files using libdfu (Richard Hughes) - Fix libfwupd self tests when a host-provided fwupd is not available (Richard Hughes) - Show the human-readable version in the 'dfu-tool dump' output (Richard Hughes) - Write the ELF files with the correct section type (Richard Hughes) Version 0.7.3 ~~~~~~~~~~~~~ Released: 2016-08-29 New Features: - Add a set-address and set-target-size commands to dfu-util (Richard Hughes) - Add a small library for talking with 0bitdo hardware (Richard Hughes) - Add Dell TPM and TB15/WD15 support via new Dell provider (Mario Limonciello) - Add FU_DEVICE_FLAG_NEEDS_BOOTLOADER (Richard Hughes) - Add fwupd_client_get_status() (Richard Hughes) - Add fwupd_result_get_unique_id() (Richard Hughes) - Add initial ELF reading and writing support to libdfu (Richard Hughes) - Add support for installing multiple devices from a CAB file (Richard Hughes) - Allow providers to export percentage completion (Richard Hughes) - Show a progress notification when installing firmware (Richard Hughes) - Show the vendor flashing instructions when installing (Richard Hughes) Bugfixes: - Add XPS 9250 to Dell TPM modeswitch blacklist (Mario Limonciello) - Allow blacklisting devices by their GUID (Richard Hughes) - Conditionally enable all providers based upon installed (Mario Limonciello) - Display flashes left in results output when it gets low (Mario Limonciello) - Do not attempt to add DFU devices not in runtime mode (Richard Hughes) - Do not use the deprecated GNOME_COMPILE_WARNINGS (Richard Hughes) - Don't fail while checking versions or locked state (Richard Hughes) - Embed fwupd version in generated documentation (Mario Limonciello) - Ensure the ID is set when getting local firmware details (Richard Hughes) - Fix gtk-doc build when srcdir != builddir (Ting-Wei Lan) - Fix libdfu hang when parsing corrupt IHEX files (Richard Hughes) - Ignore devices that do not add at least one GUID (Richard Hughes) - In get-details output, display the blob filename (Mario Limonciello) - Save the unique ID in the pending database (Richard Hughes) - Support the 'DEVO' cipher kind in libdfu (Richard Hughes) - Switch to the Amazon S3 CDN for firmware metadata (Richard Hughes) - Update fwupdmgr manpage for new commands and arguments (Mario Limonciello) - Use a private gnupg key store (Richard Hughes) - Use the correct firmware when installing a composite device (Richard Hughes) - Use the SHA1 hash of the local file data as the origin (Richard Hughes) Version 0.7.2 ~~~~~~~~~~~~~ Released: 2016-06-13 New Features: - Add a GetDetailsLocal() method to eventually replace GetDetails() (Richard Hughes) - Add fu_device_get_alternate() (Richard Hughes) - Allow devices to have multiple assigned GUIDs (Richard Hughes) - Allow metainfo files to match only specific revisions of devices (Richard Hughes) - Show the DFU protocol version in 'dfu-tool list' (Richard Hughes) Bugfixes: - Enforce allowing providers to take away flash abilities (Mario Limonciello) - Only claim the DFU interface when required (Richard Hughes) - Only return updatable devices from GetDevices() (Richard Hughes) Version 0.7.1 ~~~~~~~~~~~~~ Released: 2016-05-13 New Features: - Add a --force flag to override provider warnings (Mario Limonciello) - Add device-added, device-removed and device-changed signals (Richard Hughes) - Add dfu_image_get_element_default() (Richard Hughes) - Add for a new device field "Flashes Left" (Mario Limonciello) - Add fwupd_client_connect() (Richard Hughes) - Add the 'monitor' debugging command for fwupdmgr (Richard Hughes) - Add the 'supported' flag to the FuDevice (Richard Hughes) Bugfixes: - Add summary and name field for Rival SteelSeries (Mario Limonciello) - Fix a critical warning when restarting the daemon (Richard Hughes) - Fix BE issues when reading and writing DFU files (Mario Limonciello, Richard Hughes) - Make the device display name nicer (Richard Hughes, Richard Hughes) - Match the AppStream metadata after a device has been added (Richard Hughes) - Remove non-interactive pinentry setting from fu-keyring (Mario Limonciello) - Return all update descriptions newer than the installed version (Richard Hughes) - Set the device description when parsing local firmware files (Richard Hughes) Version 0.7.0 ~~~~~~~~~~~~~ Released: 2016-04-01 New Features: - Add a version plugin for SteelSeries hardware (Richard Hughes) - Add FwupdClient and FwupdResult to libfwupd (Richard Hughes) - Generate gtk-doc documentation for libfwupd (Richard Hughes) - Return the device flags when getting firmware details (Richard Hughes) - Support other checksum kinds (Richard Hughes) Bugfixes: - Add Alienware to the version quirk table (Mario Limonciello) - Allow the test suite to run in %check (Richard Hughes) - Do not return updates that require AC when on battery (Richard Hughes) - Do not use /tmp for downloaded files (Richard Hughes) - Test that GPG key import actually was successful (Mario Limonciello) Version 0.6.3 ~~~~~~~~~~~~~ Released: 2016-03-14 New Features: - Add an unlock method for devices (Richard Hughes) - Add a simple plugin infrastructure (Richard Hughes) - Add ESRT enable method into UEFI provider (Mario Limonciello) - Install the hardcoded firmware AppStream file (Richard Hughes) Bugfixes: - Correct the BCD version number for DFU 1.1 (Richard Hughes) - Do not use deprecated API from libappstream-glib (Richard Hughes) - Ignore the DFU runtime on the DW1820A (Richard Hughes) - Only read PCI OptionROM firmware when devices are manually unlocked (Richard Hughes) - Require AC power before scheduling some types of firmware update (Richard Hughes) - Show ignored DFU devices in dfu-util, but not in fwupd (Richard Hughes) Version 0.6.2 ~~~~~~~~~~~~~ Released: 2016-02-12 New Features: - Add 'Created' and 'Modified' properties on managed devices (Richard Hughes) Bugfixes: - Fix get-results for UEFI provider (Mario Limonciello) - Support vendor-specific UEFI version encodings (Richard Hughes) Version 0.6.1 ~~~~~~~~~~~~~ Released: 2016-01-19 Bugfixes: - Always persist ColorHug devices after replug (Richard Hughes) - Do not misdetect different ColorHug devices (Richard Hughes) - Only dump the profiling data when run with --verbose (Richard Hughes) Version 0.6.0 ~~~~~~~~~~~~~ Released: 2015-12-07 Notes: - This release adds a new GObject library called libdfu and a command line client called dfu-tool. This is a low-level tool used to upgrade USB device firmware and can either be shipped in the same package as fwupd or split off as separate subpackages. New Features: - Add support for automatically updating USB DFU-capable devices (Richard Hughes) Bugfixes: - Emit the changed signal after doing an update (Richard Hughes) - Export the AppStream ID when returning device results (Richard Hughes) - Fix compile with --disable-shared (Richard Hughes) - Use new API available in fwup 0.5 (Richard Hughes, Mario Limonciello) - Use the same device identification string format as Microsoft (Richard Hughes) Version 0.5.3 ~~~~~~~~~~~~~ Released: 2015-11-05 Bugfixes: - Avoid seeking when reading the file magic during refresh (Richard Hughes) - Do not assume that the compressed XML data will be NUL terminated (Richard Hughes) - Use the correct user agent string for fwupdmgr (Richard Hughes) Version 0.5.2 ~~~~~~~~~~~~~ Released: 2015-10-28 New Features: - Add profiling data to debug slow startup times (Richard Hughes) - Support cabinet archives files with more than one firmware (Richard Hughes) Bugfixes: - Add the update description to the GetDetails results (Richard Hughes) - Clear the in-memory firmware store only after parsing a valid XML file (Richard Hughes) - Ensure D-Bus remote errors are registered at fwupdmgr startup (Richard Hughes) - Fix verify-update to produce components with the correct provide values (Richard Hughes) - Require appstream-glib 0.5.1 (Mirco Tischler) - Show the dotted-decimal representation of the UEFI version number (Richard Hughes) - When the version is from the 'FW' extension do not cache the device (Richard Hughes) Version 0.5.1 ~~~~~~~~~~~~~ Released: 2015-09-21 Bugfixes: - Fix the error message when no devices can be updated (Richard Hughes) - Fix reading symlink to prevent crash with some compilers (Kalev Lember) Version 0.5.0 ~~~~~~~~~~~~~ Released: 2015-09-15 New Features: - Raise the dep on GLib to support and use g_autoptr() (Richard Hughes) Bugfixes: - Do not merge existing firmware metadata (Richard Hughes) - Do not reboot if racing with the PackageKit offline update mechanism (Richard Hughes) Version 0.1.6 ~~~~~~~~~~~~~ Released: 2015-09-10 New Features: - Remove fwsignd, we have the LVFS now (Richard Hughes) Bugfixes: - Add application metadata when getting the updates list (Richard Hughes) - Depend on appstream-glib >= 0.5.0 (Richard Hughes) - Don't apply firmware if something else is processing the update (Richard Hughes) - Install fwupd into /usr/lib/$(triplet)/fwupd instead (Mario Limonciello) - Simplify the version properties on devices to avoid complexity (Richard Hughes) - Update the offline update service to invoke right command (Kalev Lember) - Use the new secure metadata URI (Richard Hughes) Version 0.1.5 ~~~~~~~~~~~~~ Released: 2015-08-12 Notes: - For the device verification code to work correctly you need at least libappstream-glib 0.5.0 installed. New Features: - Add a Raspberry Pi firmware provider (Richard Hughes) - Add a simple config file to store the correct LVFS download URI (Richard Hughes) - Make parsing the option ROM runtime optional (Richard Hughes) Bugfixes: - Allow fwupd to be autostarted by systemd (Richard Hughes) - Allow no arguments to 'fwupdmgr verify-update' and use sane defaults (Richard Hughes) - Devices with option ROM are always internal (Richard Hughes) - Do not pre-convert the update description from AppStream XML (Richard Hughes) - Fix validation of written firmware (Richard Hughes) - Move the verification and metadata matching phase to the daemon (Richard Hughes) - Sign the test binary with the correct key (Richard Hughes) - Use the AppStream 0.9 firmware specification by default (Richard Hughes) Version 0.1.4 ~~~~~~~~~~~~~ Released: 2015-07-25 Notes: - In this release we've moved the LVFS website to the fwupd project and made them work really well together. To update all the firmware on your system is now just a case of "fwupdmgr refresh && fwupdmgr update" - We've also added verification of BIOS and PCI ROM firmware, which may be useful for forensics or to verify that system updates have been applied. New Features: - Actually parse the complete PCI option ROM (Richard Hughes) - Add a 'fwupdmgr update' command to update all devices to latest versions (Richard Hughes) - Add a simple signing server that operates on .cab files (Richard Hughes) - Add a 'verify' command that verifies the cryptographic hash of device firmware (Richard Hughes) - Allow clients to add new firmware metadata to the system cache (Richard Hughes) - Move GetUpdates to the daemon (Richard Hughes) - Move the LVFS website to the fwupd project (Richard Hughes) Bugfixes: - Accept multiple files at one time when using fwupdmgr dump-rom (Richard Hughes) - Automatically download metadata using fwupdmgr if required (Richard Hughes) - Do not return NULL as a gboolean (Thomas Hindoe Paaboel Andersen) - Don't call efibootmgr after fwupdate (Mario Limonciello) - Fallback to offline install when calling the update argument (Mario Limonciello) - Fix Intel VBIOS detection on Dell hardware (Richard Hughes) - Reload appstream data after refreshing (Mario Limonciello) - Use the new LVFS GPG key (Richard Hughes) - Fix build: libgusb is required even without colorhug support (Jussi Kukkonen) Version 0.1.3 ~~~~~~~~~~~~~ Released: 2015-05-28 New Features: - Get the firmware version from the device descriptors (Richard Hughes) - Run the offline actions using systemd when required (Richard Hughes) - Support OpenHardware devices using the fwupd vendor extensions (Richard Hughes) Bugfixes: - Add an UNKNOWN status so we can return meaningful enum values (Richard Hughes) - Coldplug the devices before acquiring the well known name (Richard Hughes) Version 0.1.2 ~~~~~~~~~~~~~ Released: 2015-04-22 - Add some guidelines for vendors to README (Richard Hughes) - Only allow signed firmware to be upgraded without a password (Richard Hughes) Version 0.1.1 ~~~~~~~~~~~~~ Released: 2015-03-23 New Features: - Add a 'get-updates' command to fwupdmgr (Richard Hughes) - Add and document the offline-update lifecycle (Richard Hughes) - Create a libfwupd shared library (Richard Hughes) Bugfixes: - Create runtime directories if they do not exist (Richard Hughes) - Do not crash when there are no devices to return (Richard Hughes) Version 0.1.0 ~~~~~~~~~~~~~ Released: 2015-03-16 Notes: - fwupd is a simple daemon to allow session software to update firmware. fwupd-1.0.6/README.md000066400000000000000000000056721325145456600141470ustar00rootroot00000000000000fwupd ===== [![Build Status](https://travis-ci.org/hughsie/fwupd.png?branch=master)](https://travis-ci.org/hughsie/fwupd) [![Coverity Scan Build Status](https://scan.coverity.com/projects/10744/badge.svg)](https://scan.coverity.com/projects/10744) This project aims to make updating firmware on Linux automatic, safe and reliable. Additional information is available at the website: https://fwupd.org ## Compiling The most up to date compilation instructions are available in the [Wiki](https://github.com/hughsie/fwupd/wiki/Compilation) LVFS ---- This project is configured by default to download firmware from the [Linux Vendor Firmware Service (LVFS)](https://fwupd.org/). This service is available to all OEMs and firmware creators who would like to make their firmware available to Linux users. You can find more information about the technical details of creating a firmware capsule in the hardware vendors section of the [fwupd website](https://fwupd.org). Basic usage flow (command line) ------------------------------ If you have a device with firmware supported by fwupd, this is how you will check for updates and apply them using fwupd's command line tools. `# fwupdmgr get-devices` This will display all devices detected by fwupd. `# fwupdmgr refresh` This will download the latest metadata from LVFS. `# fwupdmgr get-updates` If updates are available for any devices on the system, they'll be displayed. `# fwupdmgr update` This will download and apply all updates for your system. * Updates that can be applied live will be done immediately. * Updates that run at bootup will be staged for the next reboot. You can find more information about the update workflow in the end users section of the [fwupd website](https://fwupd.org). Reporting status --------------- fwupd will encourage users to report both successful and failed updates back to LVFS. This is an optional feature, but encouraged as it provides valuable feedback to LVFS administrators and OEM developers regarding firmware update process efficacy. The privacy policy regarding this data can be viewed on the [fwupd website](https://fwupd.org/privacy). To report the status of an update run: `# fwupdmgr report-history` To clear the local history of updates: `# fwupdmgr clear-history` Only updates that were distributed from the LVFS will be reported to the LVFS. Other frontends ------------------- Currently [GNOME Software](https://wiki.gnome.org/Apps/Software) is the only graphical frontend available. When compiled with firmware support, it will check for updates periodically and automatically download firmware in the background. After the firmware has been downloaded a popup will be displayed in Gnome Software to perform the update. On Dell IoT gateways, [Wyse Cloud Client Manager (CCM)](http://www.dell.com/us/business/p/wyse-cloud-client-manager/pd) has been built with fwupd support. The remote administration interface can be used to download and deploy firmware updates. fwupd-1.0.6/RELEASE000066400000000000000000000016751325145456600136720ustar00rootroot00000000000000fwupd Release Notes 1. Write NEWS entries for fwupd in the same format as usual. git shortlog 1.0.5.. | grep -i -v trivial | grep -v Merge > NEWS.new Version 1.0.6 ~~~~~~~~~~~~~ Released: 2018-xx-xx New Features: Bugfixes: Update translations: ninja-build fwupd-pot tx push --source tx pull --all --minimum-perc=5 git add ../po/*.po 2. Commit changes to git: # MAKE SURE THESE ARE CORRECT export release_ver="1.0.6" git commit -a -m "Release fwupd ${release_ver}" git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}" git push --tags git push 3. Generate the tarball: ninja dist 3a. Generate the additon verification metadata gpg -b -a meson-dist/fwupd-${release_ver}.tar.xz 4. Upload tarball: scp meson-dist/fwupd-${release_ver}.tar.* hughsient@people.freedesktop.org:~/public_html/releases 5. Do post release version bump in meson.build 6. Commit changes: git commit -a -m "trivial: post release version bump" git push fwupd-1.0.6/contrib/000077500000000000000000000000001325145456600143165ustar00rootroot00000000000000fwupd-1.0.6/contrib/PKGBUILD000066400000000000000000000014571325145456600154510ustar00rootroot00000000000000# Maintainer: Bruno Pagani (a.k.a. ArchangeGabriel) # Contributor: Mirco Tischler pkgname=fwupd pkgver=#VERSION# pkgrel=1 pkgdesc='A simple daemon to allow session software to update firmware' arch=('i686' 'x86_64') url='https://github.com/hughsie/fwupd' license=('GPL2') depends=('appstream-glib' 'fwupdate' 'colord') makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git' 'python-cairo' 'ttf-dejavu' 'adobe-source-han-sans-cn-fonts' 'python-gobject' 'vala') build() { cd ${pkgname} if [ -n "$CI" ]; then export CI="--werror" fi arch-meson -D b_lto=false $CI ../build ninja -v -C ../build } check() { ninja -C build test } package() { DESTDIR="${pkgdir}" ninja -C build install } fwupd-1.0.6/contrib/README.md000066400000000000000000000041331325145456600155760ustar00rootroot00000000000000Distribution packages ===================== The relevant packaging necessary to generate *RPM*, *DEB* and *PKG* distribution packages is contained here. It is used regularly for continuous integration using [Travis CI](http://travis-ci.org). The generated packages can be used on a distribution such as Fedora, Debian, Ubuntu or Arch Linux. The build can be performed using Linux containers with [Docker](https://www.docker.com). ## RPM packages A Dockerfile for Fedora can be generated in `contrib`. To prepare the Docker container run this command: ``` OS=fedora ./generate_docker.py ``` To build the RPMs run this command (from the root of your git checkout): ``` docker run -t -v `pwd`:/build fwupd-fedora ``` RPMs will be made available in your working directory when complete. ## DEB packages A Dockerfile for Debian or Ubuntu can be generated in `contrib`. To prepare the Docker container run one of these commands: ``` OS=debian-x86_64 ./generate_docker.py OS=debian-i386 ./generate_docker.py OS=ubuntu-x86_64 ./generate_docker.py ``` To build the DEBs run one of these commands (from the root of your git checkout): ``` docker run -t -v `pwd`:/build fwupd-debian-x86_64 docker run -t -v `pwd`:/build fwupd-debian-i386 docker run -t -v `pwd`:/build fwupd-ubuntu-x86_64 ``` DEBs will be made available in your working directory when complete. ## PKG packages A Dockerfile for Arch can be generated in `contrib`. To prepare the Docker container run this command: ``` OS=arch ./generate_docker.py ``` To build the PKGs run this command (from the root of your git checkout): ``` docker run -t -v `pwd`:/build fwupd-arch ``` PKGs will be made available in your working directory when complete. ## Additional packages Submissions for generating additional packages for other distribution mechanisms are also welcome. All builds should occur in Docker containers. Please feel free to submit the following: * Dockerfile for the container for your distro * Relevant technical packaging scripts (such as ebuilds, spec file etc) * A shell script that can be launched in the container to generate distribution packages fwupd-1.0.6/contrib/ci/000077500000000000000000000000001325145456600147115ustar00rootroot00000000000000fwupd-1.0.6/contrib/ci/Dockerfile-arch.in000066400000000000000000000005271325145456600202270ustar00rootroot00000000000000FROM archlinux/base %%%OS%%% ENV LANG en_US.UTF-8 ENV LC_ALL en_US.UTF-8 RUN echo fubar > /etc/machine-id RUN rm /usr/share/libalpm/hooks/package-cleanup.hook RUN echo fubar > /etc/machine-id RUN pacman -Syu --noconfirm archlinux-keyring %%%INSTALL_DEPENDENCIES_COMMAND%%% RUN mkdir /build WORKDIR /build COPY . . CMD ["./contrib/ci/arch.sh"] fwupd-1.0.6/contrib/ci/Dockerfile-debian.in000066400000000000000000000003261325145456600205310ustar00rootroot00000000000000FROM %%%ARCH_PREFIX%%%debian:testing %%%OS%%% RUN echo fubar > /etc/machine-id %%%ARCH_SPECIFIC_COMMAND%%% %%%INSTALL_DEPENDENCIES_COMMAND%%% RUN mkdir /build WORKDIR /build COPY . . CMD ["./contrib/ci/debian.sh"] fwupd-1.0.6/contrib/ci/Dockerfile-fedora.in000066400000000000000000000004661325145456600205540ustar00rootroot00000000000000FROM fedora:26 %%%OS%%% ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 RUN echo fubar > /etc/machine-id RUN dnf --enablerepo=updates-testing -y update RUN echo fubar > /etc/machine-id %%%INSTALL_DEPENDENCIES_COMMAND%%% RUN mkdir /build WORKDIR /build COPY . . CMD ["./contrib/ci/fedora.sh"] fwupd-1.0.6/contrib/ci/Dockerfile-ubuntu.in000066400000000000000000000003031325145456600206240ustar00rootroot00000000000000FROM ubuntu:devel %%%OS%%% RUN echo fubar > /etc/machine-id %%%ARCH_SPECIFIC_COMMAND%%% %%%INSTALL_DEPENDENCIES_COMMAND%%% RUN mkdir /build WORKDIR /build COPY . . CMD ["./contrib/ci/ubuntu.sh"] fwupd-1.0.6/contrib/ci/README.md000066400000000000000000000076401325145456600161770ustar00rootroot00000000000000Continuous Integration ====================== Continuous integration for fwupd is provided by [Travis CI](https://travis-ci.org/hughsie/fwupd). By using Travis CI, builds are exercised across a variety of environments attempting to maximize code coverage. For every commit or pull request 6 builds are performed: Fedora (x86_64) ------ * A fully packaged RPM build with all plugins enabled * Compiled under gcc * Tests with -Werror enabled * Tests with the built in local test suite for all plugins. * All packages are installed * An installed testing run with the "test" plugin and pulling from LVFS. Debian testing (x86_64) ------ * A fully packaged DEB build with all plugins enabled * Compiled under gcc * Tests with -Werror enabled * Tests with the built in local test suite for all plugins. * All packages are installed * An installed testing run with the "test" plugin and pulling from LVFS. * All packages are removed Debian testing (i386) ------ * A fully packaged DEB build with all plugins enabled * Compiled under gcc * Tests with -Werror enabled * Tests with the built in local test suite for all plugins. * All packages are installed * An installed testing run with the "test" plugin and pulling from LVFS. * All packages are removed Ubuntu devel release (x86_64) ------ * A fully packaged DEB build with all plugins enabled * Compiled under clang * Tests without -Werror enabled * Tests with the built in local test suite for all plugins. * All packages are installed * An installed testing run with the "test" plugin and pulling from LVFS. * All packages are removed Debian testing (cross compile s390x) ------ * Not packaged * Compiled under gcc * Tests with -Werror enabled * Runs local test suite using qemu-user Arch Linux (x86_64) ---------- * A fully packaged pkg build with all plugins enabled * Compiled under gcc * Tests with -Werror enabled * Compile with the deprecated USB plugin enabled * Tests with the built in local test suite for all plugins. * All packages are installed Adding a new target =================== Dockerfiles are generated dynamically by the python script ```generate_dockerfile.py```. The python script will recognize the environment variable ***OS*** to determine what target to generate a Dockerfile for. dependencies.xml ---------------- Initially the python script will read in ___dependencies.xml___ to generate a dependency list for that target. The XML is organized by a top level element representing the dependencies needed for building fwupd. The child elements represent individual dependencies for all distributions. * This element has an attribute ***id*** that represents the most common package name used by distributions * This element has an attribute ***type*** that reprsents if the package is needed at build time or runtime. Each dependency then has a mapping to individual distributions (___distro___). * This element has an attribute ***id*** that represents the distribution. Each distribution will have ***package*** elements and ***control*** elements. ***Package*** elements represent the name of the package needed for the distribution. * An optional attribute ***variant*** represents one deviation of that distribution. For example building a specific architecture or with a different compiler. * If the ***package*** element is empty the ***id*** of the ______ element will be used. ***Control*** elements represent specific requirements associated to a dependency. They will contain elements with individual details. * ___version___ elements represent a minimum version to be installed * ___inclusive___ elements represent an inclusive list of architectures to be installed on * ___exclusive___ elements represent an exclusive list of architectures to not be installed on Dockerfile.in ------------- The ***Dockerfile.in*** file will be used as a template to build the container. No hardcoded dependencies should be put in this file. They should be stored in ***dependencies.xml***. fwupd-1.0.6/contrib/ci/arch.sh000077500000000000000000000011441325145456600161650ustar00rootroot00000000000000#!/bin/bash set -e set -x VERSION=`git describe | sed 's/-/.r/;s/-/./'` [ -z $VERSION ] && VERSION=`head meson.build | grep ' version :' | cut -d \' -f2` # prepare the build tree rm -rf build mkdir build && pushd build cp ../contrib/PKGBUILD . sed -i "s,#VERSION#,$VERSION," PKGBUILD mkdir -p src/fwupd && pushd src/fwupd ln -s ../../../* . popd chown nobody . -R # build the package and install it sudo -E -u nobody makepkg -e --noconfirm pacman -U --noconfirm *.pkg.tar.xz # move the package to working dir mv *.pkg.tar.xz ../dist # no testing here because gnome-desktop-testing isn’t available in Arch fwupd-1.0.6/contrib/ci/debian.sh000077500000000000000000000034471325145456600165020ustar00rootroot00000000000000#!/bin/bash set -e set -x #although it's debian, we don't build packages if [ "$OS" = "debian-s390x" ]; then ./contrib/ci/debian_s390x.sh exit 0 fi #prepare export DEBFULLNAME="CI Builder" export DEBEMAIL="ci@travis-ci.org" VERSION=`git describe | sed 's/-/+r/;s/-/+/'` [ -z $VERSION ] && VERSION=`head meson.build | grep ' version :' | cut -d \' -f2` rm -rf build/ mkdir -p build shopt -s extglob cp -lR !(build|dist) build/ pushd build mv contrib/debian . sed s/quilt/native/ debian/source/format -i #generate control file ./contrib/ci/generate_debian_control.py debian/control.in debian/control #build the package EDITOR=/bin/true dch --create --package fwupd -v $VERSION "CI Build" debuild --no-lintian --preserve-envvar CI --preserve-envvar CC #check lintian output #suppress tags that are side effects of building in docker this way lintian ../*changes \ -IE \ --pedantic \ --no-tag-display-limit \ --suppress-tags bad-distribution-in-changes-file \ --suppress-tags source-contains-unsafe-symlink \ --suppress-tags changelog-should-mention-nmu \ --suppress-tags debian-watch-file-in-native-package \ --suppress-tags source-nmu-has-incorrect-version-number \ --suppress-tags no-symbols-control-file \ --allow-root #if invoked outside of CI if [ ! -f /.dockerenv ]; then echo "Not running in a container, please manually install packages" exit 0 fi #test the packages install PACKAGES=$(ls ../*.deb | grep -v 'fwupd-tests\|dbgsym') dpkg -i $PACKAGES # run the installed tests if [ "$CI" = "true" ]; then dpkg -i ../fwupd-tests*.deb service dbus restart gnome-desktop-testing-runner fwupd apt purge -y fwupd-tests fi #test the packages remove apt purge -y fwupd \ fwupd-doc \ libfwupd2 \ libfwupd-dev #place built packages in dist outside docker mkdir -p ../dist cp $PACKAGES ../dist fwupd-1.0.6/contrib/ci/debian_s390x.sh000077500000000000000000000005551325145456600174450ustar00rootroot00000000000000#!/bin/sh set -e set -x export LC_ALL=C.UTF-8 rm -rf build mkdir -p build cp contrib/ci/s390x_cross.txt build/ cd build meson .. \ --cross-file s390x_cross.txt \ --werror \ -Dplugin_uefi=false \ -Dplugin_uefi_labels=false \ -Dplugin_dell=false \ -Dplugin_synaptics=false \ -Dintrospection=false \ -Dgtkdoc=false \ -Dman=false ninja -v ninja test -v cd .. fwupd-1.0.6/contrib/ci/dependencies.xml000066400000000000000000000626311325145456600200710ustar00rootroot00000000000000 cairo-devel libcairo-dev:s390x cairo-gobject-devel libcairo-gobject2:s390x json-glib json-glib-devel (>= 1.1.1) libjson-glib-dev:s390x (>= 1.1.1) colord colord-devel (>= 1.0.0) libcolord-dev:s390x (>= 1.0.0) ttf-dejavu dejavu-sans-fonts (>= 10.3) (>= 10.3) elfutils-libelf-devel libelf-dev:s390x freetype libfreetype6-dev:s390x fwupdate fwupdate-devel (>= 10-3) amd64 arm64 armhf i386 amd64 arm64 armhf i386 (>= 0.19.8.1) (>= 0.19.8.1) glib2-devel (>= 2.45.8) libglib2.0-dev:s390x (>= 2.45.8) gobject-introspection-devel gpgme-devel libgpgme-dev:s390x gnutls-devel libgnutls28-dev:s390x libgnutls28-dev gnutls-utils gtk-doc gtk-doc appstream-glib libappstream-glib-devel (>= 0.7.4) libappstream-glib-dev:s390x (>= 0.6.9) libarchive-devel libarchive-dev:s390x libcolorhug-dev:s390x amd64 arm64 armhf armel i386 amd64 arm64 armhf armel i386 libgcab-dev:s390x libgudev1-devel libgudev-1.0-dev:s390x libgusb-devel (>= 0.2.9) libgusb-dev:s390x (>= 0.2.9) libicu-dev:s390x libidn2-0-dev:s390x libsmbios-devel i386 amd64 libsoup-devel libsoup2.4-dev:s390x pango-devel polkit (>> 0.105-14) (>> 0.105-14) polkit-devel libpolkit-gobject-1-dev:s390x python-cairo python3-cairo python-gobject python-pillow python3-pillow qemu-user sqlite-devel libsqlite3-dev:s390x (>= 231) (>= 231) umockdev-devel vala vala valgrind-devel mips sparc64 sh4 ppc64 powerpcspe hppa alpha mips64el armhf armel mipsel m68k mips sparc64 sh4 ppc64 powerpcspe hppa alpha mips64el armhf armel mipsel m68k fwupd-1.0.6/contrib/ci/fedora.sh000077500000000000000000000026621325145456600165160ustar00rootroot00000000000000#!/bin/bash set -e set -x #generate a tarball git config tar.tar.xz.command "xz -c" mkdir -p build && pushd build rm -rf * meson .. \ -Dgtkdoc=true \ -Dman=true \ -Dtests=true \ -Dplugin_dummy=true \ -Dplugin_thunderbolt=true \ -Dplugin_uefi=true \ -Dplugin_dell=true \ -Dplugin_synaptics=true \ -Dplugin_colorhug=true $@ ninja-build dist popd VERSION=`meson introspect build --projectinfo | jq -r .version` mkdir -p $HOME/rpmbuild/SOURCES/ mv build/meson-dist/fwupd-$VERSION.tar.xz $HOME/rpmbuild/SOURCES/ #generate a spec file sed "s,#VERSION#,$VERSION,; s,#BUILD#,1,; s,#LONGDATE#,`date '+%a %b %d %Y'`,; s,#ALPHATAG#,alpha,; s,enable_dummy 0,enable_dummy 1,; s,Source0.*,Source0:\tfwupd-$VERSION.tar.xz," \ contrib/fwupd.spec.in > build/fwupd.spec if [ -n "$CI" ]; then sed -i "s,enable_ci 0,enable_ci 1,;" build/fwupd.spec fi #build RPM packages rpmbuild -ba build/fwupd.spec #if invoked outside of CI if [ ! -f /.dockerenv ]; then echo "Not running in a container, please manually install packages" exit 0 fi #install RPM packages dnf install -y $HOME/rpmbuild/RPMS/*/*.rpm cp $HOME/rpmbuild/RPMS/*/*.rpm dist # run the installed tests if [ "$CI" = "true" ]; then sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf mkdir -p /run/dbus mkdir -p /var ln -s /var/run /run dbus-daemon --system --fork gnome-desktop-testing-runner fwupd fi fwupd-1.0.6/contrib/ci/generate_debian_control.py000077500000000000000000000102521325145456600221220ustar00rootroot00000000000000#!/usr/bin/python3 # # Copyright (C) 2017 Dell Inc. # # Licensed under the GNU General Public License Version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # import os import sys import xml.etree.ElementTree as etree def parse_control_dependencies(requested_type): TARGET=os.getenv('OS') deps = [] dep = '' if TARGET == '': print("Missing OS environment variable") sys.exit(1) OS = TARGET SUBOS = '' if TARGET: split = TARGET.split('-') if len(split) >= 2: OS = split[0] SUBOS = split[1] else: import lsb_release OS = lsb_release.get_distro_information()['ID'].lower() import platform SUBOS = platform.machine() tree = etree.parse(os.path.join(directory, "dependencies.xml")) root = tree.getroot() for child in root: if not "type" in child.attrib or not "id" in child.attrib: continue for distro in child: if not "id" in distro.attrib: continue if distro.attrib["id"] != OS: continue control = distro.find("control") if control is None: continue packages = distro.findall("package") for package in packages: if SUBOS: if not 'variant' in package.attrib: continue if package.attrib['variant'] != SUBOS: continue if package.text: dep = package.text else: dep = child.attrib["id"] if child.attrib["type"] == requested_type and dep: version = control.find('version') if version is not None: dep = "%s %s" % (dep, version.text) inclusions = control.findall('inclusive') if inclusions: for i in range(0, len(inclusions)): prefix = '' suffix = ' ' if i == 0: prefix = " [" if i == len(inclusions) - 1: suffix = "]" dep = "%s%s%s%s" % (dep, prefix, inclusions[i].text, suffix) exclusions = control.findall('exclusive') if exclusions: for i in range(0, len(exclusions)): prefix = '!' suffix = ' ' if i == 0: prefix = " [!" if i == len(exclusions) - 1: suffix = "]" dep = "%s%s%s%s" % (dep, prefix, exclusions[i].text, suffix) deps.append(dep) return deps directory = os.path.dirname(sys.argv[0]) if (len(sys.argv) < 3): print("Missing input and output file") sys.exit(1) deps = parse_control_dependencies("build") input = sys.argv[1] if not os.path.exists(input): print("Missing input file %s" % input) sys.exit(1) with open(input, 'r') as rfd: lines = rfd.readlines() deps.sort() output = sys.argv[2] with open(output, 'w') as wfd: for line in lines: if line.startswith("Build-Depends: %%%DYNAMIC%%%"): wfd.write("Build-Depends:\n") for i in range(0, len(deps)): wfd.write("\t%s,\n" % deps[i]) else: wfd.write(line) fwupd-1.0.6/contrib/ci/generate_docker.py000077500000000000000000000077501325145456600204200ustar00rootroot00000000000000#!/usr/bin/python3 # # Copyright (C) 2017-2018 Dell Inc. # # Licensed under the GNU General Public License Version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # import os import subprocess import sys import xml.etree.ElementTree as etree import tempfile def parse_dependencies(OS, SUBOS, requested_type): deps = [] dep = '' tree = etree.parse(os.path.join(directory, "dependencies.xml")) root = tree.getroot() for child in root: if not "type" in child.attrib or not "id" in child.attrib: continue for distro in child: if not "id" in distro.attrib: continue if distro.attrib["id"] != OS: continue packages = distro.findall("package") for package in packages: if SUBOS: if not 'variant' in package.attrib: continue if package.attrib['variant'] != SUBOS: continue if package.text: dep = package.text else: dep = child.attrib["id"] if child.attrib["type"] == requested_type and dep: deps.append(dep) return deps directory = os.path.dirname(sys.argv[0]) TARGET=os.getenv('OS') if TARGET is None: print("Missing OS environment variable") sys.exit(1) OS = TARGET SUBOS = '' split = TARGET.split('-') if len(split) >= 2: OS = split[0] SUBOS = split[1] deps = parse_dependencies(OS, SUBOS, "build") input = os.path.join(directory, "Dockerfile-%s.in" % OS) if not os.path.exists(input): print("Missing input file %s for %s" % (input, OS)) sys.exit(1) with open(input, 'r') as rfd: lines = rfd.readlines() out = tempfile.NamedTemporaryFile(dir='.', delete=True) with open(out.name, 'w') as wfd: for line in lines: if line.startswith("FROM %%%ARCH_PREFIX%%%"): if OS == "debian" and SUBOS == "i386": replace = SUBOS + "/" else: replace = '' wfd.write(line.replace("%%%ARCH_PREFIX%%%", replace)) elif line == "%%%INSTALL_DEPENDENCIES_COMMAND%%%\n": if OS == "fedora": wfd.write("RUN dnf --enablerepo=updates-testing -y install \\\n") elif OS == "debian" or OS == "ubuntu": wfd.write("RUN apt update -qq && \\\n") wfd.write("\tapt install -yq --no-install-recommends\\\n") elif OS == "arch": wfd.write("RUN pacman -Syu --noconfirm \\\n") for i in range(0, len(deps)): if i < len(deps)-1: wfd.write("\t%s \\\n" % deps[i]) else: wfd.write("\t%s \n" % deps[i]) elif line == "%%%ARCH_SPECIFIC_COMMAND%%%\n": if OS == "debian" and SUBOS == "s390x": #add sources wfd.write('RUN cat /etc/apt/sources.list | sed "s/deb/deb-src/" >> /etc/apt/sources.list\n') #add new architecture wfd.write('RUN dpkg --add-architecture %s\n' % SUBOS) elif line == "%%%OS%%%\n": wfd.write("ENV OS %s\n" % TARGET) else: wfd.write(line) wfd.flush() subprocess.check_call(["docker", "build", "-t", "fwupd-%s" % TARGET, "-f", "./%s" % os.path.basename(out.name), "."]) fwupd-1.0.6/contrib/ci/s390x_cross.txt000066400000000000000000000004221325145456600175470ustar00rootroot00000000000000[binaries] c = 's390x-linux-gnu-gcc' cpp = 's390x-linux-gnu-cpp' ar = 's390x-linux-gnu-ar' strip = 's390x-linux-gnu-strip' pkgconfig = 's390x-linux-gnu-pkg-config' exe_wrapper = 'qemu-s390x' [host_machine] system = 'linux' cpu_family = 's390x' cpu = 's390x' endian = 'big' fwupd-1.0.6/contrib/ci/ubuntu.sh000077700000000000000000000000001325145456600203402debian.shustar00rootroot00000000000000fwupd-1.0.6/contrib/debian/000077500000000000000000000000001325145456600155405ustar00rootroot00000000000000fwupd-1.0.6/contrib/debian/README.Debian000066400000000000000000000003701325145456600176010ustar00rootroot00000000000000fwupd for Debian ---------------- fwupd is still heavily in development. As of this date, the functionality it provides is not yet available on most systems. -- Daniel Jared Dominguez Wed, 20 May 2015 17:16:02 -0500 fwupd-1.0.6/contrib/debian/README.source000066400000000000000000000004201325145456600177130ustar00rootroot00000000000000fwupd for Debian ---------------- To build from the git tree, run: git-buildpackage -us -uc -S Then, if using sbuild, you can use something like: sbuild -s -c sid-amd64 -d unstable -- Daniel Jared Dominguez Thu, 21 May 2015 13:44:16 -0500 fwupd-1.0.6/contrib/debian/clean000066400000000000000000000000331325145456600165410ustar00rootroot00000000000000gtk-doc.make m4/gtk-doc.m4 fwupd-1.0.6/contrib/debian/compat000066400000000000000000000000021325145456600167360ustar00rootroot000000000000009 fwupd-1.0.6/contrib/debian/control.in000066400000000000000000000111421325145456600175470ustar00rootroot00000000000000Source: fwupd Priority: optional Maintainer: Debian EFI Uploaders: Steve McIntyre <93sam@debian.org>, Daniel Jared Dominguez , Matthias Klumpp , Mario Limonciello Build-Depends: %%%DYNAMIC%%% Standards-Version: 4.1.3 Section: admin Homepage: https://github.com/hughsie/fwupd Vcs-Git: https://salsa.debian.org/efi-team/fwupd.git Vcs-Browser: https://salsa.debian.org/efi-team/fwupd Package: libfwupd2 Section: libs Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} Multi-Arch: same Description: Firmware update daemon library fwupd is a daemon to allow session software to update device firmware. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the system D-Bus interface directly. Currently, firmware updates using the UEFI capsule format and for the ColorHug are supported. More formats may be supported in the future. See for details . This package provides the library used by the daemon. Package: fwupd Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends} Recommends: fwupdate, python3 Breaks: gir1.2-dfu-1.0 (<< 0.9.7-1), libdfu1 (<< 0.9.7-1), libdfu-dev (<< 0.9.7-1) Replaces: gir1.2-dfu-1.0 (<< 0.9.7-1), libdfu1 (<< 0.9.7-1), libdfu-dev (<< 0.9.7-1) Multi-Arch: foreign Description: Firmware update daemon fwupd is a daemon to allow session software to update device firmware. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the system D-Bus interface directly. Currently, firmware updates using the UEFI capsule format and for the ColorHug are supported. More formats may be supported in the future. See for details Package: fwupd-tests Architecture: linux-any Depends: ${misc:Depends}, ${shlibs:Depends}, ca-certificates, dbus-x11, fwupd, gnome-desktop-testing, policykit-1, python3, python3-gi, python3-requests, Breaks: fwupd (<< 0.9.4-1) Replaces: fwupd (<< 0.9.4-1) Multi-Arch: foreign Description: Test suite for firmware update daemon fwupd is a daemon to allow session software to update device firmware. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the system D-Bus interface directly. Currently, firmware updates using the UEFI capsule format and for the ColorHug are supported. More formats may be supported in the future. See for details . This package provides a set of installed tests that can be run to validate the daemon in a continuous integration system. Package: fwupd-doc Section: doc Architecture: all Multi-Arch: foreign Depends: ${misc:Depends}, Description: Firmware update daemon documentation (HTML format) fwupd is a daemon to allow session software to update device firmware. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the system D-Bus interface directly. Currently, firmware updates using the UEFI capsule format and for the ColorHug are supported. More formats may be supported in the future. See for details . This package provides development documentation for creating a package that uses fwupd. Package: libfwupd-dev Architecture: linux-any Multi-Arch: same Depends: libfwupd2 (= ${binary:Version}), gir1.2-fwupd-2.0 (= ${binary:Version}), ${misc:Depends} Breaks: fwupd-dev (<< 0.5.4-2~) Replaces: fwupd-dev (<< 0.5.4-2~) Section: libdevel Description: development files for libfwupd fwupd is a daemon to allow session software to update device firmware. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the system D-Bus interface directly. Currently, firmware updates using the UEFI capsule format and for the ColorHug are supported. More formats may be supported in the future. See for details . This package provides the development files for libfwupd Package: gir1.2-fwupd-2.0 Architecture: linux-any Multi-Arch: same Depends: ${misc:Depends}, ${gir:Depends} Section: introspection Description: GObject introspection data for libfwupd This package provides the introspection data for libfwupd. . It can be used by packages using the GIRepository format to generate dynamic bindings. fwupd-1.0.6/contrib/debian/copyright000066400000000000000000000220201325145456600174670ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: fwupd Source: https://github.com/hughsie/fwupd Files: * Copyright: 2015 Richard Hughes License: GPL-2.0+ Files: libfwupd/* Copyright: 2015 Richard Hughes License: LGPL-2.1+ Files: data/tests/colorhug/firmware.metainfo.xml Copyright: 2015 Richard Hughes License: CC0-1.0 Files: debian/* Copyright: 2015 Daniel Jared Dominguez 2015 Mario Limonciello License: GPL-2.0+ License: GPL-2.0+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". License: LGPL-2.1+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU Lesser General Public License version 2.1 can be found in "/usr/share/common-licenses/LGPL-2.1". License: CC0-1.0 Creative Commons CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. . Statement of Purpose . The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. . 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. . 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. . 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. . 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. fwupd-1.0.6/contrib/debian/docs000066400000000000000000000000051325145456600164060ustar00rootroot00000000000000NEWS fwupd-1.0.6/contrib/debian/fwupd-doc.install000066400000000000000000000000221325145456600210120ustar00rootroot00000000000000usr/share/gtk-doc fwupd-1.0.6/contrib/debian/fwupd-tests.install000066400000000000000000000004151325145456600214150ustar00rootroot00000000000000#These are in a generic looking directory because #that is where gnome-desktop-testing expects to #find them. for more information see: #https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872458 usr/share/installed-tests/* usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so fwupd-1.0.6/contrib/debian/fwupd-tests.postinst000066400000000000000000000005331325145456600216330ustar00rootroot00000000000000#!/bin/sh set -e #DEBHELPER# #only enable on installation not upgrade if [ "$1" = configure ] && [ -z "$2" ]; then if [ -f /etc/fwupd/daemon.conf ]; then if [ "$CI" = "true" ]; then sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf else echo "To enable test suite, modify /etc/fwupd/daemon.conf" fi fi fi fwupd-1.0.6/contrib/debian/fwupd-tests.postrm000066400000000000000000000004611325145456600212740ustar00rootroot00000000000000#!/bin/sh set -e #DEBHELPER# if [ "$1" = remove -o "$1" = purge ]; then if [ -f /etc/fwupd/daemon.conf ]; then if [ "$CI" = "true" ]; then sed "s,^BlacklistPlugins=,BlacklistPlugins=test," -i /etc/fwupd/daemon.conf else echo "To disable test suite, modify /etc/fwupd/daemon.conf" fi fi fi fwupd-1.0.6/contrib/debian/fwupd.dirs000066400000000000000000000000301325145456600175410ustar00rootroot00000000000000var/cache/app-info/xmls fwupd-1.0.6/contrib/debian/fwupd.install000066400000000000000000000006471325145456600202640ustar00rootroot00000000000000usr/bin/dfu-tool usr/bin/fwupdmgr etc/* usr/share/bash-completion usr/share/fwupd/* usr/share/dbus-1/* usr/share/polkit-1/* usr/share/locale usr/share/metainfo/* usr/lib/*/fwupd usr/share/man/man1/* lib/systemd/system/* var/lib/fwupd lib/udev/rules.d/* data/daemon.conf etc/fwupd debian/fwupd.pkla /var/lib/polkit-1/localauthority/10-vendor.d usr/lib/*/fwupd-plugins-*/*.so debian/lintian/fwupd usr/share/lintian/overrides fwupd-1.0.6/contrib/debian/fwupd.pkla000066400000000000000000000002071325145456600175350ustar00rootroot00000000000000[Call internal fwupd actions] Identity=unix-group:admin;unix-group:sudo Action=org.freedesktop.fwupd.update-internal ResultActive=yes fwupd-1.0.6/contrib/debian/fwupd.postinst000066400000000000000000000002541325145456600204730ustar00rootroot00000000000000#!/bin/sh set -e #DEBHELPER# if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then dpkg-maintscript-helper rm_conffile \ /etc/fwupd.conf 1.0.0~ -- "$@" fi fwupd-1.0.6/contrib/debian/fwupd.postrm000066400000000000000000000004211325145456600201300ustar00rootroot00000000000000#!/bin/sh set -e #DEBHELPER# if [ "$1" = purge ]; then rm -rf /var/lib/fwupd/gnupg rm -f /var/cache/app-info/xmls/fwupd.xml fi if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then dpkg-maintscript-helper rm_conffile \ /etc/fwupd.conf 1.0.0~ -- "$@" fi fwupd-1.0.6/contrib/debian/fwupd.preinst000066400000000000000000000002541325145456600202740ustar00rootroot00000000000000#!/bin/sh set -e #DEBHELPER# if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then dpkg-maintscript-helper rm_conffile \ /etc/fwupd.conf 1.0.0~ -- "$@" fi fwupd-1.0.6/contrib/debian/gbp.conf000066400000000000000000000001611325145456600171550ustar00rootroot00000000000000[DEFAULT] debian-branch = debian upstream-tag = %(version)s [buildpackage] sign-tags = True dist = experimental fwupd-1.0.6/contrib/debian/gir1.2-fwupd-2.0.install000066400000000000000000000000551325145456600215520ustar00rootroot00000000000000usr/lib/*/girepository-1.0/Fwupd-2.0.typelib fwupd-1.0.6/contrib/debian/libfwupd-dev.install000066400000000000000000000002361325145456600215210ustar00rootroot00000000000000usr/include/fwupd-1/fwupd.h usr/include/fwupd-1/libfwupd usr/lib/*/libfwupd*.so usr/lib/*/pkgconfig/fwupd.pc usr/share/gir-1.0/Fwupd*.gir usr/share/vala/vapi fwupd-1.0.6/contrib/debian/libfwupd2.install000066400000000000000000000000301325145456600210170ustar00rootroot00000000000000usr/lib/*/libfwup*.so.* fwupd-1.0.6/contrib/debian/lintian/000077500000000000000000000000001325145456600171765ustar00rootroot00000000000000fwupd-1.0.6/contrib/debian/lintian/fwupd000066400000000000000000000007201325145456600202450ustar00rootroot00000000000000#these are intended to be d-bus activated fwupd binary: systemd-service-file-missing-install-key lib/systemd/system/fwupd-offline-update.service fwupd binary: systemd-service-file-missing-install-key lib/systemd/system/fwupd.service fwupd binary: systemd-service-file-missing-install-key lib/systemd/system/system-update.target.wants/fwupd-offline-update.service #CAs is the right word, not Case fwupd binary: spelling-error-in-binary usr/lib/fwupd/fwupd CAs Case fwupd-1.0.6/contrib/debian/rules000077500000000000000000000024401325145456600166200ustar00rootroot00000000000000#!/usr/bin/make -f # -*- makefile -*- export LC_ALL := C.UTF-8 export DEB_BUILD_MAINT_OPTIONS = hardening=+all #GPGME needs this for proper building on 32 bit archs ifeq "$(DEB_HOST_ARCH_BITS)" "32" export DEB_CFLAGS_MAINT_APPEND = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE endif ifneq ($(CI),) export CI=--werror endif %: dh $@ --with gir,systemd override_dh_auto_clean: rm -fr debian/build override_dh_auto_configure: if pkg-config --exists fwup; then \ export UEFI="-Dplugin_uefi=true"; \ else \ export UEFI="-Dplugin_uefi=false"; \ fi; \ if pkg-config --exists libsmbios_c; then \ export DELL="-Dplugin_dell=true -Dplugin_synaptics=true"; \ else \ export DELL="-Dplugin_dell=false -Dplugin_synaptics=false"; \ fi; \ dh_auto_configure -- $$UEFI $$DELL $$CI -Dplugin_dummy=true --libexecdir=/usr/lib override_dh_install: find debian/tmp/usr -type f -name "*a" -print | xargs rm -f sed -i 's,wheel,sudo,' ./debian/tmp/usr/share/polkit-1/rules.d/org.freedesktop.fwupd.rules dh_install dh_missing --fail-missing #this is placed in fwupd-tests rm -f debian/fwupd/usr/lib/*/fwupd-plugins-3/libfu_plugin_test.so override_dh_strip_nondeterminism: dh_strip_nondeterminism -Xfirmware-example.xml.gz override_dh_auto_test: if [ -x /usr/bin/valgrind ] ; then \ dh_auto_test; \ fi fwupd-1.0.6/contrib/debian/source/000077500000000000000000000000001325145456600170405ustar00rootroot00000000000000fwupd-1.0.6/contrib/debian/source/format000066400000000000000000000000141325145456600202460ustar00rootroot000000000000003.0 (quilt) fwupd-1.0.6/contrib/debian/source/include-binaries000066400000000000000000000000421325145456600221740ustar00rootroot00000000000000debian/binary-patches/example.elf fwupd-1.0.6/contrib/debian/source/lintian-overrides000066400000000000000000000001161325145456600224170ustar00rootroot00000000000000#github doesn't have these fwupd source: debian-watch-may-check-gpg-signature fwupd-1.0.6/contrib/debian/tests/000077500000000000000000000000001325145456600167025ustar00rootroot00000000000000fwupd-1.0.6/contrib/debian/tests/ci000066400000000000000000000002001325145456600172100ustar00rootroot00000000000000#!/bin/sh set -e sed "s,^BlacklistPlugins=test,BlacklistPlugins=," -i /etc/fwupd/daemon.conf gnome-desktop-testing-runner fwupd fwupd-1.0.6/contrib/debian/tests/control000066400000000000000000000000431325145456600203020ustar00rootroot00000000000000Tests: ci Restrictions: needs-root fwupd-1.0.6/contrib/debian/watch000066400000000000000000000003551325145456600165740ustar00rootroot00000000000000# You can run the "uscan" command to check for upstream updates and more. # See uscan(1) for format version=3 opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/fwupd-$1\.tar\.gz/ \ https://github.com/hughsie/fwupd/tags .*/v?(\d\S*)\.tar\.gz fwupd-1.0.6/contrib/firmware-packager/000077500000000000000000000000001325145456600177055ustar00rootroot00000000000000fwupd-1.0.6/contrib/firmware-packager/README.md000066400000000000000000000117661325145456600211770ustar00rootroot00000000000000# Firmware Packager This script is intended to make firmware updating easier until OEMs upload their firmware packages to the LVFS. It works by extracting the firmware binary contained in a Microsoft .exe file (intended for performing the firmware update from a Windows system) and repackaging it in a cab file usable by fwupd. The cab file can then be install using `fwupdmgr install` ## Prerequisites To run this script you will need 1. Python3.5, a standard install should include all packages you need 2. 7z (for extracting .exe files) 3. gcab (for creating the cab file) ## Usage To create a firmware package, you must supply, at a minimum: 1. A string ID to name the firmware (`--firmware-id`). You are free to choose this, but [fwupd.org](http://fwupd.org/vendors.html) recommends using "a reverse-DNS prefix similar to java" and to "always use a .firmware suffix" (e.g. net.queuecumber.DellTBT.firmware) 2. A short name for the firmware package, again you are free to choose this (`--firmware-name`). 3. The unique ID of the device that the firmware is intended for (`--device-unique-id`). This *must* match the unique ID from `fwupdmgr get-devices` 4. The firmware version (`--release-version`), try to match the manufacturers versioning scheme 5. The path to the executable file to repackage (`--exe`) 6. The path *relative to the root of the exe archive* of the .bin file to package (`--bin`). Use 7z or archive-manager to inspect the .exe file and find this path. For example, if I want to package `dell-thunderbolt-firmware.exe` and I open the .exe with archive-manager and find that `Intel/tbt.bin` is the path to the bin file inside the archive, I would pass `--exe dell-thunderbolt-firmware.exe --bin Intel/tbt.bin` 7. The path to the cab file to output (`--out`). ## Documentation `--firmware-id` ID for the firmware package, can be a customized [fwupd.org](http://fwupd.org/vendors.html) recommends using "a reverse-DNS prefix similar to java" and to "always use a .firmware suffix" (e.g. net.queuecumber.DellTBT.firmware) **REQUIRED** `--firmware-name` Short name of the firmware package can be customized (e.g. DellTBT) **REQUIRED** `--firmware-summary` One line description of the firmware package (e.g. Dell thunderbolt firmware) `--firmware-description` Longer description of the firmware package. Theoretically this can include HTML but I haven't tried it `--device-unique-id` Unique ID of the device this firmware will run on, this *must* match the output from `fwupdmgr get-devices` (e.g. 72533768-6a6c-5c06-994a-367374336810) **REQUIRED** `--firmware-homepage` Website for the firmware provider (e.g. http://www.dell.com) `-contact-info` Email address of the firmware developer (e.g. someone@something.net) `--developer-name` Name of the firmware developer (e.g. John Smith) `--release-version` Version number of the firmware package (e.g. 4.21.01.002) **REQUIRED** `--release-description` Description of the firmware release, again this can theoretically include HTML but I didnt try it. `--exe` Executable file to extract firmware from (e.g. `dell-thunderbolt-firmware.exe`) **REQUIRED** `--bin` Path to the .bin file inside the executable to use as the firmware image', relative to the root of the archive (e.g. `Intel/tbt.bin`) **REQUIRED** `--out` Output cab file path (e.g. `updates/firmware.cab`) **REQUIRED** ## Example Let's say we downloaded `Intel_TBT3_FW_UPDATE_NVM21_318RY_A01_4.21.01.002.exe` (available [here](https://downloads.dell.com/FOLDER04421073M/1/Intel_TBT3_FW_UPDATE_NVM21_318RY_A01_4.21.01.002.exe)) containing updated firmware for Dell laptops thunderbolt controllers. Since Dell hasn't made this available on the LVFS yet, we want to package and install it ourselves. Opening the .exe with archive manager, we see it has a single folder: `Intel` and inside that, a set of firmware binaries (along with some microsoft junk). We pick the file `0x07BE_secure.bin` since we have a Dell XPS 9560 and that is its device string. Next we use `fwupdmgr` to get the device ID for the thunderbolt controller: ``` $ fwupdmgr get-devices Thunderbolt Controller Guid: 72533768-6a6c-5c06-994a-367374336810 DeviceID: 08001575 Plugin: thunderbolt Flags: internal|allow-online DeviceVendor: Intel Version: 21.00 Created: 2017-08-16 ``` The GUID field contains what we are looking for We can then run the firmware-packager with the following arguments: ``` $ firmware-packager --firmware-id net.queuecumber.DellTBT.firmware --firmware-name DellTBT --device-unique-id 72533768-6a6c-5c06-994a-367374336810 --release-version 4.21.01.002 --exe ~/Downloads/Intel_TBT3_FW_UPDATE_NVM21_318RY_A01_4.21.01.002.exe --bin Intel/0x07BE_secure.bin --out firmware.cab Using temp directory /tmp/tmpoey6_zx_ Extracting firmware exe Locating firmware bin Creating metainfo Cabbing firmware files Done ``` And we should have a firmware.cab that contains the packaged firmware. We can then install this firmware with ``` $ fwupdmgr install firmware.cab ``` fwupd-1.0.6/contrib/firmware-packager/firmware-packager000077500000000000000000000110231325145456600232170ustar00rootroot00000000000000#!/usr/bin/env python3 # # Copyright (C) 2017 Max Ehrlich max.ehr@gmail.com # # Licensed under the GNU General Public License Version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # import argparse import subprocess import contextlib import os import shutil import tempfile import time @contextlib.contextmanager def cd(path): prev_cwd = os.getcwd() os.chdir(path) yield os.chdir(prev_cwd) firmware_metainfo_template = """ {firmware_id} {firmware_name} {firmware_summary} {firmware_description} {device_unique_id} {firmware_homepage} CC0-1.0 proprietary {contact_info} {developer_name} {release_description} """ def make_firmware_metainfo(firmware_info, dst): firmware_metainfo = firmware_metainfo_template.format(**vars(firmware_info), timestamp=time.time()) with open(os.path.join(dst, 'firmware.metainfo.xml'), 'w') as f: f.write(firmware_metainfo) def extract_exe(exe, dst): command = ['7z', 'x', '-o{}'.format(dst), exe] subprocess.check_call(command, stdout=subprocess.DEVNULL) def get_firmware_bin(root, bin_path, dst): with cd(root): shutil.copy(bin_path, os.path.join(dst, 'firmware.bin')) def create_firmware_cab(exe, folder): with cd(folder): command = ['gcab', '--create', 'firmware.cab', 'firmware.bin', 'firmware.metainfo.xml'] subprocess.check_call(command) def main(args): with tempfile.TemporaryDirectory() as dir: print('Using temp directory {}'.format(dir)) if args.exe: print('Extracting firmware exe') extract_exe(args.exe, dir) print('Locating firmware bin') get_firmware_bin(dir, args.bin, dir) print('Creating metainfo') make_firmware_metainfo(args, dir) print('Cabbing firmware files') create_firmware_cab(args, dir) print('Done') shutil.copy(os.path.join(dir, 'firmware.cab'), args.out) parser = argparse.ArgumentParser(description='Create fwupd packaged from windows executables') parser.add_argument('--firmware-id', help='ID for the firmware package, can be a customized (e.g. net.queuecumber.DellTBT.firmware)', required=True) parser.add_argument('--firmware-name', help='Name of the firmware package can be customized (e.g. DellTBT)', required=True) parser.add_argument('--firmware-summary', help='One line description of the firmware package') parser.add_argument('--firmware-description', help='Longer description of the firmware package') parser.add_argument('--device-unique-id', help='Unique ID of the device this firmware will run on, this *must* match the output from `fwupdmgr get-devices`', required=True) parser.add_argument('--firmware-homepage', help='Website for the firmware provider') parser.add_argument('--contact-info', help='Email address of the firmware developer') parser.add_argument('--developer-name', help='Name of the firmware developer') parser.add_argument('--release-version', help='Version number of the firmware package', required=True) parser.add_argument('--release-description', help='Description of the firmware release') parser.add_argument('--exe', help='Executable file to extract firmware from') parser.add_argument('--bin', help='Path to the .bin file inside the executable to use as the firmware image', required=True) parser.add_argument('--out', help='Output cab file path', required=True) args = parser.parse_args() main(args) fwupd-1.0.6/contrib/firmware-packager/meson.build000066400000000000000000000001141325145456600220430ustar00rootroot00000000000000install_data('firmware-packager', install_dir : 'share/fwupd') fwupd-1.0.6/contrib/fwupd.spec.in000066400000000000000000000170241325145456600167300ustar00rootroot00000000000000%global glib2_version 2.45.8 %global libappstream_version 0.6.13 %global libgusb_version 0.2.11 %global libsoup_version 2.51.92 %global colord_version 1.2.12 %global systemd_version 231 %global json_glib_version 1.1.1 %define alphatag #ALPHATAG# %global enable_ci 0 %global enable_tests 1 %global enable_dummy 1 # fwupdate is only available on these arches %ifarch x86_64 aarch64 %global have_uefi 1 %endif # libsmbios is only available on x86, and fwupdate is available on just x86_64 %ifarch x86_64 %global have_dell 1 %endif Summary: Firmware update daemon Name: fwupd Version: #VERSION# Release: 0.#BUILD#%{?alphatag}%{?dist} License: GPLv2+ URL: https://github.com/hughsie/fwupd Source0: http://people.freedesktop.org/~hughsient/releases/%{name}-%{version}.tar.xz BuildRequires: gettext BuildRequires: glib2-devel >= %{glib2_version} BuildRequires: libappstream-glib-devel >= %{libappstream_version} BuildRequires: libgudev1-devel BuildRequires: libgusb-devel >= %{libgusb_version} BuildRequires: libsoup-devel >= %{libsoup_version} BuildRequires: colord-devel >= %{colord_version} BuildRequires: polkit-devel >= 0.103 BuildRequires: sqlite-devel BuildRequires: gpgme-devel BuildRequires: systemd >= %{systemd_version} BuildRequires: libarchive-devel BuildRequires: gobject-introspection-devel BuildRequires: gcab BuildRequires: valgrind BuildRequires: valgrind-devel BuildRequires: elfutils-libelf-devel BuildRequires: gtk-doc BuildRequires: libuuid-devel BuildRequires: gnutls-devel BuildRequires: gnutls-utils BuildRequires: meson BuildRequires: help2man BuildRequires: json-glib-devel >= %{json_glib_version} BuildRequires: vala %if 0%{?have_uefi} BuildRequires: python3 python3-cairo python3-gobject python3-pillow BuildRequires: pango-devel BuildRequires: cairo-devel cairo-gobject-devel BuildRequires: freetype BuildRequires: fontconfig BuildRequires: dejavu-sans-fonts BuildRequires: adobe-source-han-sans-cn-fonts %endif %if 0%{?have_dell} BuildRequires: efivar-devel BuildRequires: libsmbios-devel >= 2.3.0 %endif %if 0%{?have_uefi} BuildRequires: fwupdate-devel >= 7 %endif Requires(post): systemd Requires(preun): systemd Requires(postun): systemd Requires: glib2%{?_isa} >= %{glib2_version} Requires: libappstream-glib%{?_isa} >= %{libappstream_version} Requires: libgusb%{?_isa} >= %{libgusb_version} Requires: libsoup%{?_isa} >= %{libsoup_version} Requires: fwupd-labels = %{version}-%{release} Requires: bubblewrap Recommends: python3 Obsoletes: fwupd-sign < 0.1.6 Obsoletes: libebitdo < 0.7.5-3 Obsoletes: libdfu < 0.9.8-1 %description fwupd is a daemon to allow session software to update device firmware. %package devel Summary: Development package for %{name} Requires: %{name}%{?_isa} = %{version}-%{release} Obsoletes: libebitdo-devel < 0.7.5-3 Obsoletes: libdfu-devel < 0.9.8-1 %description devel Files for development with %{name}. %package labels Summary: Rendered labels for display during system firmware updates. # BuildArch: noarch is disabled as we can get "different" .BMP files even when # running the build on the same architecture due to the randomness introduced # by the TTF files. %description labels Rendered labels for display during system firmware updates. %package tests Summary: Data files for installed tests BuildArch: noarch %description tests Data files for installed tests. %prep %setup -q %build %meson \ %if 0%{?enable_ci} --werror \ %endif -Dgtkdoc=true \ -Dman=true \ %if 0%{?enable_tests} -Dtests=true \ %else -Dtests=false \ %endif %if 0%{?enable_dummy} -Dplugin_dummy=true \ %else -Dplugin_dummy=false \ %endif -Dplugin_thunderbolt=true \ %if 0%{?have_uefi} -Dplugin_uefi=true \ -Dplugin_uefi_labels=true \ %else -Dplugin_uefi=false \ -Dplugin_uefi_labels=false \ %endif %if 0%{?have_dell} -Dplugin_dell=true \ -Dplugin_synaptics=true \ %else -Dplugin_dell=false \ -Dplugin_synaptics=false \ %endif -Dplugin_colorhug=true %meson_build %if 0%{?enable_tests} %check %meson_test %endif %install %meson_install mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg %find_lang %{name} %post /sbin/ldconfig %systemd_post fwupd.service %preun %systemd_preun fwupd.service %postun /sbin/ldconfig %systemd_postun_with_restart fwupd.service %files -f %{name}.lang %doc README.md AUTHORS NEWS %license COPYING %config(noreplace)%{_sysconfdir}/fwupd/daemon.conf %config(noreplace)%{_sysconfdir}/fwupd/uefi.conf %dir %{_libexecdir}/fwupd %{_libexecdir}/fwupd/fwupd %{_bindir}/dfu-tool %{_bindir}/fwupdmgr %dir %{_sysconfdir}/fwupd %dir %{_sysconfdir}/fwupd/remotes.d %config(noreplace)%{_sysconfdir}/fwupd/remotes.d/fwupd.conf %config(noreplace)%{_sysconfdir}/fwupd/remotes.d/lvfs.conf %config(noreplace)%{_sysconfdir}/fwupd/remotes.d/lvfs-testing.conf %config(noreplace)%{_sysconfdir}/fwupd/remotes.d/vendor.conf %config(noreplace)%{_sysconfdir}/pki/fwupd %{_sysconfdir}/pki/fwupd-metadata %{_sysconfdir}/dbus-1/system.d/org.freedesktop.fwupd.conf %{_datadir}/bash-completion/completions/fwupdmgr %{_datadir}/fwupd/remotes.d/fwupd/metadata.xml %{_datadir}/fwupd/remotes.d/vendor/firmware/README.md %{_datadir}/dbus-1/interfaces/org.freedesktop.fwupd.xml %{_datadir}/polkit-1/actions/org.freedesktop.fwupd.policy %{_datadir}/polkit-1/rules.d/org.freedesktop.fwupd.rules %{_datadir}/dbus-1/system-services/org.freedesktop.fwupd.service %{_datadir}/man/man1/dfu-tool.1.gz %{_datadir}/man/man1/fwupdmgr.1.gz %{_datadir}/metainfo/org.freedesktop.fwupd.metainfo.xml %{_datadir}/fwupd/firmware-packager %{_unitdir}/fwupd-offline-update.service %{_unitdir}/fwupd.service %{_unitdir}/system-update.target.wants/ %dir %{_localstatedir}/lib/fwupd %dir %{_datadir}/fwupd/quirks.d %{_datadir}/fwupd/quirks.d/*.quirk %{_localstatedir}/lib/fwupd/builder/README.md %{_libdir}/libfwupd*.so.* %{_libdir}/girepository-1.0/Fwupd-2.0.typelib /usr/lib/udev/rules.d/*.rules %dir %{_libdir}/fwupd-plugins-3 %{_libdir}/fwupd-plugins-3/libfu_plugin_altos.so %{_libdir}/fwupd-plugins-3/libfu_plugin_amt.so %{_libdir}/fwupd-plugins-3/libfu_plugin_colorhug.so %{_libdir}/fwupd-plugins-3/libfu_plugin_csr.so %if 0%{?have_dell} %{_libdir}/fwupd-plugins-3/libfu_plugin_dell.so %endif %{_libdir}/fwupd-plugins-3/libfu_plugin_dfu.so %{_libdir}/fwupd-plugins-3/libfu_plugin_ebitdo.so %{_libdir}/fwupd-plugins-3/libfu_plugin_nitrokey.so %{_libdir}/fwupd-plugins-3/libfu_plugin_steelseries.so %if 0%{?have_dell} %{_libdir}/fwupd-plugins-3/libfu_plugin_synapticsmst.so %endif %if 0%{?enable_dummy} %{_libdir}/fwupd-plugins-3/libfu_plugin_test.so %endif %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so %{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so %if 0%{?have_uefi} %{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so %endif %{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so %{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so %ghost %{_localstatedir}/lib/fwupd/gnupg %files devel %{_datadir}/gir-1.0/Fwupd-2.0.gir %{_datadir}/gtk-doc/html/libfwupd %{_datadir}/vala/vapi %{_includedir}/fwupd-1 %{_libdir}/libfwupd*.so %{_libdir}/pkgconfig/fwupd.pc %files labels %if 0%{?have_uefi} %{_datadir}/locale/*/LC_IMAGES/fwupd* %endif %files tests %dir %{_datadir}/installed-tests/fwupd %{_datadir}/installed-tests/fwupd/firmware-example.xml.gz %{_datadir}/installed-tests/fwupd/firmware-example.xml.gz.asc %{_datadir}/installed-tests/fwupd/*.test %{_datadir}/installed-tests/fwupd/*.cab %{_datadir}/installed-tests/fwupd/*.sh %{_datadir}/installed-tests/fwupd/*.py* %changelog * #LONGDATE# Richard Hughes #VERSION#-0.#BUILD##ALPHATAG# - Update from git fwupd-1.0.6/contrib/meson.build000066400000000000000000000000341325145456600164550ustar00rootroot00000000000000subdir('firmware-packager') fwupd-1.0.6/data/000077500000000000000000000000001325145456600135675ustar00rootroot00000000000000fwupd-1.0.6/data/90-fwupd-devices.rules000066400000000000000000000031401325145456600176340ustar00rootroot00000000000000######################################################################## # Copyright (C) 2015 Richard Hughes # # Licensed under the GNU General Public License Version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # VIA USB 3.0 VL811 Hub SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0810", ENV{FWUPD_GUID}="adbb9034-b577-42c2-a661-1ee4f49ef64c", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL811 Hub" # VIA USB 3.0 VL811+ Hub SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0811", ENV{FWUPD_GUID}="54f84d05-c917-4c50-8b35-44feabaaa323", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL811+ Hub" # VIA USB 3.0 VL812 Hub SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="0812", ENV{FWUPD_GUID}="cd0314ec-b80f-4d1a-a24f-c409183a8b2d", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL812 Hub" # VIA USB 3.0 VL812 B2 Hub SUBSYSTEM=="usb", DRIVER=="hub", ATTRS{idVendor}=="2109", ATTRS{idProduct}=="2812", ENV{FWUPD_GUID}="26470009-97a8-4028-867a-bbbac6ee7bf0", ENV{FWUPD_VENDOR}="VIA", ENV{FWUPD_MODEL}="USB 3.0 VL812 B2 Hub" ENV{FWUPD_GUID}=="*?", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id" ENV{FWUPD_GUID}=="*?", ENV{ID_MODEL_FROM_DATABASE}=="", IMPORT{builtin}="hwdb --subsystem=usb" # PCI cards with ROM SUBSYSTEM=="pci", TEST=="/sys$devpath/rom", ENV{FWUPD_GUID}="$attr{vendor}:$attr{device}" fwupd-1.0.6/data/bash-completion/000077500000000000000000000000001325145456600166535ustar00rootroot00000000000000fwupd-1.0.6/data/bash-completion/fwupdmgr000066400000000000000000000057061325145456600204410ustar00rootroot00000000000000_fwupdmgr_cmd_list=( 'build-firmware' 'clear-history' 'clear-offline' 'clear-results' 'downgrade' 'get-details' 'get-devices' 'get-history' 'get-releases' 'get-remotes' 'get-results' 'get-updates' 'hwids' 'install' 'install-prepared' 'modify-remote' 'monitor' 'refresh' 'report-history' 'smbios-dump' 'unlock' 'update' 'verify' 'verify-update' '--version' ) _fwupdmgr_opts=( '--verbose' '--offline' '--allow-reinstall' '--allow-older' '--force' '--assume-yes' '--no-unreported-check' '--no-metadata-check' '--no-reboot-check' ) _show_modifiers() { COMPREPLY+=( $(compgen -W '${_fwupdmgr_opts[@]}' -- "$cur") ) } _show_device_ids() { local description OLDIFS=$IFS IFS=$'\n' description="$(command fwupdmgr get-devices | command awk '!/DeviceId/ { line = $0 }; /DeviceId/ { print $2 " {" line "}"}')" COMPREPLY+=( $(compgen -W "${description}" -- "$cur") ) IFS=$OLDIFS } _show_remotes() { local remotes remotes="$(command fwupdmgr get-remotes | command awk '/Remote ID/ { print $3 }')" COMPREPLY+=( $(compgen -W "${remotes}" -- "$cur") ) } _fwupdmgr() { local cur prev command COMPREPLY=() cur=`_get_cword` prev=${COMP_WORDS[COMP_CWORD-1]} command=${COMP_WORDS[1]} case $command in clear-results|downgrade|get-releases|get-results|unlock|verify|verify-update) if [[ "$prev" = "$command" ]]; then _show_device_ids else _show_modifiers fi ;; get-details|smbios-dump) #browse for file if [[ "$prev" = "$command" ]]; then _filedir #modifiers else _show_modifiers fi ;; install) #find files if [[ "$prev" = "$command" ]]; then _filedir #device ID or modifiers elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then _show_device_ids _show_modifiers #modifiers else _show_modifiers fi ;; modify-remote) #find remotes if [[ "$prev" = "$command" ]]; then _show_remotes #add key elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then local keys keys="$(command fwupdmgr get-remotes | command awk -v pattern="Remote ID:.*${prev}$" '$0~pattern{show=1; next}/Remote/{show=0}{gsub(/:.*/,"")}show')" COMPREPLY+=( $(compgen -W "${keys}" -- "$cur") ) fi ;; refresh) #find first file if [[ "$prev" = "$command" ]]; then _filedir #find second file elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then _filedir #find remote ID elif [[ "$prev" = "${COMP_WORDS[3]}" ]]; then _show_remotes else _show_modifiers fi ;; build-firmware) #file in if [[ "$prev" = "$command" ]]; then _filedir #file out elif [[ "$prev" = "${COMP_WORDS[2]}" ]]; then _filedir #script elif [[ "$prev" = "${COMP_WORDS[3]}" ]]; then _filedir #output elif [[ "$prev" = "${COMP_WORDS[4]}" ]]; then _filedir else _show_modifiers fi ;; *) #find first command if [[ ${COMP_CWORD} = 1 ]]; then COMPREPLY=( $(compgen -W '${_fwupdmgr_cmd_list[@]}' -- "$cur") ) #modifiers for all commands else _show_modifiers fi ;; esac return 0 } complete -F _fwupdmgr fwupdmgr fwupd-1.0.6/data/bash-completion/meson.build000066400000000000000000000001341325145456600210130ustar00rootroot00000000000000install_data([ 'fwupdmgr', ], install_dir : 'share/bash-completion/completions/', ) fwupd-1.0.6/data/builder/000077500000000000000000000000001325145456600152155ustar00rootroot00000000000000fwupd-1.0.6/data/builder/README.md000066400000000000000000000045751325145456600165070ustar00rootroot00000000000000Building Firmware ================= Most of the time when you’re distributing firmware you have permission from the OEM or ODM to redistribute the non-free parts of the system firmware, e.g. Dell can re-distribute the proprietary Intel Management Engine as part as the firmware capsule that gets flashed onto the hardware. In some cases that’s not possible, for example for smaller vendors or people selling OpenHardware. For reasons (IFD, FMAP and CBFS…) you need to actually build the target firmware on the system you’re deploying onto, where build means executing random low-level tools to push random blobs of specific sizes into specific unnecessarily complex partition formats rather than actually compiling .c into executable code. The solution of a manually updated interactive bash script isn’t awesome from a user-experience or security point of view. The other things that might be required is a way to `dd` a few bytes of randomness into the target image at a specific offset and also to copy the old network MAC address into the new firmware. The firmware-builder functionality allows you to ship an archive (typically in `.tar` format, as the `.cab` file will be compressed already) within the `.cab` file as the main “release”. Within the `.tar` archive will be a startup.sh file and all the utilities or scripts needed to run the build operation, statically linked if required. At firmware deploy time fwupd will explode the tar file into a newly-created temp directory, create a bubblewrap container which has no network and limited file-system access and then run the startup.sh script. Once complete, fwupd will copy out just the `firmware.bin` file and then destroy the bubblewrap container and the temporary directory. This is the directory that is available to the bubble-wrap confined script. If, for instance, a plugin needs the old system firmware blob (for a bsdiff) then the plugin can write to this directory and the startup.sh script will be able to access it as the chroot-ed `/boot`. Firmware `.cab` files using this funtionality should list the `.tar` file: and also should include the name of the script to run as additional metadata: startup.sh firmware.bin fwupd-1.0.6/data/builder/meson.build000066400000000000000000000001411325145456600173530ustar00rootroot00000000000000install_data('README.md', install_dir : join_paths(localstatedir, 'lib', 'fwupd', 'builder') ) fwupd-1.0.6/data/daemon.conf000066400000000000000000000004441325145456600157030ustar00rootroot00000000000000[fwupd] # Allow blacklisting specific devices by their GUID # Uses semicolons as delimiter BlacklistDevices= # Allow blacklisting specific plugins # Uses semicolons as delimiter BlacklistPlugins=test # Maximum archive size that can be loaded in Mb, with 0 for the default ArchiveSizeMax=0 fwupd-1.0.6/data/fwupd-offline-update.service.in000066400000000000000000000003231325145456600216010ustar00rootroot00000000000000[Unit] Description=Updates device firmware whilst offline Documentation=man:fwupdmgr OnFailure=reboot.target ConditionPathExists=/var/lib/fwupd/pending.db [Service] ExecStart=@bindir@/fwupdmgr install-prepared fwupd-1.0.6/data/fwupd.service.in000066400000000000000000000007631325145456600167110ustar00rootroot00000000000000[Unit] Description=Firmware update daemon Documentation=http://www.fwupd.org/ After=dbus.service Before=gdm.service [Service] Type=dbus BusName=org.freedesktop.fwupd ExecStart=@libexecdir@/fwupd/fwupd MemoryDenyWriteExecute=yes PrivateTmp=yes ProtectControlGroups=yes ProtectHome=yes ProtectKernelModules=yes ProtectSystem=full RestrictAddressFamilies=AF_NETLINK AF_UNIX RestrictRealtime=yes ReadWritePaths=@localstatedir@/lib/fwupd @sysconfdir@/fwupd/remotes.d -@bootdir@ SystemCallFilter=~@mount fwupd-1.0.6/data/installed-tests/000077500000000000000000000000001325145456600167065ustar00rootroot00000000000000fwupd-1.0.6/data/installed-tests/fakedevice123.bin000066400000000000000000000000211325145456600217050ustar00rootroot00000000000000fakedevice123 -n fwupd-1.0.6/data/installed-tests/fakedevice123.bin.asc000066400000000000000000000007521325145456600224650ustar00rootroot00000000000000-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQEcBAABAgAGBQJZQqynAAoJEEim2A5FOLrCVcsH/3Vn56wSeRCol0rOeXvoupg2 qpTAmqUvlubv2vX1IDbcL/lHIIEAHAlN/4LRHUh+Om0T7bMKX1uSfmcgCyUTBxl0 fm3TfXRhybi9VtZ5ZpwWxGsFsCNC9eOU0i8tB1zp9e9KjDPiYnluFkTRQ+Aw3u1u tKBMTk6Z+VQlIUFrsveFYmPMGDkvn8AWbJCz6E4jc8can/lP/9djSi91mCqtEq/j YTBz4OwfU80MRrSgoxykHgcB1RiT43ywfKlpHQzcO+rqCV7rv7LkXIEzBdWRZstk XmboCnEKuMxtr+vXlGqU4n+upQkYur3Vs+07ut1OewQnJT3eeZbAH0mr42MVf7c= =MQJe -----END PGP SIGNATURE----- fwupd-1.0.6/data/installed-tests/fakedevice123.metainfo.xml000066400000000000000000000017571325145456600235570ustar00rootroot00000000000000 fakedevice.firmware FakeDevice Firmware Firmware for the ACME Corp Integrated Webcam

Updating the firmware on your webcam device improves performance and adds new features.

b585990a-003e-5270-89d5-3705a17f9a43 http://www.acme.com/ CC0-1.0 GPL-2.0+ ACME Corp

Fixes a bug with the flux capacitor to avoid year 2038 overflow.

fwupd-1.0.6/data/installed-tests/fakedevice124.bin000066400000000000000000000000211325145456600217060ustar00rootroot00000000000000fakedevice124 -n fwupd-1.0.6/data/installed-tests/fakedevice124.bin.asc000066400000000000000000000007521325145456600224660ustar00rootroot00000000000000-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQEcBAABAgAGBQJZQqy9AAoJEEim2A5FOLrCRLEH/27k0IfUtfGS8T5CPTvwW8kF Cf6EIzw+2HgjbxLdeMNHwiHCBdIR58z44O1I9Xy6gY1vF3H4kKft6oBAUFDH0Ja5 YpQHXMZVSNdnwdg57cyC67kLOycHTSDlLXKB74tU3R4J8xntA1cY+DSYmCs2uAjq 3T3ExfjrX6PGbRhbNr8vBUQckCxcGvEZNOws2081mTosEQNpIxFyJ2tbbKLR60d0 5O/UDjNEYfUFCGy7MycXePEIOR+rO6KuEQ3vjJnv80UKE8msFxJTM1iKwct+B2HI JNecCsx14BGDXCiE0Xc0heunfWiBHmNS2lymrHsU2Z82VrFqP0obD2cm64PBf0Y= =Wsq/ -----END PGP SIGNATURE----- fwupd-1.0.6/data/installed-tests/fakedevice124.metainfo.xml000066400000000000000000000017711325145456600235540ustar00rootroot00000000000000 fakedevice.firmware FakeDevice Firmware Firmware for the ACME Corp Integrated Webcam

Updating the firmware on your webcam device improves performance and adds new features.

b585990a-003e-5270-89d5-3705a17f9a43 http://www.acme.com/ CC0-1.0 GPL-2.0+ ACME Corp

Fixes another bug with the flux capacitor to prevent time going backwards.

fwupd-1.0.6/data/installed-tests/firmware-example.xml.gz000066400000000000000000000025211325145456600233140ustar00rootroot00000000000000BYfirmware-bab11b5af4caaec75b0c715b06781a36b93d1f03.xmlWYo7~ϯ X,dAZ7R@11C]Yq}guXsXv]Al;ù7Ǻ"eۜelB3Mhc,βs^ 4CT+%.gUp,]ql(/< pY)~)49U!*[N_׵!ImG%Wn`ѹ"|plzص!@ծ5|s6#٩/Ç jzۜO]|r5`*˺6irծ;FHvU!e&/'&V?&cOؐnXwO| k}UX5`9 f3q t6E*p=MP^iSDκ[ xβbʿaO֪͙3Aci֍zhVmpۄǴz̫%G(NeuܦxO]"$ѶH]( kLά*?"q9 Ϧ% g#Rβ{:p\@ /h95> %`4q+Y.D*QC/`ϽA\d'8O%,%Aa;YwvM^M9,wQ?V.-Yu؎# Ȣ{Ȼpt9ݣhIЌF8pJ[ZCxO$DBL"5W,Eé1h'Y[kBB-1&di.JQD-|e[Fr# wj7'czGeo\^e-u9r\hlfu+}}v<0O2Yn{^/Nkarm [yIK|y F(>1뉾Ó[ɓ0DJ5D2BHrpMThm D!W)šO^zPz&N$VX>0Қ7I{[̟{@2F1(AF#0bQx}( ($|,{r\~3ktf V#KdG,'b8-O&(>!|Vս4u+n0FA"O/!3.VL!'EPsdV$8V%9" wY|:@L!' \Efwupd-1.0.6/data/installed-tests/firmware-example.xml.gz.asc000066400000000000000000000007521325145456600240650ustar00rootroot00000000000000-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQEcBAABAgAGBQJZQqy+AAoJEEim2A5FOLrCjuEH/1wIRvQ9FIUqQ2wV5pQRjF99 wTd1+VtQCPHkBXvMnrF2cnhNhr13lN8BhuY3kgT9TGQCPNM+8akNvDLKWiR/39rP z+v6KpgaYA5kghFskvW4t/1lQ+Jj+PKExb1bAusexdVvRD1iEDZ0q8u/DRGwrjYn GFbHD3K91B4nIzYQVHa8+9gRRH2uKa2U9foH3++e/PAPQCoGHa6gxV3zM05AiEpA Am5G5u8v5WnL9W9H53unj9M47iAlzdxStzK4poshlJoNITLw9SLl6rmrgMYLHVfD QyZTM8jSjFc+V1swslLNMVCkCWfx3ClzkEff50HKua/BxMxxJscShX43On59cik= =XhuO -----END PGP SIGNATURE----- fwupd-1.0.6/data/installed-tests/fwupdmgr.sh000077500000000000000000000041421325145456600211010ustar00rootroot00000000000000#!/bin/bash exec 2>&1 dirname=`dirname $0` # --- echo "Getting the list of remotes..." fwupdmgr get-remotes rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Refreshing with dummy metadata..." fwupdmgr refresh ${dirname}/firmware-example.xml.gz ${dirname}/firmware-example.xml.gz.asc lvfs rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Update the device hash database..." fwupdmgr verify-update rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Getting devices (should be one)..." fwupdmgr get-devices rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Testing the verification of firmware..." fwupdmgr verify rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Getting updates (should be one)..." fwupdmgr --no-unreported-check --no-metadata-check get-updates rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Installing test firmware..." fwupdmgr install ${dirname}/fakedevice124.cab rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Getting updates (should be none)..." fwupdmgr --no-unreported-check --no-metadata-check get-updates rc=$?; if [[ $rc != 2 ]]; then exit $rc; fi # --- echo "Testing the verification of firmware (again)..." fwupdmgr verify rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Downgrading to older release (requires network access)" fwupdmgr downgrade rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Downgrading to older release (should be none)" fwupdmgr downgrade rc=$?; if [[ $rc != 2 ]]; then exit $rc; fi # --- echo "Updating all devices to latest release (requires network access)" fwupdmgr --no-unreported-check --no-metadata-check --no-reboot-check update rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Getting updates (should be none)..." fwupdmgr --no-unreported-check --no-metadata-check get-updates rc=$?; if [[ $rc != 2 ]]; then exit $rc; fi # --- echo "Refreshing from the LVFS (requires network access)..." fwupdmgr refresh rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # --- echo "Flashing actual devices (requires specific hardware)" ${dirname}/hardware.py rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi # success! exit 0 fwupd-1.0.6/data/installed-tests/fwupdmgr.test.in000066400000000000000000000001011325145456600220370ustar00rootroot00000000000000[Test] Type=session Exec=sh -c "@installedtestsdir@/fwupdmgr.sh" fwupd-1.0.6/data/installed-tests/hardware.py000077500000000000000000000155111325145456600210630ustar00rootroot00000000000000#!/usr/bin/python3 # pylint: disable=wrong-import-position,too-many-locals,unused-argument,wrong-import-order # # Copyright (C) 2017 Richard Hughes # Licensed under the GNU General Public License Version 2 import gi import os import requests import time gi.require_version('Fwupd', '2.0') from gi.repository import Fwupd from gi.repository import Gio from gi.repository import GLib def _get_by_device_guid(client, guid): cancellable = Gio.Cancellable.new() devices = client.get_devices(cancellable) for d in devices: if d.has_guid(guid): return d return None def _get_cache_file(fn): cachedir = os.path.expanduser('~/.cache/fwupdmgr') if not os.path.exists(cachedir): os.makedirs(cachedir) cachefn = os.path.join(cachedir, fn) if not os.path.exists(cachefn): url = 'https://fwupd.org/downloads/' + fn print("Downloading", url) r = requests.get(url) r.raise_for_status() f = open(cachefn, 'wb') f.write(r.content) f.close() return cachefn class Test: def __init__(self, name, guid): self.files = [] self.name = name self.guid = guid def run(self): # connect to fwupd client = Fwupd.Client.new() dev = _get_by_device_guid(client, self.guid) if not dev: print("Skipping hardware test, no", self.name, "attached") return print(dev.get_name(), "is currently version", dev.get_version()) # apply each file for fn, ver in self.files: fn_cache = _get_cache_file(fn) if dev.get_version() == ver: flags = Fwupd.InstallFlags.ALLOW_REINSTALL else: flags = Fwupd.InstallFlags.ALLOW_OLDER cancellable = Gio.Cancellable.new() print("Installing", fn_cache) client.install(dev.get_id(), fn_cache, flags, cancellable) # verify version dev = _get_by_device_guid(client, self.guid) if not dev: raise GLib.Error('Device did not come back: ' + name) if not dev.get_version(): raise GLib.Error('No version set after flash for: ' + name) if dev.get_version() != ver: raise GLib.Error('Got: ' + dev.get_version() + ', expected: ' + ver) # FIXME: wait for device to settle? time.sleep(2) def add_file(self, fn, ver): self.files.append((fn, ver)) if __name__ == '__main__': tests = [] # DFU A3BU XPLAINED Mouse test = Test('DfuXmegaA3BU-Xplained', '80478b9a-3643-5e47-ab0f-ed28abe1019d') test.add_file('90c381f1c5932a7f9505372305a615ca000e68df-a3bu-xplained123.cab', '1.23') test.add_file('24d838541efe0340bf67e1cc5a9b95526e4d3702-a3bu-xplained124.cab', '1.24') tests.append(test) # DFU AT90USBKEY Mouse test = Test('DfuAT90USBKEY', 'c1874c52-5f6a-5864-926d-ea84bcdc82ea') test.add_file('b6bef375597e848971f230cf992c9740f7bf5b92-at90usbkey123.cab', '1.23') test.add_file('47807fd4a94a4d5514ac6bf7a73038e00ed63225-at90usbkey124.cab', '1.24') tests.append(test) # Logitech K780 Keyboard test = Test('LogitechMPK01', '3932ba15-2bbe-5bbb-817e-6c74e7088509') test.add_file('d81a81e13952e871ca2eb86cba7e66199e576a38-Logitech-K780-MPK01.02_B0021.cab', 'MPK01.02_B0021') test.add_file('b0dffe84c6d3681e7ae5f27509781bc1cf924dd7-Logitech-K780-MPK01.03_B0024.cab', 'MPK01.03_B0024') tests.append(test) # Hughski ColorHug (a special variant) using 'dfu' test = Test('ColorHugDFU', 'dfbaaded-754b-5214-a5f2-46aa3331e8ce') test.add_file('77b315dcaa7edc1d5fbb77016b94d8a0c0133838-fakedevice01_dfu.cab', '0.1') test.add_file('8bc3afd07a0af3baaab8b19893791dd3972e8305-fakedevice02_dfu.cab', '0.2') tests.append(test) # Hughski ColorHug2 using 'colorhug' test = Test('ColorHug2', '2082b5e0-7a64-478a-b1b2-e3404fab6dad') test.add_file('170f2c19f17b7819644d3fcc7617621cc3350a04-hughski-colorhug2-2.0.6.cab', '2.0.6') test.add_file('0a29848de74d26348bc5a6e24fc9f03778eddf0e-hughski-colorhug2-2.0.7.cab', '2.0.7') tests.append(test) # Hughski ColorHugALS using 'colorhug' test = Test('ColorHugALS', '84f40464-9272-4ef7-9399-cd95f12da696') test.add_file('73ac1aa98130e532c727308cc6560783b10ca3a9-hughski-colorhug-als-4.0.2.cab', '4.0.2') test.add_file('8dbdd54c712b33f72d866ce3b23b3ceed3ad494d-hughski-colorhug-als-4.0.3.cab', '4.0.3') tests.append(test) # Logitech Unifying Receiver (RQR12) using 'unifying' test = Test('UnifyingRQR12', '9d131a0c-a606-580f-8eda-80587250b8d6') test.add_file('6e5ab5961ec4c577bff198ebb465106e979cf686-Logitech-Unifying-RQR12.05_B0028.cab', 'RQR12.05_B0028') test.add_file('938fec082652c603a1cdafde7cd25d76baadc70d-Logitech-Unifying-RQR12.07_B0029.cab', 'RQR12.07_B0029') tests.append(test) # Logitech Unifying Receiver (RQR24) using 'unifying' test = Test('UnifyingRQR24', 'cc4cbfa9-bf9d-540b-b92b-172ce31013c1') test.add_file('82b90b2614a9a4d0aced1ab8a4a99e228c95585c-Logitech-Unifying-RQ024.03_B0027.cab', 'RQR24.03_B0027') test.add_file('4511b9b0d123bdbe8a2007233318ab215a59dfe6-Logitech-Unifying-RQR24.05_B0029.cab', 'RQR24.05_B0029') tests.append(test) # Jabra Speak 510 test = Test('JabraSpeak510', '443b9b32-7603-5c3a-bb30-291a7d8d6dbd') test.add_file('45f88c50e79cfd30b6599df463463578d52f2fe9-Jabra-SPEAK_510-2.10.cab', '2.10') test.add_file('c0523a98ef72508b5c7ddd687418b915ad5f4eb9-Jabra-SPEAK_510-2.14.cab', '2.14') tests.append(test) # Jabra Speak 410 test = Test('JabraSpeak410', '1764c519-4723-5514-baf9-3b42970de487') test.add_file('eab97d7e745e372e435dbd76404c3929730ac082-Jabra-SPEAK_410-1.8.cab', '1.8') test.add_file('50a03efc5df333a948e159854ea40e1a3786c34c-Jabra-SPEAK_410-1.11.cab', '1.11') tests.append(test) # Jabra Speak 710 test = Test('JabraSpeak710', '0c503ad9-4969-5668-81e5-a3748682fc16') test.add_file('d2910cdbc45cf172767d05e60d9e39a07a10d242-Jabra-SPEAK_710-1.10.cab', '1.10') test.add_file('a5c627ae42de4e5c3ae3df28977f480624f96f66-Jabra-SPEAK_710-1.28.cab', '1.28') tests.append(test) # 8Bitdo SFC30 Gamepad test = Test('8BitdoSFC30', 'a7fcfbaf-e9e8-59f4-920d-7691dc6c8699') test.add_file('fe066b57c69265f4cce8a999a5f8ab90d1c13b24-8Bitdo-SFC30_NES30_SFC30_SNES30-4.01.cab', '4.01') tests.append(test) # 8Bitdo NES30Pro Gamepad test = Test('8BitdoNES30Pro', 'c6566b1b-0c6e-5d2e-9376-78c23ab57bf2') test.add_file('1cb9a0277f536ecd81ca1cea6fd80d60cdbbdcd8-8Bitdo-SFC30PRO_NES30PRO-4.01.cab', '4.01') tests.append(test) # run each test rc = 0 for test in tests: try: test.run() except GLib.Error as e: print(str(e)) rc = 1 except requests.exceptions.HTTPError as e: print(str(e)) rc = 1 fwupd-1.0.6/data/installed-tests/meson.build000066400000000000000000000024001325145456600210440ustar00rootroot00000000000000con2 = configuration_data() con2.set('installedtestsdir', join_paths(datadir, 'installed-tests', 'fwupd')) con2.set('bindir', bindir) configure_file( input : 'fwupdmgr.test.in', output : 'fwupdmgr.test', configuration : con2, install: true, install_dir: join_paths('share', 'installed-tests', 'fwupd'), ) install_data([ 'fwupdmgr.sh', 'firmware-example.xml.gz', 'firmware-example.xml.gz.asc', 'hardware.py', ], install_dir : 'share/installed-tests/fwupd', ) gcab = find_program('gcab', required : false) if gcab.found() custom_target('installed-cab123', input : [ 'fakedevice123.bin', 'fakedevice123.bin.asc', 'fakedevice123.metainfo.xml', ], output : 'fakedevice123.cab', command : [ gcab, '--create', '--nopath', '@OUTPUT@', '@INPUT@', ], install: true, install_dir: join_paths('share', 'installed-tests', 'fwupd'), ) custom_target('installed-cab124', input : [ 'fakedevice124.bin', 'fakedevice124.bin.asc', 'fakedevice124.metainfo.xml', ], output : 'fakedevice124.cab', command : [ gcab, '--create', '--nopath', '@OUTPUT@', '@INPUT@', ], install: true, install_dir: join_paths('share', 'installed-tests', 'fwupd'), ) endif fwupd-1.0.6/data/meson.build000066400000000000000000000032071325145456600157330ustar00rootroot00000000000000subdir('builder') subdir('pki') subdir('remotes.d') subdir('bash-completion') if get_option('tests') subdir('tests') subdir('installed-tests') endif install_data(['daemon.conf'], install_dir : join_paths(sysconfdir, 'fwupd') ) install_data(['org.freedesktop.fwupd.metainfo.xml'], install_dir: join_paths(datadir, 'metainfo') ) install_data(['org.freedesktop.fwupd.conf'], install_dir : join_paths(sysconfdir, 'dbus-1', 'system.d') ) install_data(['metadata.xml'], install_dir : join_paths(datadir, 'fwupd', 'remotes.d', 'fwupd') ) install_data(['90-fwupd-devices.rules'], install_dir : join_paths(udevdir, 'rules.d') ) con2 = configuration_data() con2.set('libexecdir', libexecdir) con2.set('bindir', bindir) con2.set('localstatedir', localstatedir) con2.set('datadir', datadir) con2.set('bootdir', get_option('bootdir')) con2.set('sysconfdir', default_sysconfdir) # replace @libexecdir@ configure_file( input : 'org.freedesktop.fwupd.service.in', output : 'org.freedesktop.fwupd.service', configuration : con2, install: true, install_dir: join_paths(datadir, 'dbus-1', 'system-services'), ) if get_option('systemd') # replace @bindir@ configure_file( input : 'fwupd-offline-update.service.in', output : 'fwupd-offline-update.service', configuration : con2, install: true, install_dir: systemdunitdir, ) endif if get_option('systemd') # replace @localstatedir@, @sysconfdir@ and @bootdir@ configure_file( input : 'fwupd.service.in', output : 'fwupd.service', configuration : con2, install: true, install_dir: systemdunitdir, ) endif fwupd-1.0.6/data/metadata.xml000066400000000000000000000075451325145456600161040ustar00rootroot00000000000000 UEFI-dummy-dev0 2d47f29b-83a2-4f31-a2e8-63474f4d4c2e UEFI Updates Enable UEFI Update Functionality

Applying this update will enable the UEFI firmware reporting interface on your hardware.

You will have to restart your computer after this update is installed to be notified of any pending firmware updates.

com.via.VL811.firmware adbb9034-b577-42c2-a661-1ee4f49ef64c VL811 Firmware Firmware for VIA USB 3.0 hub VIA http://www.via.com.tw/

This stable release fixes the following problems with USB 3.0:

  • Do not wake during transition to S4
  • Do not drop from Apple USB 3.0 Host during S3/S4 and Device PnP
  • Do not drop during S3/S4 when connected to native Intel and AMD Hosts

This stable release fixes the following problems with USB 2.0:

  • Do not drop from Apple USB 3.0 Host during S3/S4 and Device PnP
com.via.VL811+.firmware 54f84d05-c917-4c50-8b35-44feabaaa323 VL811+ Firmware Firmware for VIA USB 3.0 hub VIA http://www.via.com.tw/ com.via.VL812.firmware cd0314ec-b80f-4d1a-a24f-c409183a8b2d VL812 Firmware Firmware for VIA USB 3.0 hub VIA http://www.via.com.tw/ com.via.VL812_B2.firmware 26470009-97a8-4028-867a-bbbac6ee7bf0 VL812 B2 Firmware Firmware for VIA USB 3.0 hub VIA http://www.via.com.tw/
fwupd-1.0.6/data/org.freedesktop.fwupd.conf000066400000000000000000000020231325145456600206600ustar00rootroot00000000000000 fwupd-1.0.6/data/org.freedesktop.fwupd.metainfo.xml000066400000000000000000000023421325145456600223400ustar00rootroot00000000000000 org.freedesktop.fwupd CC0-1.0 GPL-2.0+ fwupd Update device firmware on Linux

This project aims to make updating firmware on Linux automatic, safe and reliable. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the D-Bus interface directly.

The fwupd process is a simple daemon to allow session software to update device firmware on your local machine. It is designed for desktops, but this project is also usable on phones, tablets and on headless servers.

https://github.com/hughsie/fwupd/issues http://www.fwupd.org/ https://www.transifex.com/freedesktop/fwupd/ richard_at_hughsie.com fwupd
fwupd-1.0.6/data/org.freedesktop.fwupd.service.in000066400000000000000000000002241325145456600220010ustar00rootroot00000000000000[D-BUS Service] Name=org.freedesktop.fwupd Documentation=http://www.fwupd.org/ Exec=@libexecdir@/fwupd/fwupd User=root SystemdService=fwupd.service fwupd-1.0.6/data/pki/000077500000000000000000000000001325145456600143525ustar00rootroot00000000000000fwupd-1.0.6/data/pki/GPG-KEY-Hughski-Limited000066400000000000000000000032461325145456600203320ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 mQENBFUr0UoBCACsdOLuTJ81dICrSvUhyznBsL4WgEa2RUbEjJuaXwrEyPMikHE1 Clda2YI7VbpCgIVq8Zy63CGJ4Xqs2T6pyetaXnbX8J0C+7wg2IfPv7pUyCsP7/JR HRB2GNelCWrsGArN1cOPI0ESH4yHWKF9KCGlpsLfSHmvF7D8vcKlKQUlO4T6lxOP SNjMSXkMsxfDDhl1mzqrwxfU4V6nnPcuMwU7tvg+39PioP4Ny1tKP4SSpBfh7qwz XXRd505dqNLOubxmOPZ5rznVkKmW2cwahO6fr5zVA8/2TDZQ79mdbfvSJVlW06qs C5PYmLnBjyzE5uQ4oxSIuUEiMfqrn3Qs6PhhABEBAAG0Ikh1Z2hza2kgTGltaXRl ZCA8aW5mb0BodWdoc2tpLmNvbT6JATgEEwECACIFAlUr0UoCGwMGCwkIBwMCBhUI AgkKCwQWAgMBAh4BAheAAAoJEK2KUo/sRIge/fUH/Rblgzh5GeB0Zp2U9W+r26iJ t1AD5a/fKxQahz/pwMkevQCCMzI1vpX12P3HtACZOD3Zjh9RXY6Z3033YZjrRApe FkOVfcyUF1nP/z2Ox3jE3+B8v1u0UzH/MqtF/1095mqvR7gllE288KDqu7bvd5l3 z4IETk5qqoeCe9LYc8aob973dbocyS/gou/FLCKxoXVEe8DPRwv8qmXlXOujxdxd FcslpYqtjj4fgUswQ/cY/a1UcAX5zCnVqFbU7oJH2uTNewKuaZ2wgPbnzvwx8JYl VfFdPN7GZ0NMrZDLeJ0SLXer/9+qAKNH4UpQS9axXQL+VKOzsZCXuv31VDCj5Jy5 AQ0EVSvRSgEIAMgVrZP3LmA9bx7B8l+agVh5DNXrMixX9jhZ0Yfn8+UIMMNTZziD ZV3nXxswKPrcsqQ+KP9iUwq3V2oio46bvHiMMoZSGCaTv4yiKOliFOMYr9NAOSTZ 8mOI24dNXI9XqQ7ZA8m4uKmgHZQUIUUlx693uRI2Wmk/Y5XEBoL2+XdA5KalO+36 27YXpdyU3GiMCOtSBLWNfBxXw6oKdNUp+8o/fYrmQnBxuGgmVlcZEmjhrIGXaCH1 iDeWIFqaM/S+DXMF3bgqvqRZq1U2RwT2oxapAuaG/0I5JaKKpb3HqMCXfOUxpFPk zgUYpHatUcePG/94K8N8CRjnJ+l83H5PewcAEQEAAYkBHwQYAQIACQUCVSvRSgIb DAAKCRCtilKP7ESIHrrcCACc6UTZzVGbVq9pXSz2Bw2xQpAEAhnnedPgfXwEJMM0 24bMUNsyJcQZAW1d5KfJYNAihOfse3oDQ/hJAycTK3GAHsPfljEQjWGn27eC8Fxu mHpfNpxbTirChfepCNctZG818Hp2v+K4X/PjyQMQ6J5H9oinnlasVQ6wzdZifnWm 7E5OL0NV/ni9xqq4fC5y5qxNBeYVmHUF4H0E3VOuCbESAOnUDpCo998Dc68eZEmV f3IMukvvnxM9VOZQSnp7J/kkhPB5fim2z2qrlJK9N+tBjAMugxtnAV2fIaZYTiba SnN2hheFd9Y0nMmWbwRqFtwMG1m/tS3JlD52Rpwzk59B =WFoi -----END PGP PUBLIC KEY BLOCK----- fwupd-1.0.6/data/pki/GPG-KEY-Linux-Vendor-Firmware-Service000066400000000000000000000016771325145456600230530ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 mQENBFWt/98BCADZ4+lUHSp4OMlzVf4HlJNLJ7Ks5QxGwL/hy2wChoNLuA/j4GNM 9mBZutKynYmphD0Mi4XjXn7JNXyuJa8Qutz98/Iyhsjq4LeiL9ayaKMXT+3pKlTm Gd/Fzo3QEOqTJ5s2RamrfwFIVuvwoj+rNmzj5fUCgoDOZeqVl6gxb7ZPzL8sWTOU iLeGMSzZBGE0ioJ82PZzsHelrrObDP1mMre1jQ6zxLlnYUlLvtJpydAfeBxU+6yL fgPeoFeuCE6JIszyWuyAgpBpYSGgj1bpt9Sxc2+MoZ0BjDzoijZqt4O48gYuEaLf iqYzQybe1JF0McO4C0dmjdKQz2qm0XrQyNhVABEBAAG0LkxpbnV4IFZlbmRvciBG aXJtd2FyZSBTZXJ2aWNlIDxzaWduQGZ3dXBkLm9yZz6JATcEEwEIACEFAlWt/98C GwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQSKbYDkU4usJjjQgAzmTcA8qH s+1kieEZvsUzH4wun2Hlz7R5FRc/7BijgIQAA9TTrJnwbJmEBzEvHv7FKQLiBN3a 0lQIZgahmcUt1qm6VW94VAio+SDCdqTx73wUsgM3t9sAwKxkEdJQQoO8PqYHV3uK rq0t2YjXglIBHRDiJlOTAR3if37OCDKCcHOOODqYrsN7wNleez+ulkDyP7C7ZTbm /A7Xec73t2OQUnejU0uvRvc7VSnQDRFBHA9TPiBhbruMw+ZX+z/wfPd7x2RCqoOE vHh+QofE41Ya2QOkT96fAKfcJ+gvIbmwp3w7h+Hus1h3xDrykCG9cCxuH0HxooVI XL3IlFx/6OUpBA== =6Dz2 -----END PGP PUBLIC KEY BLOCK----- fwupd-1.0.6/data/pki/LVFS-CA.pem000066400000000000000000000032171325145456600161130ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEqjCCAxKgAwIBAgIBATANBgkqhkiG9w0BAQsFADA6MRAwDgYDVQQDEwdMVkZT IENBMSYwJAYDVQQKEx1MaW51eCBWZW5kb3IgRmlybXdhcmUgUHJvamVjdDAeFw0x NzA4MDEwMDAwMDBaFw00NzA4MDEwMDAwMDBaMDoxEDAOBgNVBAMTB0xWRlMgQ0Ex JjAkBgNVBAoTHUxpbnV4IFZlbmRvciBGaXJtd2FyZSBQcm9qZWN0MIIBojANBgkq hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtfUXH3NwDJzWyhkPyPcFI899+tPZ/SMp OkDtRr9dJjgQkSO9jKCue4DVq8Bd9RcL76F7XnEKG0LiuKnr+D7+x86TtDAPCbkP WAS7fAaetLtiNFU96cokhjeALB3hyamkMQnCw+5Ov+sHJfGI9Bor9UaIIbIB4r8v oU1WpE7N6Ix2qsS5b88+Z6EIV6CX8RbciOC/TfyYVnpF1cd4l7LH7TtL+ERpsPwv rk0JgVoRzG3BT5yYfuxHIe4H4Axh95tW9i6urzyQkXRz14twwwcEDvl5ALrBLNJJ 8EDz9oR8HBPbxbd4i2dBfziY7TW4o/VgZKTGWA39JfwWNc5RxaYzBhBmg5nRcVFs E7PlovhyFH/0RNm/3E6vZQCeM+FNps0ovVq8Yqg8whL/yZ0iNlavCGTWhaxisVHG 7mQopV4jZlafxvrcBFzK8RPe8Gi04FFn4ugZtJnOuMel+AiADhgtWZCENiyWV+V7 WF1SFF4HaHuS8qqna/p9lrpVq6TBr0WRAgMBAAGjgbowgbcwEgYDVR0TAQH/BAgw BgEB/wIBATAwBgNVHREEKTAnhhVodHRwOi8vd3d3LmZ3dXBkLm9yZy+BDnNpZ25A Znd1cGQub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA8GA1UdDwEB/wQFAwMHBgAw HQYDVR0OBBYEFLGN6uQjp34JjrXuMeBq3Z40N2WsMCoGA1UdHwQjMCEwH6AdoBuG GWh0dHA6Ly93d3cuZnd1cGQub3JnL3BraS8wDQYJKoZIhvcNAQELBQADggGBABNK mC4AcqsBCVRGpwJeUymh5G6uUpzkoEDw+y9TEoWzfldV0epU7ruqI2p8B8YshDK6 +D4CFmCnW8cc+Jb6jrJ2ZcjUqWE/c+uwZhwsUHNdk6ummPPKfMhRSbduk1ngdQe5 meIgWGkoCfJ48GUAVVD6MlrMTNFsot1GN9x3ALMqhSU49+X43yikcc9WY2F8JOY8 xYpGpgUQV1hBSPOGK4XhgztpFLqw0GxJiLrOfKjtJwSTkxGCpPi2dLS0huk/mreT NAQ5FnMLkoqfR1RGga3tiP5w13gqDBV7a6MYMdmMfAAZhfRtlDu6SiAmjEmlSkOK PNhdoCNVDQLQpGaKZUI5hjMfR90U8Cm/6e0ondwjV4J6f4CS4wkQ5zzITGWptagE 01tpgTXf7TLaFGtzR8cl8XgV+UO3T4DQjEQkXUaS7n72ZCGv/s4LraLunhBrVHSq glEXpU/V/JNptgArIiRFZOrto52cUnnlNEfgqIzAHv/LMFRIkMo8ZMGTgScFrA== -----END CERTIFICATE----- fwupd-1.0.6/data/pki/meson.build000066400000000000000000000011121325145456600165070ustar00rootroot00000000000000if get_option('gpg') install_data([ 'GPG-KEY-Hughski-Limited', 'GPG-KEY-Linux-Vendor-Firmware-Service', ], install_dir : join_paths(sysconfdir, 'pki', 'fwupd') ) install_data([ 'GPG-KEY-Linux-Vendor-Firmware-Service', ], install_dir : join_paths(sysconfdir, 'pki', 'fwupd-metadata') ) endif if get_option('pkcs7') install_data([ 'LVFS-CA.pem', ], install_dir : join_paths(sysconfdir, 'pki', 'fwupd') ) install_data([ 'LVFS-CA.pem', ], install_dir : join_paths(sysconfdir, 'pki', 'fwupd-metadata') ) endif fwupd-1.0.6/data/remotes.d/000077500000000000000000000000001325145456600154675ustar00rootroot00000000000000fwupd-1.0.6/data/remotes.d/README.md000066400000000000000000000051621325145456600167520ustar00rootroot00000000000000Vendor Firmware =============== These are the steps to add vendor that is installed as part of an OSTree image: * Change `/etc/fwupd/remotes.d/vendor.conf` to have `Enabled=true` * Change `/etc/fwupd/remotes.d/vendor.conf` to have the correct `Title` * Deploy the firmware to `/usr/share/fwupd/remotes.d/vendor/firmware` * Deploy the metadata to `/usr/share/fwupd/remotes.d/vendor/vendor.xml` The metadata should be of the form: FIXME.firmware FIXME FIXME FIXME FIXME

FIXME

http://FIXME 86406 firmware/FIXME.cab 96a92915c9ebaf3dd232cfc7dcc41c1c6f942877

FIXME.

FIXME
Ideally, the metadata and firmware should be signed by either GPG or a PKCS7 certificate. If this is the case also change `Keyring=gpg` or `Keyring=pkcs7` in `/etc/fwupd/remotes.d/vendor.conf` and ensure the correct public key or signing certificate is installed in the `/etc/pki/fwupd` location. Mirroring a Repository ====================== The LVFS currently outputs XML with absolute URI locations, e.g. `http://foo/bar.cab` rather than `bar.cab` This makes mirroring the master LVFS (or other slave instance) somewhat tricky. To work around this issue client remotes can specify `FirmwareBaseURI` to replace the URI of the firmware before it is downloaded. For mirroring the LVFS content to a new CDN, you could use: [fwupd Remote] Enabled=true Type=download Keyring=gpg MetadataURI=https://my.new.cdn/mirror/firmware.xml.gz FirmwareBaseURI=https://my.new.cdn/mirror New instances of the LVFS can actually output a relative URL for firmware files, e.g. `bar.cab` and when downloading the `MetadataURI` name and path prefix is used in this case. This is not enabled for the "upstream" LVFS instance as versions of fwupd older than 1.0.3 are unable to automatically use the `MetadataURI` value for firmware downloads. fwupd-1.0.6/data/remotes.d/fwupd.conf000066400000000000000000000002641325145456600174650ustar00rootroot00000000000000[fwupd Remote] # this remote provides metadata shipped with the fwupd package Enabled=true Title=Core Keyring=none MetadataURI=file://@datadir@/fwupd/remotes.d/fwupd/metadata.xml fwupd-1.0.6/data/remotes.d/lvfs-testing.conf000066400000000000000000000005071325145456600207650ustar00rootroot00000000000000[fwupd Remote] # this remote provides metadata and firmware marked as 'testing' from the LVFS Enabled=false Title=Linux Vendor Firmware Service (testing) Keyring=gpg MetadataURI=https://cdn.fwupd.org/downloads/firmware-testing.xml.gz ReportURI=https://fwupd.org/lvfs/firmware/report Username= Password= OrderBefore=lvfs,fwupd fwupd-1.0.6/data/remotes.d/lvfs.conf000066400000000000000000000004321325145456600173070ustar00rootroot00000000000000[fwupd Remote] # this remote provides metadata and firmware marked as 'stable' from the LVFS Enabled=true Title=Linux Vendor Firmware Service Keyring=gpg MetadataURI=https://cdn.fwupd.org/downloads/firmware.xml.gz ReportURI=https://fwupd.org/lvfs/firmware/report OrderBefore=fwupd fwupd-1.0.6/data/remotes.d/meson.build000066400000000000000000000012641325145456600176340ustar00rootroot00000000000000if get_option('lvfs') install_data([ 'lvfs.conf', 'lvfs-testing.conf', ], install_dir : join_paths(sysconfdir, 'fwupd', 'remotes.d') ) endif install_data('README.md', install_dir : join_paths(datadir, 'fwupd', 'remotes.d', 'vendor', 'firmware') ) # replace @datadir@ con2 = configuration_data() con2.set('datadir', datadir) configure_file( input : 'fwupd.conf', output : 'fwupd.conf', configuration : con2, install: true, install_dir: join_paths(sysconfdir, 'fwupd', 'remotes.d'), ) configure_file( input : 'vendor.conf', output : 'vendor.conf', configuration : con2, install: true, install_dir: join_paths(sysconfdir, 'fwupd', 'remotes.d'), ) fwupd-1.0.6/data/remotes.d/vendor.conf000066400000000000000000000004321325145456600176320ustar00rootroot00000000000000[fwupd Remote] # this remote provides metadata shipped by the OS vendor and can be found in # /usr/share/fwupd/remotes.d/vendor and /usr/share/fwupd/remotes.d/vendor/firmware Enabled=false Title=Vendor Keyring=none MetadataURI=file://@datadir@/fwupd/remotes.d/vendor/vendor.xml.gz fwupd-1.0.6/data/tests/000077500000000000000000000000001325145456600147315ustar00rootroot00000000000000fwupd-1.0.6/data/tests/builder/000077500000000000000000000000001325145456600163575ustar00rootroot00000000000000fwupd-1.0.6/data/tests/builder/meson.build000066400000000000000000000005341325145456600205230ustar00rootroot00000000000000if get_option('tests') tar = find_program('tar') builder_test_firmware = custom_target('builder-test-firmware', input : [ 'source.bin', 'startup.sh', ], output : 'firmware.tar', command : [ tar, '--xform', 's,.*/,,', '--absolute-names', '--create', '--file', '@OUTPUT@', '@INPUT@', ], ) endif fwupd-1.0.6/data/tests/builder/source.bin000066400000000000000000000000261325145456600203470ustar00rootroot00000000000000running in the sandboxfwupd-1.0.6/data/tests/builder/startup.sh000077500000000000000000000000551325145456600204200ustar00rootroot00000000000000#/bin/sh cat source.bin | rev > firmware.bin fwupd-1.0.6/data/tests/colorhug/000077500000000000000000000000001325145456600165535ustar00rootroot00000000000000fwupd-1.0.6/data/tests/colorhug/README.md000066400000000000000000000004371325145456600200360ustar00rootroot00000000000000# Generating the p7b file manually: certtool --p7-detached-sign --p7-time \ --load-privkey LVFS/pkcs7/secure-lvfs.rhcloud.com.key \ --load-certificate LVFS/pkcs7/secure-lvfs.rhcloud.com_signed.pem \ --infile firmware.bin \ --outfile firmware.bin.p7b fwupd-1.0.6/data/tests/colorhug/firmware.bin000066400000000000000000000175001325145456600210640ustar00rootroot000000000000001 (~1 p~ 1(00'012!1 00@012!100@012!1@000001,!~ 1*! 02=!4W(4  9GHY(KJj(0G91H!!!3{(3  9GH}(ML(0G")! 0000@001!1# !Gw)0(1T!1(#!1!1)1'!1(#!18!1)1p!1!G")#!1!1)0 >000! ()00>00! ()0 >000! ()0!0000 >000! ))!^ !_ 1#1 W! V! U! T!0 >000! 5))$0!G)#!:N)!:N) 0!Gr)0?0@001x#1!GU)0?0000G1$1!H) )T:(:(:(:(:(:(:( :(:(:(/: )::) :@):(t)!3)3  9GH)ON)UG"!TG" 0!G@0H011#1!I0!G@0H011#!I B:*@98*! A:)! *! B@9:D9:D90[!2 : ,*D9>[D9>8*D9j>[D9>[_E*0[F*`N*`D9>S*`D9j>[A:t*`l*f*D9>i*D9>0`[0[`*0`[`00`[001$1* `0 [*`**D9>*D9>;0`[00`[001$1*;0 `[ D9>0=[\0]^[!*=00{0**! 2:+=+0 g!=+0 g=1!1=!+ 3+1%10 g!0 g=?+1!10 g=V+P+s0 0001$10 g=\+1!1=o+0 0001$1=0!2w+ =+ + go g 9h!0 g= o+!8>+!8>9 0g9g!+1%1+r0 0o0g001$10 g0i+=}+ 0 000 X0000Wc+Vb+Ua+T`,d + , X00=0=0=+Wc,Vb,Ua,T` ,00000000Wc6,Vb6,Ua6,T`b,d Y, U,00=0=0=hgfeU,0000 X00=0=0=(,1T!1 Xd >0>[ZYXhgfe1C"1t srqh_,g^,f],e\,0000hgfe ,! H!.:, ,!,! ,D9>,D9j>qr,r,0q,@9:,:,:,,!H00@0q44W44q4484f404644444444 44)4444444 444444444 4!44444"4444444@4444444@444444 444444)4@444&444u444@44444)4@444444H44u44g44h44s44k44i44 44L44t44d44.4444C44o44l44o44r44H44u44g44A44L44S4444444444?4'44444444444 44!=00u-st00=0qu-0=0{00v-v05>-q5 >0?0???0q0v-==-0q!-0q!0q0v!.vj>v>v>v>0q0v.(0q 0=@00q r00q! nA?vt!$L.s#R.#s0>v  @?sA?t=vu}.uH> s0s0se.0>.0| sH00|>s?t? n.0|s0|s0| s@00|>s?t?0|s! 1p% @9:DA:./!C:/#00 0.:0!0000q/ C!:.:.:// @ 9:@/0!0000q0q! Cq!0!0000q0q! Bq! A:U/: /:&/ :U/:/:4/U/!0 0]q/[\00=0{]a/ 0000 001!1= 0^/^>^>0{0^/0000001!1=(0{ 0{n{B{!/0{0 00{001$ 0{! x/R1u"1/ R1u" R>0=yzPQx1,1,1,1,1,1m,1v,1,1|,1y,1,1,1,  9 -)4d1 3)4q 44444444K)Q)!9$:I)Q)!  905 Z)9q 00 f) f)20b)  905 v) r 9qr9 q9qr69 q9q!t0 0001$=0{=0{! u0 0001$r9 q9qr69 q9qrq00;0v)0uwxs00=)=* n:*j:*0nq=0q m: *1<& !A*0| w@00|>w?x?0|w0 000qW*u v=w=x=05 X*06 _*tsrqL* SRQP 0rq05 }*v05>*s5r05>*t5uw*wv>*wvj>rww>=*01a!1018!101!101!11%1!0W*018!1_01a!1018!1_01a!10!V0W*d1"11= 1*! ! 0jb0b0jb0b0|b!1e$10 0001$11&q8+vj>:+v>tE+0r0w>t?u?sw t@0wt0wtqn+0vj>r+0v>tw@0r0q+0?0q0rvu+0?0s0tvu+006 +tx+sw+#wqxr=uvU00 00=+#0! m:+0| tH00|>t?u?0|t!B G+!A F+G! F!19&H00 j>t?u?0jtJ,1p!1 X!01!1018!!;1!0 X01'10 X@0Y011# Z!1& T:P,d,S:+,:G,:d,w:d,:&,:,d, @ 9:,!0 a!1#'1V'0!0@ 1$1! D>!0@ ! BD>a00001$ A 015>@0r0q,006 ,ty,sx-#rq00=xuv0x>0y=tw,sv-x>uv0U0000=,#0 j000t!2:3- B=.-0/-0t! m:j-H00j>t?u?19&1!=:U-0 jta-0 jt0 jt! !0q0q m:-j 0jqm:!0 n q@00n>q?r?0nq! 0| q@00|>q?r?0|q o9..o6?905>-c5 >dnc0cn 9 :+.0f.n>@?A?cdf@>en>0A1 0c0f-@00n>c?d?1"1"0 oc:1%0q0!B0AW.AqO. W.=:W.0q0>s  @?qA?r=s j qH0q!@..>?<q00=0q0y.>?<q00=0q0.=!..0v !.1#!0| v@00|>v?w?0|v0 jv . !.1#1! 1p%0v 0| v@00|>v?w?0|v! 1p% @:0q!/0!000 B5 0q0r=?!??>0qrr s?>0qrr s0 B/B5 0q0r=?!?>?qr!! C:./:8/:h//fwupd-1.0.6/data/tests/colorhug/firmware.bin.asc000066400000000000000000000007311325145456600216270ustar00rootroot00000000000000-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVLPMHAAoJEK2KUo/sRIgeAxAH/jPY7c2qrG4UEsZXgUFxMUQe QEufh3cK9cv8kA7SAzpSHy6M0rNanC2vCqcc/fTJI/yBRfBjPPZYEsQgwpB/8m9y wiTPRuQySwCKsH+ZXNh3j6x8Oaf3DTiO7bJI/M3sOb4fdvb0Csp910g67Nt+HtMw I5EUM0uvMquZTUygp9B6BBJv8xRKtCNgqvPhyoDZKxKrPzaFwvb7BY50Q03LymU6 hQUIkjHIvMcTljNocOZNvTBHvEGB2BiBb60QhAXYyNfDrS58pm2JHfw/pgOuQTzT 3Lw9qmedRXbWR95u/piUmyUsY5ey75lD08U/2aE9RLBZ9xR17u1mAgyLGoIMYEk= =ZdoH -----END PGP SIGNATURE----- fwupd-1.0.6/data/tests/colorhug/firmware.bin.p7b000066400000000000000000000043251325145456600215540ustar00rootroot00000000000000-----BEGIN PKCS7----- MIIGYAYJKoZIhvcNAQcCoIIGUTCCBk0CAQExDTALBglghkgBZQMEAgEwCwYJKoZI hvcNAQcBoIIESDCCBEQwggKsoAMCAQICDFmdjlgcgXiV33RlVTANBgkqhkiG9w0B AQsFADA6MRAwDgYDVQQDEwdMVkZTIENBMSYwJAYDVQQKEx1MaW51eCBWZW5kb3Ig RmlybXdhcmUgUHJvamVjdDAeFw0xNzA4MDEwMDAwMDBaFw0xOTA4MDEwMDAwMDBa MBkxFzAVBgNVBAMTDlJpY2hhcmQgSHVnaGVzMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA5XlsYGdD5isOAEim4tRR9usJa8C4Gs3TUPfe5EfXcIT44dJr plVcXpH2Wau/Pbcvc/2cY/bZmgcRMgw8O/4HoJyCCCKfjCfT6yN9BlLnxAgZVLSw QT2d2JW0m5bY/VgZNwdNZWb+fMnPDx7JMCjtdpUpwQ0R6hwrryRt+6zFyhDayCCL GOsxpmo7Fc9ix/nP5DEcPjU6Bofz0jFFMesod8babaQSWm2b/QN7aTgkrPjslC+p BkTLq7IrndgQzLKI9bXn++LFKE2Srm0nHZ6DapKCgsSE3UOqDGtKTUf86aT2IGnV 5JzTZ/HZk/sGqAyS2wb5m13rJfbzkKnf9c14qwIDAQABo4HqMIHnMAwGA1UdEwEB /wQCMAAwRQYDVR0RBD4wPIYlaHR0cHM6Ly9zZWN1cmUtbHZmcy5yaGNsb3VkLmNv bS9sdmZzL4ETcmljaGFyZEBodWdoc2llLmNvbTATBgNVHSUEDDAKBggrBgEFBQcD AzAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSZpooSP4z6IVWsXkoUjpByAh5D fzAfBgNVHSMEGDAWgBSxjerkI6d+CY617jHgat2eNDdlrDAqBgNVHR8EIzAhMB+g HaAbhhlodHRwOi8vd3d3LmZ3dXBkLm9yZy9wa2kvMA0GCSqGSIb3DQEBCwUAA4IB gQBSXRGZB6YR8wTyuOdEelRcJj45Mz5tiuuCfei8ZOTyFzkGjnRno0Dl57tnmUmX ufN2Rb9yzXBGHmSTXT6j2uVg+U1xevPAVCWlIslhwxJcqncfpALxL7TwVL5PpJls /Ao7y/KkS5Bxd8u45A2/wIFkawxn/X0nRmwNh6jF9m3+NSwCv3QxYdgGcfhzD96p 6hG+DuXT97h0lJ3gJJDPbVkWTvuhoNo+iEz8fAfSmlk12HDQ+oQIGRgpFZYHREFr 2/A2HoBfAPFVdmRfYWNrxODrVg3tQEHmtxG7HIHocyRSVzqd31yJKgkwh4I9meUY rCOf0hhMjWmxiviPKJx4SEcNg7Ye8Ib2OtXxcQbZ71ax57dUyVZZXEcfR3KjBuFp vY6QnVF5D3NsyV5q3M1VV8XRh9ELRafruX+Ygx8NLkDPKqFGZh0xKDzr55gJF9q8 rfuHjQ/cd5tokRMI1qlGymbQ/bWgsLBO2MOWeZezITBO1ZVbz6QMJ4YnvHug8nsZ /SkxggHeMIIB2gIBATBKMDoxEDAOBgNVBAMTB0xWRlMgQ0ExJjAkBgNVBAoTHUxp bnV4IFZlbmRvciBGaXJtd2FyZSBQcm9qZWN0AgxZnY5YHIF4ld90ZVUwCwYJYIZI AWUDBAIBoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx DxcNMTcwODIzMTQzNTQ1WjAvBgkqhkiG9w0BCQQxIgQgoZZQTQmHHaT32DuHS1AP jubgYZq3mfB0gUsxbYj5b38wDQYJKoZIhvcNAQEBBQAEggEAWc7kxSri1v+c+N8h S8cerVmAPBm150DjB58F3gxSl91gs/z8d1uWOx88eX0DjOU4C7sQj7E9WiZSPcvb z2KvXqg7MJy+ev9wXPwDqqPtsVZdLKd665JqF7kfSXxpMFzutu/NxW7UUUrKot4v d93NlAEXmjjuQ8V6STtYapxzyuWGXThI/K89kXaMvzmqTYQ4S9+98sXG1PMX69zm z00PT+rL2QGMsZCSUcnE/u38s0q7uCEfBB9uoq5QIECYch65ezX3H2GqVcKPG4M3 6Ttko+W01+2IIPN02ZHPqXqEw8diTiMYS5HVRD7nVs5TTxNNB+rAIBR+mJJBkxin 7MLHjQ== -----END PKCS7----- fwupd-1.0.6/data/tests/colorhug/firmware.metainfo.xml000066400000000000000000000023361325145456600227160ustar00rootroot00000000000000 com.hughski.ColorHugALS.firmware ColorHugALS Firmware Firmware for the ColorHugALS Ambient Light Sensor

Updating the firmware on your ColorHugALS device improves performance and adds new features.

84f40464-9272-4ef7-9399-cd95f12da696 12345678-1234-1234-1234-123456789012 http://www.hughski.com/ CC0-1.0 GPL-2.0+ richard_at_hughsie.com Hughski Limited

This stable release fixes the following bugs:

  • Fix the return code from GetHardwareVersion
  • Scale the output of TakeReadingRaw by the datasheet values
fwupd-1.0.6/data/tests/colorhug/meson.build000066400000000000000000000014531325145456600207200ustar00rootroot00000000000000gcab = find_program('gcab', required : false) if gcab.found() colorhug_test_firmware = custom_target('colorhug-test-firmware', input : [ 'firmware.bin', 'firmware.bin.asc', 'firmware.metainfo.xml', ], output : 'colorhug-als-3.0.2.cab', command : [ gcab, '--create', '--nopath', '@OUTPUT@', '@INPUT@', ], ) endif # generate self-signed detached signature colorhug_pkcs7_signature = custom_target('firmware.bin.p7c', input: 'firmware.bin', output: 'firmware.bin.p7c', command: [certtool, '--p7-detached-sign', '--p7-time', '--load-privkey', pkcs7_privkey, '--load-certificate', pkcs7_certificate, '--infile', '@INPUT@', '--outfile', '@OUTPUT@'], ) fwupd-1.0.6/data/tests/daemon.conf000066400000000000000000000000311325145456600170350ustar00rootroot00000000000000[fwupd] ArchiveSizeMax=5 fwupd-1.0.6/data/tests/dmi/000077500000000000000000000000001325145456600155025ustar00rootroot00000000000000fwupd-1.0.6/data/tests/dmi/tables/000077500000000000000000000000001325145456600167545ustar00rootroot00000000000000fwupd-1.0.6/data/tests/dmi/tables/DMI000066400000000000000000000047331325145456600173170ustar00rootroot00000000000000*Qd44A!Intel(R) Core(TM) i7-4600U CPU @ 2.10GHzIntel(R) CorporationNoneCPU Socket - U3E1NoneNone @@L1-Cache @@L1-Cache@@L2-Cache@@L3-Cache"@@@@ChannelABANK 0ElpidaNoneNoneEDJ8416E6MB-GN-F " @@ChannelB-DIMM0BANK 2Samsung15AF7001NoneM471B1G73QH0-YK0  Intel_ASFIntel_ASF_001   ZS RNLENOVO20ARS19C0CThinkPad T440sPF01VVCALENOVO_MT_20AR_BU_Think_FM_ThinkPad T440sThinkPad T440s   LENOVO20ARS19C0CNot Defined1ZSUK45C1DZNot AvailableNot Available LENOVONot AvailablePF01VVCANo Asset InformationLENOVO_MT_20AR_BU_Think_FM_ThinkPad T440s Not AvailableUSB 1 Not AvailableUSB 2 Not AvailableUSB 3 Not AvailableUSB 4 Not AvailableUSB 5 Not AvailableUSB 6 Not AvailableUSB 7 Not AvailableUSB 8  Not AvailableEthernet Not AvailableExternal Monitor Not AvailableMini DisplayPort Not AvailableDisplayPort/DVI-D Not AvailableDisplayPort/HDMI Not AvailableHeadphone/Microphone Combo Jack1 Not AvailableHeadphone/Microphone Combo Jack2 Media Card Slot~SmartCard Slot  SimCard Slot !IBM Embedded Security hardware " #en-US$ \+;wD FrontSONY45N111103.01LiP%0*fD RearSANYO45N177703.01LION&'()TVT-Enablement*ZZ+STM TPM INFOSystem Reserved,$AMT@-5 C  Z&vPro.KHOIHGIUCCHHIIS/TPBAY I/O @0  LENOVOGJET75WW (2.25 )03/28/2014!1  C2LENOVO ca,tR)D/3LENOVO (uu#/ i"_8 ?4LENOVO 5LENOVO 6LENOVO MS 7LENOVO 8LENOVO 9":6;TP<LENOVO GJHT25WW11/07/2013+=LENOVO /fwupd-1.0.6/data/tests/dmi/tables/smbios_entry_point000066400000000000000000000000371325145456600226250ustar00rootroot00000000000000_SM__DMI_ Ӽ>'fwupd-1.0.6/data/tests/dmi/tables64/000077500000000000000000000000001325145456600171265ustar00rootroot00000000000000fwupd-1.0.6/data/tests/dmi/tables64/DMI000066400000000000000000000133051325145456600174640ustar00rootroot00000000000000ڲ@""##(())**++,,--..@@AABBCCPPUUWW\\]]eeffmmnn}}ڲ@  ++,,--..558899DDEEFFGGJJKKLLMMRRSSuuvv{{||ڲ@--..22335566JJKKLLddeeffgghhiillmmnnڲ@  %%&&))**++,,8899::;;AAڲ@BBCCFFGGHHIIJJMMNNOOPPWWXX[[\\]]^^__``aabbffggiijjkkllmmnnttuuvvwwxxyyڲ@11223366778899::;;@@ڲ@AABBCCDDEEFFGGPPQQRRaabb{{||}}~~J@J@K@K@L@L@ Yڲ@ ""0022@@BBPPRR?cDell Inc.99.01.2108/21/2017DELLR0QO2G2XPSDell Inc.XPS 13 9365077A2R0Q2G2 Dell Inc.0DVT6MA00/2R0Q2G2/CN1296374E0065/Dell Inc.2R0Q2G2Convertible0dl A5CPU 1Intel(R) CorporationIntel(R) Core(TM) i7-7Y75 CPU @ 1.30GHzTo Be Filled By O.E.M.To Be Filled By O.E.M.To Be Filled By O.E.M. L1 Cache L2 Cache L3 Cache  JKBTP1 - KeyboardNone J1A2BVideo J3A2HDMI JUSB1USB1 JUSB2USB2 JTypeCUSB3 JSD1Cardreader JHP1Audio Jack JeDP1-eDPNone JNGFF1 - WLAN/BT/Wigig CONNNone JNGFF2 - HDDNone JSPK1 - SpeakerNone JAPS1 - Automatic PowerNone JDEG1 - Debug PORTNone JRTC1 - RTCNone   PCI-Express 0  PCI-Express 4  PCI-Express 5  PCI-Express 8  "Intel HD Graphics"  Dell System1[077A]3[1.0]12[www.dell.com]14[1]15[0]  en-USIntel(R) Silicon View TechnologyFirmware Version Info$MEI(@@ @KKSystem Board Memory (UD2)0Micron000000000000000000MT52L1G32D4PG-107 (@@ @KKSystem Board Memory (UD2)0Micron000000000000000000MT52L1G32D4PG-107 nptald IG0 tald IGptali dCPU Thermal Sensora dOther Thermal Sensora dOther Thermal Sensord dHdd Thermal Sensorg dAmbient Thermal Sensorh dMemory Thermal Sensor 1 ) )Onboard IGD) )Onboard LAN) )Onboard SOUND) ) Onboard SATA CONTROLLERd #J Sys. Battery BaySMP01/03/20170CE4DELL HMPFH621.0LiPCN0HMPFHSLW00714I2DDA00 ~ Dell Inc.2R0Q2G2Docking Station$AMT@5 V &vPro T   ; A$BHP !"D QE0@CMEI1MEI2MEI3^Reference Code - CPUuCode VersionTXT ACM version   Reference Code - ME 11.0MEBx versionME Firmware VersionCorporate SKUK !! >4 > 4Reference Code - SKL PCHPCH-CRID StatusDisabledPCH-CRID Original ValuePCH-CRID New ValueOPROM - RST - RAIDSKL PCH H Bx Hsio VersionSKL PCH H Dx Hsio VersionKBL PCH H Ax Hsio VersionSKL PCH LP Bx Hsio VersionSKL PCH LP Cx Hsio Version6Reference Code - SA - System AgentReference Code - MRCSA - PCIe VersionSA-CRID StatusDisabledSA-CRID Original ValueSA-CRID New ValueOPROM - VBIOSg f Lan Phy VersionSensor Firmware VersionDebug Mode StatusDisabledPerformance Mode StatusDisabledDebug Use USB(Disabled:Serial)DisabledICC Overclocking VersionUNDI VersionEC FW VersionGOP VersionBIOS Guard VersionBase EC FW VersionEC-EC Protocol VersionRoyal Park VersionBP1.3.3.0_RP02Platform Version 0Memory Init CompleteEnd of DXE PhaseBIOS Boot Complete z2017041420170426 "Intel Corp.""2089" "02@BPR"Y_SIDARMy7y63nZgZ077Afwupd-1.0.6/data/tests/dmi/tables64/smbios_entry_point000066400000000000000000000000301325145456600227700ustar00rootroot00000000000000_SM3_ jfwupd-1.0.6/data/tests/firmware-base-uri.conf000066400000000000000000000002461325145456600211230ustar00rootroot00000000000000[fwupd Remote] Enabled=true Type=download Keyring=gpg MetadataURI=https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz FirmwareBaseURI=https://my.fancy.cdn/ fwupd-1.0.6/data/tests/firmware-nopath.conf000066400000000000000000000002001325145456600206730ustar00rootroot00000000000000[fwupd Remote] Enabled=true Type=download Keyring=gpg MetadataURI=https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz fwupd-1.0.6/data/tests/history_v1.db000066400000000000000000000300001325145456600173400ustar00rootroot00000000000000SQLite format 3@ . == itablehistoryhistoryCREATE TABLE history ( device_id TEXT PRIMARY KEY, update_state INTEGER DEFAULT 0, update_error TEXT, filename TEXT, display_name TEXT, plugin TEXT, device_created INTEGER DEFAULT 0, device_modified INTEGER DEFAULT 0, checksum TEXT DEFAULT NULL, flags INTEGER DEFAULT 0, metadata TEXT DEFAULT NULL, guid_default TEXT DEFAULT NULL, version_old TEXT, version_new TEXT)-Aindexsqlite_autoindex_history_1history 7]2ba16d10df45823dd4494ff10a0bfccfef512c9d +] 2ba16d10df45823dd4494ff10a0bfccfef512c9dfwupd-1.0.6/data/tests/hwids/000077500000000000000000000000001325145456600160475ustar00rootroot00000000000000fwupd-1.0.6/data/tests/hwids/bios_major_release000066400000000000000000000000031325145456600216070ustar00rootroot0000000000000004 fwupd-1.0.6/data/tests/hwids/bios_minor_release000066400000000000000000000000031325145456600216230ustar00rootroot0000000000000006 fwupd-1.0.6/data/tests/hwids/bios_vendor000066400000000000000000000000311325145456600202750ustar00rootroot00000000000000American Megatrends Inc. fwupd-1.0.6/data/tests/hwids/bios_version000066400000000000000000000000051325145456600204660ustar00rootroot000000000000001201 fwupd-1.0.6/data/tests/hwids/board_name000066400000000000000000000000271325145456600200600ustar00rootroot00000000000000To be filled by O.E.M. fwupd-1.0.6/data/tests/hwids/board_vendor000066400000000000000000000000271325145456600204350ustar00rootroot00000000000000To be filled by O.E.M. fwupd-1.0.6/data/tests/hwids/chassis_type000066400000000000000000000000021325145456600204600ustar00rootroot000000000000003 fwupd-1.0.6/data/tests/hwids/product_family000066400000000000000000000000271325145456600210120ustar00rootroot00000000000000To be filled by O.E.M. fwupd-1.0.6/data/tests/hwids/product_name000066400000000000000000000000271325145456600204510ustar00rootroot00000000000000To be filled by O.E.M. fwupd-1.0.6/data/tests/hwids/product_sku000066400000000000000000000000041325145456600203260ustar00rootroot00000000000000SKU fwupd-1.0.6/data/tests/hwids/sys_vendor000066400000000000000000000000271325145456600201640ustar00rootroot00000000000000To be filled by O.E.M. fwupd-1.0.6/data/tests/meson.build000066400000000000000000000004441325145456600170750ustar00rootroot00000000000000# generate private PKCS7 key certtool = find_program('certtool') pkcs7_privkey = custom_target('test-privkey.pem', output: 'test-privkey.pem', command: [certtool, '--generate-privkey', '--outfile', '@OUTPUT@'], ) subdir('builder') subdir('pki') subdir('colorhug') subdir('missing-hwid') fwupd-1.0.6/data/tests/missing-hwid/000077500000000000000000000000001325145456600173335ustar00rootroot00000000000000fwupd-1.0.6/data/tests/missing-hwid/firmware.bin000066400000000000000000000175001325145456600216440ustar00rootroot000000000000001 (~1 p~ 1(00'012!1 00@012!100@012!1@000001,!~ 1*! 02=!4W(4  9GHY(KJj(0G91H!!!3{(3  9GH}(ML(0G")! 0000@001!1# !Gw)0(1T!1(#!1!1)1'!1(#!18!1)1p!1!G")#!1!1)0 >000! ()00>00! ()0 >000! ()0!0000 >000! ))!^ !_ 1#1 W! V! U! T!0 >000! 5))$0!G)#!:N)!:N) 0!Gr)0?0@001x#1!GU)0?0000G1$1!H) )T:(:(:(:(:(:(:( :(:(:(/: )::) :@):(t)!3)3  9GH)ON)UG"!TG" 0!G@0H011#1!I0!G@0H011#!I B:*@98*! A:)! *! B@9:D9:D90[!2 : ,*D9>[D9>8*D9j>[D9>[_E*0[F*`N*`D9>S*`D9j>[A:t*`l*f*D9>i*D9>0`[0[`*0`[`00`[001$1* `0 [*`**D9>*D9>;0`[00`[001$1*;0 `[ D9>0=[\0]^[!*=00{0**! 2:+=+0 g!=+0 g=1!1=!+ 3+1%10 g!0 g=?+1!10 g=V+P+s0 0001$10 g=\+1!1=o+0 0001$1=0!2w+ =+ + go g 9h!0 g= o+!8>+!8>9 0g9g!+1%1+r0 0o0g001$10 g0i+=}+ 0 000 X0000Wc+Vb+Ua+T`,d + , X00=0=0=+Wc,Vb,Ua,T` ,00000000Wc6,Vb6,Ua6,T`b,d Y, U,00=0=0=hgfeU,0000 X00=0=0=(,1T!1 Xd >0>[ZYXhgfe1C"1t srqh_,g^,f],e\,0000hgfe ,! H!.:, ,!,! ,D9>,D9j>qr,r,0q,@9:,:,:,,!H00@0q44W44q4484f404644444444 44)4444444 444444444 4!44444"4444444@4444444@444444 444444)4@444&444u444@44444)4@444444H44u44g44h44s44k44i44 44L44t44d44.4444C44o44l44o44r44H44u44g44A44L44S4444444444?4'44444444444 44!=00u-st00=0qu-0=0{00v-v05>-q5 >0?0???0q0v-==-0q!-0q!0q0v!.vj>v>v>v>0q0v.(0q 0=@00q r00q! nA?vt!$L.s#R.#s0>v  @?sA?t=vu}.uH> s0s0se.0>.0| sH00|>s?t? n.0|s0|s0| s@00|>s?t?0|s! 1p% @9:DA:./!C:/#00 0.:0!0000q/ C!:.:.:// @ 9:@/0!0000q0q! Cq!0!0000q0q! Bq! A:U/: /:&/ :U/:/:4/U/!0 0]q/[\00=0{]a/ 0000 001!1= 0^/^>^>0{0^/0000001!1=(0{ 0{n{B{!/0{0 00{001$ 0{! x/R1u"1/ R1u" R>0=yzPQx1,1,1,1,1,1m,1v,1,1|,1y,1,1,1,  9 -)4d1 3)4q 44444444K)Q)!9$:I)Q)!  905 Z)9q 00 f) f)20b)  905 v) r 9qr9 q9qr69 q9q!t0 0001$=0{=0{! u0 0001$r9 q9qr69 q9qrq00;0v)0uwxs00=)=* n:*j:*0nq=0q m: *1<& !A*0| w@00|>w?x?0|w0 000qW*u v=w=x=05 X*06 _*tsrqL* SRQP 0rq05 }*v05>*s5r05>*t5uw*wv>*wvj>rww>=*01a!1018!101!101!11%1!0W*018!1_01a!1018!1_01a!10!V0W*d1"11= 1*! ! 0jb0b0jb0b0|b!1e$10 0001$11&q8+vj>:+v>tE+0r0w>t?u?sw t@0wt0wtqn+0vj>r+0v>tw@0r0q+0?0q0rvu+0?0s0tvu+006 +tx+sw+#wqxr=uvU00 00=+#0! m:+0| tH00|>t?u?0|t!B G+!A F+G! F!19&H00 j>t?u?0jtJ,1p!1 X!01!1018!!;1!0 X01'10 X@0Y011# Z!1& T:P,d,S:+,:G,:d,w:d,:&,:,d, @ 9:,!0 a!1#'1V'0!0@ 1$1! D>!0@ ! BD>a00001$ A 015>@0r0q,006 ,ty,sx-#rq00=xuv0x>0y=tw,sv-x>uv0U0000=,#0 j000t!2:3- B=.-0/-0t! m:j-H00j>t?u?19&1!=:U-0 jta-0 jt0 jt! !0q0q m:-j 0jqm:!0 n q@00n>q?r?0nq! 0| q@00|>q?r?0|q o9..o6?905>-c5 >dnc0cn 9 :+.0f.n>@?A?cdf@>en>0A1 0c0f-@00n>c?d?1"1"0 oc:1%0q0!B0AW.AqO. W.=:W.0q0>s  @?qA?r=s j qH0q!@..>?<q00=0q0y.>?<q00=0q0.=!..0v !.1#!0| v@00|>v?w?0|v0 jv . !.1#1! 1p%0v 0| v@00|>v?w?0|v! 1p% @:0q!/0!000 B5 0q0r=?!??>0qrr s?>0qrr s0 B/B5 0q0r=?!?>?qr!! C:./:8/:h//fwupd-1.0.6/data/tests/missing-hwid/firmware.metainfo.xml000066400000000000000000000007041325145456600234730ustar00rootroot00000000000000 com.hughski.test.firmware 12345678-1234-1234-1234-123456789012 9342d47a-1bab-5709-9869-c840b2eac501 fwupd-1.0.6/data/tests/missing-hwid/firmware2.metainfo.xml000066400000000000000000000005531325145456600235570ustar00rootroot00000000000000 com.hughski.test.firmware 12345678-1234-1234-1234-123456789012 fwupd-1.0.6/data/tests/missing-hwid/meson.build000066400000000000000000000010771325145456600215020ustar00rootroot00000000000000gcab = find_program('gcab', required : false) if gcab.found() hwid_test_firmware = custom_target('hwid-test-firmware', input : [ 'firmware.bin', 'firmware.metainfo.xml', ], output : 'hwid-1.2.3.cab', command : [ gcab, '--create', '--nopath', '@OUTPUT@', '@INPUT@', ], ) noreqs_test_firmware = custom_target('noreqs-test-firmware', input : [ 'firmware.bin', 'firmware2.metainfo.xml', ], output : 'noreqs-1.2.3.cab', command : [ gcab, '--create', '--nopath', '@OUTPUT@', '@INPUT@', ], ) endif fwupd-1.0.6/data/tests/pki/000077500000000000000000000000001325145456600155145ustar00rootroot00000000000000fwupd-1.0.6/data/tests/pki/GPG-KEY-Linux-Vendor-Firmware-Service000077700000000000000000000000001325145456600340742../../pki/GPG-KEY-Linux-Vendor-Firmware-Serviceustar00rootroot00000000000000fwupd-1.0.6/data/tests/pki/LVFS-CA.pem000077700000000000000000000000001325145456600222142../../pki/LVFS-CA.pemustar00rootroot00000000000000fwupd-1.0.6/data/tests/pki/meson.build000066400000000000000000000005741325145456600176640ustar00rootroot00000000000000# generate certificate pkcs7_config = join_paths(meson.current_source_dir(), 'test.cfg') pkcs7_certificate = custom_target('test.pem', input: pkcs7_privkey, output: 'test.pem', command: [certtool, '--generate-self-signed', '--template', pkcs7_config, '--load-privkey', '@INPUT@', '--outfile', '@OUTPUT@'], ) fwupd-1.0.6/data/tests/pki/test.cfg000066400000000000000000000001351325145456600171530ustar00rootroot00000000000000organization = "Hughski Limited" expiration_days = -1 email = "info@hughski.com" signing_key fwupd-1.0.6/data/tests/quirks.d/000077500000000000000000000000001325145456600164715ustar00rootroot00000000000000fwupd-1.0.6/data/tests/quirks.d/tests.quirk000066400000000000000000000002721325145456600207110ustar00rootroot00000000000000[fwupd-plugin-test] USB\VID_0A5C&PID_6412=ignore-runtime # this is an empty key USB\VID_FFFF&PID_FFFF= # this is a key with a space ACME Inc.=awesome # this is a wildcard CORP*=town fwupd-1.0.6/data/tests/remotes.d/000077500000000000000000000000001325145456600166315ustar00rootroot00000000000000fwupd-1.0.6/data/tests/remotes.d/broken.conf000066400000000000000000000001221325145456600207530ustar00rootroot00000000000000[fwupd Remote] Enabled=true MetadataURI=file:///tmp/fwupd-self-test/broken.xml.gz fwupd-1.0.6/data/tests/remotes.d/stable.conf000066400000000000000000000001171325145456600207510ustar00rootroot00000000000000[fwupd Remote] Enabled=true MetadataURI=file:///tmp/fwupd-self-test/stable.xml fwupd-1.0.6/data/tests/remotes.d/testing.conf000066400000000000000000000001201325145456600211460ustar00rootroot00000000000000[fwupd Remote] Enabled=true MetadataURI=file:///tmp/fwupd-self-test/testing.xml fwupd-1.0.6/data/tests/spawn.sh000077500000000000000000000002671325145456600164250ustar00rootroot00000000000000#/bin/sh echo "this is a test" sleep 1 echo "this is another line1" echo "this is another line2" echo "this is another line3" echo "this is another line4" sleep 1 echo "done!" exit 0 fwupd-1.0.6/data/tests/thunderbolt/000077500000000000000000000000001325145456600172635ustar00rootroot00000000000000fwupd-1.0.6/data/tests/thunderbolt/COPYING000066400000000000000000000027321325145456600203220ustar00rootroot00000000000000Copyright(c) 2017 Intel Corporation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. fwupd-1.0.6/data/tests/thunderbolt/minimal-fw-controller.bin000066400000000000000000000004771325145456600242060ustar00rootroot00000000000000$40`fwupd-1.0.6/data/tests/thunderbolt/minimal-fw.bin000066400000000000000000000005001325145456600220100ustar00rootroot00000000000000$40`fwupd-1.0.6/docs/000077500000000000000000000000001325145456600136065ustar00rootroot00000000000000fwupd-1.0.6/docs/architecture-plan.svg000066400000000000000000001046451325145456600177530ustar00rootroot00000000000000 image/svg+xml fwupd ESRT VendorProvders Udev systemd pending.db session system fwupdmgr downloadcache Internet Gudev + rules sqlite $home gnome-software UpdateMetadata() GetDevices() sysfs metadata firmware AppStream XML fwupd-1.0.6/docs/dfu-metadata-store.md000066400000000000000000000152451325145456600176250ustar00rootroot00000000000000 DFU File Format - Metadata Store Proposal ========================================= Introduction ------------ The DFU specification version 1.1 defines some target-specific data that can optionally be included in the DFU file to ease firmware deployment. These include items such as the runtime vendor, product and device release, but nothing else and with no provision for extra metadata. The DFU file specification does not specify any additional data structures allowing vendors to include additional metadata, although does provide the chance to include future additional data fields in the header in a backwards and forwards compatible way by increasing the `header_len` value. All software reading and writing DFU-format files should already be reading the footer length from the file, rather than assuming a fixed footer length of 0x10 bytes. This ensures that only the raw device firmware is sent to the device and not any additional data fields added in future versions of the DFU specification. There are valid reasons why we would want to add additional metadata into the distributed DFU file. Reasons are listed as follows: * Legal compliance, to tag a file with copyright and licensing information * Business-specific metadata, for instance the SHA-1 git commit for the source * Cryptographic information such as a SHA-256 hash or a detached GPG signature Although the original authors of the specification allowed for future additions to the specification, they only allowed us to extend the footer by 239 bytes as the `header_len` value is specified as just one byte, and 16 bytes are already specified by the specification. This would explain why some vendors are using vendor-specific file prefix data segments, for instance the DfuSe prefix specification from ST. This specification is not aiming to expand or standardize the various incompatible vendor-specific prefix specifications, but tries to squeeze the additional metadata into the existing DFU footer space which is compatible with all existing DFU-compliant software. Specification ------------- An additional structure would be present after the binary firmware data, and notionally contained within the DFU footer itself, although specified as a seporate object. The representation in memory and on disk would be as follows: uint16 signature='MD' uint8 number_of_keys uint8 key(n)_length ... key(n) (no NUL) uint8 value(n)_length ... value(n) (no NUL) If there are no metadata keys being set, it is expected that the metadata table signature is not be written to the file, and that the footer should be again 0x10 bytes in length. The signature of `MD` should also be checked before attempting to parse the metadata store structure to ensure other vendor-specific extensions are not already in use. The key and value fields should be parsed as UTF-8, although in the pursuit of space minimisation ASCII values are preferred where possible. Example ------- The following table shows an example firmware file with the payload 'DATA' set with vendor 0x1234, product 0xABCD and no metadata table. neg. offset description byte ---------------------------- 13 firmware'D' 0x44 12 firmware'A' 0x41 11 firmware'T' 0x54 10 firmware'A' 0x44 0f bcdDevice 0xFF 0e bcdDevice 0xFF 0d idProduct 0xCD 0c idProduct 0xAB 0b idVendor 0x34 0a idVendor 0x12 09 bcdDFU 0x00 08 bcdDFU 0x01 07 ucDfuSig'U' 0x55 06 ucDfuSig'F' 0x46 05 ucDfuSig'D' 0x44 04 bLength 0x10 03 dwCRC 0x52 02 dwCRC 0xB4 01 dwCRC 0xE5 00 dwCRC 0xCE The following table shows a second firmware file with the same payload but with the addition of a metadata table with a single metadata pair of `test=val`: neg. offset description byte ---------------------------- 1f firmware'D' 0x44 1e firmware'A' 0x41 1d firmware'T' 0x54 1c firmware'A' 0x44 1b ucMdSig'M' 0x4D 1a ucMdSig'D' 0x44 19 bMdLength 0x01 18 bKeyLen 0x04 17 KeyData't' 0x74 16 KeyData'e' 0x65 15 KeyData's' 0x73 14 KeyData't' 0x74 13 bValueLen 0x03 12 ValueData'v' 0x76 11 ValueData'a' 0x61 10 ValueData'l' 0x6c 0f bcdDevice 0xFF 0e bcdDevice 0xFF 0d idProduct 0xCD 0c idProduct 0xAB 0b idVendor 0x34 0a idVendor 0x12 09 bcdDFU 0x00 08 bcdDFU 0x01 07 ucDfuSig'U' 0x55 06 ucDfuSig'F' 0x46 05 ucDfuSig'D' 0x44 04 bLength 0x1C 03 dwCRC 0x1B 02 dwCRC 0x25 01 dwCRC 0x6D 00 dwCRC 0xF5 Conclusions ----------- The metadata store proposal allows us to store a small amount of metadata inside the DFU file footer. If the original specification had included just one more byte for the footer length (for instance a `uint16`, rather than a `uint8`) type then I would have proposed a key type allowing integers, IEEE floating point, and strings, and also made the number of keys and the length of keys much larger. Working with what we've been given, we can support a useful easy-to-parse extension that allows us to solve some of the real-world problems vendors are facing when trying to distribute firmware files for devices that support in-the-field device firmware upgrading. Several deliberate compomises have been made to this proposal due to the restricted space available: * The metadata table signature is just two bytes * The number of keys is limited to just 59 pairs * Keys are limited to just 233 chars maximum * Values are limited to just 233 chars maximum * Types are limited to just strings (which can includes empty strings) * Strings are written without a `NUL` trailing byte * The metadata table uses variable offsets rather than fixed sizes The key-value length in particular leads to some other best practices: * A value for the 'License' key should be in SPDX format, NOT the full licence * A value for the 'Copyright' key should just be the company name The author is not already aware of any vendors using this additional data area, but would be willing to work with any vendors who have implemented a similar proprietary extension already or are planning to do so. fwupd-1.0.6/docs/libfwupd/000077500000000000000000000000001325145456600154225ustar00rootroot00000000000000fwupd-1.0.6/docs/libfwupd/clean.sh000066400000000000000000000001001325145456600170270ustar00rootroot00000000000000rm -f *.txt rm -rf html/ rm -rf xml/ rm -rf tmpl/ rm -f *.stamp fwupd-1.0.6/docs/libfwupd/libfwupd-docs.xml000066400000000000000000000367761325145456600207310ustar00rootroot00000000000000 ]> fwupd Reference Manual About fwupd fwupd is a daemon for updating firmware. libfwupd Functionality exported by libfwupd for client applications. Plugin Reference Functionality available to plugins. Plugin Tutorial
Introduction At the heart of fwupd is a plugin loader that gets run at startup, when devices get hotplugged and when updates are done. The idea is we have lots of small plugins that each do one thing, and are ordered by dependencies against each other at runtime. Using plugins we can add support for new hardware or new policies without making big changes all over the source tree. There are broadly 3 types of plugin methods: Mechanism: Upload binary data into a specific hardware device. Policy: Control the system when updates are happening, e.g. preventing the user from powering-off. Helpers: Providing more metadata about devices, for instance handling device quirks. In general, building things out-of-tree isn't something that we think is a very good idea; the API and ABI internal to fwupd is still changing and there's a huge benefit to getting plugins upstream where they can undergo review and be ported as the API adapts. For this reason we don't install the plugin headers onto the system, although you can of course just install the .so binary file manually. A plugin only needs to define the vfuncs that are required, and the plugin name is taken automatically from the suffix of the .so file. A sample plugin /* * Copyright (C) 2017 Richard Hughes */ #include <fu-plugin.h> #include <fu-plugin-vfuncs.h> struct FuPluginData { gpointer proxy; }; void fu_plugin_initialize (FuPlugin *plugin) { fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_BEFORE, "dfu"); fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); destroy_proxy (data->proxy); } gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); data->proxy = create_proxy (); if (data->proxy == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to create proxy"); return FALSE; } return TRUE; } We have to define when our plugin is run in reference to other plugins, in this case, making sure we run before the dfu plugin. For most plugins it does not matter in what order they are run and this information is not required.
Creating an abstact device This section shows how you would create a device which is exported to the daemon and thus can be queried and updated by the client software. The example here is all hardcoded, and a true plugin would have to derive the details about the FuDevice from the hardware, for example reading data from sysfs or /dev. Example adding a custom device #include <fu-plugin.h> gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { g_autoptr(FuDevice) dev = NULL; fu_device_set_id (dev, "dummy-1:2:3"); fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e"); fu_device_set_version (dev, "1.2.3"); fu_device_get_version_lowest (dev, "1.2.2"); fu_device_get_version_bootloader (dev, "0.1.2"); fu_device_add_icon (dev, "computer"); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_plugin_device_add (plugin, dev); return TRUE; } This shows a lot of the plugin architecture in action. Some notable points: The device ID (dummy-1:2:3) has to be unique on the system between all plugins, so including the plugin name as a prefix is probably a good idea. The GUID value can be generated automatically using fu_device_add_guid(dev,"some-identifier") but is quoted here explicitly. The GUID value has to match the provides value in the .metainfo.xml file for the firmware update to succeed. Setting a display name and an icon is a good idea in case the GUI software needs to display the device to the user. Icons can be specified using a full path, although icon theme names should be preferred for most devices. The FWUPD_DEVICE_FLAG_UPDATABLE flag tells the client code that the device is in a state where it can be updated. If the device needs to be in a special mode (e.g. a bootloader) then the FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER flag can also be used. If the update should only be allowed when there is AC power available to the computer (i.e. not on battery) then FWUPD_DEVICE_FLAG_REQUIRE_AC should be used as well. There are other flags and the API documentation should be used when choosing what flags to use for each kind of device. Setting the lowest allows client software to refuse downgrading the device to specific versions. This is required in case the upgrade migrates some kind of data-store so as to be incompatible with previous versions. Similarly, setting the version of the bootloader (if known) allows the firmware to depend on a specific bootloader version, for instance allowing signed firmware to only be installable on hardware with a bootloader new enough to deploy it
Mechanism Plugins Although it would be a wonderful world if we could update all hardware using a standard shared protocol this is not the universe we live in. Using a mechanism like DFU or UpdateCapsule means that fwupd will just work without requiring any special code, but for the real world we need to support vendor-specific update protocols with layers of backwards compatibility. When a plugin has created a device that is FWUPD_DEVICE_FLAG_UPDATABLE we can ask the daemon to update the device with a suitable .cab file. When this is done the daemon checks the update for compatibility with the device, and then calls the vfuncs to update the device. Updating a device gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { gsize sz = 0; guint8 *buf = g_bytes_get_data (blob_fw, &sz); /* write 'buf' of size 'sz' to the hardware */ return TRUE; } It's important to note that the blob_fw is the binary firmware file (e.g. .dfu) and not the .cab binary data. If FWUPD_INSTALL_FLAG_FORCE is used then the usual checks done by the flashing process can be relaxed (e.g. checking for quirks), but please don't brick the users hardware even if they ask you to.
Policy Helpers For some hardware, we might want to do an action before or after the actual firmware is squirted into the device. This could be something as simple as checking the system battery level is over a certain theshold, or it could be as complicated as ensuring a vendor-specific GPIO is asserted when specific types of hardware are updated. Running before a device update gboolean fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error) { if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC && !on_ac_power ()) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_AC_POWER_REQUIRED, "Cannot install update " "when not on AC power"); return FALSE; } return TRUE; } Running after a device update gboolean fu_plugin_update_cleanup (FuPlugin *plugin, FuDevice *device, GError **error) { return g_file_set_contents ("/var/lib/fwupd/something", fu_device_get_id (device), -1, error); }
Detaching to bootloader mode Some hardware can only be updated in a special bootloader mode, which for most devices can be switched to automaticaly. In some cases the user to do something manually, for instance re-inserting the hardware with a secret button pressed. Before the device update is performed the fwupd daemon runs an optional update_detach() vfunc which switches the device to bootloader mode. After the update (or if the update fails) an the daemon runs an optional update_attach() vfunc which should switch the hardware back to runtime mode. Finally an optional update_reload() vfunc is run to get the new firmware version from the hardware. The optional vfuncs are only run on the plugin currently registered to handle the device ID, although the registered plugin can change during the attach and detach phases. Running before a device update gboolean fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error) { if (hardware_in_bootloader) return TRUE; return _device_detach(device, error); } Running after a device update gboolean fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error) { if (!hardware_in_bootloader) return TRUE; return _device_attach(device, error); } Running after a device update on success gboolean fu_plugin_update_reload (FuPlugin *plugin, FuDevice *device, GError **error) { g_autofree gchar *version = _get_version(plugin, device, error); if (version == NULL) return FALSE; fu_device_set_version(device, version); return TRUE; }
The Plugin Object Cache The fwupd daemon provides a per-plugin cache which allows objects to be added, removed and queried using a specified key. Objects added to the cache must be GObjects to enable the cache objects to be properly refcounted.
Debugging a Plugin If the fwupd daemon is started with --plugin-verbose=$plugin then the environment variable FWUPD_$PLUGIN_VERBOSE is set process-wide. This allows plugins to detect when they should output detailed debugging information that would normally be too verbose to keep in the journal. For example, using --plugin-verbose=unifying would set FWUPD_UNIFYING_VERBOSE=1.
API Index Index of deprecated API
fwupd-1.0.6/docs/libfwupd/libfwupd.types000066400000000000000000000002051325145456600203210ustar00rootroot00000000000000fwupd_client_get_type fwupd_device_get_type fwupd_quirks_get_type fwupd_release_get_type fwupd_remote_get_type fwupd_result_get_type fwupd-1.0.6/docs/libfwupd/meson.build000066400000000000000000000004341325145456600175650ustar00rootroot00000000000000gnome.gtkdoc( 'libfwupd', src_dir : [ join_paths(meson.source_root(), 'libfwupd'), join_paths(meson.source_root(), 'src'), join_paths(meson.build_root(), 'libfwupd'), join_paths(meson.build_root(), 'src'), ], main_xml : 'libfwupd-docs.xml', install : true ) fwupd-1.0.6/docs/meson.build000066400000000000000000000000631325145456600157470ustar00rootroot00000000000000if get_option('gtkdoc') subdir('libfwupd') endif fwupd-1.0.6/libfwupd/000077500000000000000000000000001325145456600144725ustar00rootroot00000000000000fwupd-1.0.6/libfwupd/README.md000066400000000000000000000020651325145456600157540ustar00rootroot00000000000000Migration from Version 0.9.x ============================ * Rename FU_DEVICE_FLAG -> FWUPD_DEVICE_FLAG * Rename FWUPD_DEVICE_FLAG_ALLOW_ONLINE -> FWUPD_DEVICE_FLAG_UPDATABLE * Rename FWUPD_DEVICE_FLAG_ALLOW_OFFLINE -> FWUPD_DEVICE_FLAG_ONLY_OFFLINE * Rename fwupd_client_get_devices_simple -> fwupd_client_get_devices * Rename fwupd_client_get_details_local -> fwupd_client_get_details * Rename fwupd_client_update_metadata_with_id -> fwupd_client_update_metadata * Rename fwupd_remote_get_uri -> fwupd_remote_get_metadata_uri * Rename fwupd_remote_get_uri_asc -> fwupd_remote_get_metadata_uri_sig * Rename fwupd_remote_build_uri -> fwupd_remote_build_firmware_uri * Switch FWUPD_RESULT_KEY_DEVICE_CHECKSUM_KIND to fwupd_checksum_guess_kind() * Rename fwupd_result_update_*() to fwupd_release_*() * Rename fwupd_result_*() to fwupd_device_*() * Convert FwupdResult to FwupdDevice in all callbacks * Rename fwupd_device_*_provider -> fwupd_device_*_plugin * Convert hash types sa{sv} -> a{sv} * Convert fwupd_client_get_updates() -> fwupd_client_get_upgrades() fwupd-1.0.6/libfwupd/fwupd-client.c000066400000000000000000001315431325145456600172460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include #include #include "fwupd-client.h" #include "fwupd-common.h" #include "fwupd-deprecated.h" #include "fwupd-enums.h" #include "fwupd-error.h" #include "fwupd-device-private.h" #include "fwupd-release-private.h" #include "fwupd-remote-private.h" /** * SECTION:fwupd-client * @short_description: a way of interfacing with the daemon * * An object that allows client code to call the daemon methods synchronously. * * See also: #FwupdDevice */ static void fwupd_client_finalize (GObject *object); typedef struct { FwupdStatus status; guint percentage; gchar *daemon_version; GDBusConnection *conn; GDBusProxy *proxy; } FwupdClientPrivate; enum { SIGNAL_CHANGED, SIGNAL_STATUS_CHANGED, SIGNAL_DEVICE_ADDED, SIGNAL_DEVICE_REMOVED, SIGNAL_DEVICE_CHANGED, SIGNAL_LAST }; enum { PROP_0, PROP_STATUS, PROP_PERCENTAGE, PROP_DAEMON_VERSION, PROP_LAST }; static guint signals [SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (FwupdClient, fwupd_client, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fwupd_client_get_instance_private (o)) typedef struct { gboolean ret; GError *error; GMainLoop *loop; GVariant *val; GDBusMessage *message; } FwupdClientHelper; static void fwupd_client_helper_free (FwupdClientHelper *helper) { if (helper->message != NULL) g_object_unref (helper->message); if (helper->val != NULL) g_variant_unref (helper->val); if (helper->error != NULL) g_error_free (helper->error); g_main_loop_unref (helper->loop); g_free (helper); } static FwupdClientHelper * fwupd_client_helper_new (void) { FwupdClientHelper *helper; helper = g_new0 (FwupdClientHelper, 1); helper->loop = g_main_loop_new (NULL, FALSE); return helper; } G_DEFINE_AUTOPTR_CLEANUP_FUNC(FwupdClientHelper, fwupd_client_helper_free) static void fwupd_client_set_daemon_version (FwupdClient *client, const gchar *daemon_version) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_free (priv->daemon_version); priv->daemon_version = g_strdup (daemon_version); g_object_notify (G_OBJECT (client), "daemon-version"); } static void fwupd_client_properties_changed_cb (GDBusProxy *proxy, GVariant *changed_properties, GStrv invalidated_properties, FwupdClient *client) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariantDict) dict = NULL; /* print to the console */ dict = g_variant_dict_new (changed_properties); if (g_variant_dict_contains (dict, "Status")) { g_autoptr(GVariant) val = NULL; val = g_dbus_proxy_get_cached_property (proxy, "Status"); if (val != NULL) { priv->status = g_variant_get_uint32 (val); g_debug ("Emitting ::status-changed() [%s]", fwupd_status_to_string (priv->status)); g_signal_emit (client, signals[SIGNAL_STATUS_CHANGED], 0, priv->status); g_object_notify (G_OBJECT (client), "status"); } } if (g_variant_dict_contains (dict, "Percentage")) { g_autoptr(GVariant) val = NULL; val = g_dbus_proxy_get_cached_property (proxy, "Percentage"); if (val != NULL) { priv->percentage = g_variant_get_uint32 (val); g_object_notify (G_OBJECT (client), "percentage"); } } if (g_variant_dict_contains (dict, "DaemonVersion")) { g_autoptr(GVariant) val = NULL; val = g_dbus_proxy_get_cached_property (proxy, "DaemonVersion"); if (val != NULL) fwupd_client_set_daemon_version (client, g_variant_get_string (val, NULL)); } } static void fwupd_client_signal_cb (GDBusProxy *proxy, const gchar *sender_name, const gchar *signal_name, GVariant *parameters, FwupdClient *client) { g_autoptr(FwupdDevice) dev = NULL; if (g_strcmp0 (signal_name, "Changed") == 0) { g_debug ("Emitting ::changed()"); g_signal_emit (client, signals[SIGNAL_CHANGED], 0); return; } if (g_strcmp0 (signal_name, "DeviceAdded") == 0) { dev = fwupd_device_from_variant (parameters); g_debug ("Emitting ::device-added(%s)", fwupd_device_get_id (dev)); g_signal_emit (client, signals[SIGNAL_DEVICE_ADDED], 0, dev); return; } if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) { dev = fwupd_device_from_variant (parameters); g_signal_emit (client, signals[SIGNAL_DEVICE_REMOVED], 0, dev); g_debug ("Emitting ::device-removed(%s)", fwupd_device_get_id (dev)); return; } if (g_strcmp0 (signal_name, "DeviceChanged") == 0) { dev = fwupd_device_from_variant (parameters); g_signal_emit (client, signals[SIGNAL_DEVICE_CHANGED], 0, dev); g_debug ("Emitting ::device-changed(%s)", fwupd_device_get_id (dev)); return; } g_debug ("Unknown signal name '%s' from %s", signal_name, sender_name); } /** * fwupd_client_connect: * @client: A #FwupdClient * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Sets up the client ready for use. Most other methods call this * for you, and do you only need to call this if you are just watching * the client. * * Returns: %TRUE for success * * Since: 0.7.1 **/ gboolean fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* nothing to do */ if (priv->proxy != NULL) return TRUE; /* connect to the daemon */ priv->conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (priv->conn == NULL) { g_prefix_error (error, "Failed to connect to system D-Bus: "); return FALSE; } priv->proxy = g_dbus_proxy_new_sync (priv->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, NULL, error); if (priv->proxy == NULL) return FALSE; g_signal_connect (priv->proxy, "g-properties-changed", G_CALLBACK (fwupd_client_properties_changed_cb), client); g_signal_connect (priv->proxy, "g-signal", G_CALLBACK (fwupd_client_signal_cb), client); val = g_dbus_proxy_get_cached_property (priv->proxy, "DaemonVersion"); if (val != NULL) fwupd_client_set_daemon_version (client, g_variant_get_string (val, NULL)); return TRUE; } static GPtrArray * fwupd_client_parse_releases_from_variant (GVariant *val) { GPtrArray *array = NULL; gsize sz; g_autoptr(GVariant) untuple = NULL; array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); untuple = g_variant_get_child_value (val, 0); sz = g_variant_n_children (untuple); for (guint i = 0; i < sz; i++) { FwupdRelease *rel; g_autoptr(GVariant) data = NULL; data = g_variant_get_child_value (untuple, i); rel = fwupd_release_from_variant (data); if (rel == NULL) continue; g_ptr_array_add (array, rel); } return array; } static GPtrArray * fwupd_client_parse_devices_from_variant (GVariant *val) { GPtrArray *array = NULL; gsize sz; g_autoptr(GVariant) untuple = NULL; array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); untuple = g_variant_get_child_value (val, 0); sz = g_variant_n_children (untuple); for (guint i = 0; i < sz; i++) { FwupdDevice *dev; g_autoptr(GVariant) data = NULL; data = g_variant_get_child_value (untuple, i); dev = fwupd_device_from_variant (data); if (dev == NULL) continue; g_ptr_array_add (array, dev); } return array; } static GPtrArray * fwupd_client_parse_remotes_from_data (GVariant *devices) { GPtrArray *remotes = NULL; gsize sz; g_autoptr(GVariant) untuple = NULL; remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); untuple = g_variant_get_child_value (devices, 0); sz = g_variant_n_children (untuple); for (guint i = 0; i < sz; i++) { g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i); FwupdRemote *remote = fwupd_remote_from_variant (data); g_ptr_array_add (remotes, remote); } return remotes; } static void fwupd_client_fixup_dbus_error (GError *error) { g_autofree gchar *name = NULL; g_return_if_fail (error != NULL); /* is a remote error? */ if (!g_dbus_error_is_remote_error (error)) return; /* parse the remote error */ name = g_dbus_error_get_remote_error (error); if (g_str_has_prefix (name, FWUPD_DBUS_INTERFACE)) { error->domain = FWUPD_ERROR; error->code = fwupd_error_from_string (name); } else if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) { error->domain = FWUPD_ERROR; error->code = FWUPD_ERROR_NOT_SUPPORTED; } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR)) { error->domain = FWUPD_ERROR; error->code = FWUPD_ERROR_NOT_SUPPORTED; } else { error->domain = FWUPD_ERROR; error->code = FWUPD_ERROR_INTERNAL; } g_dbus_error_strip_remote_error (error); } /** * fwupd_client_get_devices: * @client: A #FwupdClient * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets all the devices registered with the daemon. * * Returns: (element-type FwupdDevice) (transfer container): results * * Since: 0.9.2 **/ GPtrArray * fwupd_client_get_devices (FwupdClient *client, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetDevices", NULL, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_devices_from_variant (val); } /** * fwupd_client_get_history: * @client: A #FwupdClient * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets all the history. * * Returns: (element-type FwupdDevice) (transfer container): results * * Since: 1.0.4 **/ GPtrArray * fwupd_client_get_history (FwupdClient *client, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetHistory", NULL, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_devices_from_variant (val); } /** * fwupd_client_get_device_by_id: * @client: A #FwupdClient * @device_id: the device ID, e.g. `usb:00:01:03:03` * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets a device by it's device ID. * * Returns: (transfer full): a #FwupdDevice or %NULL * * Since: 0.9.3 **/ FwupdDevice * fwupd_client_get_device_by_id (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { g_autoptr(GPtrArray) devices = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (device_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* get all the devices */ devices = fwupd_client_get_devices (client, cancellable, error); if (devices == NULL) return NULL; /* find the device by ID (client side) */ for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); if (g_strcmp0 (fwupd_device_get_id (dev), device_id) == 0) return g_object_ref (dev); } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "failed to find %s", device_id); return NULL; } /** * fwupd_client_get_releases: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets all the releases for a specific device * * Returns: (element-type FwupdRelease) (transfer container): results * * Since: 0.9.3 **/ GPtrArray * fwupd_client_get_releases (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (device_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetReleases", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_releases_from_variant (val); } /** * fwupd_client_get_downgrades: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets all the downgrades for a specific device. * * Returns: (element-type FwupdRelease) (transfer container): results * * Since: 0.9.8 **/ GPtrArray * fwupd_client_get_downgrades (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (device_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetDowngrades", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_releases_from_variant (val); } /** * fwupd_client_get_upgrades: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets all the upgrades for a specific device. * * Returns: (element-type FwupdRelease) (transfer container): results * * Since: 0.9.8 **/ GPtrArray * fwupd_client_get_upgrades (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (device_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetUpgrades", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_releases_from_variant (val); } static void fwupd_client_proxy_call_cb (GObject *source, GAsyncResult *res, gpointer user_data) { FwupdClientHelper *helper = (FwupdClientHelper *) user_data; helper->val = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &helper->error); if (helper->val != NULL) helper->ret = TRUE; if (helper->error != NULL) fwupd_client_fixup_dbus_error (helper->error); g_main_loop_quit (helper->loop); } /** * fwupd_client_verify: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Verify a specific device. * * Returns: %TRUE for verification success * * Since: 0.7.0 **/ gboolean fwupd_client_verify (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(FwupdClientHelper) helper = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (device_id != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ helper = fwupd_client_helper_new (); g_dbus_proxy_call (priv->proxy, "Verify", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, fwupd_client_proxy_call_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_verify_update: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Update the verification record for a specific device. * * Returns: %TRUE for verification success * * Since: 0.8.0 **/ gboolean fwupd_client_verify_update (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(FwupdClientHelper) helper = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (device_id != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ helper = fwupd_client_helper_new (); g_dbus_proxy_call (priv->proxy, "VerifyUpdate", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, fwupd_client_proxy_call_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_unlock: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Unlocks a specific device so firmware can be read or wrote. * * Returns: %TRUE for success * * Since: 0.7.0 **/ gboolean fwupd_client_unlock (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(FwupdClientHelper) helper = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (device_id != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ helper = fwupd_client_helper_new (); g_dbus_proxy_call (priv->proxy, "Unlock", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, fwupd_client_proxy_call_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_clear_results: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Clears the results for a specific device. * * Returns: %TRUE for success * * Since: 0.7.0 **/ gboolean fwupd_client_clear_results (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(FwupdClientHelper) helper = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (device_id != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ helper = fwupd_client_helper_new (); g_dbus_proxy_call (priv->proxy, "ClearResults", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, fwupd_client_proxy_call_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_get_results: * @client: A #FwupdClient * @device_id: the device ID * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets the results of a previous firmware update for a specific device. * * Returns: (transfer full): a #FwupdDevice, or %NULL for failure * * Since: 0.7.0 **/ FwupdDevice * fwupd_client_get_results (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(FwupdClientHelper) helper = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (device_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ helper = fwupd_client_helper_new (); g_dbus_proxy_call (priv->proxy, "GetResults", g_variant_new ("(s)", device_id), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, fwupd_client_proxy_call_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return NULL; } return fwupd_device_from_variant (helper->val); } static void fwupd_client_send_message_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { FwupdClientHelper *helper = (FwupdClientHelper *) user_data; GDBusConnection *con = G_DBUS_CONNECTION (source_object); helper->message = g_dbus_connection_send_message_with_reply_finish (con, res, &helper->error); if (helper->message && !g_dbus_message_to_gerror (helper->message, &helper->error)) { helper->ret = TRUE; helper->val = g_dbus_message_get_body (helper->message); if (helper->val != NULL) g_variant_ref (helper->val); } if (helper->error != NULL) fwupd_client_fixup_dbus_error (helper->error); g_main_loop_quit (helper->loop); } /** * fwupd_client_install: * @client: A #FwupdClient * @device_id: the device ID * @filename: the filename to install * @install_flags: the #FwupdInstallFlags, e.g. %FWUPD_INSTALL_FLAG_ALLOW_REINSTALL * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Install a file onto a specific device. * * Returns: %TRUE for success * * Since: 0.7.0 **/ gboolean fwupd_client_install (FwupdClient *client, const gchar *device_id, const gchar *filename, FwupdInstallFlags install_flags, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); GVariant *body; GVariantBuilder builder; gint retval; gint fd; g_autoptr(FwupdClientHelper) helper = NULL; g_autoptr(GDBusMessage) request = NULL; g_autoptr(GUnixFDList) fd_list = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (device_id != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* set options */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); g_variant_builder_add (&builder, "{sv}", "reason", g_variant_new_string ("user-action")); g_variant_builder_add (&builder, "{sv}", "filename", g_variant_new_string (filename)); if (install_flags & FWUPD_INSTALL_FLAG_OFFLINE) { g_variant_builder_add (&builder, "{sv}", "offline", g_variant_new_boolean (TRUE)); } if (install_flags & FWUPD_INSTALL_FLAG_ALLOW_OLDER) { g_variant_builder_add (&builder, "{sv}", "allow-older", g_variant_new_boolean (TRUE)); } if (install_flags & FWUPD_INSTALL_FLAG_ALLOW_REINSTALL) { g_variant_builder_add (&builder, "{sv}", "allow-reinstall", g_variant_new_boolean (TRUE)); } if (install_flags & FWUPD_INSTALL_FLAG_FORCE) { g_variant_builder_add (&builder, "{sv}", "force", g_variant_new_boolean (TRUE)); } /* open file */ fd = open (filename, O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", filename); return FALSE; } /* set out of band file descriptor */ fd_list = g_unix_fd_list_new (); retval = g_unix_fd_list_append (fd_list, fd, NULL); g_assert (retval != -1); request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, "Install"); g_dbus_message_set_unix_fd_list (request, fd_list); /* g_unix_fd_list_append did a dup() already */ close (fd); /* call into daemon */ helper = fwupd_client_helper_new (); body = g_variant_new ("(sha{sv})", device_id, fd, &builder); g_dbus_message_set_body (request, body); g_dbus_connection_send_message_with_reply (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, G_MAXINT, NULL, cancellable, fwupd_client_send_message_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_get_details: * @client: A #FwupdClient * @filename: the firmware filename, e.g. `firmware.cab` * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets details about a specific firmware file. * * Returns: (transfer container) (element-type FwupdDevice): an array of results * * Since: 1.0.0 **/ GPtrArray * fwupd_client_get_details (FwupdClient *client, const gchar *filename, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); GVariant *body; gint fd; gint retval; g_autoptr(FwupdClientHelper) helper = NULL; g_autoptr(GDBusMessage) request = NULL; g_autoptr(GUnixFDList) fd_list = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* open file */ fd = open (filename, O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", filename); return NULL; } /* set out of band file descriptor */ fd_list = g_unix_fd_list_new (); retval = g_unix_fd_list_append (fd_list, fd, NULL); g_assert (retval != -1); request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, "GetDetails"); g_dbus_message_set_unix_fd_list (request, fd_list); /* g_unix_fd_list_append did a dup() already */ close (fd); /* call into daemon */ helper = fwupd_client_helper_new (); body = g_variant_new ("(h)", fd); g_dbus_message_set_body (request, body); g_dbus_connection_send_message_with_reply (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, cancellable, fwupd_client_send_message_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return NULL; } /* return results */ return fwupd_client_parse_devices_from_variant (helper->val); } /** * fwupd_client_get_percentage: * @client: A #FwupdClient * * Gets the last returned percentage value. * * Returns: a percentage, or 0 for unknown. * * Since: 0.7.3 **/ guint fwupd_client_get_percentage (FwupdClient *client) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_return_val_if_fail (FWUPD_IS_CLIENT (client), 0); return priv->percentage; } /** * fwupd_client_get_daemon_version: * @client: A #FwupdClient * * Gets the daemon version number. * * Returns: a string, or %NULL for unknown. * * Since: 0.9.6 **/ const gchar * fwupd_client_get_daemon_version (FwupdClient *client) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); return priv->daemon_version; } /** * fwupd_client_get_status: * @client: A #FwupdClient * * Gets the last returned status value. * * Returns: a #FwupdStatus, or %FWUPD_STATUS_UNKNOWN for unknown. * * Since: 0.7.3 **/ FwupdStatus fwupd_client_get_status (FwupdClient *client) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_return_val_if_fail (FWUPD_IS_CLIENT (client), FWUPD_STATUS_UNKNOWN); return priv->status; } /** * fwupd_client_update_metadata: * @client: A #FwupdClient * @remote_id: the remote ID, e.g. `lvfs-testing` * @metadata_fn: the XML metadata filename * @signature_fn: the GPG signature file * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Updates the metadata. This allows a session process to download the metadata * and metadata signing file to be passed into the daemon to be checked and * parsed. * * The @remote_id allows the firmware to be tagged so that the remote can be * matched when the firmware is downloaded. * * Returns: %TRUE for success * * Since: 1.0.0 **/ gboolean fwupd_client_update_metadata (FwupdClient *client, const gchar *remote_id, const gchar *metadata_fn, const gchar *signature_fn, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); GVariant *body; gint fd; gint fd_sig; g_autoptr(FwupdClientHelper) helper = NULL; g_autoptr(GDBusMessage) request = NULL; g_autoptr(GUnixFDList) fd_list = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (remote_id != NULL, FALSE); g_return_val_if_fail (metadata_fn != NULL, FALSE); g_return_val_if_fail (signature_fn != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* open file */ fd = open (metadata_fn, O_RDONLY); if (fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", metadata_fn); return FALSE; } fd_sig = open (signature_fn, O_RDONLY); if (fd_sig < 0) { close (fd); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", signature_fn); return FALSE; } /* set out of band file descriptor */ fd_list = g_unix_fd_list_new (); g_unix_fd_list_append (fd_list, fd, NULL); g_unix_fd_list_append (fd_list, fd_sig, NULL); request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE, FWUPD_DBUS_PATH, FWUPD_DBUS_INTERFACE, "UpdateMetadata"); g_dbus_message_set_unix_fd_list (request, fd_list); /* g_unix_fd_list_append did a dup() already */ close (fd); close (fd_sig); /* call into daemon */ body = g_variant_new ("(shh)", remote_id, fd, fd_sig); g_dbus_message_set_body (request, body); helper = fwupd_client_helper_new (); g_dbus_connection_send_message_with_reply (priv->conn, request, G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, cancellable, fwupd_client_send_message_cb, helper); g_main_loop_run (helper->loop); if (!helper->ret) { g_propagate_error (error, helper->error); helper->error = NULL; return FALSE; } return TRUE; } /** * fwupd_client_get_remotes: * @client: A #FwupdClient * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets the list of remotes that have been configured for the system. * * Returns: (element-type FwupdRemote) (transfer container): list of remotes, or %NULL * * Since: 0.9.3 **/ GPtrArray * fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return NULL; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "GetRemotes", NULL, G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return NULL; } return fwupd_client_parse_remotes_from_data (val); } /** * fwupd_client_modify_remote: * @client: A #FwupdClient * @remote_id: the remote ID, e.g. `lvfs-testing` * @key: the key, e.g. `Enabled` * @value: the key, e.g. `true` * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Modifies a system remote in a specific way. * * NOTE: User authentication may be required to complete this action. * * Returns: %TRUE for success * * Since: 0.9.8 **/ gboolean fwupd_client_modify_remote (FwupdClient *client, const gchar *remote_id, const gchar *key, const gchar *value, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (remote_id != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "ModifyRemote", g_variant_new ("(sss)", remote_id, key, value), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return FALSE; } return TRUE; } /** * fwupd_client_modify_device: * @client: A #FwupdClient * @device_id: the device ID * @key: the key, e.g. `Flags` * @value: the key, e.g. `reported` * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Modifies a device in a specific way. Not all properties on the #FwupdDevice * are settable by the client, and some may have other restrictions on @value. * * NOTE: User authentication may be required to complete this action. * * Returns: %TRUE for success * * Since: 1.0.4 **/ gboolean fwupd_client_modify_device (FwupdClient *client, const gchar *remote_id, const gchar *key, const gchar *value, GCancellable *cancellable, GError **error) { FwupdClientPrivate *priv = GET_PRIVATE (client); g_autoptr(GVariant) val = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), FALSE); g_return_val_if_fail (remote_id != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* connect */ if (!fwupd_client_connect (client, cancellable, error)) return FALSE; /* call into daemon */ val = g_dbus_proxy_call_sync (priv->proxy, "ModifyDevice", g_variant_new ("(sss)", remote_id, key, value), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, error); if (val == NULL) { if (error != NULL) fwupd_client_fixup_dbus_error (*error); return FALSE; } return TRUE; } static FwupdRemote * fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id) { for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0) return remote; } return NULL; } /** * fwupd_client_get_remote_by_id: * @client: A #FwupdClient * @remote_id: the remote ID, e.g. `lvfs-testing` * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Gets a specific remote that has been configured for the system. * * Returns: (transfer full): a #FwupdRemote, or %NULL if not found * * Since: 0.9.3 **/ FwupdRemote * fwupd_client_get_remote_by_id (FwupdClient *client, const gchar *remote_id, GCancellable *cancellable, GError **error) { FwupdRemote *remote; g_autoptr(GPtrArray) remotes = NULL; g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL); g_return_val_if_fail (remote_id != NULL, NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find remote in list */ remotes = fwupd_client_get_remotes (client, cancellable, error); if (remotes == NULL) return NULL; remote = fwupd_client_get_remote_by_id_noref (remotes, remote_id); if (remote == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "No remote '%s' found in search paths", remote_id); return NULL; } /* success */ return g_object_ref (remote); } static void fwupd_client_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { FwupdClient *client = FWUPD_CLIENT (object); FwupdClientPrivate *priv = GET_PRIVATE (client); switch (prop_id) { case PROP_STATUS: g_value_set_uint (value, priv->status); break; case PROP_PERCENTAGE: g_value_set_uint (value, priv->percentage); break; case PROP_DAEMON_VERSION: g_value_set_string (value, priv->daemon_version); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void fwupd_client_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FwupdClient *client = FWUPD_CLIENT (object); FwupdClientPrivate *priv = GET_PRIVATE (client); switch (prop_id) { case PROP_STATUS: priv->status = g_value_get_uint (value); break; case PROP_PERCENTAGE: priv->percentage = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void fwupd_client_class_init (FwupdClientClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fwupd_client_finalize; object_class->get_property = fwupd_client_get_property; object_class->set_property = fwupd_client_set_property; /** * FwupdClient::changed: * @client: the #FwupdClient instance that emitted the signal * * The ::changed signal is emitted when the daemon internal has * changed, for instance when a device has been added or removed. * * Since: 0.7.0 **/ signals [SIGNAL_CHANGED] = g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FwupdClientClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); /** * FwupdClient::state-changed: * @client: the #FwupdClient instance that emitted the signal * @status: the #FwupdStatus * * The ::state-changed signal is emitted when the daemon status has * changed, e.g. going from %FWUPD_STATUS_IDLE to %FWUPD_STATUS_DEVICE_WRITE. * * Since: 0.7.0 **/ signals [SIGNAL_STATUS_CHANGED] = g_signal_new ("status-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FwupdClientClass, status_changed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); /** * FwupdClient::device-added: * @client: the #FwupdClient instance that emitted the signal * @result: the #FwupdDevice * * The ::device-added signal is emitted when a device has been * added. * * Since: 0.7.1 **/ signals [SIGNAL_DEVICE_ADDED] = g_signal_new ("device-added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FwupdClientClass, device_added), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE); /** * FwupdClient::device-removed: * @client: the #FwupdClient instance that emitted the signal * @result: the #FwupdDevice * * The ::device-removed signal is emitted when a device has been * removed. * * Since: 0.7.1 **/ signals [SIGNAL_DEVICE_REMOVED] = g_signal_new ("device-removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FwupdClientClass, device_removed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE); /** * FwupdClient::device-changed: * @client: the #FwupdClient instance that emitted the signal * @result: the #FwupdDevice * * The ::device-changed signal is emitted when a device has been * changed in some way, e.g. the version number is updated. * * Since: 0.7.1 **/ signals [SIGNAL_DEVICE_CHANGED] = g_signal_new ("device-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (FwupdClientClass, device_changed), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, FWUPD_TYPE_DEVICE); /** * FwupdClient:status: * * The last-reported status of the daemon. * * Since: 0.7.0 */ pspec = g_param_spec_uint ("status", NULL, NULL, 0, FWUPD_STATUS_LAST, FWUPD_STATUS_UNKNOWN, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_STATUS, pspec); /** * FwupdClient:percentage: * * The last-reported percentage of the daemon. * * Since: 0.7.3 */ pspec = g_param_spec_uint ("percentage", NULL, NULL, 0, 100, 0, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_PERCENTAGE, pspec); /** * FwupdClient:daemon-version: * * The daemon version number. * * Since: 0.9.6 */ pspec = g_param_spec_string ("daemon-version", NULL, NULL, NULL, G_PARAM_READABLE); g_object_class_install_property (object_class, PROP_DAEMON_VERSION, pspec); } static void fwupd_client_init (FwupdClient *client) { } static void fwupd_client_finalize (GObject *object) { FwupdClient *client = FWUPD_CLIENT (object); FwupdClientPrivate *priv = GET_PRIVATE (client); g_free (priv->daemon_version); if (priv->conn != NULL) g_object_unref (priv->conn); if (priv->proxy != NULL) g_object_unref (priv->proxy); G_OBJECT_CLASS (fwupd_client_parent_class)->finalize (object); } /** * fwupd_client_new: * * Creates a new client. * * Returns: a new #FwupdClient * * Since: 0.7.0 **/ FwupdClient * fwupd_client_new (void) { FwupdClient *client; client = g_object_new (FWUPD_TYPE_CLIENT, NULL); return FWUPD_CLIENT (client); } fwupd-1.0.6/libfwupd/fwupd-client.h000066400000000000000000000121741325145456600172510ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_CLIENT_H #define __FWUPD_CLIENT_H #include #include #include "fwupd-enums.h" #include "fwupd-device.h" #include "fwupd-remote.h" G_BEGIN_DECLS #define FWUPD_TYPE_CLIENT (fwupd_client_get_type ()) G_DECLARE_DERIVABLE_TYPE (FwupdClient, fwupd_client, FWUPD, CLIENT, GObject) struct _FwupdClientClass { GObjectClass parent_class; void (*changed) (FwupdClient *client); void (*status_changed) (FwupdClient *client, FwupdStatus status); void (*device_added) (FwupdClient *client, FwupdDevice *result); void (*device_removed) (FwupdClient *client, FwupdDevice *result); void (*device_changed) (FwupdClient *client, FwupdDevice *result); /*< private >*/ void (*_fwupd_reserved1) (void); void (*_fwupd_reserved2) (void); void (*_fwupd_reserved3) (void); void (*_fwupd_reserved4) (void); void (*_fwupd_reserved5) (void); void (*_fwupd_reserved6) (void); void (*_fwupd_reserved7) (void); }; FwupdClient *fwupd_client_new (void); gboolean fwupd_client_connect (FwupdClient *client, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_devices (FwupdClient *client, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_history (FwupdClient *client, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_releases (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_downgrades (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_upgrades (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); GPtrArray *fwupd_client_get_details (FwupdClient *client, const gchar *filename, GCancellable *cancellable, GError **error); gboolean fwupd_client_verify (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); gboolean fwupd_client_verify_update (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); gboolean fwupd_client_unlock (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); gboolean fwupd_client_clear_results (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); FwupdDevice *fwupd_client_get_results (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); FwupdDevice *fwupd_client_get_device_by_id (FwupdClient *client, const gchar *device_id, GCancellable *cancellable, GError **error); gboolean fwupd_client_install (FwupdClient *client, const gchar *device_id, const gchar *filename, FwupdInstallFlags install_flags, GCancellable *cancellable, GError **error); gboolean fwupd_client_update_metadata (FwupdClient *client, const gchar *remote_id, const gchar *metadata_fn, const gchar *signature_fn, GCancellable *cancellable, GError **error); gboolean fwupd_client_modify_remote (FwupdClient *client, const gchar *remote_id, const gchar *key, const gchar *value, GCancellable *cancellable, GError **error); gboolean fwupd_client_modify_device (FwupdClient *client, const gchar *device_id, const gchar *key, const gchar *value, GCancellable *cancellable, GError **error); FwupdStatus fwupd_client_get_status (FwupdClient *client); guint fwupd_client_get_percentage (FwupdClient *client); const gchar *fwupd_client_get_daemon_version (FwupdClient *client); GPtrArray *fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError **error); FwupdRemote *fwupd_client_get_remote_by_id (FwupdClient *client, const gchar *remote_id, GCancellable *cancellable, GError **error); G_END_DECLS #endif /* __FWUPD_CLIENT_H */ fwupd-1.0.6/libfwupd/fwupd-common-private.h000066400000000000000000000022251325145456600207270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_COMMON_PRIVATE_H #define __FWUPD_COMMON_PRIVATE_H #include #include "fwupd-common.h" gchar *fwupd_checksum_format_for_display (const gchar *checksum); #endif /* __FWUPD_COMMON_PRIVATE_H */ fwupd-1.0.6/libfwupd/fwupd-common.c000066400000000000000000000351071325145456600172570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "fwupd-common-private.h" #include "fwupd-device.h" #include "fwupd-error.h" #include "fwupd-release.h" #include #include #include #include /** * fwupd_checksum_guess_kind: * @checksum: A checksum * * Guesses the checksum kind based on the length of the hash. * * Returns: a #GChecksumType, e.g. %G_CHECKSUM_SHA1 * * Since: 0.9.3 **/ GChecksumType fwupd_checksum_guess_kind (const gchar *checksum) { guint len; if (checksum == NULL) return G_CHECKSUM_SHA1; len = strlen (checksum); if (len == 32) return G_CHECKSUM_MD5; if (len == 40) return G_CHECKSUM_SHA1; if (len == 64) return G_CHECKSUM_SHA256; if (len == 128) return G_CHECKSUM_SHA512; return G_CHECKSUM_SHA1; } static const gchar * _g_checksum_type_to_string (GChecksumType checksum_type) { if (checksum_type == G_CHECKSUM_MD5) return "MD5"; if (checksum_type == G_CHECKSUM_SHA1) return "SHA1"; if (checksum_type == G_CHECKSUM_SHA256) return "SHA256"; if (checksum_type == G_CHECKSUM_SHA512) return "SHA512"; return NULL; } /** * fwupd_checksum_format_for_display: * @checksum: A checksum * * Formats a checksum for display. * * Returns: text, or %NULL for invalid * * Since: 0.9.3 **/ gchar * fwupd_checksum_format_for_display (const gchar *checksum) { GChecksumType kind = fwupd_checksum_guess_kind (checksum); return g_strdup_printf ("%s(%s)", _g_checksum_type_to_string (kind), checksum); } /** * fwupd_checksum_get_by_kind: * @checksums: (element-type utf8): checksums * @kind: a #GChecksumType, e.g. %G_CHECKSUM_SHA512 * * Gets a specific checksum kind. * * Returns: a checksum from the array, or %NULL if not found * * Since: 0.9.4 **/ const gchar * fwupd_checksum_get_by_kind (GPtrArray *checksums, GChecksumType kind) { for (guint i = 0; i < checksums->len; i++) { const gchar *checksum = g_ptr_array_index (checksums, i); if (fwupd_checksum_guess_kind (checksum) == kind) return checksum; } return NULL; } /** * fwupd_checksum_get_best: * @checksums: (element-type utf8): checksums * * Gets a the best possible checksum kind. * * Returns: a checksum from the array, or %NULL if nothing was suitable * * Since: 0.9.4 **/ const gchar * fwupd_checksum_get_best (GPtrArray *checksums) { GChecksumType checksum_types[] = { G_CHECKSUM_SHA512, G_CHECKSUM_SHA256, G_CHECKSUM_SHA1, 0 }; for (guint i = 0; checksum_types[i] != 0; i++) { for (guint j = 0; j < checksums->len; j++) { const gchar *checksum = g_ptr_array_index (checksums, j); if (fwupd_checksum_guess_kind (checksum) == checksum_types[i]) return checksum; } } return NULL; } /** * fwupd_build_distro_hash: * @error: A #GError or %NULL * * Loads information from the system os-release file. **/ static GHashTable * fwupd_build_distro_hash (GError **error) { GHashTable *hash; const gchar *filename = NULL; const gchar *paths[] = { "/etc/os-release", "/usr/lib/os-release", NULL }; g_autofree gchar *buf = NULL; g_auto(GStrv) lines = NULL; /* find the correct file */ for (guint i = 0; paths[i] != NULL; i++) { g_debug ("looking for os-release at %s", paths[i]); if (g_file_test (paths[i], G_FILE_TEST_EXISTS)) { filename = paths[i]; break; } } if (filename == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "No os-release found"); return NULL; } /* load each line */ if (!g_file_get_contents (filename, &buf, NULL, error)) return NULL; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); lines = g_strsplit (buf, "\n", -1); for (guint i = 0; lines[i] != NULL; i++) { gsize len, off = 0; g_auto(GStrv) split = NULL; /* split up into sections */ split = g_strsplit (lines[i], "=", 2); if (g_strv_length (split) < 2) continue; /* remove double quotes if set both ends */ len = strlen (split[1]); if (len == 0) continue; if (split[1][0] == '\"' && split[1][len-1] == '\"') { off++; len -= 2; } g_hash_table_insert (hash, g_strdup (split[0]), g_strndup (split[1] + off, len)); } return hash; } static gchar * fwupd_build_user_agent_os_release (void) { const gchar *keys[] = { "NAME", "VERSION_ID", "VARIANT", NULL }; g_autoptr(GHashTable) hash = NULL; g_autoptr(GPtrArray) ids_os = g_ptr_array_new (); /* get all keys */ hash = fwupd_build_distro_hash (NULL); if (hash == NULL) return NULL; /* create an array of the keys that exist */ for (guint i = 0; keys[i] != NULL; i++) { const gchar *value = g_hash_table_lookup (hash, keys[i]); if (value != NULL) g_ptr_array_add (ids_os, (gpointer) value); } if (ids_os->len == 0) return NULL; g_ptr_array_add (ids_os, NULL); return g_strjoinv (" ", (gchar **) ids_os->pdata); } static gchar * fwupd_build_user_agent_system (void) { struct utsname name_tmp = { 0 }; g_autofree gchar *locale = NULL; g_autofree gchar *os_release = NULL; g_autoptr(GPtrArray) ids = g_ptr_array_new_with_free_func (g_free); /* system, architecture and kernel, e.g. "Linux i686 4.14.5" */ if (uname (&name_tmp) >= 0) { g_ptr_array_add (ids, g_strdup_printf ("%s %s %s", name_tmp.sysname, name_tmp.machine, name_tmp.release)); } /* current locale, e.g. "en-gb" */ locale = g_strdup (setlocale (LC_MESSAGES, NULL)); if (locale != NULL) { g_strdelimit (locale, ".", '\0'); g_strdelimit (locale, "_", '-'); g_ptr_array_add (ids, g_steal_pointer (&locale)); } /* OS release, e.g. "Fedora 27 Workstation" */ os_release = fwupd_build_user_agent_os_release (); if (os_release != NULL) g_ptr_array_add (ids, g_steal_pointer (&os_release)); /* convert to string */ if (ids->len == 0) return NULL; g_ptr_array_add (ids, NULL); return g_strjoinv ("; ", (gchar **) ids->pdata); } /** * fwupd_build_user_agent: * @package_name: client program name, e.g. "gnome-software" * @package_version: client program version, e.g. "3.28.1" * * Builds a user-agent to use for the download. * * Supplying harmless details to the server means it knows more about each * client. This allows the web service to respond in a different way, for * instance sending a different metadata file for old versions of fwupd, or * returning an error for Solaris machines. * * Before freaking out about theoretical privacy implications, much more data * than this is sent to each and every website you visit. * * Returns: a string, e.g. `foo/0.1 (Linux i386 4.14.5; en; Fedora 27) fwupd/1.0.3` * * Since: 1.0.3 **/ gchar * fwupd_build_user_agent (const gchar *package_name, const gchar *package_version) { GString *str = g_string_new (NULL); g_autofree gchar *system = NULL; /* application name and version */ g_string_append_printf (str, "%s/%s", package_name, package_version); /* system information */ system = fwupd_build_user_agent_system (); if (system != NULL) g_string_append_printf (str, " (%s)", system); /* platform, which in our case is just fwupd */ if (g_strcmp0 (package_name, "fwupd") != 0) g_string_append_printf (str, " fwupd/%s", PACKAGE_VERSION); /* success */ return g_string_free (str, FALSE); } /** * fwupd_build_machine_id: * @salt: The salt, or %NULL for none * @error: A #GError or %NULL * * Gets a salted hash of the /etc/machine-id contents. This can be used to * identify a specific machine. It is not possible to recover the original * machine-id from the machine-hash. * * Returns: the SHA256 machine hash, or %NULL if the ID is not present * * Since: 1.0.4 **/ gchar * fwupd_build_machine_id (const gchar *salt, GError **error) { g_autofree gchar *buf = NULL; g_autoptr(GChecksum) csum = NULL; gsize sz = 0; /* this has to exist */ if (!g_file_get_contents ("/etc/machine-id", &buf, &sz, error)) return NULL; if (sz == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "The machine-id is present but unset"); return NULL; } csum = g_checksum_new (G_CHECKSUM_SHA256); if (salt != NULL) g_checksum_update (csum, (const guchar *) salt, (gssize) strlen (salt)); g_checksum_update (csum, (const guchar *) buf, (gssize) sz); return g_strdup (g_checksum_get_string (csum)); } static void fwupd_build_history_report_json_metadata_device (JsonBuilder *builder, FwupdDevice *dev) { FwupdRelease *rel = fwupd_device_get_release_default (dev); GHashTable *metadata = fwupd_release_get_metadata (rel); g_autoptr(GList) keys = NULL; /* add each metadata value */ keys = g_hash_table_get_keys (metadata); for (GList *l = keys; l != NULL; l = l->next) { const gchar *key = l->data; const gchar *value = g_hash_table_lookup (metadata, key); json_builder_set_member_name (builder, key); json_builder_add_string_value (builder, value); } } static void fwupd_build_history_report_json_device (JsonBuilder *builder, FwupdDevice *dev) { FwupdRelease *rel = fwupd_device_get_release_default (dev); GPtrArray *checksums; /* identify the firmware used */ json_builder_set_member_name (builder, "Checksum"); checksums = fwupd_release_get_checksums (rel); json_builder_add_string_value (builder, fwupd_checksum_get_by_kind (checksums, G_CHECKSUM_SHA1)); /* set the error state of the report */ json_builder_set_member_name (builder, "UpdateState"); json_builder_add_int_value (builder, fwupd_device_get_update_state (dev)); if (fwupd_device_get_update_error (dev) != NULL) { json_builder_set_member_name (builder, "UpdateError"); json_builder_add_string_value (builder, fwupd_device_get_update_error (dev)); } /* map back to the dev type on the LVFS */ json_builder_set_member_name (builder, "Guid"); json_builder_add_string_value (builder, fwupd_device_get_guid_default (dev)); json_builder_set_member_name (builder, "Plugin"); json_builder_add_string_value (builder, fwupd_device_get_plugin (dev)); /* report what we're trying to update *from* and *to* */ json_builder_set_member_name (builder, "VersionOld"); json_builder_add_string_value (builder, fwupd_device_get_version (dev)); json_builder_set_member_name (builder, "VersionNew"); json_builder_add_string_value (builder, fwupd_release_get_version (rel)); /* to know the state of the dev we're trying to update */ json_builder_set_member_name (builder, "Flags"); json_builder_add_int_value (builder, fwupd_device_get_flags (dev)); /* to know when the update tried to happen, and how soon after boot */ json_builder_set_member_name (builder, "Created"); json_builder_add_int_value (builder, fwupd_device_get_created (dev)); json_builder_set_member_name (builder, "Modified"); json_builder_add_int_value (builder, fwupd_device_get_modified (dev)); /* add saved metadata to the report */ json_builder_set_member_name (builder, "Metadata"); json_builder_begin_object (builder); fwupd_build_history_report_json_metadata_device (builder, dev); json_builder_end_object (builder); } static gboolean fwupd_build_history_report_json_metadata (JsonBuilder *builder, GError **error) { g_autoptr(GHashTable) hash = NULL; struct { const gchar *key; const gchar *val; } distro_kv[] = { { "ID", "DistroId" }, { "VERSION_ID", "DistroVersion" }, { "VARIANT_ID", "DistroVariant" }, { NULL, NULL } }; /* get all required os-release keys */ hash = fwupd_build_distro_hash (error); if (hash == NULL) return FALSE; for (guint i = 0; distro_kv[i].key != NULL; i++) { const gchar *tmp = g_hash_table_lookup (hash, distro_kv[i].key); if (tmp != NULL) { json_builder_set_member_name (builder, distro_kv[i].val); json_builder_add_string_value (builder, tmp); } } return TRUE; } /** * fwupd_build_history_report_json: * @devices: (element-type FwupdDevice): devices * @error: A #GError or %NULL * * Builds a JSON report for the list of devices. No filtering is done on the * @devices array, and it is expected that the caller will filter to something * sane, e.g. %FWUPD_DEVICE_FLAG_REPORTED at the bare minimum. * * Returns: a string, or %NULL if the ID is not present * * Since: 1.0.4 **/ gchar * fwupd_build_history_report_json (GPtrArray *devices, GError **error) { gchar *data; g_autofree gchar *machine_id = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; /* get a hash that represents the machine */ machine_id = fwupd_build_machine_id ("fwupd", error); if (machine_id == NULL) return FALSE; /* create header */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "ReportVersion"); json_builder_add_int_value (builder, 2); json_builder_set_member_name (builder, "MachineId"); json_builder_add_string_value (builder, machine_id); /* this is system metadata not stored in the database */ json_builder_set_member_name (builder, "Metadata"); json_builder_begin_object (builder); if (!fwupd_build_history_report_json_metadata (builder, error)) return FALSE; json_builder_end_object (builder); /* add each device */ json_builder_set_member_name (builder, "Reports"); json_builder_begin_array (builder); for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); json_builder_begin_object (builder); fwupd_build_history_report_json_device (builder, dev); json_builder_end_object (builder); } json_builder_end_array (builder); json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); if (data == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to convert to JSON string"); return NULL; } return data; } fwupd-1.0.6/libfwupd/fwupd-common.h000066400000000000000000000032711325145456600172610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_COMMON_H #define __FWUPD_COMMON_H #include #define FWUPD_DBUS_PATH "/" #define FWUPD_DBUS_SERVICE "org.freedesktop.fwupd" #define FWUPD_DBUS_INTERFACE "org.freedesktop.fwupd" #define FWUPD_DEVICE_ID_ANY "*" const gchar *fwupd_checksum_get_best (GPtrArray *checksums); const gchar *fwupd_checksum_get_by_kind (GPtrArray *checksums, GChecksumType kind); GChecksumType fwupd_checksum_guess_kind (const gchar *checksum); gchar *fwupd_build_user_agent (const gchar *package_name, const gchar *package_version); gchar *fwupd_build_machine_id (const gchar *salt, GError **error); gchar *fwupd_build_history_report_json (GPtrArray *devices, GError **error); #endif /* __FWUPD_COMMON_H */ fwupd-1.0.6/libfwupd/fwupd-deprecated.h000066400000000000000000000020561325145456600200710ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_DEPRECATED_H #define __FWUPD_DEPRECATED_H /* indeed, nothing */ #endif /* __FWUPD_DEPRECATED_H */ fwupd-1.0.6/libfwupd/fwupd-device-private.h000066400000000000000000000023521325145456600206770ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_DEVICE_PRIVATE_H #define __FWUPD_DEVICE_PRIVATE_H #include #include "fwupd-device.h" G_BEGIN_DECLS FwupdDevice *fwupd_device_from_variant (GVariant *data); GVariant *fwupd_device_to_variant (FwupdDevice *device); G_END_DECLS #endif /* __FWUPD_DEVICE_PRIVATE_H */ fwupd-1.0.6/libfwupd/fwupd-device.c000066400000000000000000001064671325145456600172360ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "fwupd-common-private.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" #include "fwupd-device-private.h" #include "fwupd-release-private.h" /** * SECTION:fwupd-device * @short_description: a hardware device * * An object that represents a physical device on the host. * * See also: #FwupdRelease */ static void fwupd_device_finalize (GObject *object); typedef struct { gchar *id; guint64 created; guint64 modified; guint64 flags; gchar *appstream_id; GPtrArray *guids; GPtrArray *icons; gchar *name; gchar *summary; gchar *description; gchar *vendor; gchar *vendor_id; gchar *homepage; gchar *plugin; gchar *version; gchar *version_lowest; gchar *version_bootloader; GPtrArray *checksums; guint32 flashes_left; FwupdUpdateState update_state; gchar *update_error; GPtrArray *releases; } FwupdDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FwupdDevice, fwupd_device, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fwupd_device_get_instance_private (o)) /** * fwupd_device_get_checksums: * @device: A #FwupdDevice * * Gets the device checksums. * * Returns: (element-type utf8) (transfer none): the checksums, which may be empty * * Since: 0.9.3 **/ GPtrArray * fwupd_device_get_checksums (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->checksums; } /** * fwupd_device_add_checksum: * @device: A #FwupdDevice * @checksum: the device checksum * * Sets the device checksum. * * Since: 0.9.3 **/ void fwupd_device_add_checksum (FwupdDevice *device, const gchar *checksum) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_return_if_fail (checksum != NULL); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum_tmp = g_ptr_array_index (priv->checksums, i); if (g_strcmp0 (checksum_tmp, checksum) == 0) return; } g_ptr_array_add (priv->checksums, g_strdup (checksum)); } /** * fwupd_device_get_summary: * @device: A #FwupdDevice * * Gets the device summary. * * Returns: the device summary, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_summary (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->summary; } /** * fwupd_device_set_summary: * @device: A #FwupdDevice * @summary: the device one line summary * * Sets the device summary. * * Since: 0.9.3 **/ void fwupd_device_set_summary (FwupdDevice *device, const gchar *summary) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->summary); priv->summary = g_strdup (summary); } /** * fwupd_device_get_id: * @device: A #FwupdDevice * * Gets the ID. * * Returns: the ID, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_id (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->id; } /** * fwupd_device_set_id: * @device: A #FwupdDevice * @id: the device ID, e.g. `USB:foo` * * Sets the ID. * * Since: 0.9.3 **/ void fwupd_device_set_id (FwupdDevice *device, const gchar *id) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->id); priv->id = g_strdup (id); } /** * fwupd_device_get_guids: * @device: A #FwupdDevice * * Gets the GUIDs. * * Returns: (element-type utf8) (transfer none): the GUIDs * * Since: 0.9.3 **/ GPtrArray * fwupd_device_get_guids (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->guids; } /** * fwupd_device_has_guid: * @device: A #FwupdDevice * @guid: the GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad` * * Finds out if the device has this specific GUID. * * Returns: %TRUE if the GUID is found * * Since: 0.9.3 **/ gboolean fwupd_device_has_guid (FwupdDevice *device, const gchar *guid) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), FALSE); for (guint i = 0; i < priv->guids->len; i++) { const gchar *guid_tmp = g_ptr_array_index (priv->guids, i); if (g_strcmp0 (guid, guid_tmp) == 0) return TRUE; } return FALSE; } /** * fwupd_device_add_guid: * @device: A #FwupdDevice * @guid: the GUID, e.g. `2082b5e0-7a64-478a-b1b2-e3404fab6dad` * * Adds the GUID if it does not already exist. * * Since: 0.9.3 **/ void fwupd_device_add_guid (FwupdDevice *device, const gchar *guid) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); if (fwupd_device_has_guid (device, guid)) return; g_ptr_array_add (priv->guids, g_strdup (guid)); } /** * fwupd_device_get_guid_default: * @device: A #FwupdDevice * * Gets the default GUID. * * Returns: the GUID, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_guid_default (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); if (priv->guids->len == 0) return NULL; return g_ptr_array_index (priv->guids, 0); } /** * fwupd_device_get_icons: * @device: A #FwupdDevice * * Gets the icon names to use for the device. * * NOTE: Icons specified without a full path are stock icons and should * be loaded from the users icon theme. * * Returns: (element-type utf8) (transfer none): an array of icon names * * Since: 0.9.8 **/ GPtrArray * fwupd_device_get_icons (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->icons; } static gboolean fwupd_device_has_icon (FwupdDevice *device, const gchar *icon) { FwupdDevicePrivate *priv = GET_PRIVATE (device); for (guint i = 0; i < priv->icons->len; i++) { const gchar *icon_tmp = g_ptr_array_index (priv->icons, i); if (g_strcmp0 (icon, icon_tmp) == 0) return TRUE; } return FALSE; } /** * fwupd_device_add_icon: * @device: A #FwupdDevice * @icon: the name, e.g. `input-mouse` or `/usr/share/icons/foo.png` * * Adds the icon name if it does not already exist. * * Since: 0.9.8 **/ void fwupd_device_add_icon (FwupdDevice *device, const gchar *icon) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); if (fwupd_device_has_icon (device, icon)) return; g_ptr_array_add (priv->icons, g_strdup (icon)); } /** * fwupd_device_get_name: * @device: A #FwupdDevice * * Gets the device name. * * Returns: the device name, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_name (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->name; } /** * fwupd_device_set_name: * @device: A #FwupdDevice * @name: the device name, e.g. `ColorHug2` * * Sets the device name. * * Since: 0.9.3 **/ void fwupd_device_set_name (FwupdDevice *device, const gchar *name) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->name); priv->name = g_strdup (name); } /** * fwupd_device_get_vendor: * @device: A #FwupdDevice * * Gets the device vendor. * * Returns: the device vendor, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_vendor (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->vendor; } /** * fwupd_device_set_vendor: * @device: A #FwupdDevice * @vendor: the description * * Sets the device vendor. * * Since: 0.9.3 **/ void fwupd_device_set_vendor (FwupdDevice *device, const gchar *vendor) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->vendor); priv->vendor = g_strdup (vendor); } /** * fwupd_device_get_vendor_id: * @device: A #FwupdDevice * * Gets the device vendor ID. * * Returns: the device vendor, e.g. 'USB:0x1234', or %NULL if unset * * Since: 0.9.4 **/ const gchar * fwupd_device_get_vendor_id (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->vendor_id; } /** * fwupd_device_set_vendor_id: * @device: A #FwupdDevice * @vendor_id: the ID, e.g. 'USB:0x1234' * * Sets the device vendor ID. * * Since: 0.9.4 **/ void fwupd_device_set_vendor_id (FwupdDevice *device, const gchar *vendor_id) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->vendor_id); priv->vendor_id = g_strdup (vendor_id); } /** * fwupd_device_get_description: * @device: A #FwupdDevice * * Gets the device description in AppStream markup format. * * Returns: the device description, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_description (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->description; } /** * fwupd_device_set_description: * @device: A #FwupdDevice * @description: the description in AppStream markup format * * Sets the device description. * * Since: 0.9.3 **/ void fwupd_device_set_description (FwupdDevice *device, const gchar *description) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->description); priv->description = g_strdup (description); } /** * fwupd_device_get_version: * @device: A #FwupdDevice * * Gets the device version. * * Returns: the device version, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_version (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->version; } /** * fwupd_device_set_version: * @device: A #FwupdDevice * @version: the device version, e.g. `1.2.3` * * Sets the device version. * * Since: 0.9.3 **/ void fwupd_device_set_version (FwupdDevice *device, const gchar *version) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->version); priv->version = g_strdup (version); } /** * fwupd_device_get_version_lowest: * @device: A #FwupdDevice * * Gets the lowest version of firmware the device will accept. * * Returns: the device version_lowest, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_version_lowest (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->version_lowest; } /** * fwupd_device_set_version_lowest: * @device: A #FwupdDevice * @version_lowest: the description * * Sets the lowest version of firmware the device will accept. * * Since: 0.9.3 **/ void fwupd_device_set_version_lowest (FwupdDevice *device, const gchar *version_lowest) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->version_lowest); priv->version_lowest = g_strdup (version_lowest); } /** * fwupd_device_get_version_bootloader: * @device: A #FwupdDevice * * Gets the version of the bootloader. * * Returns: the device version_bootloader, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_device_get_version_bootloader (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->version_bootloader; } /** * fwupd_device_set_version_bootloader: * @device: A #FwupdDevice * @version_bootloader: the description * * Sets the bootloader version. * * Since: 0.9.3 **/ void fwupd_device_set_version_bootloader (FwupdDevice *device, const gchar *version_bootloader) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->version_bootloader); priv->version_bootloader = g_strdup (version_bootloader); } /** * fwupd_device_get_flashes_left: * @device: A #FwupdDevice * * Gets the number of flash cycles left on the device * * Returns: the flash cycles left, or %NULL if unset * * Since: 0.9.3 **/ guint32 fwupd_device_get_flashes_left (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), 0); return priv->flashes_left; } /** * fwupd_device_set_flashes_left: * @device: A #FwupdDevice * @flashes_left: the description * * Sets the number of flash cycles left on the device * * Since: 0.9.3 **/ void fwupd_device_set_flashes_left (FwupdDevice *device, guint32 flashes_left) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->flashes_left = flashes_left; } /** * fwupd_device_get_plugin: * @device: A #FwupdDevice * * Gets the plugin that created the device. * * Returns: the plugin name, or %NULL if unset * * Since: 1.0.0 **/ const gchar * fwupd_device_get_plugin (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->plugin; } /** * fwupd_device_set_plugin: * @device: A #FwupdDevice * @plugin: the plugin name, e.g. `colorhug` * * Sets the plugin that created the device. * * Since: 1.0.0 **/ void fwupd_device_set_plugin (FwupdDevice *device, const gchar *plugin) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->plugin); priv->plugin = g_strdup (plugin); } /** * fwupd_device_get_flags: * @device: A #FwupdDevice * * Gets the device flags. * * Returns: the device flags, or 0 if unset * * Since: 0.9.3 **/ guint64 fwupd_device_get_flags (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), 0); return priv->flags; } /** * fwupd_device_set_flags: * @device: A #FwupdDevice * @flags: the device flags, e.g. %FWUPD_DEVICE_FLAG_REQUIRE_AC * * Sets the device flags. * * Since: 0.9.3 **/ void fwupd_device_set_flags (FwupdDevice *device, guint64 flags) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->flags = flags; } /** * fwupd_device_add_flag: * @device: A #FwupdDevice * @flag: the #FwupdDeviceFlags * * Adds a specific device flag to the device. * * Since: 0.9.3 **/ void fwupd_device_add_flag (FwupdDevice *device, FwupdDeviceFlags flag) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->flags |= flag; } /** * fwupd_device_remove_flag: * @device: A #FwupdDevice * @flag: the #FwupdDeviceFlags * * Removes a specific device flag from the device. * * Since: 0.9.3 **/ void fwupd_device_remove_flag (FwupdDevice *device, FwupdDeviceFlags flag) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->flags &= ~flag; } /** * fwupd_device_has_flag: * @device: A #FwupdDevice * @flag: the #FwupdDeviceFlags * * Finds if the device has a specific device flag. * * Returns: %TRUE if the flag is set * * Since: 0.9.3 **/ gboolean fwupd_device_has_flag (FwupdDevice *device, FwupdDeviceFlags flag) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), FALSE); return (priv->flags & flag) > 0; } /** * fwupd_device_get_created: * @device: A #FwupdDevice * * Gets when the device was created. * * Returns: the UNIX time, or 0 if unset * * Since: 0.9.3 **/ guint64 fwupd_device_get_created (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), 0); return priv->created; } /** * fwupd_device_set_created: * @device: A #FwupdDevice * @created: the UNIX time * * Sets when the device was created. * * Since: 0.9.3 **/ void fwupd_device_set_created (FwupdDevice *device, guint64 created) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->created = created; } /** * fwupd_device_get_modified: * @device: A #FwupdDevice * * Gets when the device was modified. * * Returns: the UNIX time, or 0 if unset * * Since: 0.9.3 **/ guint64 fwupd_device_get_modified (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), 0); return priv->modified; } /** * fwupd_device_set_modified: * @device: A #FwupdDevice * @modified: the UNIX time * * Sets when the device was modified. * * Since: 0.9.3 **/ void fwupd_device_set_modified (FwupdDevice *device, guint64 modified) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->modified = modified; } /** * fwupd_device_to_variant: * @device: A #FwupdDevice * * Creates a GVariant from the device data. * * Returns: the GVariant, or %NULL for error * * Since: 1.0.0 **/ GVariant * fwupd_device_to_variant (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); GVariantBuilder builder; g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); /* create an array with all the metadata in */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); if (priv->id != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_DEVICE_ID, g_variant_new_string (priv->id)); } if (priv->guids->len > 0) { const gchar * const *tmp = (const gchar * const *) priv->guids->pdata; g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_GUID, g_variant_new_strv (tmp, priv->guids->len)); } if (priv->icons->len > 0) { const gchar * const *tmp = (const gchar * const *) priv->icons->pdata; g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_ICON, g_variant_new_strv (tmp, priv->icons->len)); } if (priv->name != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_NAME, g_variant_new_string (priv->name)); } if (priv->vendor != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VENDOR, g_variant_new_string (priv->vendor)); } if (priv->vendor_id != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VENDOR_ID, g_variant_new_string (priv->vendor_id)); } if (priv->flags > 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_FLAGS, g_variant_new_uint64 (priv->flags)); } if (priv->created > 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CREATED, g_variant_new_uint64 (priv->created)); } if (priv->modified > 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_MODIFIED, g_variant_new_uint64 (priv->modified)); } if (priv->description != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_DESCRIPTION, g_variant_new_string (priv->description)); } if (priv->summary != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_SUMMARY, g_variant_new_string (priv->summary)); } if (priv->checksums->len > 0) { g_autoptr(GString) str = g_string_new (""); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum = g_ptr_array_index (priv->checksums, i); g_string_append_printf (str, "%s,", checksum); } if (str->len > 0) g_string_truncate (str, str->len - 1); g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CHECKSUM, g_variant_new_string (str->str)); } if (priv->plugin != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_PLUGIN, g_variant_new_string (priv->plugin)); } if (priv->version != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VERSION, g_variant_new_string (priv->version)); } if (priv->version_lowest != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VERSION_LOWEST, g_variant_new_string (priv->version_lowest)); } if (priv->version_bootloader != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VERSION_BOOTLOADER, g_variant_new_string (priv->version_bootloader)); } if (priv->flashes_left > 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_FLASHES_LEFT, g_variant_new_uint32 (priv->flashes_left)); } if (priv->update_error != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_UPDATE_ERROR, g_variant_new_string (priv->update_error)); } if (priv->update_state != FWUPD_UPDATE_STATE_UNKNOWN) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_UPDATE_STATE, g_variant_new_uint32 (priv->update_state)); } /* create an array with all the metadata in */ if (priv->releases->len > 0) { g_autofree GVariant **children = NULL; children = g_new0 (GVariant *, priv->releases->len); for (guint i = 0; i < priv->releases->len; i++) { FwupdRelease *release = g_ptr_array_index (priv->releases, i); children[i] = fwupd_release_to_variant (release); } g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_RELEASE, g_variant_new_array (G_VARIANT_TYPE ("a{sv}"), children, priv->releases->len)); } return g_variant_new ("a{sv}", &builder); } static void fwupd_device_from_key_value (FwupdDevice *device, const gchar *key, GVariant *value) { if (g_strcmp0 (key, FWUPD_RESULT_KEY_RELEASE) == 0) { GVariantIter iter; GVariant *child; g_variant_iter_init (&iter, value); while ((child = g_variant_iter_next_value (&iter))) { g_autoptr(FwupdRelease) release = fwupd_release_from_variant (child); if (release != NULL) fwupd_device_add_release (device, release); g_variant_unref (child); } return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_DEVICE_ID) == 0) { fwupd_device_set_id (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLAGS) == 0) { fwupd_device_set_flags (device, g_variant_get_uint64 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_CREATED) == 0) { fwupd_device_set_created (device, g_variant_get_uint64 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_MODIFIED) == 0) { fwupd_device_set_modified (device, g_variant_get_uint64 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_GUID) == 0) { g_autofree const gchar **guids = g_variant_get_strv (value, NULL); for (guint i = 0; guids[i] != NULL; i++) fwupd_device_add_guid (device, guids[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_ICON) == 0) { g_autofree const gchar **icons = g_variant_get_strv (value, NULL); for (guint i = 0; icons[i] != NULL; i++) fwupd_device_add_icon (device, icons[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) { fwupd_device_set_name (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR) == 0) { fwupd_device_set_vendor (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR_ID) == 0) { fwupd_device_set_vendor_id (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_SUMMARY) == 0) { fwupd_device_set_summary (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) { fwupd_device_set_description (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) { const gchar *checksums = g_variant_get_string (value, NULL); g_auto(GStrv) split = g_strsplit (checksums, ",", -1); for (guint i = 0; split[i] != NULL; i++) fwupd_device_add_checksum (device, split[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_PLUGIN) == 0) { fwupd_device_set_plugin (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION) == 0) { fwupd_device_set_version (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION_LOWEST) == 0) { fwupd_device_set_version_lowest (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION_BOOTLOADER) == 0) { fwupd_device_set_version_bootloader (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_FLASHES_LEFT) == 0) { fwupd_device_set_flashes_left (device, g_variant_get_uint32 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_ERROR) == 0) { fwupd_device_set_update_error (device, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_UPDATE_STATE) == 0) { fwupd_device_set_update_state (device, g_variant_get_uint32 (value)); return; } } static void fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value) { /* ignore */ if (key == NULL || value == NULL) return; g_string_append_printf (str, " %s: ", key); for (gsize i = strlen (key); i < 20; i++) g_string_append (str, " "); g_string_append_printf (str, "%s\n", value); } static void fwupd_pad_kv_unx (GString *str, const gchar *key, guint64 value) { g_autoptr(GDateTime) date = NULL; g_autofree gchar *tmp = NULL; /* ignore */ if (value == 0) return; date = g_date_time_new_from_unix_utc ((gint64) value); tmp = g_date_time_format (date, "%F"); fwupd_pad_kv_str (str, key, tmp); } static void fwupd_pad_kv_dfl (GString *str, const gchar *key, guint64 device_flags) { g_autoptr(GString) tmp = g_string_new (""); for (guint i = 0; i < 64; i++) { if ((device_flags & ((guint64) 1 << i)) == 0) continue; g_string_append_printf (tmp, "%s|", fwupd_device_flag_to_string ((guint64) 1 << i)); } if (tmp->len == 0) { g_string_append (tmp, fwupd_device_flag_to_string (0)); } else { g_string_truncate (tmp, tmp->len - 1); } fwupd_pad_kv_str (str, key, tmp->str); } static void fwupd_pad_kv_int (GString *str, const gchar *key, guint32 value) { g_autofree gchar *tmp = NULL; /* ignore */ if (value == 0) return; tmp = g_strdup_printf("%" G_GUINT32_FORMAT, value); fwupd_pad_kv_str (str, key, tmp); } /** * fwupd_device_get_update_state: * @device: A #FwupdDevice * * Gets the update state. * * Returns: the update state, or %FWUPD_UPDATE_STATE_UNKNOWN if unset * * Since: 0.9.8 **/ FwupdUpdateState fwupd_device_get_update_state (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), FWUPD_UPDATE_STATE_UNKNOWN); return priv->update_state; } /** * fwupd_device_set_update_state: * @device: A #FwupdDevice * @update_state: the state, e.g. %FWUPD_UPDATE_STATE_PENDING * * Sets the update state. * * Since: 0.9.8 **/ void fwupd_device_set_update_state (FwupdDevice *device, FwupdUpdateState update_state) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); priv->update_state = update_state; } /** * fwupd_device_get_update_error: * @device: A #FwupdDevice * * Gets the update error. * * Returns: the update error, or %NULL if unset * * Since: 0.9.8 **/ const gchar * fwupd_device_get_update_error (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->update_error; } /** * fwupd_device_set_update_error: * @device: A #FwupdDevice * @update_error: the update error string * * Sets the update error. * * Since: 0.9.8 **/ void fwupd_device_set_update_error (FwupdDevice *device, const gchar *update_error) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_free (priv->update_error); priv->update_error = g_strdup (update_error); } /** * fwupd_device_get_release_default: * @device: A #FwupdDevice * * Gets the default release for this device. * * Returns: (transfer none): the #FwupdRelease, or %NULL if not set * * Since: 0.9.8 **/ FwupdRelease * fwupd_device_get_release_default (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); if (priv->releases->len == 0) return NULL; return FWUPD_RELEASE (g_ptr_array_index (priv->releases, 0)); } /** * fwupd_device_get_releases: * @device: A #FwupdDevice * * Gets all the releases for this device. * * Returns: (transfer none) (element-type FwupdRelease): array of releases * * Since: 0.9.8 **/ GPtrArray * fwupd_device_get_releases (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); return priv->releases; } /** * fwupd_device_add_release: * @device: A #FwupdDevice * @release: a #FwupdRelease * * Adds a release for this device. * * Since: 0.9.8 **/ void fwupd_device_add_release (FwupdDevice *device, FwupdRelease *release) { FwupdDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (FWUPD_IS_DEVICE (device)); g_ptr_array_add (priv->releases, g_object_ref (release)); } static void fwupd_pad_kv_ups (GString *str, const gchar *key, FwupdUpdateState value) { if (value == FWUPD_UPDATE_STATE_UNKNOWN) return; fwupd_pad_kv_str (str, key, fwupd_update_state_to_string (value)); } /** * fwupd_device_to_string: * @device: A #FwupdDevice * * Builds a text representation of the object. * * Returns: text, or %NULL for invalid * * Since: 0.9.3 **/ gchar * fwupd_device_to_string (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); GString *str; g_return_val_if_fail (FWUPD_IS_DEVICE (device), NULL); str = g_string_new (""); if (priv->name != NULL) g_string_append_printf (str, "%s\n", priv->name); else str = g_string_append (str, "Unknown Device\n"); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DEVICE_ID, priv->id); for (guint i = 0; i < priv->guids->len; i++) { const gchar *guid = g_ptr_array_index (priv->guids, i); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_GUID, guid); } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_PLUGIN, priv->plugin); fwupd_pad_kv_dfl (str, FWUPD_RESULT_KEY_FLAGS, priv->flags); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum = g_ptr_array_index (priv->checksums, i); g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CHECKSUM, checksum_display); } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR_ID, priv->vendor_id); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_LOWEST, priv->version_lowest); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION_BOOTLOADER, priv->version_bootloader); if (priv->flashes_left < 2) fwupd_pad_kv_int (str, FWUPD_RESULT_KEY_FLASHES_LEFT, priv->flashes_left); if (priv->icons->len > 0) { g_autoptr(GString) tmp = g_string_new (NULL); for (guint i = 0; i < priv->icons->len; i++) { const gchar *icon = g_ptr_array_index (priv->icons, i); g_string_append_printf (tmp, "%s,", icon); } if (tmp->len > 1) g_string_truncate (tmp, tmp->len - 1); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_ICON, tmp->str); } fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_CREATED, priv->created); fwupd_pad_kv_unx (str, FWUPD_RESULT_KEY_MODIFIED, priv->modified); fwupd_pad_kv_ups (str, FWUPD_RESULT_KEY_UPDATE_STATE, priv->update_state); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_UPDATE_ERROR, priv->update_error); for (guint i = 0; i < priv->releases->len; i++) { FwupdRelease *release = g_ptr_array_index (priv->releases, i); g_autofree gchar *tmp = fwupd_release_to_string (release); g_string_append_printf (str, " \n [%s]\n%s", FWUPD_RESULT_KEY_RELEASE, tmp); } return g_string_free (str, FALSE); } static void fwupd_device_class_init (FwupdDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fwupd_device_finalize; } static void fwupd_device_init (FwupdDevice *device) { FwupdDevicePrivate *priv = GET_PRIVATE (device); priv->guids = g_ptr_array_new_with_free_func (g_free); priv->icons = g_ptr_array_new_with_free_func (g_free); priv->checksums = g_ptr_array_new_with_free_func (g_free); priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); } static void fwupd_device_finalize (GObject *object) { FwupdDevice *device = FWUPD_DEVICE (object); FwupdDevicePrivate *priv = GET_PRIVATE (device); g_free (priv->description); g_free (priv->id); g_free (priv->name); g_free (priv->summary); g_free (priv->vendor); g_free (priv->vendor_id); g_free (priv->plugin); g_free (priv->update_error); g_free (priv->version); g_free (priv->version_lowest); g_free (priv->version_bootloader); g_ptr_array_unref (priv->guids); g_ptr_array_unref (priv->icons); g_ptr_array_unref (priv->checksums); g_ptr_array_unref (priv->releases); G_OBJECT_CLASS (fwupd_device_parent_class)->finalize (object); } static void fwupd_device_set_from_variant_iter (FwupdDevice *device, GVariantIter *iter) { GVariant *value; const gchar *key; while (g_variant_iter_next (iter, "{&sv}", &key, &value)) { fwupd_device_from_key_value (device, key, value); g_variant_unref (value); } } /** * fwupd_device_from_variant: * @data: a #GVariant * * Creates a new device using packed data. * * Returns: (transfer full): a new #FwupdDevice, or %NULL if @data was invalid * * Since: 1.0.0 **/ FwupdDevice * fwupd_device_from_variant (GVariant *data) { FwupdDevice *dev = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; /* format from GetDetails */ type_string = g_variant_get_type_string (data); if (g_strcmp0 (type_string, "(a{sv})") == 0) { dev = fwupd_device_new (); g_variant_get (data, "(a{sv})", &iter); fwupd_device_set_from_variant_iter (dev, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { dev = fwupd_device_new (); g_variant_get (data, "a{sv}", &iter); fwupd_device_set_from_variant_iter (dev, iter); } else { g_warning ("type %s not known", type_string); } return dev; } /** * fwupd_device_new: * * Creates a new device. * * Returns: a new #FwupdDevice * * Since: 0.9.3 **/ FwupdDevice * fwupd_device_new (void) { FwupdDevice *device; device = g_object_new (FWUPD_TYPE_DEVICE, NULL); return FWUPD_DEVICE (device); } fwupd-1.0.6/libfwupd/fwupd-device.h000066400000000000000000000121031325145456600172220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_DEVICE_H #define __FWUPD_DEVICE_H #include #include "fwupd-enums.h" #include "fwupd-release.h" G_BEGIN_DECLS #define FWUPD_TYPE_DEVICE (fwupd_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FwupdDevice, fwupd_device, FWUPD, DEVICE, GObject) struct _FwupdDeviceClass { GObjectClass parent_class; /*< private >*/ void (*_fwupd_reserved1) (void); void (*_fwupd_reserved2) (void); void (*_fwupd_reserved3) (void); void (*_fwupd_reserved4) (void); void (*_fwupd_reserved5) (void); void (*_fwupd_reserved6) (void); void (*_fwupd_reserved7) (void); }; FwupdDevice *fwupd_device_new (void); gchar *fwupd_device_to_string (FwupdDevice *device); const gchar *fwupd_device_get_id (FwupdDevice *device); void fwupd_device_set_id (FwupdDevice *device, const gchar *id); const gchar *fwupd_device_get_name (FwupdDevice *device); void fwupd_device_set_name (FwupdDevice *device, const gchar *name); const gchar *fwupd_device_get_summary (FwupdDevice *device); void fwupd_device_set_summary (FwupdDevice *device, const gchar *summary); const gchar *fwupd_device_get_description (FwupdDevice *device); void fwupd_device_set_description (FwupdDevice *device, const gchar *description); const gchar *fwupd_device_get_version (FwupdDevice *device); void fwupd_device_set_version (FwupdDevice *device, const gchar *version); const gchar *fwupd_device_get_version_lowest (FwupdDevice *device); void fwupd_device_set_version_lowest (FwupdDevice *device, const gchar *version_lowest); const gchar *fwupd_device_get_version_bootloader (FwupdDevice *device); void fwupd_device_set_version_bootloader (FwupdDevice *device, const gchar *version_bootloader); guint32 fwupd_device_get_flashes_left (FwupdDevice *device); void fwupd_device_set_flashes_left (FwupdDevice *device, guint32 flashes_left); guint64 fwupd_device_get_flags (FwupdDevice *device); void fwupd_device_set_flags (FwupdDevice *device, guint64 flags); void fwupd_device_add_flag (FwupdDevice *device, FwupdDeviceFlags flag); void fwupd_device_remove_flag (FwupdDevice *device, FwupdDeviceFlags flag); gboolean fwupd_device_has_flag (FwupdDevice *device, FwupdDeviceFlags flag); guint64 fwupd_device_get_created (FwupdDevice *device); void fwupd_device_set_created (FwupdDevice *device, guint64 created); guint64 fwupd_device_get_modified (FwupdDevice *device); void fwupd_device_set_modified (FwupdDevice *device, guint64 modified); GPtrArray *fwupd_device_get_checksums (FwupdDevice *device); void fwupd_device_add_checksum (FwupdDevice *device, const gchar *checksum); const gchar *fwupd_device_get_plugin (FwupdDevice *device); void fwupd_device_set_plugin (FwupdDevice *device, const gchar *plugin); const gchar *fwupd_device_get_vendor (FwupdDevice *device); void fwupd_device_set_vendor (FwupdDevice *device, const gchar *vendor); const gchar *fwupd_device_get_vendor_id (FwupdDevice *device); void fwupd_device_set_vendor_id (FwupdDevice *device, const gchar *vendor_id); void fwupd_device_add_guid (FwupdDevice *device, const gchar *guid); gboolean fwupd_device_has_guid (FwupdDevice *device, const gchar *guid); GPtrArray *fwupd_device_get_guids (FwupdDevice *device); const gchar *fwupd_device_get_guid_default (FwupdDevice *device); void fwupd_device_add_icon (FwupdDevice *device, const gchar *icon); GPtrArray *fwupd_device_get_icons (FwupdDevice *device); FwupdUpdateState fwupd_device_get_update_state (FwupdDevice *device); void fwupd_device_set_update_state (FwupdDevice *device, FwupdUpdateState update_state); const gchar *fwupd_device_get_update_error (FwupdDevice *device); void fwupd_device_set_update_error (FwupdDevice *device, const gchar *update_error); void fwupd_device_add_release (FwupdDevice *device, FwupdRelease *release); GPtrArray *fwupd_device_get_releases (FwupdDevice *device); FwupdRelease *fwupd_device_get_release_default (FwupdDevice *device); G_END_DECLS #endif /* __FWUPD_DEVICE_H */ fwupd-1.0.6/libfwupd/fwupd-enums-private.h000066400000000000000000000052251325145456600205710ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_ENUMS_PRIVATE_H #define __FWUPD_ENUMS_PRIVATE_H #define FWUPD_RESULT_KEY_APPSTREAM_ID "AppstreamId" /* s */ #define FWUPD_RESULT_KEY_CHECKSUM "Checksum" /* as */ #define FWUPD_RESULT_KEY_CREATED "Created" /* t */ #define FWUPD_RESULT_KEY_DESCRIPTION "Description" /* s */ #define FWUPD_RESULT_KEY_DEVICE_ID "DeviceId" /* s */ #define FWUPD_RESULT_KEY_FILENAME "Filename" /* s */ #define FWUPD_RESULT_KEY_FLAGS "Flags" /* t */ #define FWUPD_RESULT_KEY_FLASHES_LEFT "FlashesLeft" /* u */ #define FWUPD_RESULT_KEY_GUID "Guid" /* as */ #define FWUPD_RESULT_KEY_HOMEPAGE "Homepage" /* s */ #define FWUPD_RESULT_KEY_ICON "Icon" /* as */ #define FWUPD_RESULT_KEY_LICENSE "License" /* s */ #define FWUPD_RESULT_KEY_MODIFIED "Modified" /* t */ #define FWUPD_RESULT_KEY_METADATA "Metadata" /* a{ss} */ #define FWUPD_RESULT_KEY_NAME "Name" /* s */ #define FWUPD_RESULT_KEY_PLUGIN "Plugin" /* s */ #define FWUPD_RESULT_KEY_RELEASE "Release" /* a{sv} */ #define FWUPD_RESULT_KEY_REMOTE_ID "RemoteId" /* s */ #define FWUPD_RESULT_KEY_SIZE "Size" /* t */ #define FWUPD_RESULT_KEY_SUMMARY "Summary" /* s */ #define FWUPD_RESULT_KEY_TRUST_FLAGS "TrustFlags" /* t */ #define FWUPD_RESULT_KEY_UPDATE_ERROR "UpdateError" /* s */ #define FWUPD_RESULT_KEY_UPDATE_STATE "UpdateState" /* u */ #define FWUPD_RESULT_KEY_URI "Uri" /* s */ #define FWUPD_RESULT_KEY_VENDOR_ID "VendorId" /* s */ #define FWUPD_RESULT_KEY_VENDOR "Vendor" /* s */ #define FWUPD_RESULT_KEY_VENDOR "Vendor" /* s */ #define FWUPD_RESULT_KEY_VERSION_BOOTLOADER "VersionBootloader" /* s */ #define FWUPD_RESULT_KEY_VERSION_LOWEST "VersionLowest" /* s */ #define FWUPD_RESULT_KEY_VERSION "Version" /* s */ #endif /* __FWUPD_ENUMS_PRIVATE_H */ fwupd-1.0.6/libfwupd/fwupd-enums.c000066400000000000000000000234731325145456600171210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "fwupd-enums.h" /** * SECTION:fwupd-enums * @short_description: enumerated values shared by the daemon and library * * This file also provides helper functions to map enums to strings and back * again. * * See also: #fwupd-error */ /** * fwupd_status_to_string: * @status: A #FwupdStatus, e.g. %FWUPD_STATUS_DECOMPRESSING * * Converts a #FwupdStatus to a string. * * Return value: identifier string * * Since: 0.1.1 **/ const gchar * fwupd_status_to_string (FwupdStatus status) { if (status == FWUPD_STATUS_UNKNOWN) return "unknown"; if (status == FWUPD_STATUS_IDLE) return "idle"; if (status == FWUPD_STATUS_DECOMPRESSING) return "decompressing"; if (status == FWUPD_STATUS_LOADING) return "loading"; if (status == FWUPD_STATUS_DEVICE_RESTART) return "device-restart"; if (status == FWUPD_STATUS_DEVICE_WRITE) return "device-write"; if (status == FWUPD_STATUS_DEVICE_READ) return "device-read"; if (status == FWUPD_STATUS_DEVICE_ERASE) return "device-erase"; if (status == FWUPD_STATUS_DEVICE_VERIFY) return "device-verify"; if (status == FWUPD_STATUS_DEVICE_BUSY) return "device-busy"; if (status == FWUPD_STATUS_SCHEDULING) return "scheduling"; if (status == FWUPD_STATUS_DOWNLOADING) return "downloading"; if (status == FWUPD_STATUS_WAITING_FOR_AUTH) return "waiting-for-auth"; return NULL; } /** * fwupd_status_from_string: * @status: A string, e.g. `decompressing` * * Converts a string to a #FwupdStatus. * * Return value: enumerated value * * Since: 0.1.1 **/ FwupdStatus fwupd_status_from_string (const gchar *status) { if (g_strcmp0 (status, "unknown") == 0) return FWUPD_STATUS_UNKNOWN; if (g_strcmp0 (status, "idle") == 0) return FWUPD_STATUS_IDLE; if (g_strcmp0 (status, "decompressing") == 0) return FWUPD_STATUS_DECOMPRESSING; if (g_strcmp0 (status, "loading") == 0) return FWUPD_STATUS_LOADING; if (g_strcmp0 (status, "device-restart") == 0) return FWUPD_STATUS_DEVICE_RESTART; if (g_strcmp0 (status, "device-write") == 0) return FWUPD_STATUS_DEVICE_WRITE; if (g_strcmp0 (status, "device-verify") == 0) return FWUPD_STATUS_DEVICE_VERIFY; if (g_strcmp0 (status, "scheduling") == 0) return FWUPD_STATUS_SCHEDULING; if (g_strcmp0 (status, "downloading") == 0) return FWUPD_STATUS_DOWNLOADING; if (g_strcmp0 (status, "device-read") == 0) return FWUPD_STATUS_DEVICE_READ; if (g_strcmp0 (status, "device-erase") == 0) return FWUPD_STATUS_DEVICE_ERASE; if (g_strcmp0 (status, "device-busy") == 0) return FWUPD_STATUS_DEVICE_BUSY; if (g_strcmp0 (status, "waiting-for-auth") == 0) return FWUPD_STATUS_WAITING_FOR_AUTH; return FWUPD_STATUS_LAST; } /** * fwupd_device_flag_to_string: * @device_flag: A #FwupdDeviceFlags, e.g. %FWUPD_DEVICE_FLAG_REQUIRE_AC * * Converts a #FwupdDeviceFlags to a string. * * Return value: identifier string * * Since: 0.7.0 **/ const gchar * fwupd_device_flag_to_string (FwupdDeviceFlags device_flag) { if (device_flag == FWUPD_DEVICE_FLAG_NONE) return "none"; if (device_flag == FWUPD_DEVICE_FLAG_INTERNAL) return "internal"; if (device_flag == FWUPD_DEVICE_FLAG_UPDATABLE) return "updatable"; if (device_flag == FWUPD_DEVICE_FLAG_ONLY_OFFLINE) return "only-offline"; if (device_flag == FWUPD_DEVICE_FLAG_REQUIRE_AC) return "require-ac"; if (device_flag == FWUPD_DEVICE_FLAG_LOCKED) return "locked"; if (device_flag == FWUPD_DEVICE_FLAG_SUPPORTED) return "supported"; if (device_flag == FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER) return "needs-bootloader"; if (device_flag == FWUPD_DEVICE_FLAG_REGISTERED) return "registered"; if (device_flag == FWUPD_DEVICE_FLAG_NEEDS_REBOOT) return "needs-reboot"; if (device_flag == FWUPD_DEVICE_FLAG_REPORTED) return "reported"; if (device_flag == FWUPD_DEVICE_FLAG_NOTIFIED) return "notified"; if (device_flag == FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION) return "use-runtime-version"; if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN) return "unknown"; return NULL; } /** * fwupd_device_flag_from_string: * @device_flag: A string, e.g. `require-ac` * * Converts a string to a #FwupdDeviceFlags. * * Return value: enumerated value * * Since: 0.7.0 **/ FwupdDeviceFlags fwupd_device_flag_from_string (const gchar *device_flag) { if (g_strcmp0 (device_flag, "none") == 0) return FWUPD_DEVICE_FLAG_NONE; if (g_strcmp0 (device_flag, "internal") == 0) return FWUPD_DEVICE_FLAG_INTERNAL; if (g_strcmp0 (device_flag, "updatable") == 0 || g_strcmp0 (device_flag, "allow-online") == 0) return FWUPD_DEVICE_FLAG_UPDATABLE; if (g_strcmp0 (device_flag, "only-offline") == 0 || g_strcmp0 (device_flag, "allow-offline") == 0) return FWUPD_DEVICE_FLAG_ONLY_OFFLINE; if (g_strcmp0 (device_flag, "require-ac") == 0) return FWUPD_DEVICE_FLAG_REQUIRE_AC; if (g_strcmp0 (device_flag, "locked") == 0) return FWUPD_DEVICE_FLAG_LOCKED; if (g_strcmp0 (device_flag, "supported") == 0) return FWUPD_DEVICE_FLAG_SUPPORTED; if (g_strcmp0 (device_flag, "needs-bootloader") == 0) return FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER; if (g_strcmp0 (device_flag, "registered") == 0) return FWUPD_DEVICE_FLAG_REGISTERED; if (g_strcmp0 (device_flag, "needs-reboot") == 0) return FWUPD_DEVICE_FLAG_NEEDS_REBOOT; if (g_strcmp0 (device_flag, "reported") == 0) return FWUPD_DEVICE_FLAG_REPORTED; if (g_strcmp0 (device_flag, "notified") == 0) return FWUPD_DEVICE_FLAG_NOTIFIED; if (g_strcmp0 (device_flag, "use-runtime-version") == 0) return FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION; return FWUPD_DEVICE_FLAG_UNKNOWN; } /** * fwupd_update_state_to_string: * @update_state: A #FwupdUpdateState, e.g. %FWUPD_UPDATE_STATE_PENDING * * Converts a #FwupdUpdateState to a string. * * Return value: identifier string * * Since: 0.7.0 **/ const gchar * fwupd_update_state_to_string (FwupdUpdateState update_state) { if (update_state == FWUPD_UPDATE_STATE_UNKNOWN) return "unknown"; if (update_state == FWUPD_UPDATE_STATE_PENDING) return "pending"; if (update_state == FWUPD_UPDATE_STATE_SUCCESS) return "success"; if (update_state == FWUPD_UPDATE_STATE_FAILED) return "failed"; if (update_state == FWUPD_UPDATE_STATE_NEEDS_REBOOT) return "needs-reboot"; return NULL; } /** * fwupd_update_state_from_string: * @update_state: A string, e.g. `pending` * * Converts a string to a #FwupdUpdateState. * * Return value: enumerated value * * Since: 0.7.0 **/ FwupdUpdateState fwupd_update_state_from_string (const gchar *update_state) { if (g_strcmp0 (update_state, "unknown") == 0) return FWUPD_UPDATE_STATE_UNKNOWN; if (g_strcmp0 (update_state, "pending") == 0) return FWUPD_UPDATE_STATE_PENDING; if (g_strcmp0 (update_state, "success") == 0) return FWUPD_UPDATE_STATE_SUCCESS; if (g_strcmp0 (update_state, "failed") == 0) return FWUPD_UPDATE_STATE_FAILED; if (g_strcmp0 (update_state, "needs-reboot") == 0) return FWUPD_UPDATE_STATE_NEEDS_REBOOT; return FWUPD_UPDATE_STATE_UNKNOWN; } /** * fwupd_trust_flag_to_string: * @trust_flag: A #FwupdTrustFlags, e.g. %FWUPD_TRUST_FLAG_PAYLOAD * * Converts a #FwupdTrustFlags to a string. * * Return value: identifier string * * Since: 0.7.0 **/ const gchar * fwupd_trust_flag_to_string (FwupdTrustFlags trust_flag) { if (trust_flag == FWUPD_TRUST_FLAG_NONE) return "none"; if (trust_flag == FWUPD_TRUST_FLAG_PAYLOAD) return "payload"; if (trust_flag == FWUPD_TRUST_FLAG_METADATA) return "metadata"; return NULL; } /** * fwupd_trust_flag_from_string: * @trust_flag: A string, e.g. `payload` * * Converts a string to a #FwupdTrustFlags. * * Return value: enumerated value * * Since: 0.7.0 **/ FwupdTrustFlags fwupd_trust_flag_from_string (const gchar *trust_flag) { if (g_strcmp0 (trust_flag, "none") == 0) return FWUPD_TRUST_FLAG_NONE; if (g_strcmp0 (trust_flag, "payload") == 0) return FWUPD_TRUST_FLAG_PAYLOAD; if (g_strcmp0 (trust_flag, "metadata") == 0) return FWUPD_TRUST_FLAG_METADATA; return FWUPD_TRUST_FLAG_LAST; } /** * fwupd_keyring_kind_from_string: * @keyring_kind: a string, e.g. `gpg` * * Converts an printable string to an enumerated type. * * Returns: a #FwupdKeyringKind, e.g. %FWUPD_KEYRING_KIND_GPG * * Since: 0.9.7 **/ FwupdKeyringKind fwupd_keyring_kind_from_string (const gchar *keyring_kind) { if (g_strcmp0 (keyring_kind, "none") == 0) return FWUPD_KEYRING_KIND_NONE; if (g_strcmp0 (keyring_kind, "gpg") == 0) return FWUPD_KEYRING_KIND_GPG; if (g_strcmp0 (keyring_kind, "pkcs7") == 0) return FWUPD_KEYRING_KIND_PKCS7; return FWUPD_KEYRING_KIND_UNKNOWN; } /** * fwupd_keyring_kind_to_string: * @keyring_kind: a #FwupdKeyringKind, e.g. %FWUPD_KEYRING_KIND_GPG * * Converts an enumerated type to a printable string. * * Returns: a string, e.g. `gpg` * * Since: 0.9.7 **/ const gchar * fwupd_keyring_kind_to_string (FwupdKeyringKind keyring_kind) { if (keyring_kind == FWUPD_KEYRING_KIND_NONE) return "none"; if (keyring_kind == FWUPD_KEYRING_KIND_GPG) return "gpg"; if (keyring_kind == FWUPD_KEYRING_KIND_PKCS7) return "pkcs7"; return NULL; } fwupd-1.0.6/libfwupd/fwupd-enums.h000066400000000000000000000166531325145456600171300ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_ENUMS_H #define __FWUPD_ENUMS_H #include /** * FwupdStatus: * @FWUPD_STATUS_UNKNOWN: Unknown state * @FWUPD_STATUS_IDLE: Idle * @FWUPD_STATUS_LOADING: Loading a resource * @FWUPD_STATUS_DECOMPRESSING: Decompressing firmware * @FWUPD_STATUS_DEVICE_RESTART: Restarting the device * @FWUPD_STATUS_DEVICE_WRITE: Writing to a device * @FWUPD_STATUS_DEVICE_VERIFY: Verifying (reading) a device * @FWUPD_STATUS_SCHEDULING: Scheduling an offline update * @FWUPD_STATUS_DOWNLOADING: A file is downloading * @FWUPD_STATUS_DEVICE_READ: Reading from a device * @FWUPD_STATUS_DEVICE_ERASE: Erasing a device * @FWUPD_STATUS_WAITING_FOR_AUTH: Waiting for authentication * @FWUPD_STATUS_DEVICE_BUSY: The device is busy * * The flags to show daemon status. **/ typedef enum { FWUPD_STATUS_UNKNOWN, /* Since: 0.1.1 */ FWUPD_STATUS_IDLE, /* Since: 0.1.1 */ FWUPD_STATUS_LOADING, /* Since: 0.1.1 */ FWUPD_STATUS_DECOMPRESSING, /* Since: 0.1.1 */ FWUPD_STATUS_DEVICE_RESTART, /* Since: 0.1.1 */ FWUPD_STATUS_DEVICE_WRITE, /* Since: 0.1.1 */ FWUPD_STATUS_DEVICE_VERIFY, /* Since: 0.1.1 */ FWUPD_STATUS_SCHEDULING, /* Since: 0.1.1 */ FWUPD_STATUS_DOWNLOADING, /* Since: 0.9.4 */ FWUPD_STATUS_DEVICE_READ, /* Since: 1.0.0 */ FWUPD_STATUS_DEVICE_ERASE, /* Since: 1.0.0 */ FWUPD_STATUS_WAITING_FOR_AUTH, /* Since: 1.0.0 */ FWUPD_STATUS_DEVICE_BUSY, /* Since: 1.0.1 */ /*< private >*/ FWUPD_STATUS_LAST } FwupdStatus; /** * FwupdTrustFlags: * @FWUPD_TRUST_FLAG_NONE: No trust * @FWUPD_TRUST_FLAG_PAYLOAD: The firmware is trusted * @FWUPD_TRUST_FLAG_METADATA: The metadata is trusted * * The flags to show the level of trust. **/ typedef enum { FWUPD_TRUST_FLAG_NONE = 0, /* Since: 0.1.2 */ FWUPD_TRUST_FLAG_PAYLOAD = 1 << 0, /* Since: 0.1.2 */ FWUPD_TRUST_FLAG_METADATA = 1 << 1, /* Since: 0.1.2 */ /*< private >*/ FWUPD_TRUST_FLAG_LAST } FwupdTrustFlags; /** * FwupdDeviceFlags: * @FWUPD_DEVICE_FLAG_NONE: No flags set * @FWUPD_DEVICE_FLAG_INTERNAL: Device cannot be removed easily * @FWUPD_DEVICE_FLAG_UPDATABLE: Device is updatable in this or any other mode * @FWUPD_DEVICE_FLAG_ONLY_OFFLINE: Update can only be done from offline mode * @FWUPD_DEVICE_FLAG_REQUIRE_AC: Requires AC power * @FWUPD_DEVICE_FLAG_LOCKED: Is locked and can be unlocked * @FWUPD_DEVICE_FLAG_SUPPORTED: Is found in current metadata * @FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER: Requires a bootloader mode to be manually enabled by the user * @FWUPD_DEVICE_FLAG_REGISTERED: Has been registered with other plugins * @FWUPD_DEVICE_FLAG_NEEDS_REBOOT: Requires a reboot to apply firmware or to reload hardware * @FWUPD_DEVICE_FLAG_REPORTED: Has been reported to a metadata server * @FWUPD_DEVICE_FLAG_NOTIFIED: User has been notified * @FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION: Always use the runtime version rather than the bootloader * * The device flags. **/ #define FWUPD_DEVICE_FLAG_NONE (0u) /* Since: 0.1.3 */ #define FWUPD_DEVICE_FLAG_INTERNAL (1u << 0) /* Since: 0.1.3 */ #define FWUPD_DEVICE_FLAG_UPDATABLE (1u << 1) /* Since: 0.9.7 */ #define FWUPD_DEVICE_FLAG_ONLY_OFFLINE (1u << 2) /* Since: 0.9.7 */ #define FWUPD_DEVICE_FLAG_REQUIRE_AC (1u << 3) /* Since: 0.6.3 */ #define FWUPD_DEVICE_FLAG_LOCKED (1u << 4) /* Since: 0.6.3 */ #define FWUPD_DEVICE_FLAG_SUPPORTED (1u << 5) /* Since: 0.7.1 */ #define FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER (1u << 6) /* Since: 0.7.3 */ #define FWUPD_DEVICE_FLAG_REGISTERED (1u << 7) /* Since: 0.9.7 */ #define FWUPD_DEVICE_FLAG_NEEDS_REBOOT (1u << 8) /* Since: 0.9.7 */ #define FWUPD_DEVICE_FLAG_REPORTED (1u << 9) /* Since: 1.0.4 */ #define FWUPD_DEVICE_FLAG_NOTIFIED (1u << 10) /* Since: 1.0.5 */ #define FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION (1u << 11) /* Since: 1.0.6 */ #define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */ typedef guint64 FwupdDeviceFlags; /** * FwupdInstallFlags: * @FWUPD_INSTALL_FLAG_NONE: No flags set * @FWUPD_INSTALL_FLAG_OFFLINE: Schedule this for next boot * @FWUPD_INSTALL_FLAG_ALLOW_REINSTALL: Allow reinstalling the same version * @FWUPD_INSTALL_FLAG_ALLOW_OLDER: Allow downgrading firmware * @FWUPD_INSTALL_FLAG_FORCE: Force the update even if not a good idea * * Flags to set when performing the firwmare update or install. **/ typedef enum { FWUPD_INSTALL_FLAG_NONE = 0, /* Since: 0.7.0 */ FWUPD_INSTALL_FLAG_OFFLINE = 1, /* Since: 0.7.0 */ FWUPD_INSTALL_FLAG_ALLOW_REINSTALL = 2, /* Since: 0.7.0 */ FWUPD_INSTALL_FLAG_ALLOW_OLDER = 4, /* Since: 0.7.0 */ FWUPD_INSTALL_FLAG_FORCE = 8, /* Since: 0.7.1 */ /*< private >*/ FWUPD_INSTALL_FLAG_LAST } FwupdInstallFlags; /** * FwupdUpdateState: * @FWUPD_UPDATE_STATE_UNKNOWN: Unknown * @FWUPD_UPDATE_STATE_PENDING: Update is pending * @FWUPD_UPDATE_STATE_SUCCESS: Update was successfull * @FWUPD_UPDATE_STATE_FAILED: Update failed * @FWUPD_UPDATE_STATE_NEEDS_REBOOT: Waiting for a reboot to apply * * The update state. **/ typedef enum { FWUPD_UPDATE_STATE_UNKNOWN, /* Since: 0.7.0 */ FWUPD_UPDATE_STATE_PENDING, /* Since: 0.7.0 */ FWUPD_UPDATE_STATE_SUCCESS, /* Since: 0.7.0 */ FWUPD_UPDATE_STATE_FAILED, /* Since: 0.7.0 */ FWUPD_UPDATE_STATE_NEEDS_REBOOT, /* Since: 1.0.4 */ /*< private >*/ FWUPD_UPDATE_STATE_LAST } FwupdUpdateState; /** * FwupdKeyringKind: * @FWUPD_KEYRING_KIND_UNKNOWN: Unknown * @FWUPD_KEYRING_KIND_NONE: No verification * @FWUPD_KEYRING_KIND_GPG: Verification using GPG * @FWUPD_KEYRING_KIND_PKCS7: Verification using PKCS7 * * The update state. **/ typedef enum { FWUPD_KEYRING_KIND_UNKNOWN, /* Since: 0.9.7 */ FWUPD_KEYRING_KIND_NONE, /* Since: 0.9.7 */ FWUPD_KEYRING_KIND_GPG, /* Since: 0.9.7 */ FWUPD_KEYRING_KIND_PKCS7, /* Since: 0.9.7 */ /*< private >*/ FWUPD_KEYRING_KIND_LAST } FwupdKeyringKind; const gchar *fwupd_status_to_string (FwupdStatus status); FwupdStatus fwupd_status_from_string (const gchar *status); const gchar *fwupd_device_flag_to_string (FwupdDeviceFlags device_flag); FwupdDeviceFlags fwupd_device_flag_from_string (const gchar *device_flag); const gchar *fwupd_update_state_to_string (FwupdUpdateState update_state); FwupdUpdateState fwupd_update_state_from_string (const gchar *update_state); const gchar *fwupd_trust_flag_to_string (FwupdTrustFlags trust_flag); FwupdTrustFlags fwupd_trust_flag_from_string (const gchar *trust_flag); FwupdKeyringKind fwupd_keyring_kind_from_string (const gchar *keyring_kind); const gchar *fwupd_keyring_kind_to_string (FwupdKeyringKind keyring_kind); #endif /* __FWUPD_ENUMS_H */ fwupd-1.0.6/libfwupd/fwupd-error.c000066400000000000000000000113411325145456600171120ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fwupd-common.h" #include "fwupd-enums.h" #include "fwupd-error.h" /** * SECTION:fwupd-error * @short_description: an error domain shared by the daemon and library * * This file also provides helper functions to map errors to strings and back * again. * * See also: #fwupd-enums */ /** * fwupd_error_to_string: * @error: A #FwupdError, e.g. %FWUPD_ERROR_VERSION_NEWER * * Converts a #FwupdError to a string. * * Return value: identifier string * * Since: 0.7.0 **/ const gchar * fwupd_error_to_string (FwupdError error) { if (error == FWUPD_ERROR_INTERNAL) return FWUPD_DBUS_INTERFACE ".Internal"; if (error == FWUPD_ERROR_VERSION_NEWER) return FWUPD_DBUS_INTERFACE ".VersionNewer"; if (error == FWUPD_ERROR_VERSION_SAME) return FWUPD_DBUS_INTERFACE ".VersionSame"; if (error == FWUPD_ERROR_ALREADY_PENDING) return FWUPD_DBUS_INTERFACE ".AlreadyPending"; if (error == FWUPD_ERROR_AUTH_FAILED) return FWUPD_DBUS_INTERFACE ".AuthFailed"; if (error == FWUPD_ERROR_READ) return FWUPD_DBUS_INTERFACE ".Read"; if (error == FWUPD_ERROR_WRITE) return FWUPD_DBUS_INTERFACE ".Write"; if (error == FWUPD_ERROR_INVALID_FILE) return FWUPD_DBUS_INTERFACE ".InvalidFile"; if (error == FWUPD_ERROR_NOT_FOUND) return FWUPD_DBUS_INTERFACE ".NotFound"; if (error == FWUPD_ERROR_NOTHING_TO_DO) return FWUPD_DBUS_INTERFACE ".NothingToDo"; if (error == FWUPD_ERROR_NOT_SUPPORTED) return FWUPD_DBUS_INTERFACE ".NotSupported"; if (error == FWUPD_ERROR_SIGNATURE_INVALID) return FWUPD_DBUS_INTERFACE ".SignatureInvalid"; if (error == FWUPD_ERROR_AC_POWER_REQUIRED) return FWUPD_DBUS_INTERFACE ".AcPowerRequired"; if (error == FWUPD_ERROR_PERMISSION_DENIED) return FWUPD_DBUS_INTERFACE ".PermissionDenied"; return NULL; } /** * fwupd_error_from_string: * @error: A string, e.g. `org.freedesktop.fwupd.VersionNewer` * * Converts a string to a #FwupdError. * * Return value: enumerated value * * Since: 0.7.0 **/ FwupdError fwupd_error_from_string (const gchar *error) { if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".Internal") == 0) return FWUPD_ERROR_INTERNAL; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".VersionNewer") == 0) return FWUPD_ERROR_VERSION_NEWER; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".VersionSame") == 0) return FWUPD_ERROR_VERSION_SAME; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".AlreadyPending") == 0) return FWUPD_ERROR_ALREADY_PENDING; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".AuthFailed") == 0) return FWUPD_ERROR_AUTH_FAILED; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".Read") == 0) return FWUPD_ERROR_READ; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".Write") == 0) return FWUPD_ERROR_WRITE; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".InvalidFile") == 0) return FWUPD_ERROR_INVALID_FILE; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".NotFound") == 0) return FWUPD_ERROR_NOT_FOUND; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".NothingToDo") == 0) return FWUPD_ERROR_NOTHING_TO_DO; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".NotSupported") == 0) return FWUPD_ERROR_NOT_SUPPORTED; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".SignatureInvalid") == 0) return FWUPD_ERROR_SIGNATURE_INVALID; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".AcPowerRequired") == 0) return FWUPD_ERROR_AC_POWER_REQUIRED; if (g_strcmp0 (error, FWUPD_DBUS_INTERFACE ".PermissionDenied") == 0) return FWUPD_ERROR_PERMISSION_DENIED; return FWUPD_ERROR_LAST; } /** * fwupd_error_quark: * * Return value: An error quark. * * Since: 0.1.1 **/ GQuark fwupd_error_quark (void) { static GQuark quark = 0; if (!quark) { quark = g_quark_from_static_string ("FwupdError"); for (gint i = 0; i < FWUPD_ERROR_LAST; i++) { g_dbus_error_register_error (quark, i, fwupd_error_to_string (i)); } } return quark; } fwupd-1.0.6/libfwupd/fwupd-error.h000066400000000000000000000054051325145456600171230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_ERROR_H #define __FWUPD_ERROR_H #include #define FWUPD_ERROR fwupd_error_quark() /** * FwupdError: * @FWUPD_ERROR_INTERNAL: Internal error * @FWUPD_ERROR_VERSION_NEWER: Installed newer firmware version * @FWUPD_ERROR_VERSION_SAME: Installed same firmware version * @FWUPD_ERROR_ALREADY_PENDING: Already set be be installed offline * @FWUPD_ERROR_AUTH_FAILED: Failed to get authentication * @FWUPD_ERROR_READ: Failed to read from device * @FWUPD_ERROR_WRITE: Failed to write to the device * @FWUPD_ERROR_INVALID_FILE: Invalid file format * @FWUPD_ERROR_NOT_FOUND: No matching device exists * @FWUPD_ERROR_NOTHING_TO_DO: Nothing to do * @FWUPD_ERROR_NOT_SUPPORTED: Action was not possible * @FWUPD_ERROR_SIGNATURE_INVALID: Signature was invalid * @FWUPD_ERROR_AC_POWER_REQUIRED: AC power was required * @FWUPD_ERROR_PERMISSION_DENIED: Permission was denied * * The error code. **/ typedef enum { FWUPD_ERROR_INTERNAL, /* Since: 0.1.1 */ FWUPD_ERROR_VERSION_NEWER, /* Since: 0.1.1 */ FWUPD_ERROR_VERSION_SAME, /* Since: 0.1.1 */ FWUPD_ERROR_ALREADY_PENDING, /* Since: 0.1.1 */ FWUPD_ERROR_AUTH_FAILED, /* Since: 0.1.1 */ FWUPD_ERROR_READ, /* Since: 0.1.1 */ FWUPD_ERROR_WRITE, /* Since: 0.1.1 */ FWUPD_ERROR_INVALID_FILE, /* Since: 0.1.1 */ FWUPD_ERROR_NOT_FOUND, /* Since: 0.1.1 */ FWUPD_ERROR_NOTHING_TO_DO, /* Since: 0.1.1 */ FWUPD_ERROR_NOT_SUPPORTED, /* Since: 0.1.1 */ FWUPD_ERROR_SIGNATURE_INVALID, /* Since: 0.1.2 */ FWUPD_ERROR_AC_POWER_REQUIRED, /* Since: 0.8.0 */ FWUPD_ERROR_PERMISSION_DENIED, /* Since: 0.9.8 */ /*< private >*/ FWUPD_ERROR_LAST } FwupdError; GQuark fwupd_error_quark (void); const gchar *fwupd_error_to_string (FwupdError error); FwupdError fwupd_error_from_string (const gchar *error); #endif /* __FWUPD_ERROR_H */ fwupd-1.0.6/libfwupd/fwupd-release-private.h000066400000000000000000000023631325145456600210620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_RELEASE_PRIVATE_H #define __FWUPD_RELEASE_PRIVATE_H #include #include "fwupd-release.h" G_BEGIN_DECLS FwupdRelease *fwupd_release_from_variant (GVariant *data); GVariant *fwupd_release_to_variant (FwupdRelease *release); G_END_DECLS #endif /* __FWUPD_RELEASE_PRIVATE_H */ fwupd-1.0.6/libfwupd/fwupd-release.c000066400000000000000000000650441325145456600174120ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "fwupd-common-private.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" #include "fwupd-release-private.h" /** * SECTION:fwupd-release * @short_description: a firmware release * * An object that represents a firmware release with a specific version. * Devices can have more than one release, and the releases are typically * ordered by their version. * * See also: #FwupdDevice */ static void fwupd_release_finalize (GObject *object); typedef struct { GPtrArray *checksums; GHashTable *metadata; gchar *description; gchar *filename; gchar *homepage; gchar *appstream_id; gchar *license; gchar *name; gchar *summary; gchar *uri; gchar *vendor; gchar *version; gchar *remote_id; guint64 size; FwupdTrustFlags trust_flags; } FwupdReleasePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FwupdRelease, fwupd_release, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fwupd_release_get_instance_private (o)) /** * fwupd_release_get_remote_id: * @release: A #FwupdRelease * * Gets the remote ID that can be used for downloading. * * Returns: the ID, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_remote_id (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->remote_id; } /** * fwupd_release_set_remote_id: * @release: A #FwupdRelease * @remote_id: the release ID, e.g. `USB:foo` * * Sets the remote ID that can be used for downloading. * * Since: 0.9.3 **/ void fwupd_release_set_remote_id (FwupdRelease *release, const gchar *remote_id) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->remote_id); priv->remote_id = g_strdup (remote_id); } /** * fwupd_release_get_version: * @release: A #FwupdRelease * * Gets the update version. * * Returns: the update version, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_version (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->version; } /** * fwupd_release_set_version: * @release: A #FwupdRelease * @version: the update version, e.g. `1.2.4` * * Sets the update version. * * Since: 0.9.3 **/ void fwupd_release_set_version (FwupdRelease *release, const gchar *version) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->version); priv->version = g_strdup (version); } /** * fwupd_release_get_filename: * @release: A #FwupdRelease * * Gets the update filename. * * Returns: the update filename, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_filename (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->filename; } /** * fwupd_release_set_filename: * @release: A #FwupdRelease * @filename: the update filename on disk * * Sets the update filename. * * Since: 0.9.3 **/ void fwupd_release_set_filename (FwupdRelease *release, const gchar *filename) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->filename); priv->filename = g_strdup (filename); } /** * fwupd_release_get_checksums: * @release: A #FwupdRelease * * Gets the release checksums. * * Returns: (element-type utf8) (transfer none): the checksums, which may be empty * * Since: 0.9.3 **/ GPtrArray * fwupd_release_get_checksums (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->checksums; } /** * fwupd_release_add_checksum: * @release: A #FwupdRelease * @checksum: the update checksum * * Sets the update checksum. * * Since: 0.9.3 **/ void fwupd_release_add_checksum (FwupdRelease *release, const gchar *checksum) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_return_if_fail (checksum != NULL); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum_tmp = g_ptr_array_index (priv->checksums, i); if (g_strcmp0 (checksum_tmp, checksum) == 0) return; } g_ptr_array_add (priv->checksums, g_strdup (checksum)); } /** * fwupd_release_get_metadata: * @release: A #FwupdRelease * * Gets the release metadata. * * Returns: (transfer none): the metadata, which may be empty * * Since: 1.0.4 **/ GHashTable * fwupd_release_get_metadata (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->metadata; } /** * fwupd_release_add_metadata_item: * @release: A #FwupdRelease * @key: the key * @value: the value * * Sets a release metadata item. * * Since: 1.0.4 **/ void fwupd_release_add_metadata_item (FwupdRelease *release, const gchar *key, const gchar *value) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_return_if_fail (key != NULL); g_return_if_fail (value != NULL); g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value)); } /** * fwupd_release_add_metadata: * @release: A #FwupdRelease * @hash: the key-values * * Sets multiple release metadata items. * * Since: 1.0.4 **/ void fwupd_release_add_metadata (FwupdRelease *release, GHashTable *hash) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_autoptr(GList) keys = NULL; g_return_if_fail (FWUPD_IS_RELEASE (release)); g_return_if_fail (hash != NULL); /* deep copy the whole map */ keys = g_hash_table_get_keys (hash); for (GList *l = keys; l != NULL; l = l->next) { const gchar *key = l->data; const gchar *value = g_hash_table_lookup (hash, key); g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value)); } } /** * fwupd_release_get_metadata_item: * @release: A #FwupdRelease * @key: the key * * Gets a release metadata item. * * Returns: the value, or %NULL if unset * * Since: 1.0.4 **/ const gchar * fwupd_release_get_metadata_item (FwupdRelease *release, const gchar *key) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); g_return_val_if_fail (key != NULL, NULL); return g_hash_table_lookup (priv->metadata, key); } /** * fwupd_release_get_uri: * @release: A #FwupdRelease * * Gets the update uri. * * Returns: the update uri, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_uri (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->uri; } /** * fwupd_release_set_uri: * @release: A #FwupdRelease * @uri: the update URI * * Sets the update uri, i.e. where you can download the firmware from. * * Since: 0.9.3 **/ void fwupd_release_set_uri (FwupdRelease *release, const gchar *uri) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->uri); priv->uri = g_strdup (uri); } /** * fwupd_release_get_homepage: * @release: A #FwupdRelease * * Gets the update homepage. * * Returns: the update homepage, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_homepage (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->homepage; } /** * fwupd_release_set_homepage: * @release: A #FwupdRelease * @homepage: the description * * Sets the update homepage. * * Since: 0.9.3 **/ void fwupd_release_set_homepage (FwupdRelease *release, const gchar *homepage) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->homepage); priv->homepage = g_strdup (homepage); } /** * fwupd_release_get_description: * @release: A #FwupdRelease * * Gets the update description in AppStream markup format. * * Returns: the update description, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_description (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->description; } /** * fwupd_release_set_description: * @release: A #FwupdRelease * @description: the update description in AppStream markup format * * Sets the update description. * * Since: 0.9.3 **/ void fwupd_release_set_description (FwupdRelease *release, const gchar *description) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->description); priv->description = g_strdup (description); } /** * fwupd_release_get_appstream_id: * @release: A #FwupdRelease * * Gets the AppStream ID. * * Returns: the AppStream ID, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_appstream_id (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->appstream_id; } /** * fwupd_release_set_appstream_id: * @release: A #FwupdRelease * @appstream_id: the AppStream component ID, e.g. `org.hughski.ColorHug2.firmware` * * Sets the AppStream ID. * * Since: 0.9.3 **/ void fwupd_release_set_appstream_id (FwupdRelease *release, const gchar *appstream_id) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->appstream_id); priv->appstream_id = g_strdup (appstream_id); } /** * fwupd_release_get_size: * @release: A #FwupdRelease * * Gets the update size. * * Returns: the update size in bytes, or 0 if unset * * Since: 0.9.3 **/ guint64 fwupd_release_get_size (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), 0); return priv->size; } /** * fwupd_release_set_size: * @release: A #FwupdRelease * @size: the update size in bytes * * Sets the update size. * * Since: 0.9.3 **/ void fwupd_release_set_size (FwupdRelease *release, guint64 size) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); priv->size = size; } /** * fwupd_release_get_summary: * @release: A #FwupdRelease * * Gets the update summary. * * Returns: the update summary, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_summary (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->summary; } /** * fwupd_release_set_summary: * @release: A #FwupdRelease * @summary: the update one line summary * * Sets the update summary. * * Since: 0.9.3 **/ void fwupd_release_set_summary (FwupdRelease *release, const gchar *summary) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->summary); priv->summary = g_strdup (summary); } /** * fwupd_release_get_vendor: * @release: A #FwupdRelease * * Gets the update vendor. * * Returns: the update vendor, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_vendor (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->vendor; } /** * fwupd_release_set_vendor: * @release: A #FwupdRelease * @vendor: the vendor name, e.g. `Hughski Limited` * * Sets the update vendor. * * Since: 0.9.3 **/ void fwupd_release_set_vendor (FwupdRelease *release, const gchar *vendor) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->vendor); priv->vendor = g_strdup (vendor); } /** * fwupd_release_get_license: * @release: A #FwupdRelease * * Gets the update license. * * Returns: the update license, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_license (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->license; } /** * fwupd_release_set_license: * @release: A #FwupdRelease * @license: the description * * Sets the update license. * * Since: 0.9.3 **/ void fwupd_release_set_license (FwupdRelease *release, const gchar *license) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->license); priv->license = g_strdup (license); } /** * fwupd_release_get_name: * @release: A #FwupdRelease * * Gets the update name. * * Returns: the update name, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_release_get_name (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); return priv->name; } /** * fwupd_release_set_name: * @release: A #FwupdRelease * @name: the description * * Sets the update name. * * Since: 0.9.3 **/ void fwupd_release_set_name (FwupdRelease *release, const gchar *name) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); g_free (priv->name); priv->name = g_strdup (name); } /** * fwupd_release_get_trust_flags: * @release: A #FwupdRelease * * Gets the trust level of the release. * * Returns: the trust bitfield, e.g. #FWUPD_TRUST_FLAG_PAYLOAD * * Since: 0.9.8 **/ FwupdTrustFlags fwupd_release_get_trust_flags (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_val_if_fail (FWUPD_IS_RELEASE (release), 0); return priv->trust_flags; } /** * fwupd_release_set_trust_flags: * @release: A #FwupdRelease * @trust_flags: the bitfield, e.g. #FWUPD_TRUST_FLAG_PAYLOAD * * Sets the trust level of the release. * * Since: 0.9.8 **/ void fwupd_release_set_trust_flags (FwupdRelease *release, FwupdTrustFlags trust_flags) { FwupdReleasePrivate *priv = GET_PRIVATE (release); g_return_if_fail (FWUPD_IS_RELEASE (release)); priv->trust_flags = trust_flags; } static GVariant * _hash_kv_to_variant (GHashTable *hash) { GVariantBuilder builder; g_autoptr(GList) keys = g_hash_table_get_keys (hash); g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); for (GList *l = keys; l != NULL; l = l->next) { const gchar *key = l->data; const gchar *value = g_hash_table_lookup (hash, key); g_variant_builder_add (&builder, "{ss}", key, value); } return g_variant_builder_end (&builder); } static GHashTable * _variant_to_hash_kv (GVariant *dict) { GHashTable *hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); GVariantIter iter; const gchar *key; const gchar *value; g_variant_iter_init (&iter, dict); while (g_variant_iter_loop (&iter, "{ss}", &key, &value)) g_hash_table_insert (hash, g_strdup (key), g_strdup (value)); return hash; } /** * fwupd_release_to_variant: * @release: A #FwupdRelease * * Creates a GVariant from the release data. * * Returns: the GVariant, or %NULL for error * * Since: 1.0.0 **/ GVariant * fwupd_release_to_variant (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); GVariantBuilder builder; g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); /* create an array with all the metadata in */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); if (priv->remote_id != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_REMOTE_ID, g_variant_new_string (priv->remote_id)); } if (priv->appstream_id != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_APPSTREAM_ID, g_variant_new_string (priv->appstream_id)); } if (priv->filename != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_FILENAME, g_variant_new_string (priv->filename)); } if (priv->license != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_LICENSE, g_variant_new_string (priv->license)); } if (priv->name != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_NAME, g_variant_new_string (priv->name)); } if (priv->size != 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_SIZE, g_variant_new_uint64 (priv->size)); } if (priv->summary != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_SUMMARY, g_variant_new_string (priv->summary)); } if (priv->description != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_DESCRIPTION, g_variant_new_string (priv->description)); } if (priv->checksums->len > 0) { g_autoptr(GString) str = g_string_new (""); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum = g_ptr_array_index (priv->checksums, i); g_string_append_printf (str, "%s,", checksum); } if (str->len > 0) g_string_truncate (str, str->len - 1); g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CHECKSUM, g_variant_new_string (str->str)); } if (priv->uri != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_URI, g_variant_new_string (priv->uri)); } if (priv->homepage != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_HOMEPAGE, g_variant_new_string (priv->homepage)); } if (priv->version != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VERSION, g_variant_new_string (priv->version)); } if (priv->vendor != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_VENDOR, g_variant_new_string (priv->vendor)); } if (priv->trust_flags != 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_TRUST_FLAGS, g_variant_new_uint64 (priv->trust_flags)); } if (g_hash_table_size (priv->metadata) > 0) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_METADATA, _hash_kv_to_variant (priv->metadata)); } return g_variant_new ("a{sv}", &builder); } static void fwupd_release_from_key_value (FwupdRelease *release, const gchar *key, GVariant *value) { FwupdReleasePrivate *priv = GET_PRIVATE (release); if (g_strcmp0 (key, FWUPD_RESULT_KEY_REMOTE_ID) == 0) { fwupd_release_set_remote_id (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_APPSTREAM_ID) == 0) { fwupd_release_set_appstream_id (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_FILENAME) == 0) { fwupd_release_set_filename (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_LICENSE) == 0) { fwupd_release_set_license (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_NAME) == 0) { fwupd_release_set_name (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_SIZE) == 0) { fwupd_release_set_size (release, g_variant_get_uint64 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_SUMMARY) == 0) { fwupd_release_set_summary (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_DESCRIPTION) == 0) { fwupd_release_set_description (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) { const gchar *checksums = g_variant_get_string (value, NULL); g_auto(GStrv) split = g_strsplit (checksums, ",", -1); for (guint i = 0; split[i] != NULL; i++) fwupd_release_add_checksum (release, split[i]); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_URI) == 0) { fwupd_release_set_uri (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_HOMEPAGE) == 0) { fwupd_release_set_homepage (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VERSION) == 0) { fwupd_release_set_version (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_VENDOR) == 0) { fwupd_release_set_vendor (release, g_variant_get_string (value, NULL)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_TRUST_FLAGS) == 0) { fwupd_release_set_trust_flags (release, g_variant_get_uint64 (value)); return; } if (g_strcmp0 (key, FWUPD_RESULT_KEY_METADATA) == 0) { g_hash_table_unref (priv->metadata); priv->metadata = _variant_to_hash_kv (value); return; } } static void fwupd_pad_kv_str (GString *str, const gchar *key, const gchar *value) { /* ignore */ if (key == NULL || value == NULL) return; g_string_append_printf (str, " %s: ", key); for (gsize i = strlen (key); i < 20; i++) g_string_append (str, " "); g_string_append_printf (str, "%s\n", value); } static void fwupd_pad_kv_siz (GString *str, const gchar *key, guint64 value) { g_autofree gchar *tmp = NULL; /* ignore */ if (value == 0) return; tmp = g_format_size (value); fwupd_pad_kv_str (str, key, tmp); } static void fwupd_pad_kv_tfl (GString *str, const gchar *key, FwupdTrustFlags trust_flags) { g_autoptr(GString) tmp = g_string_new (""); for (guint i = 1; i < FWUPD_TRUST_FLAG_LAST; i *= 2) { if ((trust_flags & i) == 0) continue; g_string_append_printf (tmp, "%s|", fwupd_trust_flag_to_string (i)); } if (tmp->len == 0) { g_string_append (tmp, fwupd_trust_flag_to_string (0)); } else { g_string_truncate (tmp, tmp->len - 1); } fwupd_pad_kv_str (str, key, tmp->str); } /** * fwupd_release_to_string: * @release: A #FwupdRelease * * Builds a text representation of the object. * * Returns: text, or %NULL for invalid * * Since: 0.9.3 **/ gchar * fwupd_release_to_string (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); GString *str; g_autoptr(GList) keys = NULL; g_return_val_if_fail (FWUPD_IS_RELEASE (release), NULL); str = g_string_new (""); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_APPSTREAM_ID, priv->appstream_id); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_REMOTE_ID, priv->remote_id); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_SUMMARY, priv->summary); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_DESCRIPTION, priv->description); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VERSION, priv->version); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_FILENAME, priv->filename); for (guint i = 0; i < priv->checksums->len; i++) { const gchar *checksum = g_ptr_array_index (priv->checksums, i); g_autofree gchar *checksum_display = fwupd_checksum_format_for_display (checksum); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_CHECKSUM, checksum_display); } fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_LICENSE, priv->license); fwupd_pad_kv_siz (str, FWUPD_RESULT_KEY_SIZE, priv->size); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_URI, priv->uri); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_HOMEPAGE, priv->homepage); fwupd_pad_kv_str (str, FWUPD_RESULT_KEY_VENDOR, priv->vendor); fwupd_pad_kv_tfl (str, FWUPD_RESULT_KEY_TRUST_FLAGS, priv->trust_flags); /* metadata */ keys = g_hash_table_get_keys (priv->metadata); for (GList *l = keys; l != NULL; l = l->next) { const gchar *key = l->data; const gchar *value = g_hash_table_lookup (priv->metadata, key); fwupd_pad_kv_str (str, key, value); } return g_string_free (str, FALSE); } static void fwupd_release_class_init (FwupdReleaseClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fwupd_release_finalize; } static void fwupd_release_init (FwupdRelease *release) { FwupdReleasePrivate *priv = GET_PRIVATE (release); priv->checksums = g_ptr_array_new_with_free_func (g_free); priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static void fwupd_release_finalize (GObject *object) { FwupdRelease *release = FWUPD_RELEASE (object); FwupdReleasePrivate *priv = GET_PRIVATE (release); g_free (priv->description); g_free (priv->filename); g_free (priv->appstream_id); g_free (priv->license); g_free (priv->name); g_free (priv->summary); g_free (priv->uri); g_free (priv->homepage); g_free (priv->vendor); g_free (priv->version); g_free (priv->remote_id); g_ptr_array_unref (priv->checksums); g_hash_table_unref (priv->metadata); G_OBJECT_CLASS (fwupd_release_parent_class)->finalize (object); } static void fwupd_release_set_from_variant_iter (FwupdRelease *release, GVariantIter *iter) { GVariant *value; const gchar *key; while (g_variant_iter_next (iter, "{&sv}", &key, &value)) { fwupd_release_from_key_value (release, key, value); g_variant_unref (value); } } /** * fwupd_release_from_variant: * @data: a #GVariant * * Creates a new release using packed data. * * Returns: (transfer full): a new #FwupdRelease, or %NULL if @data was invalid * * Since: 1.0.0 **/ FwupdRelease * fwupd_release_from_variant (GVariant *data) { FwupdRelease *rel = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; /* format from GetDetails */ type_string = g_variant_get_type_string (data); if (g_strcmp0 (type_string, "(a{sv})") == 0) { rel = fwupd_release_new (); g_variant_get (data, "(a{sv})", &iter); fwupd_release_set_from_variant_iter (rel, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { rel = fwupd_release_new (); g_variant_get (data, "a{sv}", &iter); fwupd_release_set_from_variant_iter (rel, iter); } else { g_warning ("type %s not known", type_string); } return rel; } /** * fwupd_release_new: * * Creates a new release. * * Returns: a new #FwupdRelease * * Since: 0.9.3 **/ FwupdRelease * fwupd_release_new (void) { FwupdRelease *release; release = g_object_new (FWUPD_TYPE_RELEASE, NULL); return FWUPD_RELEASE (release); } fwupd-1.0.6/libfwupd/fwupd-release.h000066400000000000000000000102051325145456600174040ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_RELEASE_H #define __FWUPD_RELEASE_H #include #include "fwupd-enums.h" G_BEGIN_DECLS #define FWUPD_TYPE_RELEASE (fwupd_release_get_type ()) G_DECLARE_DERIVABLE_TYPE (FwupdRelease, fwupd_release, FWUPD, RELEASE, GObject) struct _FwupdReleaseClass { GObjectClass parent_class; /*< private >*/ void (*_fwupd_reserved1) (void); void (*_fwupd_reserved2) (void); void (*_fwupd_reserved3) (void); void (*_fwupd_reserved4) (void); void (*_fwupd_reserved5) (void); void (*_fwupd_reserved6) (void); void (*_fwupd_reserved7) (void); }; FwupdRelease *fwupd_release_new (void); gchar *fwupd_release_to_string (FwupdRelease *release); const gchar *fwupd_release_get_version (FwupdRelease *release); void fwupd_release_set_version (FwupdRelease *release, const gchar *version); const gchar *fwupd_release_get_uri (FwupdRelease *release); void fwupd_release_set_uri (FwupdRelease *release, const gchar *uri); GPtrArray *fwupd_release_get_checksums (FwupdRelease *release); void fwupd_release_add_checksum (FwupdRelease *release, const gchar *checksum); GHashTable *fwupd_release_get_metadata (FwupdRelease *release); void fwupd_release_add_metadata (FwupdRelease *release, GHashTable *hash); void fwupd_release_add_metadata_item (FwupdRelease *release, const gchar *key, const gchar *value); const gchar *fwupd_release_get_metadata_item (FwupdRelease *release, const gchar *key); const gchar *fwupd_release_get_filename (FwupdRelease *release); void fwupd_release_set_filename (FwupdRelease *release, const gchar *filename); const gchar *fwupd_release_get_appstream_id (FwupdRelease *release); void fwupd_release_set_appstream_id (FwupdRelease *release, const gchar *appstream_id); const gchar *fwupd_release_get_remote_id (FwupdRelease *release); void fwupd_release_set_remote_id (FwupdRelease *release, const gchar *remote_id); const gchar *fwupd_release_get_vendor (FwupdRelease *release); void fwupd_release_set_vendor (FwupdRelease *release, const gchar *vendor); const gchar *fwupd_release_get_name (FwupdRelease *release); void fwupd_release_set_name (FwupdRelease *release, const gchar *name); const gchar *fwupd_release_get_summary (FwupdRelease *release); void fwupd_release_set_summary (FwupdRelease *release, const gchar *summary); const gchar *fwupd_release_get_description (FwupdRelease *release); void fwupd_release_set_description (FwupdRelease *release, const gchar *description); const gchar *fwupd_release_get_homepage (FwupdRelease *release); void fwupd_release_set_homepage (FwupdRelease *release, const gchar *homepage); guint64 fwupd_release_get_size (FwupdRelease *release); void fwupd_release_set_size (FwupdRelease *release, guint64 size); const gchar *fwupd_release_get_license (FwupdRelease *release); void fwupd_release_set_license (FwupdRelease *release, const gchar *license); FwupdTrustFlags fwupd_release_get_trust_flags (FwupdRelease *release); void fwupd_release_set_trust_flags (FwupdRelease *release, FwupdTrustFlags trust_flags); G_END_DECLS #endif /* __FWUPD_RELEASE_H */ fwupd-1.0.6/libfwupd/fwupd-remote-private.h000066400000000000000000000031761325145456600207400ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_REMOTE_PRIVATE_H #define __FWUPD_REMOTE_PRIVATE_H #include "fwupd-remote.h" G_BEGIN_DECLS FwupdRemote *fwupd_remote_from_variant (GVariant *data); GVariant *fwupd_remote_to_variant (FwupdRemote *self); gboolean fwupd_remote_load_from_filename (FwupdRemote *self, const gchar *filename, GCancellable *cancellable, GError **error); void fwupd_remote_set_priority (FwupdRemote *self, gint priority); void fwupd_remote_set_mtime (FwupdRemote *self, guint64 mtime); gchar **fwupd_remote_get_order_after (FwupdRemote *self); gchar **fwupd_remote_get_order_before (FwupdRemote *self); G_END_DECLS #endif /* __FWUPD_REMOTE_PRIVATE_H */ fwupd-1.0.6/libfwupd/fwupd-remote.c000066400000000000000000000747401325145456600172700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fwupd-deprecated.h" #include "fwupd-enums-private.h" #include "fwupd-error.h" #include "fwupd-remote-private.h" /** * SECTION:fwupd-remote * @short_description: a source of firmware * * An object that represents a source of metadata that provides firmware. * * See also: #FwupdClient */ static void fwupd_remote_finalize (GObject *obj); typedef struct { GObject parent_instance; FwupdRemoteKind kind; FwupdKeyringKind keyring_kind; gchar *id; gchar *firmware_base_uri; gchar *report_uri; gchar *metadata_uri; gchar *metadata_uri_sig; gchar *username; gchar *password; gchar *title; gchar *checksum; gchar *filename_cache; gchar *filename_cache_sig; gchar *filename_source; gboolean enabled; gint priority; guint64 mtime; gchar **order_after; gchar **order_before; } FwupdRemotePrivate; enum { PROP_0, PROP_ID, PROP_ENABLED, PROP_LAST }; G_DEFINE_TYPE_WITH_PRIVATE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fwupd_remote_get_instance_private (o)) static void fwupd_remote_set_username (FwupdRemote *self, const gchar *username) { FwupdRemotePrivate *priv = GET_PRIVATE (self); if (username != NULL && username[0] == '\0') username = NULL; priv->username = g_strdup (username); } static void fwupd_remote_set_title (FwupdRemote *self, const gchar *title) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_free (priv->title); priv->title = g_strdup (title); } static void fwupd_remote_set_checksum (FwupdRemote *self, const gchar *checksum) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_free (priv->checksum); priv->checksum = g_strdup (checksum); } static void fwupd_remote_set_password (FwupdRemote *self, const gchar *password) { FwupdRemotePrivate *priv = GET_PRIVATE (self); if (password != NULL && password[0] == '\0') password = NULL; priv->password = g_strdup (password); } static void fwupd_remote_set_kind (FwupdRemote *self, FwupdRemoteKind kind) { FwupdRemotePrivate *priv = GET_PRIVATE (self); priv->kind = kind; } static void fwupd_remote_set_keyring_kind (FwupdRemote *self, FwupdKeyringKind keyring_kind) { FwupdRemotePrivate *priv = GET_PRIVATE (self); priv->keyring_kind = keyring_kind; } /* note, this has to be set before url */ static void fwupd_remote_set_id (FwupdRemote *self, const gchar *id) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_free (priv->id); priv->id = g_strdup (id); g_strdelimit (priv->id, ".", '\0'); } static void fwupd_remote_set_filename_source (FwupdRemote *self, const gchar *filename_source) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_free (priv->filename_source); priv->filename_source = g_strdup (filename_source); } static const gchar * fwupd_remote_get_suffix_for_keyring_kind (FwupdKeyringKind keyring_kind) { if (keyring_kind == FWUPD_KEYRING_KIND_GPG) return ".asc"; if (keyring_kind == FWUPD_KEYRING_KIND_PKCS7) return ".p7b"; return NULL; } static SoupURI * fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error) { FwupdRemotePrivate *priv = GET_PRIVATE (self); SoupURI *uri; g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); g_return_val_if_fail (url != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* create URI, substituting if required */ if (priv->firmware_base_uri != NULL) { g_autoptr(SoupURI) uri_tmp = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *url2 = NULL; uri_tmp = soup_uri_new (url); if (uri_tmp == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse URI '%s'", url); return NULL; } basename = g_path_get_basename (soup_uri_get_path (uri_tmp)); url2 = g_build_filename (priv->firmware_base_uri, basename, NULL); uri = soup_uri_new (url2); if (uri == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse URI '%s'", url2); return NULL; } /* use the base URI of the metadata to build the full path */ } else if (g_strstr_len (url, -1, "/") == NULL) { g_autofree gchar *basename = NULL; g_autofree gchar *path = NULL; uri = soup_uri_new (priv->metadata_uri); if (uri == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse metadata URI '%s'", url); return NULL; } basename = g_path_get_dirname (soup_uri_get_path (uri)); path = g_build_filename (basename, url, NULL); soup_uri_set_path (uri, path); /* a normal URI */ } else { uri = soup_uri_new (url); if (uri == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse URI '%s'", url); return NULL; } } /* set the username and password */ if (priv->username != NULL) soup_uri_set_user (uri, priv->username); if (priv->password != NULL) soup_uri_set_password (uri, priv->password); return uri; } /* note, this has to be set before username and password */ static void fwupd_remote_set_metadata_uri (FwupdRemote *self, const gchar *metadata_uri) { FwupdRemotePrivate *priv = GET_PRIVATE (self); const gchar *suffix; g_autoptr(SoupURI) uri = NULL; /* build the URI */ uri = soup_uri_new (metadata_uri); if (uri == NULL) return; /* save this so we can export the object as a GVariant */ priv->metadata_uri = g_strdup (metadata_uri); /* generate the signature URI too */ suffix = fwupd_remote_get_suffix_for_keyring_kind (priv->keyring_kind); if (suffix != NULL) priv->metadata_uri_sig = g_strconcat (metadata_uri, suffix, NULL); } /* note, this has to be set after MetadataURI */ static void fwupd_remote_set_firmware_base_uri (FwupdRemote *self, const gchar *firmware_base_uri) { FwupdRemotePrivate *priv = GET_PRIVATE (self); priv->firmware_base_uri = g_strdup (firmware_base_uri); } static void fwupd_remote_set_report_uri (FwupdRemote *self, const gchar *report_uri) { FwupdRemotePrivate *priv = GET_PRIVATE (self); priv->report_uri = g_strdup (report_uri); } /** * fwupd_remote_kind_from_string: * @kind: a string, e.g. `download` * * Converts an printable string to an enumerated type. * * Returns: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD * * Since: 0.9.6 **/ FwupdRemoteKind fwupd_remote_kind_from_string (const gchar *kind) { if (g_strcmp0 (kind, "download") == 0) return FWUPD_REMOTE_KIND_DOWNLOAD; if (g_strcmp0 (kind, "local") == 0) return FWUPD_REMOTE_KIND_LOCAL; return FWUPD_REMOTE_KIND_UNKNOWN; } /** * fwupd_remote_kind_to_string: * @kind: a #FwupdRemoteKind, e.g. %FWUPD_REMOTE_KIND_DOWNLOAD * * Converts an enumerated type to a printable string. * * Returns: a string, e.g. `download` * * Since: 0.9.6 **/ const gchar * fwupd_remote_kind_to_string (FwupdRemoteKind kind) { if (kind == FWUPD_REMOTE_KIND_DOWNLOAD) return "download"; if (kind == FWUPD_REMOTE_KIND_LOCAL) return "local"; return NULL; } static void fwupd_remote_set_filename_cache (FwupdRemote *self, const gchar *filename) { FwupdRemotePrivate *priv = GET_PRIVATE (self); const gchar *suffix; g_return_if_fail (FWUPD_IS_REMOTE (self)); g_free (priv->filename_cache); priv->filename_cache = g_strdup (filename); /* create for all remote types */ suffix = fwupd_remote_get_suffix_for_keyring_kind (priv->keyring_kind); if (suffix != NULL) { g_free (priv->filename_cache_sig); priv->filename_cache_sig = g_strconcat (filename, suffix, NULL); } } /** * fwupd_remote_load_from_filename: * @self: A #FwupdRemote * @filename: A filename * @cancellable: the #GCancellable, or %NULL * @error: the #GError, or %NULL * * Sets up the remote ready for use. Most other methods call this * for you, and do you only need to call this if you are just watching * the self. * * Returns: %TRUE for success * * Since: 0.9.3 **/ gboolean fwupd_remote_load_from_filename (FwupdRemote *self, const gchar *filename, GCancellable *cancellable, GError **error) { FwupdRemotePrivate *priv = GET_PRIVATE (self); const gchar *group = "fwupd Remote"; g_autofree gchar *firmware_base_uri = NULL; g_autofree gchar *id = NULL; g_autofree gchar *keyring_kind = NULL; g_autofree gchar *metadata_uri = NULL; g_autofree gchar *order_after = NULL; g_autofree gchar *order_before = NULL; g_autofree gchar *report_uri = NULL; g_autoptr(GKeyFile) kf = NULL; g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE); g_return_val_if_fail (filename != NULL, FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* set ID */ id = g_path_get_basename (filename); fwupd_remote_set_id (self, id); /* load file */ kf = g_key_file_new (); if (!g_key_file_load_from_file (kf, filename, G_KEY_FILE_NONE, error)) return FALSE; /* get verification type, falling back to GPG */ keyring_kind = g_key_file_get_string (kf, group, "Keyring", NULL); if (keyring_kind == NULL) { priv->keyring_kind = FWUPD_KEYRING_KIND_GPG; } else { priv->keyring_kind = fwupd_keyring_kind_from_string (keyring_kind); if (priv->keyring_kind == FWUPD_KEYRING_KIND_UNKNOWN) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse type '%s'", keyring_kind); return FALSE; } } /* all remotes need a URI, even if it's file:// to the cache */ metadata_uri = g_key_file_get_string (kf, group, "MetadataURI", error); if (metadata_uri == NULL) return FALSE; if (g_str_has_prefix (metadata_uri, "file://")) { priv->kind = FWUPD_REMOTE_KIND_LOCAL; } else if (g_str_has_prefix (metadata_uri, "http://") || g_str_has_prefix (metadata_uri, "https://")) { priv->kind = FWUPD_REMOTE_KIND_DOWNLOAD; } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse MetadataURI type '%s'", metadata_uri); return FALSE; } /* extract data */ priv->enabled = g_key_file_get_boolean (kf, group, "Enabled", NULL); priv->title = g_key_file_get_string (kf, group, "Title", NULL); /* reporting is optional */ report_uri = g_key_file_get_string (kf, group, "ReportURI", NULL); if (report_uri != NULL && report_uri[0] != '\0') fwupd_remote_set_report_uri (self, report_uri); /* DOWNLOAD-type remotes */ if (priv->kind == FWUPD_REMOTE_KIND_DOWNLOAD) { g_autofree gchar *filename_cache = NULL; g_autofree gchar *username = NULL; g_autofree gchar *password = NULL; /* the client has to download this and the signature */ fwupd_remote_set_metadata_uri (self, metadata_uri); /* check the URI was valid */ if (priv->metadata_uri == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse URI '%s' in %s", metadata_uri, filename); return FALSE; } /* username and password are optional */ username = g_key_file_get_string (kf, group, "Username", NULL); if (username != NULL) fwupd_remote_set_username (self, username); password = g_key_file_get_string (kf, group, "Password", NULL); if (password != NULL) fwupd_remote_set_password (self, password); /* set cache to /var/lib... */ filename_cache = g_build_filename (LOCALSTATEDIR, "lib", "fwupd", "remotes.d", priv->id, "metadata.xml.gz", NULL); fwupd_remote_set_filename_cache (self, filename_cache); } /* all LOCAL remotes have to include a valid MetadataURI */ if (priv->kind == FWUPD_REMOTE_KIND_LOCAL) { const gchar *filename_cache = metadata_uri; if (g_str_has_prefix (filename_cache, "file://")) filename_cache += 7; fwupd_remote_set_filename_cache (self, filename_cache); } /* load the checksum */ if (priv->filename_cache_sig != NULL && g_file_test (priv->filename_cache_sig, G_FILE_TEST_EXISTS)) { gsize sz = 0; g_autofree gchar *buf = NULL; g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256); if (!g_file_get_contents (priv->filename_cache_sig, &buf, &sz, error)) { g_prefix_error (error, "failed to get checksum: "); return FALSE; } g_checksum_update (checksum, (guchar *) buf, (gssize) sz); fwupd_remote_set_checksum (self, g_checksum_get_string (checksum)); } else { fwupd_remote_set_checksum (self, NULL); } /* the base URI is optional */ firmware_base_uri = g_key_file_get_string (kf, group, "FirmwareBaseURI", NULL); if (firmware_base_uri != NULL) fwupd_remote_set_firmware_base_uri (self, firmware_base_uri); /* dep logic */ order_before = g_key_file_get_string (kf, group, "OrderBefore", NULL); if (order_before != NULL) priv->order_before = g_strsplit_set (order_before, ",:;", -1); order_after = g_key_file_get_string (kf, group, "OrderAfter", NULL); if (order_after != NULL) priv->order_after = g_strsplit_set (order_after, ",:;", -1); /* success */ fwupd_remote_set_filename_source (self, filename); return TRUE; } /** * fwupd_remote_get_order_after: * @self: A #FwupdRemote * * Gets the list of remotes this plugin should be ordered after. * * Returns: (transfer none): an array * * Since: 0.9.5 **/ gchar ** fwupd_remote_get_order_after (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->order_after; } /** * fwupd_remote_get_order_before: * @self: A #FwupdRemote * * Gets the list of remotes this plugin should be ordered before. * * Returns: (transfer none): an array * * Since: 0.9.5 **/ gchar ** fwupd_remote_get_order_before (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->order_before; } /** * fwupd_remote_get_filename_cache: * @self: A #FwupdRemote * * Gets the path and filename that the remote is using for a cache. * * Returns: a string, or %NULL for unset * * Since: 0.9.6 **/ const gchar * fwupd_remote_get_filename_cache (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->filename_cache; } /** * fwupd_remote_get_filename_cache_sig: * @self: A #FwupdRemote * * Gets the path and filename that the remote is using for a signature cache. * * Returns: a string, or %NULL for unset * * Since: 0.9.7 **/ const gchar * fwupd_remote_get_filename_cache_sig (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->filename_cache_sig; } /** * fwupd_remote_get_filename_source: * @self: A #FwupdRemote * * Gets the path and filename of the remote itself, typically a `.conf` file. * * Returns: a string, or %NULL for unset * * Since: 0.9.8 **/ const gchar * fwupd_remote_get_filename_source (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->filename_source; } /** * fwupd_remote_get_priority: * @self: A #FwupdRemote * * Gets the priority of the remote, where bigger numbers are better. * * Returns: a priority, or 0 for the default value * * Since: 0.9.5 **/ gint fwupd_remote_get_priority (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0); return priv->priority; } /** * fwupd_remote_get_kind: * @self: A #FwupdRemote * * Gets the kind of the remote. * * Returns: a #FwupdRemoteKind, e.g. #FWUPD_REMOTE_KIND_LOCAL * * Since: 0.9.6 **/ FwupdRemoteKind fwupd_remote_get_kind (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0); return priv->kind; } /** * fwupd_remote_get_keyring_kind: * @self: A #FwupdRemote * * Gets the keyring kind of the remote. * * Returns: a #FwupdKeyringKind, e.g. #FWUPD_KEYRING_KIND_GPG * * Since: 0.9.7 **/ FwupdKeyringKind fwupd_remote_get_keyring_kind (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0); return priv->keyring_kind; } /** * fwupd_remote_get_age: * @self: A #FwupdRemote * * Gets the age of the remote in seconds. * * Returns: a age, or %G_MAXUINT64 for unavailable * * Since: 0.9.5 **/ guint64 fwupd_remote_get_age (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); guint64 now; g_return_val_if_fail (FWUPD_IS_REMOTE (self), 0); now = (guint64) g_get_real_time () / G_USEC_PER_SEC; if (priv->mtime > now) return G_MAXUINT64; return now - priv->mtime; } /** * fwupd_remote_set_priority: * @self: A #FwupdRemote * @priority: an integer, where 1 is better * * Sets the plugin priority. * * Since: 0.9.5 **/ void fwupd_remote_set_priority (FwupdRemote *self, gint priority) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_if_fail (FWUPD_IS_REMOTE (self)); priv->priority = priority; } /** * fwupd_remote_set_mtime: * @self: A #FwupdRemote * @mtime: a UNIX itmestamp * * Sets the plugin modification time. * * Since: 0.9.5 **/ void fwupd_remote_set_mtime (FwupdRemote *self, guint64 mtime) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_if_fail (FWUPD_IS_REMOTE (self)); priv->mtime = mtime; } /** * fwupd_remote_get_username: * @self: A #FwupdRemote * * Gets the username configured for the remote. * * Returns: a string, or %NULL for unset * * Since: 0.9.5 **/ const gchar * fwupd_remote_get_username (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->username; } /** * fwupd_remote_get_password: * @self: A #FwupdRemote * * Gets the password configured for the remote. * * Returns: a string, or %NULL for unset * * Since: 0.9.5 **/ const gchar * fwupd_remote_get_password (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->password; } /** * fwupd_remote_get_title: * @self: A #FwupdRemote * * Gets the remote title, e.g. `Linux Vendor Firmware Service`. * * Returns: a string, or %NULL if unset * * Since: 0.9.8 **/ const gchar * fwupd_remote_get_title (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->title; } /** * fwupd_remote_get_checksum: * @self: A #FwupdRemote * * Gets the remote checksum. * * Returns: a string, or %NULL if unset * * Since: 1.0.0 **/ const gchar * fwupd_remote_get_checksum (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->checksum; } /** * fwupd_remote_build_firmware_uri: * @self: A #FwupdRemote * @url: the URL to use * @error: the #GError, or %NULL * * Builds a URI for the URL using the username and password set for the remote, * including any basename URI substitution. * * Returns: (transfer full): a URI, or %NULL for error * * Since: 0.9.7 **/ gchar * fwupd_remote_build_firmware_uri (FwupdRemote *self, const gchar *url, GError **error) { g_autoptr(SoupURI) uri = fwupd_remote_build_uri (self, url, error); if (uri == NULL) return NULL; return soup_uri_to_string (uri, FALSE); } /** * fwupd_remote_get_report_uri: * @self: A #FwupdRemote * * Gets the URI for the remote reporting. * * Returns: (transfer none): a URI, or %NULL for invalid. * * Since: 1.0.4 **/ const gchar * fwupd_remote_get_report_uri (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->report_uri; } /** * fwupd_remote_get_metadata_uri: * @self: A #FwupdRemote * * Gets the URI for the remote metadata. * * Returns: (transfer none): a URI, or %NULL for invalid. * * Since: 0.9.7 **/ const gchar * fwupd_remote_get_metadata_uri (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->metadata_uri; } /** * fwupd_remote_get_metadata_uri_sig: * @self: A #FwupdRemote * * Gets the URI for the remote metadata signature. * * Returns: (transfer none): a URI, or %NULL for invalid. * * Since: 0.9.7 **/ const gchar * fwupd_remote_get_metadata_uri_sig (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->metadata_uri_sig; } /** * fwupd_remote_get_firmware_base_uri: * @self: A #FwupdRemote * * Gets the base URI for firmware. * * Returns: (transfer none): a URI, or %NULL for unset. * * Since: 0.9.7 **/ const gchar * fwupd_remote_get_firmware_base_uri (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->firmware_base_uri; } /** * fwupd_remote_get_enabled: * @self: A #FwupdRemote * * Gets if the remote is enabled and should be used. * * Returns: a #TRUE if the remote is enabled * * Since: 0.9.3 **/ gboolean fwupd_remote_get_enabled (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), FALSE); return priv->enabled; } /** * fwupd_remote_get_id: * @self: A #FwupdRemote * * Gets the remote ID, e.g. `lvfs-testing`. * * Returns: a string, or %NULL if unset * * Since: 0.9.3 **/ const gchar * fwupd_remote_get_id (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); return priv->id; } static void fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter) { FwupdRemotePrivate *priv = GET_PRIVATE (self); GVariant *value; const gchar *key; g_autoptr(GVariantIter) iter2 = g_variant_iter_copy (iter); g_autoptr(GVariantIter) iter3 = g_variant_iter_copy (iter); /* three passes, as we have to construct Id -> Url -> * */ while (g_variant_iter_loop (iter, "{sv}", &key, &value)) { if (g_strcmp0 (key, FWUPD_RESULT_KEY_REMOTE_ID) == 0) fwupd_remote_set_id (self, g_variant_get_string (value, NULL)); if (g_strcmp0 (key, "Type") == 0) fwupd_remote_set_kind (self, g_variant_get_uint32 (value)); if (g_strcmp0 (key, "Keyring") == 0) fwupd_remote_set_keyring_kind (self, g_variant_get_uint32 (value)); } while (g_variant_iter_loop (iter2, "{sv}", &key, &value)) { if (g_strcmp0 (key, FWUPD_RESULT_KEY_URI) == 0) fwupd_remote_set_metadata_uri (self, g_variant_get_string (value, NULL)); if (g_strcmp0 (key, "FilenameCache") == 0) fwupd_remote_set_filename_cache (self, g_variant_get_string (value, NULL)); if (g_strcmp0 (key, "FilenameSource") == 0) fwupd_remote_set_filename_source (self, g_variant_get_string (value, NULL)); if (g_strcmp0 (key, "ReportUri") == 0) fwupd_remote_set_report_uri (self, g_variant_get_string (value, NULL)); } while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) { if (g_strcmp0 (key, "Username") == 0) { fwupd_remote_set_username (self, g_variant_get_string (value, NULL)); } else if (g_strcmp0 (key, "Password") == 0) { fwupd_remote_set_password (self, g_variant_get_string (value, NULL)); } else if (g_strcmp0 (key, "Title") == 0) { fwupd_remote_set_title (self, g_variant_get_string (value, NULL)); } else if (g_strcmp0 (key, FWUPD_RESULT_KEY_CHECKSUM) == 0) { fwupd_remote_set_checksum (self, g_variant_get_string (value, NULL)); } else if (g_strcmp0 (key, "Enabled") == 0) { priv->enabled = g_variant_get_boolean (value); } else if (g_strcmp0 (key, "Priority") == 0) { priv->priority = g_variant_get_int32 (value); } else if (g_strcmp0 (key, "ModificationTime") == 0) { priv->mtime = g_variant_get_uint64 (value); } else if (g_strcmp0 (key, "FirmwareBaseUri") == 0) { fwupd_remote_set_firmware_base_uri (self, g_variant_get_string (value, NULL)); } } } /** * fwupd_remote_to_variant: * @self: A #FwupdRemote * * Creates a GVariant from the remote data. * * Returns: the GVariant, or %NULL for error * * Since: 1.0.0 **/ GVariant * fwupd_remote_to_variant (FwupdRemote *self) { FwupdRemotePrivate *priv = GET_PRIVATE (self); GVariantBuilder builder; g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL); /* create an array with all the metadata in */ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); if (priv->id != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_REMOTE_ID, g_variant_new_string (priv->id)); } if (priv->username != NULL) { g_variant_builder_add (&builder, "{sv}", "Username", g_variant_new_string (priv->username)); } if (priv->password != NULL) { g_variant_builder_add (&builder, "{sv}", "Password", g_variant_new_string (priv->password)); } if (priv->title != NULL) { g_variant_builder_add (&builder, "{sv}", "Title", g_variant_new_string (priv->title)); } if (priv->checksum != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_CHECKSUM, g_variant_new_string (priv->checksum)); } if (priv->metadata_uri != NULL) { g_variant_builder_add (&builder, "{sv}", FWUPD_RESULT_KEY_URI, g_variant_new_string (priv->metadata_uri)); } if (priv->report_uri != NULL) { g_variant_builder_add (&builder, "{sv}", "ReportUri", g_variant_new_string (priv->report_uri)); } if (priv->firmware_base_uri != NULL) { g_variant_builder_add (&builder, "{sv}", "FirmwareBaseUri", g_variant_new_string (priv->firmware_base_uri)); } if (priv->priority != 0) { g_variant_builder_add (&builder, "{sv}", "Priority", g_variant_new_int32 (priv->priority)); } if (priv->kind != FWUPD_REMOTE_KIND_UNKNOWN) { g_variant_builder_add (&builder, "{sv}", "Type", g_variant_new_uint32 (priv->kind)); } if (priv->keyring_kind != FWUPD_KEYRING_KIND_UNKNOWN) { g_variant_builder_add (&builder, "{sv}", "Keyring", g_variant_new_uint32 (priv->keyring_kind)); } if (priv->mtime != 0) { g_variant_builder_add (&builder, "{sv}", "ModificationTime", g_variant_new_uint64 (priv->mtime)); } if (priv->filename_cache != NULL) { g_variant_builder_add (&builder, "{sv}", "FilenameCache", g_variant_new_string (priv->filename_cache)); } if (priv->filename_source != NULL) { g_variant_builder_add (&builder, "{sv}", "FilenameSource", g_variant_new_string (priv->filename_source)); } g_variant_builder_add (&builder, "{sv}", "Enabled", g_variant_new_boolean (priv->enabled)); return g_variant_new ("a{sv}", &builder); } static void fwupd_remote_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) { FwupdRemote *self = FWUPD_REMOTE (obj); FwupdRemotePrivate *priv = GET_PRIVATE (self); switch (prop_id) { case PROP_ENABLED: g_value_set_boolean (value, priv->enabled); break; case PROP_ID: g_value_set_string (value, priv->id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; } } static void fwupd_remote_set_property (GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) { FwupdRemote *self = FWUPD_REMOTE (obj); FwupdRemotePrivate *priv = GET_PRIVATE (self); switch (prop_id) { case PROP_ENABLED: priv->enabled = g_value_get_boolean (value); break; case PROP_ID: fwupd_remote_set_id (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; } } static void fwupd_remote_class_init (FwupdRemoteClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fwupd_remote_finalize; object_class->get_property = fwupd_remote_get_property; object_class->set_property = fwupd_remote_set_property; /** * FwupdRemote:id: * * The remote ID. * * Since: 0.9.3 */ pspec = g_param_spec_string ("id", NULL, NULL, NULL, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_ID, pspec); /** * FwupdRemote:enabled: * * If the remote is enabled and should be used. * * Since: 0.9.3 */ pspec = g_param_spec_boolean ("enabled", NULL, NULL, FALSE, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_ENABLED, pspec); } static void fwupd_remote_init (FwupdRemote *self) { } static void fwupd_remote_finalize (GObject *obj) { FwupdRemote *self = FWUPD_REMOTE (obj); FwupdRemotePrivate *priv = GET_PRIVATE (self); g_free (priv->id); g_free (priv->metadata_uri); g_free (priv->metadata_uri_sig); g_free (priv->firmware_base_uri); g_free (priv->report_uri); g_free (priv->username); g_free (priv->password); g_free (priv->title); g_free (priv->checksum); g_free (priv->filename_cache); g_free (priv->filename_cache_sig); g_free (priv->filename_source); g_strfreev (priv->order_after); g_strfreev (priv->order_before); G_OBJECT_CLASS (fwupd_remote_parent_class)->finalize (obj); } /** * fwupd_remote_from_variant: * @data: a #GVariant * * Creates a new remote using packed data. * * Returns: (transfer full): a new #FwupdRemote, or %NULL if @data was invalid * * Since: 1.0.0 **/ FwupdRemote * fwupd_remote_from_variant (GVariant *data) { FwupdRemote *rel = NULL; const gchar *type_string; g_autoptr(GVariantIter) iter = NULL; type_string = g_variant_get_type_string (data); if (g_strcmp0 (type_string, "(a{sv})") == 0) { rel = fwupd_remote_new (); g_variant_get (data, "(a{sv})", &iter); fwupd_remote_set_from_variant_iter (rel, iter); fwupd_remote_set_from_variant_iter (rel, iter); } else if (g_strcmp0 (type_string, "a{sv}") == 0) { rel = fwupd_remote_new (); g_variant_get (data, "a{sv}", &iter); fwupd_remote_set_from_variant_iter (rel, iter); } else { g_warning ("type %s not known", type_string); } return rel; } /** * fwupd_remote_new: * * Creates a new fwupd remote. * * Returns: a new #FwupdRemote * * Since: 0.9.3 **/ FwupdRemote * fwupd_remote_new (void) { FwupdRemote *self; self = g_object_new (FWUPD_TYPE_REMOTE, NULL); return FWUPD_REMOTE (self); } fwupd-1.0.6/libfwupd/fwupd-remote.h000066400000000000000000000057551325145456600172750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017-2018 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FWUPD_REMOTE_H #define __FWUPD_REMOTE_H #include "fwupd-enums.h" G_BEGIN_DECLS #define FWUPD_TYPE_REMOTE (fwupd_remote_get_type ()) G_DECLARE_DERIVABLE_TYPE (FwupdRemote, fwupd_remote, FWUPD, REMOTE, GObject) struct _FwupdRemoteClass { GObjectClass parent_class; /*< private >*/ void (*_fwupd_reserved1) (void); void (*_fwupd_reserved2) (void); void (*_fwupd_reserved3) (void); void (*_fwupd_reserved4) (void); void (*_fwupd_reserved5) (void); void (*_fwupd_reserved6) (void); void (*_fwupd_reserved7) (void); }; typedef enum { FWUPD_REMOTE_KIND_UNKNOWN, FWUPD_REMOTE_KIND_DOWNLOAD, FWUPD_REMOTE_KIND_LOCAL, /*< private >*/ FWUPD_REMOTE_KIND_LAST } FwupdRemoteKind; FwupdRemoteKind fwupd_remote_kind_from_string (const gchar *kind); const gchar *fwupd_remote_kind_to_string (FwupdRemoteKind kind); FwupdRemote *fwupd_remote_new (void); const gchar *fwupd_remote_get_id (FwupdRemote *self); const gchar *fwupd_remote_get_title (FwupdRemote *self); const gchar *fwupd_remote_get_checksum (FwupdRemote *self); const gchar *fwupd_remote_get_username (FwupdRemote *self); const gchar *fwupd_remote_get_password (FwupdRemote *self); const gchar *fwupd_remote_get_filename_cache (FwupdRemote *self); const gchar *fwupd_remote_get_filename_cache_sig (FwupdRemote *self); const gchar *fwupd_remote_get_filename_source (FwupdRemote *self); const gchar *fwupd_remote_get_firmware_base_uri (FwupdRemote *self); const gchar *fwupd_remote_get_report_uri (FwupdRemote *self); const gchar *fwupd_remote_get_metadata_uri (FwupdRemote *self); const gchar *fwupd_remote_get_metadata_uri_sig (FwupdRemote *self); gboolean fwupd_remote_get_enabled (FwupdRemote *self); gint fwupd_remote_get_priority (FwupdRemote *self); guint64 fwupd_remote_get_age (FwupdRemote *self); FwupdRemoteKind fwupd_remote_get_kind (FwupdRemote *self); FwupdKeyringKind fwupd_remote_get_keyring_kind (FwupdRemote *self); gchar *fwupd_remote_build_firmware_uri (FwupdRemote *self, const gchar *url, GError **error); G_END_DECLS #endif /* __FWUPD_REMOTE_H */ fwupd-1.0.6/libfwupd/fwupd-self-test.c000066400000000000000000000367531325145456600177050ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "fwupd-client.h" #include "fwupd-common.h" #include "fwupd-enums.h" #include "fwupd-error.h" #include "fwupd-release-private.h" #include "fwupd-remote-private.h" static gboolean fu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error) { g_autofree gchar *output = NULL; /* exactly the same */ if (g_strcmp0 (txt1, txt2) == 0) return TRUE; /* matches a pattern */ if (fnmatch (txt2, txt1, FNM_NOESCAPE) == 0) return TRUE; /* save temp files and diff them */ if (!g_file_set_contents ("/tmp/a", txt1, -1, error)) return FALSE; if (!g_file_set_contents ("/tmp/b", txt2, -1, error)) return FALSE; if (!g_spawn_command_line_sync ("diff -urNp /tmp/b /tmp/a", &output, NULL, NULL, error)) return FALSE; /* just output the diff */ g_set_error_literal (error, 1, 0, output); return FALSE; } static void fwupd_enums_func (void) { /* enums */ for (guint i = 0; i < FWUPD_ERROR_LAST; i++) { const gchar *tmp = fwupd_error_to_string (i); g_assert_cmpstr (tmp, !=, NULL); g_assert_cmpint (fwupd_error_from_string (tmp), ==, i); } for (guint i = 0; i < FWUPD_STATUS_LAST; i++) { const gchar *tmp = fwupd_status_to_string (i); g_assert_cmpstr (tmp, !=, NULL); g_assert_cmpint (fwupd_status_from_string (tmp), ==, i); } for (guint i = 0; i < FWUPD_UPDATE_STATE_LAST; i++) { const gchar *tmp = fwupd_update_state_to_string (i); g_assert_cmpstr (tmp, !=, NULL); g_assert_cmpint (fwupd_update_state_from_string (tmp), ==, i); } for (guint i = 0; i < FWUPD_TRUST_FLAG_LAST; i++) { const gchar *tmp = fwupd_trust_flag_to_string (i); g_assert_cmpstr (tmp, !=, NULL); g_assert_cmpint (fwupd_trust_flag_from_string (tmp), ==, i); } /* bitfield */ for (guint64 i = 1; i < FWUPD_DEVICE_FLAG_UNKNOWN; i *= 2) { const gchar *tmp = fwupd_device_flag_to_string (i); if (tmp == NULL) break; g_assert_cmpint (fwupd_device_flag_from_string (tmp), ==, i); } } static void fwupd_remote_download_func (void) { gboolean ret; g_autofree gchar *fn = NULL; g_autoptr(FwupdRemote) remote = NULL; g_autoptr(GError) error = NULL; remote = fwupd_remote_new (); fn = g_build_filename (FU_SELF_TEST_REMOTES_DIR, "remotes.d", "lvfs.conf", NULL); ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (fwupd_remote_get_kind (remote), ==, FWUPD_REMOTE_KIND_DOWNLOAD); g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_GPG); g_assert_cmpint (fwupd_remote_get_priority (remote), ==, 0); g_assert (fwupd_remote_get_enabled (remote)); g_assert (fwupd_remote_get_metadata_uri (remote) != NULL); g_assert (fwupd_remote_get_metadata_uri_sig (remote) != NULL); g_assert_cmpstr (fwupd_remote_get_title (remote), ==, "Linux Vendor Firmware Service"); g_assert_cmpstr (fwupd_remote_get_report_uri (remote), ==, "https://fwupd.org/lvfs/firmware/report"); g_assert_cmpstr (fwupd_remote_get_filename_cache (remote), ==, LOCALSTATEDIR "/lib/fwupd/remotes.d/lvfs/metadata.xml.gz"); g_assert_cmpstr (fwupd_remote_get_filename_cache_sig (remote), ==, LOCALSTATEDIR "/lib/fwupd/remotes.d/lvfs/metadata.xml.gz.asc"); } /* verify we used the FirmwareBaseURI just for firmware */ static void fwupd_remote_baseuri_func (void) { gboolean ret; g_autofree gchar *firmware_uri = NULL; g_autofree gchar *fn = NULL; g_autoptr(FwupdRemote) remote = NULL; g_autoptr(GError) error = NULL; remote = fwupd_remote_new (); fn = g_build_filename (TESTDATADIR, "tests", "firmware-base-uri.conf", NULL); ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (fwupd_remote_get_kind (remote), ==, FWUPD_REMOTE_KIND_DOWNLOAD); g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_GPG); g_assert_cmpint (fwupd_remote_get_priority (remote), ==, 0); g_assert (fwupd_remote_get_enabled (remote)); g_assert_cmpstr (fwupd_remote_get_checksum (remote), ==, NULL); g_assert_cmpstr (fwupd_remote_get_metadata_uri (remote), ==, "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz"); g_assert_cmpstr (fwupd_remote_get_metadata_uri_sig (remote), ==, "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz.asc"); firmware_uri = fwupd_remote_build_firmware_uri (remote, "http://bbc.co.uk/firmware.cab", &error); g_assert_no_error (error); g_assert_cmpstr (firmware_uri, ==, "https://my.fancy.cdn/firmware.cab"); } /* verify we used the metadata path for firmware */ static void fwupd_remote_nopath_func (void) { gboolean ret; g_autofree gchar *firmware_uri = NULL; g_autofree gchar *fn = NULL; g_autoptr(FwupdRemote) remote = NULL; g_autoptr(GError) error = NULL; remote = fwupd_remote_new (); fn = g_build_filename (TESTDATADIR, "tests", "firmware-nopath.conf", NULL); ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (fwupd_remote_get_kind (remote), ==, FWUPD_REMOTE_KIND_DOWNLOAD); g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_GPG); g_assert_cmpint (fwupd_remote_get_priority (remote), ==, 0); g_assert (fwupd_remote_get_enabled (remote)); g_assert_cmpstr (fwupd_remote_get_checksum (remote), ==, NULL); g_assert_cmpstr (fwupd_remote_get_metadata_uri (remote), ==, "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz"); g_assert_cmpstr (fwupd_remote_get_metadata_uri_sig (remote), ==, "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.xml.gz.asc"); firmware_uri = fwupd_remote_build_firmware_uri (remote, "firmware.cab", &error); g_assert_no_error (error); g_assert_cmpstr (firmware_uri, ==, "https://s3.amazonaws.com/lvfsbucket/downloads/firmware.cab"); } static void fwupd_remote_local_func (void) { gboolean ret; g_autofree gchar *fn = NULL; g_autoptr(FwupdRemote) remote = NULL; g_autoptr(GError) error = NULL; remote = fwupd_remote_new (); fn = g_build_filename (FU_SELF_TEST_REMOTES_DIR, "remotes.d", "fwupd.conf", NULL); ret = fwupd_remote_load_from_filename (remote, fn, NULL, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (fwupd_remote_get_kind (remote), ==, FWUPD_REMOTE_KIND_LOCAL); g_assert_cmpint (fwupd_remote_get_keyring_kind (remote), ==, FWUPD_KEYRING_KIND_NONE); g_assert (fwupd_remote_get_enabled (remote)); g_assert (fwupd_remote_get_metadata_uri (remote) == NULL); g_assert (fwupd_remote_get_metadata_uri_sig (remote) == NULL); g_assert (fwupd_remote_get_report_uri (remote) == NULL); g_assert_cmpstr (fwupd_remote_get_title (remote), ==, "Core"); g_assert_cmpstr (fwupd_remote_get_filename_cache (remote), ==, "@datadir@/fwupd/remotes.d/fwupd/metadata.xml"); g_assert_cmpstr (fwupd_remote_get_filename_cache_sig (remote), ==, NULL); g_assert_cmpstr (fwupd_remote_get_checksum (remote), ==, NULL); } static void fwupd_release_func (void) { g_autoptr(FwupdRelease) release1 = NULL; g_autoptr(FwupdRelease) release2 = NULL; g_autoptr(GVariant) data = NULL; release1 = fwupd_release_new (); fwupd_release_add_metadata_item (release1, "foo", "bar"); fwupd_release_add_metadata_item (release1, "baz", "bam"); data = fwupd_release_to_variant (release1); release2 = fwupd_release_from_variant (data); g_assert_cmpstr (fwupd_release_get_metadata_item (release2, "foo"), ==, "bar"); g_assert_cmpstr (fwupd_release_get_metadata_item (release2, "baz"), ==, "bam"); } static void fwupd_device_func (void) { gboolean ret; g_autofree gchar *str = NULL; g_autoptr(FwupdDevice) dev = NULL; g_autoptr(FwupdRelease) rel = NULL; g_autoptr(GError) error = NULL; /* create dummy object */ dev = fwupd_device_new (); fwupd_device_add_checksum (dev, "beefdead"); fwupd_device_set_created (dev, 1); fwupd_device_set_flags (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fwupd_device_set_id (dev, "USB:foo"); fwupd_device_set_modified (dev, 60 * 60 * 24); fwupd_device_set_name (dev, "ColorHug2"); fwupd_device_add_guid (dev, "2082b5e0-7a64-478a-b1b2-e3404fab6dad"); fwupd_device_add_guid (dev, "00000000-0000-0000-0000-000000000000"); fwupd_device_add_icon (dev, "input-gaming"); fwupd_device_add_icon (dev, "input-mouse"); fwupd_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC); rel = fwupd_release_new (); fwupd_release_set_trust_flags (rel, FWUPD_TRUST_FLAG_PAYLOAD); fwupd_release_add_checksum (rel, "deadbeef"); fwupd_release_set_description (rel, "

Hi there!

"); fwupd_release_set_filename (rel, "firmware.bin"); fwupd_release_set_appstream_id (rel, "org.dave.ColorHug.firmware"); fwupd_release_set_size (rel, 1024); fwupd_release_set_uri (rel, "http://foo.com"); fwupd_release_set_version (rel, "1.2.3"); fwupd_device_add_release (dev, rel); str = fwupd_device_to_string (dev); g_print ("\n%s", str); /* check GUIDs */ g_assert (fwupd_device_has_guid (dev, "2082b5e0-7a64-478a-b1b2-e3404fab6dad")); g_assert (fwupd_device_has_guid (dev, "00000000-0000-0000-0000-000000000000")); g_assert (!fwupd_device_has_guid (dev, "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")); ret = fu_test_compare_lines (str, "ColorHug2\n" " DeviceId: USB:foo\n" " Guid: 2082b5e0-7a64-478a-b1b2-e3404fab6dad\n" " Guid: 00000000-0000-0000-0000-000000000000\n" " Flags: updatable|require-ac\n" " Checksum: SHA1(beefdead)\n" " Icon: input-gaming,input-mouse\n" " Created: 1970-01-01\n" " Modified: 1970-01-02\n" " \n" " [Release]\n" " AppstreamId: org.dave.ColorHug.firmware\n" " Description:

Hi there!

\n" " Version: 1.2.3\n" " Filename: firmware.bin\n" " Checksum: SHA1(deadbeef)\n" " Size: 1.0 kB\n" " Uri: http://foo.com\n" " TrustFlags: payload\n", &error); g_assert_no_error (error); g_assert (ret); } static void fwupd_client_devices_func (void) { FwupdDevice *dev; gboolean ret; g_autoptr(FwupdClient) client = NULL; g_autoptr(GPtrArray) array = NULL; g_autoptr(GError) error = NULL; client = fwupd_client_new (); /* only run if running fwupd is new enough */ ret = fwupd_client_connect (client, NULL, &error); g_assert_no_error (error); g_assert_true (ret); if (fwupd_client_get_daemon_version (client) == NULL) { g_test_skip ("no enabled fwupd daemon"); return; } if (as_utils_vercmp (fwupd_client_get_daemon_version (client), "1.0.0") < 0) { g_test_skip ("running fwupd is too old"); return; } array = fwupd_client_get_devices (client, NULL, &error); if (array == NULL && g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) { g_test_skip ("no available fwupd devices"); return; } if (array == NULL && g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_test_skip ("no available fwupd daemon"); return; } g_assert_no_error (error); g_assert (array != NULL); g_assert_cmpint (array->len, >, 0); /* check device */ dev = g_ptr_array_index (array, 0); g_assert (FWUPD_IS_DEVICE (dev)); g_assert_cmpstr (fwupd_device_get_guid_default (dev), !=, NULL); g_assert_cmpstr (fwupd_device_get_id (dev), !=, NULL); } static void fwupd_client_remotes_func (void) { gboolean ret; g_autoptr(FwupdClient) client = NULL; g_autoptr(FwupdRemote) remote2 = NULL; g_autoptr(FwupdRemote) remote3 = NULL; g_autoptr(GError) error = NULL; g_autoptr(GPtrArray) array = NULL; g_setenv ("FU_SELF_TEST_REMOTES_DIR", FU_SELF_TEST_REMOTES_DIR, TRUE); client = fwupd_client_new (); /* only run if running fwupd is new enough */ ret = fwupd_client_connect (client, NULL, &error); g_assert_no_error (error); g_assert_true (ret); if (fwupd_client_get_daemon_version (client) == NULL) { g_test_skip ("no enabled fwupd daemon"); return; } if (as_utils_vercmp (fwupd_client_get_daemon_version (client), "1.0.0") < 0) { g_test_skip ("running fwupd is too old"); return; } array = fwupd_client_get_remotes (client, NULL, &error); if (array == NULL && g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) { g_test_skip ("no available fwupd remotes"); return; } if (array == NULL && g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_test_skip ("no available fwupd daemon"); return; } g_assert_no_error (error); g_assert (array != NULL); g_assert_cmpint (array->len, >, 0); /* check we can find the right thing */ remote2 = fwupd_client_get_remote_by_id (client, "lvfs", NULL, &error); g_assert_no_error (error); g_assert (remote2 != NULL); g_assert_cmpstr (fwupd_remote_get_id (remote2), ==, "lvfs"); g_assert (fwupd_remote_get_enabled (remote2)); g_assert (fwupd_remote_get_metadata_uri (remote2) != NULL); /* check we set an error when unfound */ remote3 = fwupd_client_get_remote_by_id (client, "XXXX", NULL, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND); g_assert (remote3 == NULL); } static gboolean fwupd_has_system_bus (void) { g_autoptr(GDBusConnection) conn = NULL; conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); if (conn != NULL) return TRUE; g_debug ("D-Bus system bus unavailable, skipping tests."); return FALSE; } static void fwupd_common_machine_hash_func (void) { g_autofree gchar *mhash1 = NULL; g_autofree gchar *mhash2 = NULL; g_autoptr(GError) error = NULL; if (!g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS)) { g_test_skip ("Missing /etc/machine-id"); return; } mhash1 = fwupd_build_machine_id ("salt1", &error); g_assert_no_error (error); g_assert_cmpstr (mhash1, !=, NULL); mhash2 = fwupd_build_machine_id ("salt2", &error); g_assert_no_error (error); g_assert_cmpstr (mhash2, !=, NULL); g_assert_cmpstr (mhash2, !=, mhash1); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); /* tests go here */ g_test_add_func ("/fwupd/enums", fwupd_enums_func); g_test_add_func ("/fwupd/common{machine-hash}", fwupd_common_machine_hash_func); g_test_add_func ("/fwupd/release", fwupd_release_func); g_test_add_func ("/fwupd/device", fwupd_device_func); g_test_add_func ("/fwupd/remote{download}", fwupd_remote_download_func); g_test_add_func ("/fwupd/remote{base-uri}", fwupd_remote_baseuri_func); g_test_add_func ("/fwupd/remote{no-path}", fwupd_remote_nopath_func); g_test_add_func ("/fwupd/remote{local}", fwupd_remote_local_func); if (fwupd_has_system_bus ()) { g_test_add_func ("/fwupd/client{remotes}", fwupd_client_remotes_func); g_test_add_func ("/fwupd/client{devices}", fwupd_client_devices_func); } return g_test_run (); } fwupd-1.0.6/libfwupd/fwupd-version.h.in000066400000000000000000000044771325145456600200740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:fwupd-version * @short_description: Obtains the version for the installed fwupd * * These compile time macros allow the user to enable parts of client code * depending on the version of libfwupd installed. */ #if !defined (__FWUPD_H_INSIDE__) && !defined (FWUPD_COMPILATION) #error "Only can be included directly." #endif #ifndef __FWUPD_VERSION_H #define __FWUPD_VERSION_H /** * FWUPD_MAJOR_VERSION: * * The compile-time major version */ #ifndef FWUPD_MAJOR_VERSION #define FWUPD_MAJOR_VERSION (@FWUPD_MAJOR_VERSION@) #endif /** * FWUPD_MINOR_VERSION: * * The compile-time minor version */ #ifndef FWUPD_MINOR_VERSION #define FWUPD_MINOR_VERSION (@FWUPD_MINOR_VERSION@) #endif /** * FWUPD_MICRO_VERSION: * * The compile-time micro version */ #ifndef FWUPD_MICRO_VERSION #define FWUPD_MICRO_VERSION (@FWUPD_MICRO_VERSION@) #endif /** * FWUPD_CHECK_VERSION: * @major: Major version number * @minor: Minor version number * @micro: Micro version number * * Check whether a fwupd version equal to or greater than * major.minor.micro. */ #define FWUPD_CHECK_VERSION(major,minor,micro) \ (FWUPD_MAJOR_VERSION > (major) || \ (FWUPD_MAJOR_VERSION == (major) && FWUPD_MINOR_VERSION > (minor)) || \ (FWUPD_MAJOR_VERSION == (major) && FWUPD_MINOR_VERSION == (minor) && \ FWUPD_MICRO_VERSION >= (micro))) #endif /* __FWUPD_VERSION_H */ fwupd-1.0.6/libfwupd/fwupd.h000066400000000000000000000027611325145456600157760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:fwupd * @short_description: Helper objects for accessing fwupd */ #ifndef __FWUPD_H__ #define __FWUPD_H__ #define __FWUPD_H_INSIDE__ #include #include #include #include #include #include #include #include #ifndef FWUPD_DISABLE_DEPRECATED #include #endif #undef __FWUPD_H_INSIDE__ #endif /* __FWUPD_H__ */ fwupd-1.0.6/libfwupd/fwupd.map000066400000000000000000000134501325145456600163210ustar00rootroot00000000000000# generated automatically, do not edit! LIBFWUPD_0.1.1 { global: fwupd_error_quark; fwupd_status_from_string; fwupd_status_to_string; local: *; }; LIBFWUPD_0.7.0 { global: fwupd_client_clear_results; fwupd_client_get_results; fwupd_client_get_type; fwupd_client_install; fwupd_client_new; fwupd_client_unlock; fwupd_client_verify; fwupd_device_flag_from_string; fwupd_device_flag_to_string; fwupd_error_from_string; fwupd_error_to_string; fwupd_trust_flag_from_string; fwupd_trust_flag_to_string; fwupd_update_state_from_string; fwupd_update_state_to_string; local: *; } LIBFWUPD_0.1.1; LIBFWUPD_0.7.1 { global: fwupd_client_connect; local: *; } LIBFWUPD_0.7.0; LIBFWUPD_0.7.3 { global: fwupd_client_get_percentage; fwupd_client_get_status; local: *; } LIBFWUPD_0.7.1; LIBFWUPD_0.8.0 { global: fwupd_client_verify_update; local: *; } LIBFWUPD_0.7.3; LIBFWUPD_0.9.2 { global: fwupd_client_get_devices; local: *; } LIBFWUPD_0.8.0; LIBFWUPD_0.9.3 { global: fwupd_checksum_format_for_display; fwupd_checksum_guess_kind; fwupd_client_get_device_by_id; fwupd_client_get_releases; fwupd_client_get_remote_by_id; fwupd_client_get_remotes; fwupd_device_add_checksum; fwupd_device_add_flag; fwupd_device_add_guid; fwupd_device_get_checksums; fwupd_device_get_created; fwupd_device_get_description; fwupd_device_get_flags; fwupd_device_get_flashes_left; fwupd_device_get_guid_default; fwupd_device_get_guids; fwupd_device_get_id; fwupd_device_get_modified; fwupd_device_get_name; fwupd_device_get_summary; fwupd_device_get_type; fwupd_device_get_vendor; fwupd_device_get_version; fwupd_device_get_version_bootloader; fwupd_device_get_version_lowest; fwupd_device_has_flag; fwupd_device_has_guid; fwupd_device_new; fwupd_device_remove_flag; fwupd_device_set_created; fwupd_device_set_description; fwupd_device_set_flags; fwupd_device_set_flashes_left; fwupd_device_set_id; fwupd_device_set_modified; fwupd_device_set_name; fwupd_device_set_summary; fwupd_device_set_vendor; fwupd_device_set_version; fwupd_device_set_version_bootloader; fwupd_device_set_version_lowest; fwupd_device_to_string; fwupd_release_add_checksum; fwupd_release_get_appstream_id; fwupd_release_get_checksums; fwupd_release_get_description; fwupd_release_get_filename; fwupd_release_get_homepage; fwupd_release_get_license; fwupd_release_get_name; fwupd_release_get_remote_id; fwupd_release_get_size; fwupd_release_get_summary; fwupd_release_get_type; fwupd_release_get_uri; fwupd_release_get_vendor; fwupd_release_get_version; fwupd_release_new; fwupd_release_set_appstream_id; fwupd_release_set_description; fwupd_release_set_filename; fwupd_release_set_homepage; fwupd_release_set_license; fwupd_release_set_name; fwupd_release_set_remote_id; fwupd_release_set_size; fwupd_release_set_summary; fwupd_release_set_uri; fwupd_release_set_vendor; fwupd_release_set_version; fwupd_release_to_string; fwupd_remote_get_enabled; fwupd_remote_get_id; fwupd_remote_get_type; fwupd_remote_load_from_filename; fwupd_remote_new; local: *; } LIBFWUPD_0.9.2; LIBFWUPD_0.9.4 { global: fwupd_checksum_get_best; fwupd_checksum_get_by_kind; fwupd_device_get_vendor_id; fwupd_device_set_vendor_id; local: *; } LIBFWUPD_0.9.3; LIBFWUPD_0.9.5 { global: fwupd_remote_get_age; fwupd_remote_get_order_after; fwupd_remote_get_order_before; fwupd_remote_get_password; fwupd_remote_get_priority; fwupd_remote_get_username; fwupd_remote_set_mtime; fwupd_remote_set_priority; local: *; } LIBFWUPD_0.9.4; LIBFWUPD_0.9.6 { global: fwupd_client_get_daemon_version; fwupd_remote_get_filename_cache; fwupd_remote_get_kind; fwupd_remote_kind_from_string; fwupd_remote_kind_to_string; local: *; } LIBFWUPD_0.9.5; LIBFWUPD_0.9.7 { global: fwupd_keyring_kind_from_string; fwupd_keyring_kind_to_string; fwupd_remote_build_firmware_uri; fwupd_remote_get_filename_cache_sig; fwupd_remote_get_firmware_base_uri; fwupd_remote_get_keyring_kind; fwupd_remote_get_metadata_uri; fwupd_remote_get_metadata_uri_sig; local: *; } LIBFWUPD_0.9.6; LIBFWUPD_0.9.8 { global: fwupd_client_get_downgrades; fwupd_client_get_upgrades; fwupd_client_modify_remote; fwupd_device_add_icon; fwupd_device_add_release; fwupd_device_get_icons; fwupd_device_get_release_default; fwupd_device_get_releases; fwupd_device_get_update_error; fwupd_device_get_update_state; fwupd_device_set_update_error; fwupd_device_set_update_state; fwupd_release_get_trust_flags; fwupd_release_set_trust_flags; fwupd_remote_get_filename_source; fwupd_remote_get_title; local: *; } LIBFWUPD_0.9.7; LIBFWUPD_1.0.0 { global: fwupd_client_get_details; fwupd_client_update_metadata; fwupd_device_from_variant; fwupd_device_get_plugin; fwupd_device_set_plugin; fwupd_device_to_variant; fwupd_release_from_variant; fwupd_release_to_variant; fwupd_remote_from_variant; fwupd_remote_get_checksum; fwupd_remote_to_variant; local: *; } LIBFWUPD_0.9.8; LIBFWUPD_1.0.3 { global: fwupd_build_user_agent; local: *; } LIBFWUPD_1.0.0; LIBFWUPD_1.0.4 { global: fwupd_build_history_report_json; fwupd_build_machine_id; fwupd_client_get_history; fwupd_client_modify_device; fwupd_release_add_metadata; fwupd_release_add_metadata_item; fwupd_release_get_metadata; fwupd_release_get_metadata_item; fwupd_remote_get_report_uri; local: *; } LIBFWUPD_1.0.3; fwupd-1.0.6/libfwupd/generate-version-script.py000077500000000000000000000102151325145456600216250ustar00rootroot00000000000000#!/usr/bin/env python3 # pylint: disable=invalid-name,missing-docstring # # Copyright (C) 2017 Richard Hughes # # Licensed under the GNU General Public License Version 2 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . import sys import xml.etree.ElementTree as ET XMLNS = '{http://www.gtk.org/introspection/core/1.0}' XMLNS_C = '{http://www.gtk.org/introspection/c/1.0}' def usage(return_code): """ print usage and exit with the supplied return code """ if return_code == 0: out = sys.stdout else: out = sys.stderr out.write("usage: %s \n" % sys.argv[0]) sys.exit(return_code) class LdVersionScript: """ Rasterize some text """ def __init__(self, library_name): self.library_name = library_name self.releases = {} def _add_node(self, node): identifier = node.attrib[XMLNS_C + 'identifier'] if 'version' not in node.attrib: print('No version for', identifier) sys.exit(1) return version = node.attrib['version'] if version not in self.releases: self.releases[version] = [] release = self.releases[version] release.append(identifier) return version def import_gir(self, filename): tree = ET.parse(filename) root = tree.getroot() for ns in root.findall(XMLNS + 'namespace'): for node in ns.findall(XMLNS + 'function'): self._add_node(node) for cls in ns.findall(XMLNS + 'class'): # add all class functions for node in cls.findall(XMLNS + 'function'): self._add_node(node) # add the constructor for node in cls.findall(XMLNS + 'constructor'): self._add_node(node) # choose the lowest version method for the _get_type symbol version_lowest = None type_name = cls.attrib['{http://www.gtk.org/introspection/glib/1.0}get-type'] # add all class methods for node in cls.findall(XMLNS + 'method'): version_tmp = self._add_node(node) if version_tmp: if not version_lowest or version_tmp < version_lowest: version_lowest = version_tmp # finally add the get_type symbol if version_lowest: self.releases[version_lowest].append(type_name) def render(self): # get a sorted list of all the versions versions = [] for version in self.releases: versions.append(version) # output the version data to a file verout = '# generated automatically, do not edit!\n' oldversion = None for version in sorted(versions): symbols = sorted(self.releases[version]) verout += '\n%s_%s {\n' % (self.library_name, version) verout += ' global:\n' for symbol in symbols: verout += ' %s;\n' % symbol verout += ' local: *;\n' if oldversion: verout += '} %s_%s;\n' % (self.library_name, oldversion) else: verout += '};\n' oldversion = version return verout if __name__ == '__main__': if {'-?', '--help', '--usage'}.intersection(set(sys.argv)): usage(0) if len(sys.argv) != 4: usage(1) ld = LdVersionScript(library_name=sys.argv[1]) ld.import_gir(sys.argv[2]) open(sys.argv[3], 'w').write(ld.render()) fwupd-1.0.6/libfwupd/meson.build000066400000000000000000000074751325145456600166510ustar00rootroot00000000000000cargs = [ '-DG_LOG_DOMAIN="Fwupd"', ] fwupd_version_h = configure_file( input : 'fwupd-version.h.in', output : 'fwupd-version.h', configuration : conf ) install_headers( 'fwupd.h', subdir : 'fwupd-1', ) install_headers([ 'fwupd-client.h', 'fwupd-common.h', 'fwupd-deprecated.h', 'fwupd-device.h', 'fwupd-enums.h', 'fwupd-error.h', 'fwupd-remote.h', 'fwupd-release.h', fwupd_version_h, ], subdir : 'fwupd-1/libfwupd', ) mapfile = 'fwupd.map' vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile) fwupd = shared_library( 'fwupd', sources : [ 'fwupd-client.c', 'fwupd-common.c', 'fwupd-device.c', 'fwupd-enums.c', 'fwupd-error.c', 'fwupd-release.c', 'fwupd-remote.c', ], soversion : lt_current, version : lt_version, dependencies : [ giounix, soup, libjsonglib, ], c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', ], include_directories : include_directories('..'), link_args : vflag, link_depends : mapfile, install : true ) pkgg = import('pkgconfig') pkgg.generate( libraries : fwupd, requires : [ 'gio-2.0' ], subdirs : 'fwupd-1', version : meson.project_version(), name : 'fwupd', filebase : 'fwupd', description : 'fwupd is a system daemon for installing device firmware', ) if get_option('introspection') gir = gnome.generate_gir(fwupd, sources : [ 'fwupd-client.c', 'fwupd-client.h', 'fwupd-common.c', 'fwupd-common.h', 'fwupd-common-private.h', 'fwupd-device.c', 'fwupd-device.h', 'fwupd-device-private.h', 'fwupd-enums.c', 'fwupd-enums.h', 'fwupd-enums-private.h', 'fwupd-error.c', 'fwupd-error.h', 'fwupd-release.c', 'fwupd-release.h', 'fwupd-release-private.h', 'fwupd-remote.c', 'fwupd-remote.h', 'fwupd-remote-private.h', ], nsversion : '2.0', namespace : 'Fwupd', symbol_prefix : 'fwupd', identifier_prefix : 'Fwupd', export_packages : 'fwupd', extra_args : '--c-include=fwupd.h', # This can be replaced with header : 'fwupd.h' once can depend on Meson 0.43.0 dependencies : [ giounix, soup, ], includes : [ 'Gio-2.0', 'GObject-2.0', 'Soup-2.4', ], install : true ) gnome.generate_vapi('fwupd', sources : gir[0], packages : ['gio-2.0', 'libsoup-2.4'], install : true, ) # Verify the map file is correct -- note we can't actually use the generated # file for two reasons: # # 1. We don't hard depend on GObject Introspection # 2. The map file is required to build the lib that the GIR is built from # # To avoid the circular dep, and to ensure we don't change exported API # accidentaly actually check in a version of the version script to git. mapfile_target = custom_target('mapfile', input: gir[0], output: 'fwupd.map', command: [ join_paths(meson.current_source_dir(), 'generate-version-script.py'), 'LIBFWUPD', '@INPUT@', '@OUTPUT@', ], ) diffcmd = find_program('diff') test('fwupd-exported-api', diffcmd, args : [ '-urNp', join_paths(meson.current_source_dir(), 'fwupd.map'), mapfile_target, ], ) endif if get_option('tests') testdatadir = join_paths(meson.source_root(), 'data') e = executable( 'fwupd-self-test', sources : [ 'fwupd-self-test.c' ], include_directories : [ include_directories('..'), ], dependencies : [ appstream_glib, gio, soup, ], link_with : fwupd, c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', '-DTESTDATADIR="' + testdatadir + '"', '-DFU_SELF_TEST_REMOTES_DIR="' + testdatadir + '"', ], ) test('fwupd-self-test', e) endif fwupd-1.0.6/meson.build000066400000000000000000000211031325145456600150150ustar00rootroot00000000000000project('fwupd', 'c', version : '1.0.6', license : 'LGPL-2.1+', meson_version : '>=0.37.0', default_options : ['warning_level=2', 'c_std=c99'], ) fwupd_version = meson.project_version() varr = fwupd_version.split('.') fwupd_major_version = varr[0] fwupd_minor_version = varr[1] fwupd_micro_version = varr[2] conf = configuration_data() conf.set('FWUPD_MAJOR_VERSION', fwupd_major_version) conf.set('FWUPD_MINOR_VERSION', fwupd_minor_version) conf.set('FWUPD_MICRO_VERSION', fwupd_micro_version) conf.set_quoted('PACKAGE_VERSION', fwupd_version) archiver = find_program('git', required : false) if archiver.found() result = run_command('git', 'describe') if result.returncode() == 0 describe = result.stdout().strip() conf.set_quoted('FWUPD_GIT_DESCRIBE', describe) endif endif # libtool versioning - this applies to libfwupd # # See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details # # - If interfaces have been changed or added, but binary compatibility # has been preserved, change: # CURRENT += 1 # REVISION = 0 # AGE += 1 # - If binary compatibility has been broken (eg removed or changed # interfaces), change: # CURRENT += 1 # REVISION = 0 # AGE = 0 # - If the interface is the same as the previous version, but bugs are # fixed, change: # REVISION += 1 lt_current = '2' lt_revision = '0' lt_age = '0' lt_version = '@0@.@1@.@2@'.format(lt_current, lt_age, lt_revision) # get suported warning flags test_args = [ '-fstack-protector-strong', '-Waggregate-return', '-Wunused', '-Warray-bounds', '-Wcast-align', '-Wclobbered', '-Wdeclaration-after-statement', '-Wduplicated-branches', '-Wduplicated-cond', '-Wempty-body', '-Wformat=2', '-Wformat-nonliteral', '-Wformat-security', '-Wformat-signedness', '-Wignored-qualifiers', '-Wimplicit-function-declaration', '-Wincompatible-pointer-types-discards-qualifiers', '-Winit-self', '-Wlogical-op', '-Wmissing-declarations', '-Wmissing-format-attribute', '-Wmissing-include-dirs', '-Wmissing-noreturn', '-Wmissing-parameter-type', '-Wmissing-prototypes', '-Wnested-externs', '-Wno-error=cpp', '-Wno-discarded-qualifiers', '-Wno-missing-field-initializers', '-Wno-strict-aliasing', '-Wno-suggest-attribute=format', '-Wno-unused-parameter', '-Wnull-dereference', '-Wold-style-definition', '-Woverride-init', '-Wpointer-arith', '-Wredundant-decls', '-Wreturn-type', '-Wshadow', '-Wsign-compare', '-Wstrict-aliasing', '-Wstrict-prototypes', '-Wswitch-default', '-Wtype-limits', '-Wundef', '-Wuninitialized', '-Wunused-but-set-variable', '-Wunused-variable', '-Wwrite-strings' ] cc = meson.get_compiler('c') foreach arg: test_args if cc.has_argument(arg) add_project_arguments(arg, language : 'c') endif endforeach # enable full RELRO where possible # FIXME: until https://github.com/mesonbuild/meson/issues/1140 is fixed global_link_args = [] test_link_args = [ '-Wl,-z,relro', '-Wl,-z,now', ] foreach arg: test_link_args if cc.has_argument(arg) global_link_args += arg endif endforeach add_global_link_arguments( global_link_args, language: 'c' ) # Needed for realpath(), syscall(), cfmakeraw(), etc. add_project_arguments('-D_DEFAULT_SOURCE', language : 'c') # do not use deprecated symbols or defines internally add_project_arguments('-DFWUPD_DISABLE_DEPRECATED', language : 'c') gio = dependency('gio-2.0', version : '>= 2.45.8') gmodule = dependency('gmodule-2.0') giounix = dependency('gio-unix-2.0', version : '>= 2.45.8') polkit = dependency('polkit-gobject-1', version : '>= 0.103') if polkit.version().version_compare('>= 0.114') conf.set('HAVE_POLKIT_0_114', '1') endif gudev = dependency('gudev-1.0') if gudev.version().version_compare('>= 232') conf.set('HAVE_GUDEV_232', '1') endif appstream_glib = dependency('appstream-glib', version : '>= 0.6.13') gusb = dependency('gusb', version : '>= 0.2.9') sqlite = dependency('sqlite3') libarchive = dependency('libarchive') libjsonglib = dependency('json-glib-1.0', version : '>= 1.1.1') if meson.version().version_compare('>0.41.0') valgrind = dependency('valgrind', required: false) else valgrind = dependency('valgrindXXX', required: false) endif soup = dependency('libsoup-2.4', version : '>= 2.51.92') if get_option('pkcs7') gnutls = dependency('gnutls') conf.set('ENABLE_PKCS7', '1') endif if get_option('gpg') gpgme = cc.find_library('gpgme') gpgerror = cc.find_library('gpg-error') conf.set('ENABLE_GPG', '1') endif libm = cc.find_library('m', required: false) udev = dependency('udev') uuid = dependency('uuid') libgcab = dependency('libgcab-1.0') if libgcab.version().version_compare('>= 0.8') conf.set('HAVE_GCAB_0_8', '1') endif if libgcab.version().version_compare('>= 1.0') conf.set('HAVE_GCAB_1_0', '1') endif if get_option('plugin_uefi_labels') cairo = dependency('cairo') fontconfig = cc.find_library('fontconfig') freetype = cc.find_library('freetype') r = run_command('po/test-deps') if r.returncode() != 0 error(r.stdout()) endif endif if valgrind.found() conf.set('HAVE_VALGRIND', '1') endif if get_option('plugin_colorhug') colorhug = dependency('colorhug', version : '>= 1.2.12') conf.set('HAVE_COLORHUG', '1') endif if get_option('plugin_altos') libelf = dependency('libelf') endif if get_option('plugin_uefi') fwup = dependency('fwup', version : '>= 5') if fwup.version().version_compare('>= 11') conf.set('HAVE_FWUP_GET_ESP_MOUNTPOINT', '1') endif if fwup.version().version_compare('>= 10') conf.set('HAVE_FWUP_GET_BGRT_INFO', '1') conf.set('HAVE_FWUP_CUSTOM_ESP', '1') endif efivar = dependency('efivar') conf.set_quoted('EFIVAR_LIBRARY_VERSION', efivar.version()) conf.set_quoted('LIBFWUP_LIBRARY_VERSION', fwup.version()) endif if get_option('plugin_dell') libsmbios_c = dependency('libsmbios_c', version : '>= 2.3.0') efivar = dependency('efivar') fwup = dependency('fwup', version : '>= 5') conf.set('HAVE_DELL', '1') endif if get_option('plugin_synaptics') conf.set('HAVE_SYNAPTICS', '1') endif if get_option('plugin_thunderbolt') umockdev = dependency('umockdev-1.0', required: false) conf.set('HAVE_THUNDERBOLT', '1') endif if get_option('systemd') systemd = dependency('systemd', version : '>= 231') conf.set('HAVE_SYSTEMD' , '1') endif if get_option('consolekit') conf.set('HAVE_CONSOLEKIT' , '1') endif prefix = get_option('prefix') bindir = join_paths(prefix, get_option('bindir')) libdir = join_paths(prefix, get_option('libdir')) datadir = join_paths(prefix, get_option('datadir')) libexecdir = join_paths(prefix, get_option('libexecdir')) sysconfdir = join_paths(prefix, get_option('sysconfdir')) localstatedir = join_paths(prefix, get_option('localstatedir')) mandir = join_paths(prefix, get_option('mandir')) localedir = join_paths(prefix, get_option('localedir')) systemdunitdir = get_option('systemdunitdir') if systemdunitdir == '' and get_option('systemd') systemdunitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir') endif udevdir = get_option('udevdir') if udevdir == '' udevdir = udev.get_pkgconfig_variable('udevdir') endif gnome = import('gnome') i18n = import('i18n') plugin_dir = join_paths(libdir, 'fwupd-plugins-3') conf.set_quoted('BINDIR', bindir) conf.set_quoted('LIBEXECDIR', libexecdir) conf.set_quoted('GETTEXT_PACKAGE', meson.project_name()) conf.set_quoted('PACKAGE_NAME', meson.project_name()) conf.set_quoted('VERSION', meson.project_version()) conf.set_quoted('LOCALEDIR', localedir) configure_file( output : 'config.h', configuration : conf ) default_sysconfdir = get_option('sysconfdir') if default_sysconfdir == 'etc' message('sysconfdir of etc makes no sense, using /etc') default_sysconfdir = '/etc' endif plugin_deps = [] plugin_deps += appstream_glib plugin_deps += gio plugin_deps += giounix plugin_deps += gmodule plugin_deps += gusb plugin_deps += soup plugin_deps += libarchive subdir('data') subdir('docs') subdir('libfwupd') subdir('po') subdir('policy') subdir('src') subdir('plugins') subdir('contrib') if meson.version().version_compare('<0.41.0') if archiver.found() run_target('dist', # git config tar.tar.xz.command "xz -c" command: [ 'git', 'archive', '--prefix=' + meson.project_name() + '-' + meson.project_version() + '/', 'HEAD', '--format=tar.xz', '--output', meson.project_name() + '-' + meson.project_version() + '.tar.xz' ] ) else message('git not found, you will not be able to run `ninja dist`') endif endif if get_option('systemd') meson.add_install_script('meson_post_install.sh', systemdunitdir, localstatedir) endif fwupd-1.0.6/meson_options.txt000066400000000000000000000037421325145456600163210ustar00rootroot00000000000000option('bootdir', type : 'string', value : '/boot/efi', description : 'Directory for EFI system partition') option('consolekit', type : 'boolean', value : true, description : 'enable ConsoleKit support') option('gpg', type : 'boolean', value : true, description : 'enable the GPG verification support') option('gtkdoc', type : 'boolean', value : true, description : 'enable developer documentation') option('introspection', type : 'boolean', value : true, description : 'generate GObject Introspection data') option('lvfs', type : 'boolean', value : true, description : 'enable LVFS remotes') option('man', type : 'boolean', value : true, description : 'enable man pages') option('pkcs7', type : 'boolean', value : true, description : 'enable the PKCS7 verification support') option('plugin_altos', type : 'boolean', value : true, description : 'enable altos support') option('plugin_amt', type : 'boolean', value : true, description : 'enable Intel AMT support') option('plugin_colorhug', type : 'boolean', value : true, description : 'enable ColorHug support') option('plugin_dell', type : 'boolean', value : true, description : 'enable Dell-specific support') option('plugin_dummy', type : 'boolean', value : false, description : 'enable the dummy device') option('plugin_synaptics', type: 'boolean', value: true, description : 'enable Synaptics MST hub support') option('plugin_thunderbolt', type : 'boolean', value : true, description : 'enable Thunderbolt support') option('plugin_uefi_labels', type : 'boolean', value : true, description : 'enable UEFI labels support') option('plugin_uefi', type : 'boolean', value : true, description : 'enable UEFI support') option('systemd', type : 'boolean', value : true, description : 'enable systemd support') option('systemdunitdir', type: 'string', value: '', description: 'Directory for systemd units') option('tests', type : 'boolean', value : true, description : 'enable tests') option('udevdir', type: 'string', value: '', description: 'Directory for udev rules') fwupd-1.0.6/meson_post_install.sh000077500000000000000000000007621325145456600171360ustar00rootroot00000000000000#!/bin/sh if [ -z $MESON_INSTALL_PREFIX ]; then echo 'This is meant to be ran from Meson only!' exit 1 fi SYSTEMDUNITDIR=$1 LOCALSTATEDIR=$2 #if [ -z $DESTDIR ]; then echo 'Updating systemd deps' mkdir -p ${DESTDIR}${SYSTEMDUNITDIR}/system-update.target.wants ln -sf ../fwupd-offline-update.service ${DESTDIR}${SYSTEMDUNITDIR}/system-update.target.wants/fwupd-offline-update.service echo 'Creating stateful directory' mkdir -p ${DESTDIR}${LOCALSTATEDIR}/lib/fwupd #fi fwupd-1.0.6/plugins/000077500000000000000000000000001325145456600143375ustar00rootroot00000000000000fwupd-1.0.6/plugins/README.md000066400000000000000000000015621325145456600156220ustar00rootroot00000000000000Adding a new plugin ------------------- An extensible architecture allows for providing new plugin types (for reading and writing different firmware) as well as ways quirk their behavior. You can find more information about the architecture in the developers section of the [fwupd website](http://www.fwupd.org). If you have a firmware specification and would like to see support in this project, please file an issue and share the spec. Patches are also welcome. Plugin interaction ------------------ Some plugins may be able to influence the behavior of other plugins. This includes things like one plugin turning on a device, or providing missing metadata to another plugin. The ABI for these interactions is defined in: https://github.com/hughsie/fwupd/blob/master/src/fu-device-metadata.h All interactions between plugins should have the interface defined in that file. fwupd-1.0.6/plugins/altos/000077500000000000000000000000001325145456600154615ustar00rootroot00000000000000fwupd-1.0.6/plugins/altos/README.md000066400000000000000000000026061325145456600167440ustar00rootroot00000000000000Altos Support ============= Introduction ------------ Altos is a 8051 operating system for Altus-Metrum projects. The ChaosKey is a hardware random number generator that attaches via USB. When the ChaosKey when inserted it appears as a device handled by the kernel with VID 0x1d50 and PID 0x60c6. If pins 1 and 5 are shorted as the device is connected then the bootloader is run, which presents VID 0xfffe and PID 0x000a. The bootloader communication is not handled in the kernel, and a tty device is created so userspace can communicate with the hardware. Commands the bootloader accept are as follows: ### List Information Command: `l\n` Several lines of text about the device are transferred to the host, e.g. altos-loader manufacturer altusmetrum.org product AltosFlash flash-range 08001000 08008000 software-version 1.6.8 There doesn't appear to be any kind of end-of-message signal. ### Read Flash Command: `R $addr\n` where `$addr` is a memory address `0x8001000->0x8008000`. 256 bytes of raw data are then transferred to the host. ### Write Flash Command: `W $addr\n` where `$addr` is a memory address `0x8001000->0x8008000`. 256 bytes of raw data are then transferred to the device. ### Application Mode Command: `v\n` The device will reboot into application mode. This is typically performed after flashing firmware completes successfully. fwupd-1.0.6/plugins/altos/data/000077500000000000000000000000001325145456600163725ustar00rootroot00000000000000fwupd-1.0.6/plugins/altos/data/lsusb-bootloader.txt000066400000000000000000000056651325145456600224270ustar00rootroot00000000000000Bus 001 Device 037: ID fffe:000a Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 2 Communications bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0xfffe idProduct 0x000a bcdDevice 1.00 iManufacturer 1 altusmetrum.org iProduct 2 AltosFlash iSerial 3 000001 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 67 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 2 Communications bInterfaceSubClass 2 Abstract (modem) bInterfaceProtocol 1 AT-commands (v.25ter) iInterface 0 CDC Header: bcdCDC 1.10 CDC Call Management: bmCapabilities 0x01 call management bDataInterface 1 CDC ACM: bmCapabilities 0x02 line coding and serial state CDC Union: bMasterInterface 0 bSlaveInterface 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 255 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 10 CDC Data bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/altos/data/lsusb-runtime.txt000066400000000000000000000037001325145456600217440ustar00rootroot00000000000000Bus 001 Device 036: ID 1d50:60c6 OpenMoko, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x1d50 OpenMoko, Inc. idProduct 0x60c6 bcdDevice 1.00 iManufacturer 1 altusmetrum.org iProduct 2 ChaosKey-hw-1.0-sw-1.6.7 iSerial 3 001b002f5346430b20333632 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x86 EP 6 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/altos/fu-altos-device.c000066400000000000000000000513301325145456600206160ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include #include #include "fu-altos-device.h" #include "fu-altos-firmware.h" typedef struct { FuAltosDeviceKind kind; guint32 serial[9]; gchar *guid; gchar *tty; gchar *version; guint64 addr_base; guint64 addr_bound; struct termios tty_termios; gint tty_fd; } FuAltosDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FuAltosDevice, fu_altos_device, FU_TYPE_USB_DEVICE) #define GET_PRIVATE(o) (fu_altos_device_get_instance_private (o)) #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) #endif /** * fu_altos_device_kind_from_string: * @kind: the string. * * Converts the text representation to an enumerated value. * * Returns: (transfer full): a #FuAltosDeviceKind, or %FU_ALTOS_DEVICE_KIND_UNKNOWN for unknown. * * Since: 0.1.0 **/ FuAltosDeviceKind fu_altos_device_kind_from_string (const gchar *kind) { if (g_strcmp0 (kind, "BOOTLOADER") == 0) return FU_ALTOS_DEVICE_KIND_BOOTLOADER; if (g_strcmp0 (kind, "CHAOSKEY") == 0) return FU_ALTOS_DEVICE_KIND_CHAOSKEY; return FU_ALTOS_DEVICE_KIND_UNKNOWN; } /** * fu_altos_device_kind_to_string: * @kind: the #FuAltosDeviceKind. * * Converts the enumerated value to an text representation. * * Returns: string version of @kind * * Since: 0.1.0 **/ const gchar * fu_altos_device_kind_to_string (FuAltosDeviceKind kind) { if (kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER) return "BOOTLOADER"; if (kind == FU_ALTOS_DEVICE_KIND_CHAOSKEY) return "CHAOSKEY"; return NULL; } static void fu_altos_device_finalize (GObject *object) { FuAltosDevice *device = FU_ALTOS_DEVICE (object); FuAltosDevicePrivate *priv = GET_PRIVATE (device); g_free (priv->guid); g_free (priv->tty); g_free (priv->version); G_OBJECT_CLASS (fu_altos_device_parent_class)->finalize (object); } static void fu_altos_device_init (FuAltosDevice *device) { } static void fu_altos_device_class_init (FuAltosDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fu_altos_device_finalize; } FuAltosDeviceKind fu_altos_device_get_kind (FuAltosDevice *device) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); return priv->kind; } static gboolean fu_altos_device_find_tty (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GList) devices = NULL; g_autoptr(GUdevClient) gudev_client = g_udev_client_new (NULL); /* find all tty devices */ devices = g_udev_client_query_by_subsystem (gudev_client, "tty"); for (GList *l = devices; l != NULL; l = l->next) { GUdevDevice *dev = G_UDEV_DEVICE (l->data); /* get the tty device */ const gchar *dev_file = g_udev_device_get_device_file (dev); if (dev_file == NULL) continue; /* get grandparent */ dev = g_udev_device_get_parent (dev); if (dev == NULL) continue; dev = g_udev_device_get_parent (dev); if (dev == NULL) continue; /* check correct device */ if (g_udev_device_get_sysfs_attr_as_int (dev, "busnum") != g_usb_device_get_bus (usb_device)) continue; if (g_udev_device_get_sysfs_attr_as_int (dev, "devnum") != g_usb_device_get_address (usb_device)) continue; /* success */ priv->tty = g_strdup (dev_file); return TRUE; } /* failure */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to find tty for %u:%u", g_usb_device_get_bus (usb_device), g_usb_device_get_address (usb_device)); return FALSE; } static gboolean fu_altos_device_tty_write (FuAltosDevice *device, const gchar *data, gssize data_len, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); gint rc; gssize idx = 0; guint timeout_ms = 500; struct pollfd fds; /* lets assume this is text */ if (data_len < 0) data_len = strlen (data); fds.fd = priv->tty_fd; fds.events = POLLOUT; g_debug ("write, with timeout %ums", timeout_ms); while (idx < data_len) { /* wait for data to be allowed to write without blocking */ rc = poll (&fds, 1, (gint) timeout_ms); if (rc == 0) break; if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "failed to poll %i", priv->tty_fd); return FALSE; } /* we can write data */ if (fds.revents & POLLOUT) { gssize len; g_debug ("writing %" G_GSSIZE_FORMAT " bytes: %s", data_len, data); len = write (priv->tty_fd, data + idx, data_len - idx); if (len < 0) { if (errno == EAGAIN) { g_debug ("got EAGAIN, trying harder"); continue; } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to write %" G_GSSIZE_FORMAT " bytes to %i: %s" , data_len, priv->tty_fd, strerror (errno)); return FALSE; } g_debug ("wrote %" G_GSSIZE_FORMAT " bytes", len); idx += len; } } return TRUE; } static GString * fu_altos_device_tty_read (FuAltosDevice *device, guint timeout_ms, gssize max_size, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); gint rc; struct pollfd fds; g_autoptr(GString) str = g_string_new (NULL); fds.fd = priv->tty_fd; fds.events = POLLIN; g_debug ("read, with timeout %ums", timeout_ms); for (;;) { /* wait for data to appear */ rc = poll (&fds, 1, (gint) timeout_ms); if (rc == 0) break; if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "failed to poll %i", priv->tty_fd); return NULL; } /* we have data to read */ if (fds.revents & POLLIN) { guint8 buf[1024]; gssize len = read (priv->tty_fd, buf, sizeof (buf)); if (len < 0) { if (errno == EAGAIN) { g_debug ("got EAGAIN, trying harder"); continue; } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "failed to read %i: %s", priv->tty_fd, strerror (errno)); return NULL; } if (len > 0) { g_debug ("read %" G_GSSIZE_FORMAT " bytes from device", len); g_string_append_len (str, (gchar *) buf, len); } /* check maximum size */ if (max_size > 0 && str->len >= (guint) max_size) break; continue; } if (fds.revents & POLLERR) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "error condition"); return NULL; } if (fds.revents & POLLHUP) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "connection hung up"); return NULL; } if (fds.revents & POLLNVAL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "invalid request"); return NULL; } } /* no data */ if (str->len == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "no data received from device in %ums", timeout_ms); return NULL; } /* return blob */ return g_steal_pointer (&str); } static gboolean fu_altos_device_tty_open (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); struct termios termios; g_autoptr(GString) str = NULL; /* open device */ priv->tty_fd = open (priv->tty, O_RDWR | O_NONBLOCK); if (priv->tty_fd < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "failed to open %s", priv->tty); return FALSE; } /* get the old termios settings so we can restore later */ if (tcgetattr (priv->tty_fd, &termios) < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to get attributes from fd"); return FALSE; } priv->tty_termios = termios; cfmakeraw (&termios); /* set speed */ if (cfsetspeed (&termios, B9600) < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to set terminal speed"); return FALSE; } /* one input byte is enough to return * inter-character timer off */ termios.c_cc[VMIN] = 1; termios.c_cc[VTIME] = 0; /* set all new data */ if (tcsetattr (priv->tty_fd, TCSAFLUSH, &termios) < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to set attributes on fd"); return FALSE; } /* dump any pending input */ str = fu_altos_device_tty_read (device, 50, -1, NULL); if (str != NULL) g_debug ("dumping pending buffer: %s", str->str); return TRUE; } static gboolean fu_altos_device_tty_close (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); tcsetattr (priv->tty_fd, TCSAFLUSH, &priv->tty_termios); close (priv->tty_fd); return TRUE; } static GString * fu_altos_device_read_page (FuAltosDevice *device, guint address, GError **error) { g_autoptr(GString) str = NULL; g_autofree gchar *cmd = g_strdup_printf ("R %x\n", address); if (!fu_altos_device_tty_write (device, cmd, -1, error)) return NULL; str = fu_altos_device_tty_read (device, 1500, 256, error); if (str == NULL) return NULL; return g_steal_pointer (&str); } static gboolean fu_altos_device_write_page (FuAltosDevice *device, guint address, const guint8 *data, guint data_len, GError **error) { g_autofree gchar *cmd = g_strdup_printf ("W %x\n", address); if (!fu_altos_device_tty_write (device, cmd, -1, error)) return FALSE; if (!fu_altos_device_tty_write (device, (const gchar *) data, data_len, error)) return FALSE; return TRUE; } gboolean fu_altos_device_write_firmware (FuAltosDevice *device, GBytes *fw, FuAltosDeviceWriteFirmwareFlag flags, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); GBytes *fw_blob; const gchar *data; const gsize data_len; guint flash_len; g_autoptr(FuAltosFirmware) altos_firmware = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GString) buf = g_string_new (NULL); /* check kind */ if (priv->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "verification only supported in bootloader"); return FALSE; } /* check sizes */ if (priv->addr_base == 0x0 || priv->addr_bound == 0x0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "address base and bound are unset"); return FALSE; } /* read in blocks of 256 bytes */ flash_len = priv->addr_bound - priv->addr_base; if (flash_len == 0x0 || flash_len > 0x100000) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "address range was icorrect"); return FALSE; } /* load ihex blob */ altos_firmware = fu_altos_firmware_new (); if (!fu_altos_firmware_parse (altos_firmware, fw, error)) return FALSE; /* check the start address */ if (fu_altos_firmware_get_address (altos_firmware) != priv->addr_base) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "start address not correct %" G_GUINT64_FORMAT ":" "%" G_GUINT64_FORMAT, fu_altos_firmware_get_address (altos_firmware), priv->addr_base); return FALSE; } /* check firmware will fit */ fw_blob = fu_altos_firmware_get_data (altos_firmware); data = g_bytes_get_data (fw_blob, (gsize *) &data_len); if (data_len > flash_len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware too large for device %" G_GSIZE_FORMAT ":%u", data_len, flash_len); return FALSE; } /* open tty for download */ locker = fu_device_locker_new_full (device, (FuDeviceLockerFunc) fu_altos_device_tty_open, (FuDeviceLockerFunc) fu_altos_device_tty_close, error); if (locker == NULL) return FALSE; for (guint i = 0; i < flash_len; i+= 0x100) { g_autoptr(GString) str = NULL; guint8 buf_tmp[0x100]; /* copy remaining data into buf if required */ memset (buf_tmp, 0xff, sizeof (buf)); if (i < data_len) { gsize chunk_len = 0x100; if (i + 0x100 > data_len) chunk_len = data_len - i; memcpy (buf_tmp, data + i, chunk_len); } /* verify data from device */ if (!fu_altos_device_write_page (device, priv->addr_base + i, buf_tmp, 0x100, error)) return FALSE; /* verify data written on device */ str = fu_altos_device_read_page (device, priv->addr_base + i, error); if (str == NULL) return FALSE; if (str->len != 0x100) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to verify @%x, " "not enough data returned", (guint) (priv->addr_base + i)); return FALSE; } if (memcmp (str->str, buf_tmp, 0x100) != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to verify @%x", (guint) (priv->addr_base + i)); return FALSE; } /* progress */ fu_device_set_progress_full (FU_DEVICE (device), i, flash_len); g_string_append_len (buf, str->str, str->len); } /* go to application mode */ if (flags & FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_REBOOT) { if (!fu_altos_device_tty_write (device, "a\n", -1, error)) return FALSE; } /* progress complete */ fu_device_set_progress_full (FU_DEVICE (device), flash_len, flash_len); /* success */ return TRUE; } GBytes * fu_altos_device_read_firmware (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); guint flash_len; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GString) buf = g_string_new (NULL); /* check kind */ if (priv->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "verification only supported in bootloader"); return NULL; } /* check sizes */ if (priv->addr_base == 0x0 || priv->addr_bound == 0x0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "address base and bound are unset"); return NULL; } /* read in blocks of 256 bytes */ flash_len = priv->addr_bound - priv->addr_base; if (flash_len == 0x0 || flash_len > 0x100000) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "address range was icorrect"); return NULL; } /* open tty for download */ locker = fu_device_locker_new_full (device, (FuDeviceLockerFunc) fu_altos_device_tty_open, (FuDeviceLockerFunc) fu_altos_device_tty_close, error); if (locker == NULL) return NULL; for (guint i = priv->addr_base; i < priv->addr_bound; i+= 0x100) { g_autoptr(GString) str = NULL; /* request data from device */ str = fu_altos_device_read_page (device, i, error); if (str == NULL) return NULL; /* progress */ fu_device_set_progress_full (FU_DEVICE (device), i - priv->addr_base, priv->addr_bound - priv->addr_base); g_string_append_len (buf, str->str, str->len); } /* success */ return g_bytes_new (buf->str, buf->len); } static gboolean fu_altos_device_probe_bootloader (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(FuDeviceLocker) locker = NULL; g_auto(GStrv) lines = NULL; g_autoptr(GString) str = NULL; /* get tty for upload */ if (!fu_altos_device_find_tty (device, error)) return FALSE; locker = fu_device_locker_new_full (device, (FuDeviceLockerFunc) fu_altos_device_tty_open, (FuDeviceLockerFunc) fu_altos_device_tty_close, error); if (locker == NULL) return FALSE; /* get the version information */ if (!fu_altos_device_tty_write (device, "v\n", -1, error)) return FALSE; str = fu_altos_device_tty_read (device, 100, -1, error); if (str == NULL) return FALSE; /* parse each line */ lines = g_strsplit_set (str->str, "\n\r", -1); for (guint i = 0; lines[i] != NULL; i++) { /* ignore */ if (lines[i][0] == '\0') continue; if (g_str_has_prefix (lines[i], "manufacturer ")) continue; if (g_str_has_prefix (lines[i], "product ")) continue; /* we can flash firmware */ if (g_strcmp0 (lines[i], "altos-loader") == 0) { fu_device_remove_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); continue; } /* version number */ if (g_str_has_prefix (lines[i], "software-version ")) { fu_device_set_version (FU_DEVICE (device), lines[i] + 17); continue; } /* address base and bound */ if (g_str_has_prefix (lines[i], "flash-range ")) { g_auto(GStrv) addrs = g_strsplit (lines[i] + 17, " ", -1); priv->addr_base = g_ascii_strtoull (addrs[0], NULL, 16); priv->addr_bound = g_ascii_strtoull (addrs[1], NULL, 16); g_debug ("base: %x, bound: %x", (guint) priv->addr_base, (guint) priv->addr_bound); continue; } /* unknown line */ g_debug ("unknown data: '%s'", lines[i]); } return TRUE; } gboolean fu_altos_device_probe (FuAltosDevice *device, GError **error) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); /* bootloader uses tty */ if (priv->kind == FU_ALTOS_DEVICE_KIND_BOOTLOADER) return fu_altos_device_probe_bootloader (device, error); /* get version */ if (priv->kind == FU_ALTOS_DEVICE_KIND_CHAOSKEY) { const gchar *version_prefix = "ChaosKey-hw-1.0-sw-"; guint8 version_idx; g_autofree gchar *version = NULL; g_autoptr(FuDeviceLocker) locker = NULL; /* open */ locker = fu_device_locker_new (usb_device, error); if (locker == NULL) return FALSE; /* get string */ version_idx = g_usb_device_get_product_index (usb_device); version = g_usb_device_get_string_descriptor (usb_device, version_idx, error); if (version == NULL) return FALSE; if (!g_str_has_prefix (version, version_prefix)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not a ChaosKey v1.0 device: %s", version); return FALSE; } fu_device_set_version (FU_DEVICE (device), version + 19); } /* success */ return TRUE; } /* now with kind and usb_device set */ static void fu_altos_device_init_real (FuAltosDevice *device) { FuAltosDevicePrivate *priv = GET_PRIVATE (device); /* allowed, but requires manual bootloader step */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); /* set default vendor */ fu_device_set_vendor (FU_DEVICE (device), "altusmetrum.org"); /* set name */ switch (priv->kind) { case FU_ALTOS_DEVICE_KIND_BOOTLOADER: fu_device_set_name (FU_DEVICE (device), "Altos [bootloader]"); break; case FU_ALTOS_DEVICE_KIND_CHAOSKEY: fu_device_set_name (FU_DEVICE (device), "Altos ChaosKey"); break; default: g_assert_not_reached (); break; } /* set one line summary */ fu_device_set_summary (FU_DEVICE (device), "A USB hardware random number generator"); /* only the bootloader can do the update */ if (priv->kind != FU_ALTOS_DEVICE_KIND_BOOTLOADER) { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); } } typedef struct { guint16 vid; guint16 pid; FuAltosDeviceKind kind; } FuAltosDeviceVidPid; FuAltosDevice * fu_altos_device_new (GUsbDevice *usb_device) { const FuAltosDeviceVidPid vidpids[] = { { 0xfffe, 0x000a, FU_ALTOS_DEVICE_KIND_BOOTLOADER }, { 0x1d50, 0x60c6, FU_ALTOS_DEVICE_KIND_CHAOSKEY }, { 0x0000, 0x0000, FU_ALTOS_DEVICE_KIND_UNKNOWN } }; /* set kind */ for (guint j = 0; vidpids[j].vid != 0x0000; j++) { if (g_usb_device_get_vid (usb_device) == vidpids[j].vid && g_usb_device_get_pid (usb_device) == vidpids[j].pid) { FuAltosDevice *device; FuAltosDevicePrivate *priv; device = g_object_new (FU_TYPE_ALTOS_DEVICE, "usb-device", usb_device, NULL); priv = GET_PRIVATE (device); priv->kind = vidpids[j].kind; fu_altos_device_init_real (device); return device; } } return NULL; } fwupd-1.0.6/plugins/altos/fu-altos-device.h000066400000000000000000000044641325145456600206310ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_ALTOS_DEVICE_H #define __FU_ALTOS_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_ALTOS_DEVICE (fu_altos_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuAltosDevice, fu_altos_device, FU, ALTOS_DEVICE, FuUsbDevice) struct _FuAltosDeviceClass { FuUsbDeviceClass parent_class; }; typedef enum { FU_ALTOS_DEVICE_KIND_UNKNOWN, FU_ALTOS_DEVICE_KIND_BOOTLOADER, FU_ALTOS_DEVICE_KIND_CHAOSKEY, /*< private >*/ FU_ALTOS_DEVICE_KIND_LAST } FuAltosDeviceKind; typedef enum { FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_NONE = 0, FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_REBOOT = 1 << 0, /*< private >*/ FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_LAST } FuAltosDeviceWriteFirmwareFlag; FuAltosDevice *fu_altos_device_new (GUsbDevice *usb_device); FuAltosDeviceKind fu_altos_device_kind_from_string (const gchar *kind); const gchar *fu_altos_device_kind_to_string (FuAltosDeviceKind kind); FuAltosDeviceKind fu_altos_device_get_kind (FuAltosDevice *device); gboolean fu_altos_device_probe (FuAltosDevice *device, GError **error); gboolean fu_altos_device_write_firmware (FuAltosDevice *device, GBytes *fw, FuAltosDeviceWriteFirmwareFlag flags, GError **error); GBytes *fu_altos_device_read_firmware (FuAltosDevice *device, GError **error); G_END_DECLS #endif /* __FU_ALTOS_DEVICE_H */ fwupd-1.0.6/plugins/altos/fu-altos-firmware.c000066400000000000000000000075231325145456600212000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "fu-altos-firmware.h" #include "fwupd-error.h" struct _FuAltosFirmware { GObject parent_instance; GBytes *data; guint64 address; }; G_DEFINE_TYPE (FuAltosFirmware, fu_altos_firmware, G_TYPE_OBJECT) G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end); GBytes * fu_altos_firmware_get_data (FuAltosFirmware *self) { return self->data; } guint64 fu_altos_firmware_get_address (FuAltosFirmware *self) { return self->address; } gboolean fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error) { const gchar *name; Elf_Scn *scn = NULL; GElf_Shdr shdr; size_t shstrndx; g_autoptr(Elf) e = NULL; /* load library */ if (elf_version (EV_CURRENT) == EV_NONE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ELF library init failed: %s", elf_errmsg (-1)); return FALSE; } /* parse data */ e = elf_memory ((gchar *) g_bytes_get_data (blob, NULL), g_bytes_get_size (blob)); if (e == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to load data as ELF: %s", elf_errmsg (-1)); return FALSE; } if (elf_kind (e) != ELF_K_ELF) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "not a supported ELF format: %s", elf_errmsg (-1)); return FALSE; } /* add interesting section */ if (elf_getshdrstrndx (e, &shstrndx) != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid ELF file: %s", elf_errmsg (-1)); return FALSE; } while ((scn = elf_nextscn (e, scn)) != NULL ) { if (gelf_getshdr (scn, &shdr) != & shdr) continue; /* not program data with the same section name */ if (shdr.sh_type != SHT_PROGBITS) continue; if ((name = elf_strptr (e, shstrndx, shdr.sh_name)) == NULL) continue; if (g_strcmp0 (name, ".text") == 0) { Elf_Data *data = elf_getdata (scn, NULL); if (data != NULL && data->d_buf != NULL) { self->data = g_bytes_new (data->d_buf, data->d_size); self->address = shdr.sh_addr; } return TRUE; } } g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "no firmware found in ELF file"); return FALSE; } static void fu_altos_firmware_finalize (GObject *object) { FuAltosFirmware *self = FU_ALTOS_FIRMWARE (object); if (self->data != NULL) g_bytes_unref (self->data); G_OBJECT_CLASS (fu_altos_firmware_parent_class)->finalize (object); } static void fu_altos_firmware_class_init (FuAltosFirmwareClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fu_altos_firmware_finalize; } static void fu_altos_firmware_init (FuAltosFirmware *self) { } FuAltosFirmware * fu_altos_firmware_new (void) { FuAltosFirmware *self; self = g_object_new (FU_TYPE_ALTOS_FIRMWARE, NULL); return FU_ALTOS_FIRMWARE (self); } fwupd-1.0.6/plugins/altos/fu-altos-firmware.h000066400000000000000000000030021325145456600211710ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_ALTOS_FIRMWARE_H #define __FU_ALTOS_FIRMWARE_H #include G_BEGIN_DECLS #define FU_TYPE_ALTOS_FIRMWARE (fu_altos_firmware_get_type ()) G_DECLARE_FINAL_TYPE (FuAltosFirmware, fu_altos_firmware, FU, ALTOS_FIRMWARE, GObject) FuAltosFirmware *fu_altos_firmware_new (void); GBytes *fu_altos_firmware_get_data (FuAltosFirmware *self); guint64 fu_altos_firmware_get_address (FuAltosFirmware *self); gboolean fu_altos_firmware_parse (FuAltosFirmware *self, GBytes *blob, GError **error); G_END_DECLS #endif /* __FU_ALTOS_FIRMWARE_H */ fwupd-1.0.6/plugins/altos/fu-altos-tool.c000066400000000000000000000060301325145456600203310ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-altos-device.h" static void fu_altos_tool_progress_cb (FuDevice *device, GParamSpec *pspec, gpointer user_data) { g_print ("Written %u%%\n", fu_device_get_progress (device)); } int main (int argc, char **argv) { gsize len; g_autofree guint8 *data = NULL; g_autoptr(FuAltosDevice) dev = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(GError) error = NULL; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GUsbContext) usb_ctx = NULL; g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); /* require filename */ if (argc != 2) { g_print ("USAGE: %s \n", argv[0]); return 1; } /* get the device */ usb_ctx = g_usb_context_new (&error); if (usb_ctx == NULL) { g_print ("Failed to open USB devices: %s\n", error->message); return 1; } g_usb_context_enumerate (usb_ctx); devices = g_usb_context_get_devices (usb_ctx); for (guint i = 0; i < devices->len; i++) { GUsbDevice *usb_dev_tmp = g_ptr_array_index (devices, i); g_autoptr(FuAltosDevice) dev_tmp = fu_altos_device_new (usb_dev_tmp); if (dev_tmp == NULL) continue; if (fu_altos_device_get_kind (dev_tmp) == FU_ALTOS_DEVICE_KIND_BOOTLOADER) { dev = g_object_ref (dev_tmp); break; } } /* nothing supported */ if (dev == NULL) { g_print ("No supported device plugged in!\n"); return 1; } g_debug ("found %s", fu_altos_device_kind_to_string (fu_altos_device_get_kind (dev))); /* open device */ if (!fu_altos_device_probe (dev, &error)) { g_print ("Failed to probe device: %s\n", error->message); return 1; } g_print ("Device Firmware Ver: %s\n", fu_device_get_version (FU_DEVICE (dev))); /* load firmware file */ if (!g_file_get_contents (argv[1], (gchar **) &data, &len, &error)) { g_print ("Failed to load file: %s\n", error->message); return 1; } /* update with data blob */ fw = g_bytes_new (data, len); g_signal_connect (dev, "notify::progress", G_CALLBACK (fu_altos_tool_progress_cb), NULL); if (!fu_altos_device_write_firmware (dev, fw, FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_NONE, &error)) { g_print ("Failed to write firmware: %s\n", error->message); return 1; } return 0; } fwupd-1.0.6/plugins/altos/fu-plugin-altos.c000066400000000000000000000061641325145456600206620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-altos-device.h" gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { const gchar *platform_id = NULL; g_autofree gchar *runtime_id = NULL; g_autoptr(FuAltosDevice) dev = NULL; /* get kind */ dev = fu_altos_device_new (usb_device); if (dev == NULL) return TRUE; /* get device properties */ if (!fu_altos_device_probe (dev, error)) return FALSE; /* only the bootloader can do the update */ platform_id = g_usb_device_get_platform_id (usb_device); runtime_id = g_strdup_printf ("%s-runtime", platform_id); if (fu_altos_device_get_kind (dev) == FU_ALTOS_DEVICE_KIND_BOOTLOADER) { FuDevice *dev_runtime; dev_runtime = fu_plugin_cache_lookup (plugin, runtime_id); if (dev_runtime != NULL) { const gchar *guid = fu_device_get_guid_default (dev_runtime); g_debug ("adding runtime GUID of %s", guid); fu_device_add_guid (FU_DEVICE (dev), guid); fu_device_set_version (FU_DEVICE (dev), fu_device_get_version (dev_runtime)); } } else { fu_plugin_cache_add (plugin, runtime_id, dev); } /* success */ fu_plugin_device_add (plugin, FU_DEVICE (dev)); return TRUE; } gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *dev, FuPluginVerifyFlags flags, GError **error) { g_autoptr(GBytes) blob_fw = NULL; GChecksumType checksum_types[] = { G_CHECKSUM_SHA1, G_CHECKSUM_SHA256, 0 }; /* get data */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_VERIFY); blob_fw = fu_altos_device_read_firmware (FU_ALTOS_DEVICE (dev), error); if (blob_fw == NULL) return FALSE; for (guint i = 0; checksum_types[i] != 0; i++) { g_autofree gchar *hash = NULL; hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw); fu_device_add_checksum (dev, hash); } return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { fu_device_set_status (dev, FWUPD_STATUS_DEVICE_WRITE); if (!fu_altos_device_write_firmware (FU_ALTOS_DEVICE (dev), blob_fw, FU_ALTOS_DEVICE_WRITE_FIRMWARE_FLAG_REBOOT, error)) { return FALSE; } return TRUE; } fwupd-1.0.6/plugins/altos/meson.build000066400000000000000000000015311325145456600176230ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginAltos"'] shared_module('fu_plugin_altos', sources : [ 'fu-altos-device.c', 'fu-altos-firmware.c', 'fu-plugin-altos.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ gudev, libelf, plugin_deps, ], ) executable( 'fu-altos-tool', sources : [ 'fu-altos-device.c', 'fu-altos-firmware.c', 'fu-altos-tool.c', ], include_directories : [ include_directories('../..'), include_directories('../../libfwupd'), include_directories('../../src'), ], dependencies : [ gudev, libelf, plugin_deps, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs, ) fwupd-1.0.6/plugins/amt/000077500000000000000000000000001325145456600151205ustar00rootroot00000000000000fwupd-1.0.6/plugins/amt/README.md000066400000000000000000000011711325145456600163770ustar00rootroot00000000000000Intel Management Engine ======================= Introduction ------------ This plugin is used to get the version number on the Intel Management Engine. If AMT is enabled and provisioned and the AMT version is between 6.0 and 11.2, and you have not upgraded your firmware, you are vulnerable to CVE-2017-5689 and you should disable AMT in your system firmware. This code is inspired by 'AMT status checker for Linux' by Matthew Garrett which can be found here: https://github.com/mjg59/mei-amt-check That tool in turn is heavily based on mei-amt-version from samples/mei in the Linux source tree and copyright Intel Corporation. fwupd-1.0.6/plugins/amt/fu-plugin-amt.c000066400000000000000000000315061325145456600177560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2012 Intel Corporation. All rights reserved. * Copyright (C) 2017 Google, Inc. * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" typedef struct { uuid_le guid; guint buf_size; guchar prot_ver; gint fd; } mei_context; static void mei_context_free (mei_context *cl) { if (cl->fd != -1) close(cl->fd); g_free (cl); } static gboolean mei_context_new (mei_context *ctx, const uuid_le *guid, guchar req_protocol_version, GError **error) { gint result; struct mei_client *cl; struct mei_connect_client_data data; ctx->fd = open ("/dev/mei0", O_RDWR); if (ctx->fd == -1 && errno == ENOENT) ctx->fd = open ("/dev/mei", O_RDWR); if (ctx->fd == -1) { if (errno == ENOENT) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "Unable to find a ME interface"); } else { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "Cannot open /dev/mei0"); } return FALSE; } memcpy (&ctx->guid, guid, sizeof(*guid)); memset (&data, 0, sizeof(data)); memcpy (&data.in_client_uuid, &ctx->guid, sizeof(ctx->guid)); result = ioctl (ctx->fd, IOCTL_MEI_CONNECT_CLIENT, &data); if (result != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "ME refused connection"); return FALSE; } cl = &data.out_client_properties; if ((req_protocol_version > 0) && (cl->protocol_version != req_protocol_version)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Intel MEI protocol version not supported %i", cl->protocol_version); return FALSE; } ctx->buf_size = cl->max_msg_length; ctx->prot_ver = cl->protocol_version; return TRUE; } static gssize mei_recv_msg (mei_context *ctx, guchar *buffer, gssize len, unsigned long timeout, GError **error) { gssize rc; g_debug ("call read length = %zd", len); rc = read (ctx->fd, buffer, len); if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "read failed with status %zd %s", rc, strerror(errno)); } else { g_debug ("read succeeded with result %zd", rc); } return rc; } static gssize mei_send_msg (mei_context *ctx, const guchar *buffer, gssize len, unsigned long timeout, GError **error) { struct timeval tv; gssize written; gssize rc; fd_set set; tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000000; g_debug ("call write length = %zd", len); written = write (ctx->fd, buffer, len); if (written < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "write failed with status %zd %s", written, strerror(errno)); return -errno; } FD_ZERO(&set); FD_SET(ctx->fd, &set); rc = select (ctx->fd + 1 , &set, NULL, NULL, &tv); if (rc > 0 && FD_ISSET(ctx->fd, &set)) { g_debug ("write success"); return written; } /* timed out */ if (rc == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "write failed on timeout with status"); return 0; } /* rc < 0 */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "write failed on select with status %zd", rc); return rc; } /*************************************************************************** * Intel Advanced Management Technology ME Client ***************************************************************************/ #define AMT_MAJOR_VERSION 1 #define AMT_MINOR_VERSION 1 #define AMT_STATUS_SUCCESS 0x0 #define AMT_STATUS_INTERNAL_ERROR 0x1 #define AMT_STATUS_NOT_READY 0x2 #define AMT_STATUS_INVALID_AMT_MODE 0x3 #define AMT_STATUS_INVALID_MESSAGE_LENGTH 0x4 #define AMT_STATUS_HOST_IF_EMPTY_RESPONSE 0x4000 #define AMT_STATUS_SDK_RESOURCES 0x1004 #define AMT_BIOS_VERSION_LEN 65 #define AMT_VERSIONS_NUMBER 50 #define AMT_UNICODE_STRING_LEN 20 struct amt_unicode_string { guint16 length; char string[AMT_UNICODE_STRING_LEN]; } __attribute__((packed)); struct amt_version_type { struct amt_unicode_string description; struct amt_unicode_string version; } __attribute__((packed)); struct amt_version { guint8 major; guint8 minor; } __attribute__((packed)); struct amt_code_versions { guint8 bios[AMT_BIOS_VERSION_LEN]; guint32 count; struct amt_version_type versions[AMT_VERSIONS_NUMBER]; } __attribute__((packed)); struct amt_provisioning_state { guint8 bios[AMT_BIOS_VERSION_LEN]; guint32 count; guint8 state; } __attribute__((packed)); /*************************************************************************** * Intel Advanced Management Technology Host Interface ***************************************************************************/ struct amt_host_if_msg_header { struct amt_version version; guint16 _reserved; guint32 command; guint32 length; } __attribute__((packed)); struct amt_host_if_resp_header { struct amt_host_if_msg_header header; guint32 status; guchar data[0]; } __attribute__((packed)); #define AMT_HOST_IF_CODE_VERSIONS_REQUEST 0x0400001A #define AMT_HOST_IF_CODE_VERSIONS_RESPONSE 0x0480001A const struct amt_host_if_msg_header CODE_VERSION_REQ = { .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, ._reserved = 0, .command = AMT_HOST_IF_CODE_VERSIONS_REQUEST, .length = 0 }; #define AMT_HOST_IF_PROVISIONING_MODE_REQUEST 0x04000008 #define AMT_HOST_IF_PROVISIONING_MODE_RESPONSE 0x04800008 const struct amt_host_if_msg_header PROVISIONING_MODE_REQUEST = { .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, ._reserved = 0, .command = AMT_HOST_IF_PROVISIONING_MODE_REQUEST, .length = 0 }; #define AMT_HOST_IF_PROVISIONING_STATE_REQUEST 0x04000011 #define AMT_HOST_IF_PROVISIONING_STATE_RESPONSE 0x04800011 const struct amt_host_if_msg_header PROVISIONING_STATE_REQUEST = { .version = {AMT_MAJOR_VERSION, AMT_MINOR_VERSION}, ._reserved = 0, .command = AMT_HOST_IF_PROVISIONING_STATE_REQUEST, .length = 0 }; struct amt_host_if { mei_context mei_cl; }; static guint32 amt_verify_code_versions (const struct amt_host_if_resp_header *resp) { struct amt_code_versions *code_ver = (struct amt_code_versions *)resp->data; gsize code_ver_len = resp->header.length - sizeof(guint32); guint32 ver_type_cnt = code_ver_len - sizeof(code_ver->bios) - sizeof(code_ver->count); if (code_ver->count != ver_type_cnt / sizeof(struct amt_version_type)) return AMT_STATUS_INTERNAL_ERROR; for (guint32 i = 0; i < code_ver->count; i++) { guint32 len = code_ver->versions[i].description.length; if (len > AMT_UNICODE_STRING_LEN) return AMT_STATUS_INTERNAL_ERROR; len = code_ver->versions[i].version.length; if (code_ver->versions[i].version.string[len] != '\0' || len != strlen(code_ver->versions[i].version.string)) return AMT_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } static guint32 amt_verify_response_header (guint32 command, const struct amt_host_if_msg_header *resp_hdr, guint32 response_size) { if (response_size < sizeof(struct amt_host_if_resp_header)) { return AMT_STATUS_INTERNAL_ERROR; } else if (response_size != (resp_hdr->length + sizeof(struct amt_host_if_msg_header))) { return AMT_STATUS_INTERNAL_ERROR; } else if (resp_hdr->command != command) { return AMT_STATUS_INTERNAL_ERROR; } else if (resp_hdr->_reserved != 0) { return AMT_STATUS_INTERNAL_ERROR; } else if (resp_hdr->version.major != AMT_MAJOR_VERSION || resp_hdr->version.minor < AMT_MINOR_VERSION) { return AMT_STATUS_INTERNAL_ERROR; } return AMT_STATUS_SUCCESS; } static guint32 amt_host_if_call (mei_context *mei_cl, const guchar *command, gssize command_sz, guint8 **read_buf, guint32 rcmd, guint expected_sz, unsigned long send_timeout, GError **error) { guint32 in_buf_sz; guint32 out_buf_sz; gssize written; guint32 status; struct amt_host_if_resp_header *msg_hdr; in_buf_sz = mei_cl->buf_size; *read_buf = (guint8 *) g_malloc0 (in_buf_sz); msg_hdr = (struct amt_host_if_resp_header *) *read_buf; written = mei_send_msg (mei_cl, command, command_sz, send_timeout, error); if (written != command_sz) return AMT_STATUS_INTERNAL_ERROR; out_buf_sz = mei_recv_msg (mei_cl, *read_buf, in_buf_sz, 2000, error); if (out_buf_sz <= 0) return AMT_STATUS_HOST_IF_EMPTY_RESPONSE; status = msg_hdr->status; if (status != AMT_STATUS_SUCCESS) return status; status = amt_verify_response_header(rcmd, &msg_hdr->header, out_buf_sz); if (status != AMT_STATUS_SUCCESS) return status; if (expected_sz && expected_sz != out_buf_sz) return AMT_STATUS_INTERNAL_ERROR; return AMT_STATUS_SUCCESS; } static guint32 amt_get_provisioning_state (mei_context *mei_cl, guint8 *state, GError **error) { g_autofree struct amt_host_if_resp_header *response = NULL; guint32 status; status = amt_host_if_call (mei_cl, (const guchar *)&PROVISIONING_STATE_REQUEST, sizeof(PROVISIONING_STATE_REQUEST), (guint8 **)&response, AMT_HOST_IF_PROVISIONING_STATE_RESPONSE, 0, 5000, error); if (status != AMT_STATUS_SUCCESS) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Unable to get provisioning state"); return FALSE; } *state = response->data[0]; return TRUE; } G_DEFINE_AUTOPTR_CLEANUP_FUNC(mei_context, mei_context_free) static FuDevice * fu_plugin_amt_create_device (GError **error) { gchar guid_buf[37]; guint32 status; guint8 state; struct amt_code_versions ver; uuid_t uu; g_autofree struct amt_host_if_resp_header *response = NULL; g_autoptr(FuDevice) dev = NULL; g_autoptr(mei_context) ctx = g_new0 (mei_context, 1); const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, \ 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); /* create context */ if (!mei_context_new (ctx, &MEI_IAMTHIF, 0, error)) return NULL; /* check version */ status = amt_host_if_call (ctx, (const guchar *) &CODE_VERSION_REQ, sizeof(CODE_VERSION_REQ), (guint8 **) &response, AMT_HOST_IF_CODE_VERSIONS_RESPONSE, 0, 5000, error); if (status != AMT_STATUS_SUCCESS) return NULL; status = amt_verify_code_versions (response); if (status == AMT_STATUS_HOST_IF_EMPTY_RESPONSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Intel AMT is disabled"); return NULL; } if (status != AMT_STATUS_SUCCESS) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Failed to verify code versions"); return NULL; } memcpy (&ver, response->data, sizeof(struct amt_code_versions)); dev = fu_device_new (); fu_device_set_id (dev, "/dev/mei"); fu_device_set_vendor (dev, "Intel Corporation"); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); fu_device_add_icon (dev, "computer"); if (!amt_get_provisioning_state (ctx, &state, error)) return NULL; switch (state) { case 0: fu_device_set_name (dev, "Intel AMT [unprovisioned]"); break; case 1: fu_device_set_name (dev, "Intel AMT [being provisioned]"); break; case 2: fu_device_set_name (dev, "Intel AMT [provisioned]"); break; default: fu_device_set_name (dev, "Intel AMT [unknown]"); break; } fu_device_set_summary (dev, "Hardware and firmware technology for remote " "out-of-band management"); /* add guid */ memcpy (&uu, &ctx->guid, 16); uuid_unparse (uu, guid_buf); fu_device_add_guid (dev, guid_buf); /* get version numbers */ for (guint i = 0; i < ver.count; i++) { if (g_strcmp0 (ver.versions[i].description.string, "AMT") == 0) { fu_device_set_version (dev, ver.versions[i].version.string); continue; } if (g_strcmp0 (ver.versions[i].description.string, "Recovery Version") == 0) { fu_device_set_version_bootloader (dev, ver.versions[i].version.string); continue; } } return g_steal_pointer (&dev); } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { g_autoptr(FuDevice) dev = NULL; dev = fu_plugin_amt_create_device (error); if (dev == NULL) return FALSE; fu_plugin_device_add (plugin, dev); return TRUE; } fwupd-1.0.6/plugins/amt/meson.build000066400000000000000000000005711325145456600172650ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginAmt"'] shared_module('fu_plugin_amt', sources : [ 'fu-plugin-amt.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, uuid, ], ) fwupd-1.0.6/plugins/colorhug/000077500000000000000000000000001325145456600161615ustar00rootroot00000000000000fwupd-1.0.6/plugins/colorhug/README.md000066400000000000000000000014001325145456600174330ustar00rootroot00000000000000ColorHug Support ================ Introduction ------------ The ColorHug is an affordable open source display colorimeter built by Hughski Limited. The USB device allows you to calibrate your screen for accurate color matching. ColorHug versions 1 and 2 support a custom HID-based flashing protocol, but version 3 (ColorHug+) has now switched to DFU. Build Requirements ------------------ For colorhug support you need to install colord 1.2.12 or later. * source: https://github.com/hughsie/colord * rpms: http://people.freedesktop.org/~hughsient/fedora/ * debs (Debian): https://tracker.debian.org/pkg/fwupd * debs (Ubuntu): https://launchpad.net/ubuntu/+source/fwupd If you don't want or need this functionality you can use the `--disable-colorhug` option. fwupd-1.0.6/plugins/colorhug/fu-colorhug-device.c000066400000000000000000000246321325145456600220230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "fu-colorhug-device.h" typedef struct { ChDeviceQueue *device_queue; gboolean is_bootloader; } FuColorhugDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FuColorhugDevice, fu_colorhug_device, FU_TYPE_USB_DEVICE) #define GET_PRIVATE(o) (fu_colorhug_device_get_instance_private (o)) static void fu_colorhug_device_finalize (GObject *object) { FuColorhugDevice *device = FU_COLORHUG_DEVICE (object); FuColorhugDevicePrivate *priv = GET_PRIVATE (device); g_object_unref (priv->device_queue); G_OBJECT_CLASS (fu_colorhug_device_parent_class)->finalize (object); } static void fu_colorhug_device_progress_cb (ChDeviceQueue *device_queue, guint percentage, FuColorhugDevice *device) { fu_device_set_progress (FU_DEVICE (device), percentage); } gboolean fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); return priv->is_bootloader; } gboolean fu_colorhug_device_detach (FuColorhugDevice *device, GError **error) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_RESTART); ch_device_queue_reset (priv->device_queue, usb_device); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to reset device: %s", error_local->message); return FALSE; } return TRUE; } gboolean fu_colorhug_device_attach (FuColorhugDevice *device, GError **error) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_RESTART); ch_device_queue_boot_flash (priv->device_queue, usb_device); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to boot to runtime: %s", error_local->message); return FALSE; } return TRUE; } gboolean fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; g_debug ("setting flash success"); ch_device_queue_set_flash_success (priv->device_queue, usb_device, 0x01); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to set flash success: %s", error_local->message); return FALSE; } return TRUE; } static gboolean fu_colorhug_device_probe (FuUsbDevice *device, GError **error) { FuColorhugDevice *self = FU_COLORHUG_DEVICE (device); FuColorhugDevicePrivate *priv = GET_PRIVATE (self); GUsbDevice *usb_device = fu_usb_device_get_dev (device); ChDeviceMode mode; /* ignore */ mode = ch_device_get_mode (usb_device); if (mode == CH_DEVICE_MODE_UNKNOWN || mode == CH_DEVICE_MODE_BOOTLOADER_PLUS || mode == CH_DEVICE_MODE_FIRMWARE_PLUS) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported with this device"); return FALSE; } /* add hardcoded bits */ fu_device_add_guid (FU_DEVICE (device), ch_device_get_guid (usb_device)); fu_device_add_icon (FU_DEVICE (device), "colorimeter-colorhug"); fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); /* set the display name */ switch (mode) { case CH_DEVICE_MODE_BOOTLOADER: case CH_DEVICE_MODE_FIRMWARE: case CH_DEVICE_MODE_LEGACY: fu_device_set_summary (FU_DEVICE (device), "An open source display colorimeter"); break; case CH_DEVICE_MODE_BOOTLOADER2: case CH_DEVICE_MODE_FIRMWARE2: fu_device_set_summary (FU_DEVICE (device), "An open source display colorimeter"); break; case CH_DEVICE_MODE_BOOTLOADER_ALS: case CH_DEVICE_MODE_FIRMWARE_ALS: fu_device_set_summary (FU_DEVICE (device), "An open source ambient light sensor"); break; default: break; } /* is the device in bootloader mode */ switch (mode) { case CH_DEVICE_MODE_BOOTLOADER: case CH_DEVICE_MODE_BOOTLOADER2: case CH_DEVICE_MODE_BOOTLOADER_ALS: priv->is_bootloader = TRUE; break; default: priv->is_bootloader = FALSE; break; } /* success */ return TRUE; } static gboolean fu_colorhug_device_open (FuUsbDevice *device, GError **error) { FuColorhugDevice *self = FU_COLORHUG_DEVICE (device); FuColorhugDevicePrivate *priv = GET_PRIVATE (self); GUsbDevice *usb_device = fu_usb_device_get_dev (device); /* got the version using the HID API */ if (!g_usb_device_set_configuration (usb_device, CH_USB_CONFIG, error)) return FALSE; if (!g_usb_device_claim_interface (usb_device, CH_USB_INTERFACE, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { return FALSE; } if (fu_device_get_version (FU_DEVICE (device)) == NULL) { guint16 major; guint16 micro; guint16 minor; g_autofree gchar *version = NULL; g_autoptr(GError) error_local = NULL; ch_device_queue_get_firmware_ver (priv->device_queue, usb_device, &major, &minor, µ); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_warning ("failed to get firmware version: %s", error_local->message); } version = g_strdup_printf ("%i.%i.%i", major, minor, micro); g_debug ("obtained fwver using API '%s'", version); fu_device_set_version (FU_DEVICE (device), version); } /* success */ return TRUE; } gboolean fu_colorhug_device_verify_firmware (FuColorhugDevice *device, GError **error) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); gsize len; g_autoptr(GError) error_local = NULL; g_autofree guint8 *data2 = NULL; GChecksumType checksum_types[] = { G_CHECKSUM_SHA1, G_CHECKSUM_SHA256, 0 }; /* get the firmware from the device */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_VERIFY); ch_device_queue_read_firmware (priv->device_queue, usb_device, &data2, &len); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to dump firmware: %s", error_local->message); return FALSE; } /* get the checksum */ for (guint i = 0; checksum_types[i] != 0; i++) { g_autofree gchar *hash = NULL; hash = g_compute_checksum_for_data (checksum_types[i], (guchar *) data2, len); fu_device_add_checksum (device, hash); } return TRUE; } gboolean fu_colorhug_device_write_firmware (FuColorhugDevice *device, GBytes *fw, GError **error) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; /* write firmware */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_WRITE); ch_device_queue_set_flash_success (priv->device_queue, usb_device, 0x00); ch_device_queue_write_firmware (priv->device_queue, usb_device, g_bytes_get_data (fw, NULL), g_bytes_get_size (fw)); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to write firmware: %s", error_local->message); return FALSE; } /* verify firmware */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_VERIFY); ch_device_queue_verify_firmware (priv->device_queue, usb_device, g_bytes_get_data (fw, NULL), g_bytes_get_size (fw)); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "failed to verify firmware: %s", error_local->message); return FALSE; } /* success! */ return TRUE; } static void fu_colorhug_device_init (FuColorhugDevice *device) { FuColorhugDevicePrivate *priv = GET_PRIVATE (device); priv->device_queue = ch_device_queue_new (); g_signal_connect (priv->device_queue, "progress_changed", G_CALLBACK (fu_colorhug_device_progress_cb), device); } static void fu_colorhug_device_class_init (FuColorhugDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); object_class->finalize = fu_colorhug_device_finalize; klass_usb_device->open = fu_colorhug_device_open; klass_usb_device->probe = fu_colorhug_device_probe; } /** * fu_colorhug_device_new: * * Creates a new #FuColorhugDevice. * * Returns: (transfer full): a #FuColorhugDevice, or %NULL if not a game pad * * Since: 0.1.0 **/ FuColorhugDevice * fu_colorhug_device_new (GUsbDevice *usb_device) { FuColorhugDevice *device = NULL; device = g_object_new (FU_TYPE_COLORHUG_DEVICE, "usb-device", usb_device, NULL); return device; } fwupd-1.0.6/plugins/colorhug/fu-colorhug-device.h000066400000000000000000000040071325145456600220220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_COLORHUG_DEVICE_H #define __FU_COLORHUG_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_COLORHUG_DEVICE (fu_colorhug_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuColorhugDevice, fu_colorhug_device, FU, COLORHUG_DEVICE, FuUsbDevice) struct _FuColorhugDeviceClass { FuUsbDeviceClass parent_class; }; FuColorhugDevice *fu_colorhug_device_new (GUsbDevice *usb_device); gboolean fu_colorhug_device_get_is_bootloader (FuColorhugDevice *device); /* object methods */ gboolean fu_colorhug_device_detach (FuColorhugDevice *device, GError **error); gboolean fu_colorhug_device_attach (FuColorhugDevice *device, GError **error); gboolean fu_colorhug_device_set_flash_success (FuColorhugDevice *device, GError **error); gboolean fu_colorhug_device_write_firmware (FuColorhugDevice *device, GBytes *fw, GError **error); gboolean fu_colorhug_device_verify_firmware (FuColorhugDevice *device, GError **error); G_END_DECLS #endif /* __FU_COLORHUG_DEVICE_H */ fwupd-1.0.6/plugins/colorhug/fu-plugin-colorhug.c000066400000000000000000000131341325145456600220550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-colorhug-device.h" void fu_plugin_init (FuPlugin *plugin) { g_autofree gchar *tmp = g_strdup_printf ("%i.%i.%i", CH_MAJOR_VERSION, CH_MINOR_VERSION, CH_MICRO_VERSION); fu_plugin_add_report_metadata (plugin, "ColorhugVersion", tmp); } gboolean fu_plugin_update_detach (FuPlugin *plugin, FuDevice *device, GError **error) { FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GUsbDevice) usb_device2 = NULL; /* open device */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* switch to bootloader mode is not required */ if (fu_colorhug_device_get_is_bootloader (colorhug_dev)) { g_debug ("already in bootloader mode, skipping"); return TRUE; } /* reset */ if (!fu_colorhug_device_detach (colorhug_dev, error)) return FALSE; /* wait for replug */ g_clear_object (&locker); usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin), usb_device, 10000, error); if (usb_device2 == NULL) { g_prefix_error (error, "device did not come back: "); return FALSE; } /* set the new device until we can use a new FuDevice */ fu_usb_device_set_dev (FU_USB_DEVICE (colorhug_dev), usb_device2); /* success */ return TRUE; } gboolean fu_plugin_update_attach (FuPlugin *plugin, FuDevice *device, GError **error) { FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GUsbDevice) usb_device2 = NULL; /* open device */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* switch to runtime mode is not required */ if (!fu_colorhug_device_get_is_bootloader (colorhug_dev)) { g_debug ("already in runtime mode, skipping"); return TRUE; } /* reset */ if (!fu_colorhug_device_attach (colorhug_dev, error)) return FALSE; /* wait for replug */ g_clear_object (&locker); usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin), usb_device, 10000, error); if (usb_device2 == NULL) { g_prefix_error (error, "device did not come back: "); return FALSE; } /* set the new device until we can use a new FuDevice */ fu_usb_device_set_dev (FU_USB_DEVICE (colorhug_dev), usb_device2); /* success */ return TRUE; } gboolean fu_plugin_update_reload (FuPlugin *plugin, FuDevice *device, GError **error) { FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device); g_autoptr(FuDeviceLocker) locker = NULL; /* also set flash success */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!fu_colorhug_device_set_flash_success (colorhug_dev, error)) return FALSE; return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; /* check this firmware is actually for this device */ if (!ch_device_check_firmware (usb_device, g_bytes_get_data (blob_fw, NULL), g_bytes_get_size (blob_fw), &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "firmware is not suitable: %s", error_local->message); return FALSE; } /* write firmware */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; return fu_colorhug_device_write_firmware (colorhug_dev, blob_fw, error); } gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *device, FuPluginVerifyFlags flags, GError **error) { FuColorhugDevice *colorhug_dev = FU_COLORHUG_DEVICE (device); g_autoptr(FuDeviceLocker) locker = NULL; /* write firmware */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; return fu_colorhug_device_verify_firmware (colorhug_dev, error); } gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuColorhugDevice) device = NULL; /* open the device */ device = fu_colorhug_device_new (usb_device); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* insert to hash */ fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } fwupd-1.0.6/plugins/colorhug/meson.build000066400000000000000000000006501325145456600203240ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginColorHug"'] shared_module('fu_plugin_colorhug', sources : [ 'fu-colorhug-device.c', 'fu-plugin-colorhug.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, colorhug, ], ) fwupd-1.0.6/plugins/csr/000077500000000000000000000000001325145456600151265ustar00rootroot00000000000000fwupd-1.0.6/plugins/csr/csr-aiaiai-h05.quirk000066400000000000000000000005441325145456600206020ustar00rootroot00000000000000[FuCsrDevice] # AIAIAI H05 bluetooth headphones USB\VID_0A12&PID_1337=none [FuUsbDevice:name] USB\VID_0A12&PID_1337=H05 [FuUsbDevice:summary] USB\VID_0A12&PID_1337=Bluetooth headphones [FuUsbDevice:icon] USB\VID_0A12&PID_1337=audio-headphones [FuUsbDevice:vendor] USB\VID_0A12&PID_1337=AIAIAI [FuUsbDevice:version] USB\VID_0A12&PID_1337&REV_2520=1.2 fwupd-1.0.6/plugins/csr/csr-aiaiai-h60.quirk000066400000000000000000000004521325145456600206010ustar00rootroot00000000000000[FuCsrDevice] # AIAIAI H60 bluetooth headphones USB\VID_0A12&PID_4004=none [FuUsbDevice:name] USB\VID_0A12&PID_4004=H60 [FuUsbDevice:summary] USB\VID_0A12&PID_4004=Bluetooth headphones [FuUsbDevice:icon] USB\VID_0A12&PID_4004=audio-headphones [FuUsbDevice:vendor] USB\VID_0A12&PID_4004=AIAIAI fwupd-1.0.6/plugins/csr/data/000077500000000000000000000000001325145456600160375ustar00rootroot00000000000000fwupd-1.0.6/plugins/csr/data/lsusb.txt000066400000000000000000000036411325145456600177340ustar00rootroot00000000000000Bus 001 Device 040: ID 0a12:1337 Cambridge Silicon Radio, Ltd Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0a12 Cambridge Silicon Radio, Ltd idProduct 0x1337 bcdDevice 25.20 iManufacturer 0 iProduct 2 AIAIAI H05 in iSerial 3 ABCDEF0123456789 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 40 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/csr/data/upgrade.tdc.gz000066400000000000000000000163611325145456600206100ustar00rootroot00000000000000*Zupgrade.tdcZiXҮ=#8h<" .=\#q`.0Ѡ1ո-JF%^DKP$;Ow?3y[VԡOzd! _7,0 WAG><H>c&*S|"x ?RfǼn9 5ǡq`I` I4@5,& ~?pMJD LDD*o!F11`n‚@!eT$.PE|&/؅HvnQtP\x4C.)Ƀ@*\<쐖vHBĔO+**xqPEe$@.$ Bm?cHqJJCF|=( -%7tKE'Xӣ%%|IQ5(R'#K||X 'p7JJ57Md> zaCk-,\8GҎTD]bh⧑' qބRWXk 1:oQ'uv#2wKY{k 6JƎeV(2x? +!V6A5OϼԒq) N ^_ƷAR?OqU1_GW4KoJ5MaT#KRrC/H ?GNo7n}cjUH:8 wG"/ON!l^zR^/S倯}g2^ċ67S:9Ay^/l\qD=.KsNܐ@{Cl9׽{Cߏ18Q(pGl9{x-nH .y#GG 'Lq~Lk iO pk$ )t色rs@GΓjetq+V Fњ]Tkurn#Z9ߙVB[ 1 -)\xJ) ㍪I@BM7YψF\z036Eˑ[lAG㗔D[Aevf9DUb{㍋'ôwo'(ZUfFzt !_U7i(uƋRыlБ4tp'ء1Ia$VTB@JvjMIF31.#o qSRB^o@[9e.R=ϖYDTeG ,J}ĺ64&S 1n$)4艳h@*3^TB:3qgw~ %Q~F]oZɿP5 jn,G?3|A[{M"% )”Qv)n] lif0ss}7 +[ : w'-pBfҿc=0BˊmpvFg4J/2$*וJ_Ԯ 1QSedUuLqnxI0|w3=zG9+2Q,( M5,nY`AjZxGrr4}Ie9IxG/g}<%r?u5ӫfPZRÓՉVra2]3{tY\w-{yhmm..2"dQ8Rtw$6u4nQ7/`l޳dxMFSY *%Ӳ(8ʑ'VmE1o8Dtܚi_UAa`S.CIhKӵLŤhb1/. P mZ_I`#|i f+dPDF\2*}aʃKp a a.n#L:( y 7Xp`V8>ާ).BQwnW9Rwf8p[o*84Z+{\y)j"Qс-q=R.Qh@%6Gl |KUX5Jef+& u>b Gʁ0nqg0lDX1“Tr&B36`)whI+\k"b[|\6UDO 8A2v쾚rP㬏^3N\ƅB(, d k| xf;7 6׫a`9WLdp r.P4%p5v؉-k{l3I8I\>qU*px{Rrhl"`#Z%f9$ToqQIF#l7 :K/^QiqbLSwr焕2dp NQG7t()C*2ob3ܗ5-bPH}6sN9^uG<x ¹`фpXl,8D:DTq+\GMGǪ>6oN[)3mp. pq78; qH EEUNo{+>$R$Qa2?L+=D4q}3 *nw'PPS5Crܼpkyؤgl~y܉ 5.,ݽ u˿ٷnӖ _rzO@&۬кa3pMJUmy'q":I茺jeQ^=9hа7U+'kZXg[;X \M߿q{JX9 gir+7LnAt}C|hèRV 9ϐC@N97H+=tՊS^E%tTHqQcy52fЌ2J掃úqVSI[&dnvIV|Cd$?W 4L[{606;Lq5`d1aJu|MXRx|] %Gn7fsn$OQUǮn~*+Y6Ƞ?f]`&^U;H#v~~F ܘ~SҖL+#.-ϴ٧"nykVPcp˪E?+đ5GgW2yrtۤ5 "QM*XIx-2-d_FgߒUM"hUNdp"L j}s*o#GO"JA2 QC4}EFdL@lWWmtٮnn c5[IL_H@bTq DrbLj\)6zJ/U6E8>,x5tZj ;J \-T:ST,lu40z*@zJ򂪁3GL^ۦf%qVHTf7RR&kQ;BVƻJ޴w$9膟ALZ ?g[f^?t-ӿ$Mr]3Wrj١OQ ٭+ tm- GѿE'C/vxX9xHHTXgdN^}/޸9A.Na=q'@ }gD8L[}Zc #dD֜cxѽ(}AW=@#W.+/±k}F>M|%{8& СT=x0@+?`luE{.%64XZgU'?C [|nɤr|ն^qqt+\g6Z18 UHJCh`d&1.B>f~>\ZB*Qmf0 ' l~Cd!D߂!kؒ3D#V=~UFوdp֏PeV/TDKv B-r@ar|c?{rp7'T )#?xPJe629C.9.D𓵪ƺiC85H]'#oyCa4^5TGMƣ up5Cя5*ܵ%YQ4a ץ5fXc)- Pq.cưfXA4 g0ߛXX9J#sdمh!?G t5{Z:FK-xu#KQVr"3VJt W$o~gZofJ.7}|8";)%vWljmVKXAT[ܡ<[5<vbys)ym &UlZW%,Ux_7]OUr1r T}[s~ˇ]bv`P1dtx V4QQ:jbyݻZP]3MV_XGKٟr%V Xz7nLLy^6)lx'ZjgӛUw2jz&t3u~oSLt&"jm63~r#fj'*1Wz R #(S PJr3OU:ne]Ng\cB *P|]$3/i"sEIg>U|دk~#t-3y"ޗ+^S/u7S/MںH]& [k}&*KuL^s&VȠȰ@n^ʃ~X͙V#bMI`80#XVF!e{ߢz2akW9 Yd^1A*QADBN$hvDvŧ :&B ABWmv*ZHvtH:$/*ST*YW1)GwLٝ<J &}GRj3}-TQ, ')Ew]7OAۛ3+Ty}a* _z, oU";Yvw7ResZ)ȋ#k+ꈮp ˎ깑gdp`ݱv2> pVp"DEKHLG}:kH "=PWnbډÆv0&bq_I!]-F*F$ f 20/ntI-fwupd-1.0.6/plugins/csr/fu-csr-device.c000066400000000000000000000417111325145456600177320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fu-csr-device.h" #include "dfu-common.h" #include "dfu-chunked.h" #include "dfu-firmware.h" struct _FuCsrDevice { FuUsbDevice parent_instance; FuCsrDeviceQuirks quirks; DfuState dfu_state; guint32 dnload_timeout; }; G_DEFINE_TYPE (FuCsrDevice, fu_csr_device, FU_TYPE_USB_DEVICE) #define HID_REPORT_GET 0x01 #define HID_REPORT_SET 0x09 #define HID_REPORT_TYPE_INPUT 0x01 #define HID_REPORT_TYPE_OUTPUT 0x02 #define HID_REPORT_TYPE_FEATURE 0x03 #define HID_FEATURE 0x0300 #define FU_CSR_REPORT_ID_COMMAND 0x01 #define FU_CSR_REPORT_ID_STATUS 0x02 #define FU_CSR_REPORT_ID_CONTROL 0x03 #define FU_CSR_COMMAND_HEADER_SIZE 6 /* bytes */ #define FU_CSR_COMMAND_UPGRADE 0x01 #define FU_CSR_STATUS_HEADER_SIZE 7 #define FU_CSR_CONTROL_HEADER_SIZE 2 /* bytes */ #define FU_CSR_CONTROL_CLEAR_STATUS 0x04 #define FU_CSR_CONTROL_RESET 0xff /* maximum firmware packet, including the command header */ #define FU_CSR_PACKET_DATA_SIZE 1023 /* bytes */ #define FU_CSR_DEVICE_TIMEOUT 5000 /* ms */ static void fu_csr_device_to_string (FuDevice *device, GString *str) { FuCsrDevice *self = FU_CSR_DEVICE (device); g_string_append (str, " DfuCsrDevice:\n"); g_string_append_printf (str, " state:\t\t%s\n", dfu_state_to_string (self->dfu_state)); g_string_append_printf (str, " timeout:\t\t%" G_GUINT32_FORMAT "\n", self->dnload_timeout); } static void fu_csr_device_dump (const gchar *title, const guint8 *buf, gsize sz) { if (g_getenv ("FWUPD_CSR_VERBOSE") == NULL) return; g_print ("%s (%" G_GSIZE_FORMAT "):\n", title, sz); for (gsize i = 0; i < sz; i++) g_print ("%02x ", buf[i]); g_print ("\n"); } void fu_csr_device_set_quirks (FuCsrDevice *self, FuCsrDeviceQuirks quirks) { self->quirks = quirks; } gboolean fu_csr_device_attach (FuCsrDevice *self, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); gsize sz = 0; guint8 buf[] = { FU_CSR_REPORT_ID_CONTROL, FU_CSR_CONTROL_RESET }; fu_csr_device_dump ("Reset", buf, sz); if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, HID_REPORT_SET, /* bRequest */ HID_FEATURE | FU_CSR_REPORT_ID_CONTROL, /* wValue */ 0x0000, /* wIndex */ buf, sizeof(buf), &sz, FU_CSR_DEVICE_TIMEOUT, /* timeout */ NULL, error)) { g_prefix_error (error, "Failed to ClearStatus: "); return FALSE; } /* check packet */ if (sz != FU_CSR_CONTROL_HEADER_SIZE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Reset packet was %" G_GSIZE_FORMAT " expected %i", sz, FU_CSR_CONTROL_HEADER_SIZE); return FALSE; } return TRUE; } static gboolean fu_csr_device_get_status (FuCsrDevice *self, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); gsize sz = 0; guint8 buf[64] = {0}; /* hit hardware */ if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, HID_REPORT_GET, /* bRequest */ HID_FEATURE | FU_CSR_REPORT_ID_STATUS, /* wValue */ 0x0000, /* wIndex */ buf, sizeof(buf), &sz, FU_CSR_DEVICE_TIMEOUT, NULL, error)) { g_prefix_error (error, "Failed to GetStatus: "); return FALSE; } fu_csr_device_dump ("GetStatus", buf, sz); /* check packet */ if (sz != FU_CSR_STATUS_HEADER_SIZE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "GetStatus packet was %" G_GSIZE_FORMAT " expected %i", sz, FU_CSR_STATUS_HEADER_SIZE); return FALSE; } if (buf[0] != FU_CSR_REPORT_ID_STATUS) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "GetStatus packet-id was %i expected %i", buf[0], FU_CSR_REPORT_ID_STATUS); return FALSE; } self->dfu_state = buf[5]; self->dnload_timeout = buf[2] + (((guint32) buf[3]) << 8) + (((guint32) buf[4]) << 16); g_debug ("timeout=%" G_GUINT32_FORMAT, self->dnload_timeout); g_debug ("state=%s", dfu_state_to_string (self->dfu_state)); g_debug ("status=%s", dfu_status_to_string (buf[6])); return TRUE; } static gboolean fu_csr_device_clear_status (FuCsrDevice *self, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); gsize sz = 0; guint8 buf[] = { FU_CSR_REPORT_ID_CONTROL, FU_CSR_CONTROL_CLEAR_STATUS }; /* only clear the status if the state is error */ if (!fu_csr_device_get_status (self, error)) return FALSE; if (self->dfu_state != DFU_STATE_DFU_ERROR) return TRUE; /* hit hardware */ fu_csr_device_dump ("ClearStatus", buf, sz); if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, HID_REPORT_SET, /* bRequest */ HID_FEATURE | FU_CSR_REPORT_ID_CONTROL, /* wValue */ 0x0000, /* wIndex */ buf, sizeof(buf), &sz, FU_CSR_DEVICE_TIMEOUT, NULL, error)) { g_prefix_error (error, "Failed to ClearStatus: "); return FALSE; } /* check packet */ if (sz != FU_CSR_CONTROL_HEADER_SIZE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ClearStatus packet was %" G_GSIZE_FORMAT " expected %i", sz, FU_CSR_CONTROL_HEADER_SIZE); return FALSE; } /* check the hardware again */ return fu_csr_device_get_status (self, error); } static GBytes * fu_csr_device_upload_chunk (FuCsrDevice *self, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); gsize sz = 0; guint16 data_sz; guint8 buf[64] = {0}; /* hit hardware */ if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, HID_REPORT_GET, /* bRequest */ HID_FEATURE | FU_CSR_REPORT_ID_COMMAND, /* wValue */ 0x0000, /* wIndex */ buf, sizeof(buf), &sz, FU_CSR_DEVICE_TIMEOUT, NULL, error)) { g_prefix_error (error, "Failed to ReadFirmware: "); return NULL; } fu_csr_device_dump ("ReadFirmware", buf, sz); /* too small to parse */ if (sz < FU_CSR_COMMAND_HEADER_SIZE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ReadFirmware packet too small, got %" G_GSIZE_FORMAT, sz); return NULL; } /* check command byte */ if (buf[0] != FU_CSR_REPORT_ID_COMMAND) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "wrong report ID %u", buf[0]); return NULL; } /* check the length */ data_sz = fu_common_read_uint16 (&buf[1], G_LITTLE_ENDIAN); if (data_sz + FU_CSR_COMMAND_HEADER_SIZE != (guint16) sz) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "wrong data length %" G_GUINT16_FORMAT, data_sz); return NULL; } /* return as bytes */ return g_bytes_new (buf + FU_CSR_COMMAND_HEADER_SIZE, sz - FU_CSR_COMMAND_HEADER_SIZE); } GBytes * fu_csr_device_upload (FuCsrDevice *self, GError **error) { g_autoptr(GPtrArray) chunks = NULL; guint32 total_sz = 0; gsize done_sz = 0; /* notify UI */ fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_DEVICE_READ); chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); for (guint32 i = 0; i < 0x3ffffff; i++) { g_autoptr(GBytes) chunk = NULL; gsize chunk_sz; /* hit hardware */ chunk = fu_csr_device_upload_chunk (self, error); if (chunk == NULL) return FALSE; chunk_sz = g_bytes_get_size (chunk); /* get the total size using the CSR header */ if (i == 0 && chunk_sz >= 10) { const guint8 *buf = g_bytes_get_data (chunk, NULL); if (memcmp (buf, "CSR-dfu", 7) == 0) { guint16 hdr_ver; guint16 hdr_len; hdr_ver = fu_common_read_uint16 (buf + 8, G_LITTLE_ENDIAN); if (hdr_ver != 0x03) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "CSR header version is " "invalid %" G_GUINT16_FORMAT, hdr_ver); return NULL; } total_sz = fu_common_read_uint32 (buf + 10, G_LITTLE_ENDIAN); if (total_sz == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "CSR header data length " "invalid %" G_GUINT32_FORMAT, total_sz); return NULL; } hdr_len = fu_common_read_uint16 (buf + 14, G_LITTLE_ENDIAN); g_debug ("CSR header length: %" G_GUINT16_FORMAT, hdr_len); } } /* add to chunk array */ done_sz += chunk_sz; g_ptr_array_add (chunks, g_steal_pointer (&chunk)); fu_device_set_progress_full (FU_DEVICE (self), done_sz, (gsize) total_sz); /* we're done */ if (chunk_sz < 64 - FU_CSR_COMMAND_HEADER_SIZE) break; } /* notify UI */ fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_IDLE); return dfu_utils_bytes_join_array (chunks); } static gboolean fu_csr_device_download_chunk (FuCsrDevice *self, guint16 idx, GBytes *chunk, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self)); const guint8 *chunk_data; gsize chunk_sz = 0; gsize write_sz = 0; guint8 buf[FU_CSR_PACKET_DATA_SIZE] = {0}; /* too large? */ chunk_data = g_bytes_get_data (chunk, &chunk_sz); if (chunk_sz + FU_CSR_COMMAND_HEADER_SIZE > FU_CSR_PACKET_DATA_SIZE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "packet was too large: %" G_GSIZE_FORMAT, chunk_sz); return FALSE; } g_debug ("writing %" G_GSIZE_FORMAT " bytes of data", chunk_sz); /* create packet */ buf[0] = FU_CSR_REPORT_ID_COMMAND; buf[1] = FU_CSR_COMMAND_UPGRADE; fu_common_write_uint16 (&buf[2], idx, G_LITTLE_ENDIAN); fu_common_write_uint16 (&buf[4], chunk_sz, G_LITTLE_ENDIAN); memcpy (buf + FU_CSR_COMMAND_HEADER_SIZE, chunk_data, chunk_sz); /* hit hardware */ fu_csr_device_dump ("Upgrade", buf, sizeof(buf)); if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, HID_REPORT_SET, /* bRequest */ HID_FEATURE | FU_CSR_REPORT_ID_COMMAND, /* wValue */ 0x0000, /* wIndex */ buf, sizeof(buf), &write_sz, FU_CSR_DEVICE_TIMEOUT, NULL, error)) { g_prefix_error (error, "Failed to Upgrade: "); return FALSE; } /* check packet */ if (write_sz != sizeof(buf)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Not all packet written for upgrade got " "%" G_GSIZE_FORMAT " expected %" G_GSIZE_FORMAT, write_sz, sizeof(buf)); return FALSE; } /* wait for hardware */ if (self->quirks & FU_CSR_DEVICE_QUIRK_REQUIRE_DELAY) { g_debug ("sleeping for %ums", self->dnload_timeout); g_usleep (self->dnload_timeout * 1000); } /* get status */ if (!fu_csr_device_get_status (self, error)) return FALSE; /* is still busy */ if (self->dfu_state == DFU_STATE_DFU_DNBUSY) { g_debug ("busy, so sleeping a bit longer"); g_usleep (G_USEC_PER_SEC); if (!fu_csr_device_get_status (self, error)) return FALSE; } /* not correct */ if (self->dfu_state != DFU_STATE_DFU_DNLOAD_IDLE && self->dfu_state != DFU_STATE_DFU_IDLE) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "device did not return to IDLE"); return FALSE; } /* success */ return TRUE; } static GBytes * _dfu_firmware_get_default_element_data (DfuFirmware *firmware) { DfuElement *element; DfuImage *image; image = dfu_firmware_get_image_default (firmware); if (image == NULL) return NULL; element = dfu_image_get_element_default (image); if (element == NULL) return NULL; return dfu_element_get_contents (element); } gboolean fu_csr_device_download (FuCsrDevice *self, GBytes *blob, GError **error) { GBytes *blob_noftr; const guint8 *data; gsize sz = 0; guint16 idx; g_autoptr(DfuFirmware) dfu_firmware = dfu_firmware_new (); g_autoptr(GBytes) blob_empty = NULL; g_autoptr(GPtrArray) packets = NULL; /* notify UI */ fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_DEVICE_WRITE); /* parse the file */ if (!dfu_firmware_parse_data (dfu_firmware, blob, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) return FALSE; if (g_getenv ("FWUPD_CSR_VERBOSE") != NULL) { g_autofree gchar *fw_str = NULL; fw_str = dfu_firmware_to_string (dfu_firmware); g_debug ("%s", fw_str); } if (dfu_firmware_get_format (dfu_firmware) != DFU_FIRMWARE_FORMAT_DFU) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "expected DFU firmware"); return FALSE; } /* get the blob from the firmware file */ blob_noftr = _dfu_firmware_get_default_element_data (dfu_firmware); if (blob_noftr == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware contained no data"); return FALSE; } /* create packets */ data = g_bytes_get_data (blob_noftr, &sz); packets = dfu_chunked_new (data, (guint32) sz, 0x0, 0x0, FU_CSR_PACKET_DATA_SIZE - FU_CSR_COMMAND_HEADER_SIZE); /* send to hardware */ for (idx = 0; idx < packets->len; idx++) { DfuChunkedPacket *pkt = g_ptr_array_index (packets, idx); g_autoptr(GBytes) blob_tmp = g_bytes_new_static (pkt->data, pkt->data_sz); /* send packet */ if (!fu_csr_device_download_chunk (self, idx, blob_tmp, error)) return FALSE; /* update progress */ fu_device_set_progress_full (FU_DEVICE (self), (gsize) idx, (gsize) packets->len); } /* all done */ blob_empty = g_bytes_new (NULL, 0); if (!fu_csr_device_download_chunk (self, idx, blob_empty, error)) return FALSE; /* notify UI */ fu_device_set_status (FU_DEVICE (self), FWUPD_STATUS_IDLE); return TRUE; } static gboolean fu_csr_device_probe (FuUsbDevice *device, GError **error) { const gchar *quirk_str; /* devices have to be whitelisted */ quirk_str = fu_device_get_plugin_hints (FU_DEVICE (device)); if (quirk_str == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported with this device"); return FALSE; } if (g_strcmp0 (quirk_str, "require-delay") == 0) { fu_csr_device_set_quirks (FU_CSR_DEVICE (device), FU_CSR_DEVICE_QUIRK_REQUIRE_DELAY); } /* hardcoded */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); /* success */ return TRUE; } static gboolean fu_csr_device_open (FuUsbDevice *device, GError **error) { FuCsrDevice *self = FU_CSR_DEVICE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (device); /* open device and clear status */ if (!g_usb_device_claim_interface (usb_device, 0x00, /* HID */ G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "failed to claim HID interface: "); return FALSE; } if (!fu_csr_device_clear_status (self, error)) return FALSE; /* success */ return TRUE; } static gboolean fu_csr_device_close (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); /* we're done here */ if (!g_usb_device_release_interface (usb_device, 0x00, /* HID */ G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "failed to release interface: "); return FALSE; } /* success */ return TRUE; } static void fu_csr_device_init (FuCsrDevice *device) { } static void fu_csr_device_class_init (FuCsrDeviceClass *klass) { FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); klass_device->to_string = fu_csr_device_to_string; klass_usb_device->open = fu_csr_device_open; klass_usb_device->close = fu_csr_device_close; klass_usb_device->probe = fu_csr_device_probe; } FuCsrDevice * fu_csr_device_new (GUsbDevice *usb_device) { FuCsrDevice *device = NULL; device = g_object_new (FU_TYPE_CSR_DEVICE, "usb-device", usb_device, NULL); return device; } fwupd-1.0.6/plugins/csr/fu-csr-device.h000066400000000000000000000034341325145456600177370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_CSR_DEVICE_H #define __FU_CSR_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_CSR_DEVICE (fu_csr_device_get_type ()) G_DECLARE_FINAL_TYPE (FuCsrDevice, fu_csr_device, FU, CSR_DEVICE, FuUsbDevice) typedef enum { FU_CSR_DEVICE_QUIRK_NONE = 0, FU_CSR_DEVICE_QUIRK_REQUIRE_DELAY = (1 << 0), FU_CSR_DEVICE_QUIRK_LAST } FuCsrDeviceQuirks; FuCsrDevice *fu_csr_device_new (GUsbDevice *usb_device); gboolean fu_csr_device_attach (FuCsrDevice *self, GError **error); gboolean fu_csr_device_download (FuCsrDevice *self, GBytes *blob, GError **error); GBytes *fu_csr_device_upload (FuCsrDevice *self, GError **error); void fu_csr_device_set_quirks (FuCsrDevice *self, FuCsrDeviceQuirks quirks); G_END_DECLS #endif /* __FU_CSR_DEVICE_H */ fwupd-1.0.6/plugins/csr/fu-csr-tool.c000066400000000000000000000256431325145456600174560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "dfu-firmware.h" #include "fu-progressbar.h" #include "fu-csr-device.h" typedef struct { FuQuirks *quirks; GPtrArray *cmd_array; FuProgressbar *progressbar; } FuCsrToolPrivate; static void fu_csr_tool_private_free (FuCsrToolPrivate *priv) { if (priv == NULL) return; g_object_unref (priv->quirks); g_object_unref (priv->progressbar); if (priv->cmd_array != NULL) g_ptr_array_unref (priv->cmd_array); g_free (priv); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuCsrToolPrivate, fu_csr_tool_private_free) typedef gboolean (*FuCsrToolPrivateCb) (FuCsrToolPrivate *util, gchar **values, GError **error); typedef struct { gchar *name; gchar *arguments; gchar *description; FuCsrToolPrivateCb callback; } FuCsrToolItem; static void fu_csr_tool_item_free (FuCsrToolItem *item) { g_free (item->name); g_free (item->arguments); g_free (item->description); g_free (item); } static gint fu_csr_tool_sort_command_name_cb (FuCsrToolItem **item1, FuCsrToolItem **item2) { return g_strcmp0 ((*item1)->name, (*item2)->name); } static void fu_csr_tool_add (GPtrArray *array, const gchar *name, const gchar *arguments, const gchar *description, FuCsrToolPrivateCb callback) { g_auto(GStrv) names = NULL; g_return_if_fail (name != NULL); g_return_if_fail (description != NULL); g_return_if_fail (callback != NULL); /* add each one */ names = g_strsplit (name, ",", -1); for (guint i = 0; names[i] != NULL; i++) { FuCsrToolItem *item = g_new0 (FuCsrToolItem, 1); item->name = g_strdup (names[i]); if (i == 0) { item->description = g_strdup (description); } else { item->description = g_strdup_printf ("Alias to %s", names[0]); } item->arguments = g_strdup (arguments); item->callback = callback; g_ptr_array_add (array, item); } } static gchar * fu_csr_tool_get_descriptions (GPtrArray *array) { const gsize max_len = 31; GString *str; /* print each command */ str = g_string_new (""); for (guint i = 0; i < array->len; i++) { FuCsrToolItem *item = g_ptr_array_index (array, i); gsize len; g_string_append (str, " "); g_string_append (str, item->name); len = strlen (item->name) + 2; if (item->arguments != NULL) { g_string_append (str, " "); g_string_append (str, item->arguments); len += strlen (item->arguments) + 1; } if (len < max_len) { for (guint j = len; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } else { g_string_append_c (str, '\n'); for (guint j = 0; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } } /* remove trailing newline */ if (str->len > 0) g_string_set_size (str, str->len - 1); return g_string_free (str, FALSE); } static gboolean fu_csr_tool_run (FuCsrToolPrivate *priv, const gchar *command, gchar **values, GError **error) { /* find command */ for (guint i = 0; i < priv->cmd_array->len; i++) { FuCsrToolItem *item = g_ptr_array_index (priv->cmd_array, i); if (g_strcmp0 (item->name, command) == 0) return item->callback (priv, values, error); } /* not found */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Command not found"); return FALSE; } static FuCsrDevice * fu_csr_get_default_device (FuCsrToolPrivate *priv, GError **error) { g_autoptr(GUsbContext) usb_context = NULL; g_autoptr(GPtrArray) devices = NULL; /* get all the DFU devices */ usb_context = g_usb_context_new (error); if (usb_context == NULL) return NULL; devices = g_usb_context_get_devices (usb_context); for (guint i = 0; i < devices->len; i++) { GUsbDevice *usb_device = g_ptr_array_index (devices, i); g_autoptr(FuCsrDevice) device = fu_csr_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), priv->quirks); if (fu_usb_device_probe (FU_USB_DEVICE (device), NULL)) return g_steal_pointer (&device); } /* unsupported */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "no supported devices found"); return NULL; } static gboolean fu_csr_tool_info (FuCsrToolPrivate *priv, gchar **values, GError **error) { g_autoptr(FuCsrDevice) device = fu_csr_get_default_device (priv, error); g_autofree gchar *str = NULL; if (device == NULL) return FALSE; if (!fu_usb_device_open (FU_USB_DEVICE (device), error)) return FALSE; str = fu_device_to_string (FU_DEVICE (device)); g_print ("%s", str); return TRUE; } static void fu_csr_tool_progress_cb (FuDevice *device, GParamSpec *pspec, FuCsrToolPrivate *priv) { fu_progressbar_update (priv->progressbar, fu_device_get_status (device), fu_device_get_progress (device)); } static gboolean fu_csr_tool_dump (FuCsrToolPrivate *priv, gchar **values, GError **error) { GUsbDevice *usb_device; g_autoptr(DfuElement) dfu_element = dfu_element_new (); g_autoptr(DfuFirmware) dfu_firmware = dfu_firmware_new (); g_autoptr(DfuImage) dfu_image = dfu_image_new (); g_autoptr(FuCsrDevice) device = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid arguments, expected FILENAME" " -- e.g. `firmware.hex`"); return FALSE; } /* upload from the device */ device = fu_csr_get_default_device (priv, error); if (device == NULL) return FALSE; if (!fu_usb_device_open (FU_USB_DEVICE (device), error)) return FALSE; g_signal_connect (device, "notify::status", G_CALLBACK (fu_csr_tool_progress_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_csr_tool_progress_cb), priv); blob = fu_csr_device_upload (device, error); if (blob == NULL) return FALSE; /* create DFU file */ usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); dfu_element_set_contents (dfu_element, blob); dfu_image_add_element (dfu_image, dfu_element); dfu_firmware_add_image (dfu_firmware, dfu_image); dfu_firmware_set_format (dfu_firmware, DFU_FIRMWARE_FORMAT_DFU); dfu_firmware_set_vid (dfu_firmware, g_usb_device_get_vid (usb_device)); dfu_firmware_set_pid (dfu_firmware, g_usb_device_get_pid (usb_device)); /* save file */ file = g_file_new_for_path (values[0]); return dfu_firmware_write_file (dfu_firmware, file, error); } static gboolean fu_csr_tool_write (FuCsrToolPrivate *priv, gchar **values, GError **error) { g_autoptr(FuCsrDevice) device = NULL; g_autoptr(GBytes) blob = NULL; /* check args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid arguments, expected " "FILENAME -- e.g. `firmware.hex`"); return FALSE; } /* get device */ device = fu_csr_get_default_device (priv, error); if (device == NULL) return FALSE; /* load firmware file */ blob = fu_common_get_contents_bytes (values[0], error); if (blob == NULL) return FALSE; /* write new firmware */ if (!fu_usb_device_open (FU_USB_DEVICE (device), error)) return FALSE; g_signal_connect (device, "notify::status", G_CALLBACK (fu_csr_tool_progress_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_csr_tool_progress_cb), priv); return fu_csr_device_download (device, blob, error); } static gboolean fu_csr_tool_attach (FuCsrToolPrivate *priv, gchar **values, GError **error) { g_autoptr(FuCsrDevice) device = NULL; device = fu_csr_get_default_device (priv, error); if (device == NULL) return FALSE; if (!fu_usb_device_open (FU_USB_DEVICE (device), error)) return FALSE; return fu_csr_device_attach (device, error); } int main (int argc, char **argv) { gboolean verbose = FALSE; g_autofree gchar *cmd_descriptions = NULL; g_autoptr(GError) error = NULL; g_autoptr(GOptionContext) context = NULL; g_autoptr(FuCsrToolPrivate) priv = g_new0 (FuCsrToolPrivate, 1); const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Print verbose debug statements", NULL }, { NULL} }; setlocale (LC_ALL, ""); priv->progressbar = fu_progressbar_new (); fu_progressbar_set_length_percentage (priv->progressbar, 50); fu_progressbar_set_length_status (priv->progressbar, 20); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_csr_tool_item_free); fu_csr_tool_add (priv->cmd_array, "info", NULL, "Show information about the device", fu_csr_tool_info); fu_csr_tool_add (priv->cmd_array, "write", "FILENAME", "Update the firmware", fu_csr_tool_write); fu_csr_tool_add (priv->cmd_array, "dump", "FILENAME", "Dump the firmware", fu_csr_tool_dump); fu_csr_tool_add (priv->cmd_array, "attach", NULL, "Attach to firmware mode", fu_csr_tool_attach); /* sort by command name */ g_ptr_array_sort (priv->cmd_array, (GCompareFunc) fu_csr_tool_sort_command_name_cb); /* get a list of the commands */ context = g_option_context_new (NULL); cmd_descriptions = fu_csr_tool_get_descriptions (priv->cmd_array); g_option_context_set_summary (context, cmd_descriptions); g_set_application_name ("CSR Debug Tool"); g_option_context_add_main_entries (context, options, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("%s: %s\n", "Failed to parse arguments", error->message); return EXIT_FAILURE; } /* set verbose? */ if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); /* use quirks */ priv->quirks = fu_quirks_new (); if (!fu_quirks_load (priv->quirks, &error)) { g_print ("Failed to load quirks: %s\n", error->message); return EXIT_FAILURE; } /* run the specified command */ if (!fu_csr_tool_run (priv, argv[1], (gchar**) &argv[2], &error)) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_autofree gchar *tmp = NULL; tmp = g_option_context_get_help (context, TRUE, NULL); g_print ("%s\n\n%s", error->message, tmp); } else { g_print ("%s\n", error->message); } return EXIT_FAILURE; } return 0; } fwupd-1.0.6/plugins/csr/fu-plugin-csr.c000066400000000000000000000050101325145456600177610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-csr-device.h" gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(FuCsrDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; device = fu_csr_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), fu_plugin_get_quirks (plugin)); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *device, FuPluginVerifyFlags flags, GError **error) { g_autoptr(GBytes) blob_fw = NULL; g_autoptr(FuDeviceLocker) locker = NULL; GChecksumType checksum_types[] = { G_CHECKSUM_SHA1, G_CHECKSUM_SHA256, 0 }; /* get data */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; blob_fw = fu_csr_device_upload (FU_CSR_DEVICE (device), error); if (blob_fw == NULL) return FALSE; for (guint i = 0; checksum_types[i] != 0; i++) { g_autofree gchar *hash = NULL; hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw); fu_device_add_checksum (device, hash); } return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { g_autoptr(FuDeviceLocker) locker = NULL; locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!fu_csr_device_download (FU_CSR_DEVICE (device), blob_fw, error)) return FALSE; return fu_csr_device_attach (FU_CSR_DEVICE (device), error); } fwupd-1.0.6/plugins/csr/meson.build000066400000000000000000000017271325145456600172770ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginCsr"'] install_data([ 'csr-aiaiai-h05.quirk', 'csr-aiaiai-h60.quirk', ], install_dir: join_paths(datadir, 'fwupd', 'quirks.d') ) shared_module('fu_plugin_csr', sources : [ 'fu-csr-device.c', 'fu-plugin-csr.c', ], include_directories : [ include_directories('../..'), include_directories('../dfu'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], link_with : [ dfu, ], ) executable( 'fu-csr-tool', sources : [ 'fu-csr-device.c', 'fu-csr-tool.c', ], include_directories : [ include_directories('../..'), include_directories('../dfu'), include_directories('../../libfwupd'), include_directories('../../src'), ], dependencies : [ plugin_deps, ], link_with : [ dfu, fwupd, libfwupdprivate, ], c_args : cargs, ) fwupd-1.0.6/plugins/dell/000077500000000000000000000000001325145456600152575ustar00rootroot00000000000000fwupd-1.0.6/plugins/dell/README.md000066400000000000000000000124531325145456600165430ustar00rootroot00000000000000Dell Support ============ Introduction ------------ This allows installing Dell capsules that are not part of the ESRT table. Build Requirements ------------------ For Dell support you will need libsmbios_c version 2.3.0 or later and efivar. * source: http://linux.dell.com/cgi-bin/cgit.cgi/libsmbios.git/ * rpms: https://apps.fedoraproject.org/packages/libsmbios * debs (Debian): http://tracker.debian.org/pkg/libsmbios * debs (Ubuntu): http://launchpad.net/ubuntu/+source/libsmbios If you don't want or need this functionality you can use the `--disable-dell` option. # Devices powered by the Dell Plugin The Dell plugin creates device nodes for PC's that have switchable TPMs as well as the Type-C docks (WD15/TB16). These device nodes can be flashed using UEFI capsule (and fwupdate) but don't use the ESRT table to communicate device status or version information. This is intentional behavior because more complicated decisions need to be made on the OS side to determine if the devices should be offered to flash. ## Switchable TPM Devices Machines with switchable TPMs can operate in both TPM 1.2 and TPM 2.0 modes. Switching modes will require flashing an alternative firmware and clearing the contents of the TPM. Machines that offer this functionality will display two devices in ```# fwupdmgr get-devices``` output. Example (from a *Precision 5510*): ``` Precision 5510 TPM 1.2 Guid: b2088ba1-51ae-514e-8f0a-64756c6e4ffc DeviceID: DELL-b2088ba1-51ae-514e-8f0a-64756c6e4ffclu Plugin: dell Flags: internal|allow-offline|require-ac Version: 5.81.0.0 Created: 2016-07-19 Precision 5510 TPM 2.0 Guid: 475d9bbd-1b7a-554e-8ca7-54985174a962 DeviceID: DELL-475d9bbd-1b7a-554e-8ca7-54985174a962lu Plugin: dell Flags: internal|require-ac|locked Created: 2016-07-19 ``` In this example, the TPM is currently operating in **TPM 1.2 mode**. Any firmware updates posted to *LVFS* for TPM 1.2 mode will be applied. ### Switching TPM Modes In order to be offered to switch the TPM to **TPM 2.0 mode**, the virtual device representing the *TPM 2.0 mode* will need to be unlocked. ```# fwupdmgr unlock DELL-475d9bbd-1b7a-554e-8ca7-54985174a962lu``` If the TPM is currently *owned*, an error will be displayed such as this one: ERROR: Precision 5510 TPM 1.2 is currently OWNED. Ownership must be removed to switch modes. TPM Ownership can be cleared from within the BIOS setup menus. If the unlock process was successful, then the devices will be modified: ``` Precision 5510 TPM 1.2 Guid: b2088ba1-51ae-514e-8f0a-64756c6e4ffc DeviceID: DELL-b2088ba1-51ae-514e-8f0a-64756c6e4ffclu Plugin: dell Flags: internal|require-ac Version: 5.81.0.0 Created: 2016-07-19 Precision 5510 TPM 2.0 Guid: 475d9bbd-1b7a-554e-8ca7-54985174a962 DeviceID: DELL-475d9bbd-1b7a-554e-8ca7-54985174a962lu Plugin: dell Flags: internal|allow-offline|require-ac Version: 0.0.0.0 Created: 2016-07-19 Modified: 2016-07-19 ``` Now the firmware for TPM 2.0 mode can be pulled down from LVFS and flashed: ```# fwupdmgr update``` Upon the next reboot, the new TPM firmware will be flashed. If the firmware is *not offered from LVFS*, then switching modes may not work on this machine. After updating the output from ```# fwupdmgr get-devices``` will reflect the new mode. ``` Precision 5510 TPM 2.0 Guid: 475d9bbd-1b7a-554e-8ca7-54985174a962 DeviceID: DELL-475d9bbd-1b7a-554e-8ca7-54985174a962lu Plugin: dell Flags: internal|allow-offline|require-ac Version: 1.3.0.1 Created: 2016-07-20 Precision 5510 TPM 1.2 Guid: b2088ba1-51ae-514e-8f0a-64756c6e4ffc DeviceID: DELL-b2088ba1-51ae-514e-8f0a-64756c6e4ffclu Plugin: dell Flags: internal|require-ac|locked Created: 2016-07-20 ``` Keep in mind that **TPM 1.2** and **TPM 2.0** will require different userspace tools. ## Dock Devices The *TB16* and *WD15* have a variety of updatable components. Each component will create a virtual device in ```# fwupdmgr get-devices``` For example the WD15 will display these components: ``` Dell WD15 Port Controller 1 Guid: 8ba2b709-6f97-47fc-b7e7-6a87b578fe25 DeviceID: DELL-8ba2b709-6f97-47fc-b7e7-6a87b578fe25lu Plugin: dell Flags: allow-offline|require-ac Version: 0.1.1.8 Created: 2016-07-19 Dell WD15 Guid: e7ca1f36-bf73-4574-afe6-a4ccacabf479 DeviceID: DELL-e7ca1f36-bf73-4574-afe6-a4ccacabf479lu Plugin: dell Flags: allow-offline|require-ac Version: 0.0.0.67 Created: 2016-07-19 ``` Components that can be updated via UEFI capsule will have the ```allow-offline``` moniker applied. These updates can be performed the standard method of using: ```# fwupdmgr update``` Some components are updatable via other plugins in fwupd such as multi stream transport hub (MST) and thunderbolt NVM. fwupd-1.0.6/plugins/dell/dell.quirk000066400000000000000000000002611325145456600172530ustar00rootroot00000000000000[fwupd-uefi-version-format] # Dell & Alienware use AA.BB.CC.DD rather than AA.BB.CCDD Dell Inc.=none Alienware=none [fwupd-daemon-version-format] com.dell.uefi*.firmware=none fwupd-1.0.6/plugins/dell/fu-dell-smi.c000066400000000000000000000150771325145456600175530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Mario Limonciello * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-dell-smi.h" /* These are for dock query capabilities */ struct dock_count_in { guint32 argument; guint32 reserved1; guint32 reserved2; guint32 reserved3; }; struct dock_count_out { guint32 ret; guint32 count; guint32 location; guint32 reserved; }; /* This is used for host flash GUIDs */ typedef union _ADDR_UNION{ uint8_t *buf; efi_guid_t *guid; } ADDR_UNION; #pragma pack() static void _dell_smi_obj_free (FuDellSmiObj *obj) { dell_smi_obj_free (obj->smi); g_free(obj); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (FuDellSmiObj, _dell_smi_obj_free); /* don't actually clear if we're testing */ gboolean fu_dell_clear_smi (FuDellSmiObj *obj) { if (obj->fake_smbios) return TRUE; for (gint i=0; i < 4; i++) { obj->input[i] = 0; obj->output[i] = 0; } return TRUE; } gboolean fu_dell_execute_smi (FuDellSmiObj *obj) { gint ret; if (obj->fake_smbios) return TRUE; ret = dell_smi_obj_execute (obj->smi); if (ret != 0) { g_debug ("SMI execution failed: %i", ret); return FALSE; } return TRUE; } guint32 fu_dell_get_res (FuDellSmiObj *smi_obj, guint8 arg) { if (smi_obj->fake_smbios) return smi_obj->output[arg]; return dell_smi_obj_get_res (smi_obj->smi, arg); } gboolean fu_dell_execute_simple_smi (FuDellSmiObj *obj, guint16 class, guint16 select) { /* test suite will mean don't actually call */ if (obj->fake_smbios) return TRUE; if (dell_simple_ci_smi (class, select, obj->input, obj->output)) { g_debug ("failed to run query %u/%u", class, select); return FALSE; } return TRUE; } gboolean fu_dell_detect_dock (FuDellSmiObj *smi_obj, guint32 *location) { struct dock_count_in *count_args; struct dock_count_out *count_out; /* look up dock count */ count_args = (struct dock_count_in *) smi_obj->input; count_out = (struct dock_count_out *) smi_obj->output; if (!fu_dell_clear_smi (smi_obj)) { g_debug ("failed to clear SMI buffers"); return FALSE; } count_args->argument = DACI_DOCK_ARG_COUNT; if (!fu_dell_execute_simple_smi (smi_obj, DACI_DOCK_CLASS, DACI_DOCK_SELECT)) return FALSE; if (count_out->ret != 0) { g_debug ("Failed to query system for dock count: " "(%" G_GUINT32_FORMAT ")", count_out->ret); return FALSE; } if (count_out->count < 1) { g_debug ("no dock plugged in"); return FALSE; } if (location != NULL) *location = count_out->location; return TRUE; } gboolean fu_dell_query_dock (FuDellSmiObj *smi_obj, DOCK_UNION *buf) { gint result; guint32 location; guint buf_size; if (!fu_dell_detect_dock (smi_obj, &location)) return FALSE; fu_dell_clear_smi (smi_obj); /* look up more information on dock */ if (smi_obj->fake_smbios) buf->buf = smi_obj->fake_buffer; else { dell_smi_obj_set_class (smi_obj->smi, DACI_DOCK_CLASS); dell_smi_obj_set_select (smi_obj->smi, DACI_DOCK_SELECT); dell_smi_obj_set_arg (smi_obj->smi, cbARG1, DACI_DOCK_ARG_INFO); dell_smi_obj_set_arg (smi_obj->smi, cbARG2, location); buf_size = sizeof (DOCK_INFO_RECORD); buf->buf = dell_smi_obj_make_buffer_frombios_auto (smi_obj->smi, cbARG3, buf_size); if (!buf->buf) { g_debug ("Failed to initialize buffer"); return FALSE; } } if (!fu_dell_execute_smi (smi_obj)) return FALSE; result = fu_dell_get_res (smi_obj, cbARG1); if (result != SMI_SUCCESS) { if (result == SMI_INVALID_BUFFER) { g_debug ("Invalid buffer size, needed %" G_GUINT32_FORMAT, fu_dell_get_res (smi_obj, cbARG2)); } else { g_debug ("SMI execution returned error: %d", result); } return FALSE; } return TRUE; } const gchar* fu_dell_get_dock_type (guint8 type) { g_autoptr (FuDellSmiObj) smi_obj = NULL; DOCK_UNION buf; /* not yet initialized, look it up */ if (type == DOCK_TYPE_NONE) { smi_obj = g_malloc0 (sizeof(FuDellSmiObj)); smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS); if (!fu_dell_query_dock (smi_obj, &buf)) return NULL; type = buf.record->dock_info_header.dock_type; } switch (type) { case DOCK_TYPE_TB16: return "TB16"; case DOCK_TYPE_WD15: return "WD15"; default: g_debug ("Dock type %d unknown", type); } return NULL; } gboolean fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode, guint32 dock_location, GError **error) { /* Put into mode to accept AR/MST */ fu_dell_clear_smi (smi_obj); smi_obj->input[0] = DACI_DOCK_ARG_MODE; smi_obj->input[1] = dock_location; smi_obj->input[2] = new_mode; if (!fu_dell_execute_simple_smi (smi_obj, DACI_DOCK_CLASS, DACI_DOCK_SELECT)) return FALSE; if (smi_obj->output[1] != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to set dock flash mode: %u", smi_obj->output[1]); return FALSE; } return TRUE; } gboolean fu_dell_toggle_host_mode (FuDellSmiObj *smi_obj, const efi_guid_t guid, int mode) { gint ret; ADDR_UNION buf; dell_smi_obj_set_class (smi_obj->smi, DACI_FLASH_INTERFACE_CLASS); dell_smi_obj_set_select (smi_obj->smi, DACI_FLASH_INTERFACE_SELECT); dell_smi_obj_set_arg (smi_obj->smi, cbARG1, DACI_FLASH_ARG_FLASH_MODE); dell_smi_obj_set_arg (smi_obj->smi, cbARG4, mode); /* needs to be padded with an empty GUID */ buf.buf = dell_smi_obj_make_buffer_frombios_withoutheader(smi_obj->smi, cbARG2, sizeof(efi_guid_t) * 2); if (!buf.buf) { g_debug ("Failed to initialize SMI buffer"); return FALSE; } *buf.guid = guid; ret = dell_smi_obj_execute(smi_obj->smi); if (ret != SMI_SUCCESS){ g_debug ("failed to execute SMI: %d", ret); return FALSE; } ret = dell_smi_obj_get_res(smi_obj->smi, cbRES1); if (ret != SMI_SUCCESS) { g_debug ("SMI execution returned error: %d", ret); return FALSE; } return TRUE; }fwupd-1.0.6/plugins/dell/fu-dell-smi.h000066400000000000000000000073471325145456600175610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Mario Limonciello * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_DELL_COMMON_H #define __FU_DELL_COMMON_H #include "fu-device.h" #include #include #include typedef struct { struct dell_smi_obj *smi; guint32 input[4]; guint32 output[4]; gboolean fake_smbios; guint8 *fake_buffer; } FuDellSmiObj; /* Dock Info version 1 */ #pragma pack(1) #define MAX_COMPONENTS 5 typedef struct _COMPONENTS { gchar description[80]; guint32 fw_version; /* BCD format: 0x00XXYYZZ */ } COMPONENTS; typedef struct _DOCK_INFO { gchar dock_description[80]; guint32 flash_pkg_version; /* BCD format: 0x00XXYYZZ */ guint32 cable_type; /* bit0-7 cable type, bit7-31 set to 0 */ guint8 location; /* Location of the dock */ guint8 reserved; guint8 component_count; COMPONENTS components[MAX_COMPONENTS]; /* number of component_count */ } DOCK_INFO; typedef struct _DOCK_INFO_HEADER { guint8 dir_version; /* version 1, 2 … */ guint8 dock_type; guint16 reserved; } DOCK_INFO_HEADER; typedef struct _DOCK_INFO_RECORD { DOCK_INFO_HEADER dock_info_header; /* dock version specific definition */ DOCK_INFO dock_info; } DOCK_INFO_RECORD; typedef union _DOCK_UNION{ guint8 *buf; DOCK_INFO_RECORD *record; } DOCK_UNION; #pragma pack() typedef enum _DOCK_TYPE { DOCK_TYPE_NONE, DOCK_TYPE_TB16, DOCK_TYPE_WD15 } DOCK_TYPE; typedef enum _CABLE_TYPE { CABLE_TYPE_NONE, CABLE_TYPE_LEGACY, CABLE_TYPE_UNIV, CABLE_TYPE_TBT } CABLE_TYPE; gboolean fu_dell_clear_smi (FuDellSmiObj *obj); guint32 fu_dell_get_res (FuDellSmiObj *smi_obj, guint8 arg); gboolean fu_dell_execute_smi (FuDellSmiObj *obj); gboolean fu_dell_execute_simple_smi (FuDellSmiObj *obj, guint16 class, guint16 select); gboolean fu_dell_detect_dock (FuDellSmiObj *obj, guint32 *location); gboolean fu_dell_query_dock (FuDellSmiObj *smi_obj, DOCK_UNION *buf); const gchar* fu_dell_get_dock_type (guint8 type); gboolean fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode, guint32 dock_location, GError **error); gboolean fu_dell_toggle_host_mode (FuDellSmiObj *smi_obj, const efi_guid_t guid, int mode); /* SMI return values used */ #define SMI_SUCCESS 0 #define SMI_INVALID_BUFFER -6 /* These are DACI class/select needed for * flash capability queries */ #define DACI_FLASH_INTERFACE_CLASS 7 #define DACI_FLASH_INTERFACE_SELECT 3 #define DACI_FLASH_ARG_TPM 2 #define DACI_FLASH_ARG_FLASH_MODE 3 #define DACI_FLASH_MODE_USER 0 #define DACI_FLASH_MODE_FLASH 1 /* DACI class/select for dock capabilities */ #define DACI_DOCK_CLASS 17 #define DACI_DOCK_SELECT 22 #define DACI_DOCK_ARG_COUNT 0 #define DACI_DOCK_ARG_INFO 1 #define DACI_DOCK_ARG_MODE 2 #define DACI_DOCK_ARG_MODE_USER 0 #define DACI_DOCK_ARG_MODE_FLASH 1 /* VID/PID of ethernet controller on dock */ #define DOCK_NIC_VID 0x0bda #define DOCK_NIC_PID 0x8153 #endif /* __FU_DELL_COMMON_H */ fwupd-1.0.6/plugins/dell/fu-plugin-dell.c000066400000000000000000001042341325145456600202530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * Copyright (C) 2016 Mario Limonciello * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include #include "fu-plugin-dell.h" #include "fu-plugin-vfuncs.h" #include "fu-device-metadata.h" /* These are used to indicate the status of a previous DELL flash */ #define DELL_SUCCESS 0x0000 #define DELL_CONSISTENCY_FAIL 0x0001 #define DELL_FLASH_MEMORY_FAIL 0x0002 #define DELL_FLASH_NOT_READY 0x0003 #define DELL_FLASH_DISABLED 0x0004 #define DELL_BATTERY_MISSING 0x0005 #define DELL_BATTERY_DEAD 0x0006 #define DELL_AC_MISSING 0x0007 #define DELL_CANT_SET_12V 0x0008 #define DELL_CANT_UNSET_12V 0x0009 #define DELL_FAILURE_BLOCK_ERASE 0x000A #define DELL_GENERAL_FAILURE 0x000B #define DELL_DATA_MISCOMPARE 0x000C #define DELL_IMAGE_MISSING 0x000D #define DELL_DID_NOTHING 0xFFFF /* Delay for settling */ #define DELL_FLASH_MODE_DELAY 2 typedef struct _DOCK_DESCRIPTION { const efi_guid_t guid; const gchar * query; const gchar * desc; } DOCK_DESCRIPTION; /* These are for matching the components */ #define WD15_EC_STR "2 0 2 2 0" #define TB16_EC_STR "2 0 2 1 0" #define TB16_PC2_STR "2 1 0 1 1" #define TB16_PC1_STR "2 1 0 1 0" #define WD15_PC1_STR "2 1 0 2 0" #define LEGACY_CBL_STR "2 2 2 1 0" #define UNIV_CBL_STR "2 2 2 2 0" #define TBT_CBL_STR "2 2 2 3 0" /* supported dock related GUIDs */ #define DOCK_FLASH_GUID EFI_GUID (0xE7CA1F36, 0xBF73, 0x4574, 0xAFE6, 0xA4, 0xCC, 0xAC, 0xAB, 0xF4, 0x79) #define WD15_EC_GUID EFI_GUID (0xE8445370, 0x0211, 0x449D, 0x9FAA, 0x10, 0x79, 0x06, 0xAB, 0x18, 0x9F) #define TB16_EC_GUID EFI_GUID (0x33CC8870, 0xB1FC, 0x4EC7, 0x948A, 0xC0, 0x74, 0x96, 0x87, 0x4F, 0xAF) #define TB16_PC2_GUID EFI_GUID (0x1B52C630, 0x86F6, 0x4AEE, 0x9F0C, 0x47, 0x4D, 0xC6, 0xBE, 0x49, 0xB6) #define TB16_PC1_GUID EFI_GUID (0x8FE183DA, 0xC94E, 0x4804, 0xB319, 0x0F, 0x1B, 0xA5, 0x45, 0x7A, 0x69) #define WD15_PC1_GUID EFI_GUID (0x8BA2B709, 0x6F97, 0x47FC, 0xB7E7, 0x6A, 0x87, 0xB5, 0x78, 0xFE, 0x25) #define LEGACY_CBL_GUID EFI_GUID (0xFECE1537, 0xD683, 0x4EA8, 0xB968, 0x15, 0x45, 0x30, 0xBB, 0x6F, 0x73) #define UNIV_CBL_GUID EFI_GUID (0xE2BF3AAD, 0x61A3, 0x44BF, 0x91EF, 0x34, 0x9B, 0x39, 0x51, 0x5D, 0x29) #define TBT_CBL_GUID EFI_GUID (0x6DC832FC, 0x5BB0, 0x4E63, 0xA2FF, 0x02, 0xAA, 0xBA, 0x5B, 0xC1, 0xDC) #define EC_DESC "EC" #define PC1_DESC "Port Controller 1" #define PC2_DESC "Port Controller 2" #define LEGACY_CBL_DESC "Passive Cable" #define UNIV_CBL_DESC "Universal Cable" #define TBT_CBL_DESC "Thunderbolt Cable" /* supported host related GUIDs */ #define MST_GPIO_GUID EFI_GUID (0xF24F9bE4, 0x2a13, 0x4344, 0xBC05, 0x01, 0xCE, 0xF7, 0xDA, 0xEF, 0x92) /** * Devices that should allow modeswitching */ static guint16 tpm_switch_whitelist[] = {0x06F2, 0x06F3, 0x06DD, 0x06DE, 0x06DF, 0x06DB, 0x06DC, 0x06BB, 0x06C6, 0x06BA, 0x06B9, 0x05CA, 0x06C7, 0x06B7, 0x06E0, 0x06E5, 0x06D9, 0x06DA, 0x06E4, 0x0704, 0x0720, 0x0730, 0x0758, 0x0759, 0x075B, 0x07A0, 0x079F, 0x07A4, 0x07A5, 0x07A6, 0x07A7, 0x07A8, 0x07A9, 0x07AA, 0x07AB, 0x07B0, 0x07B1, 0x07B2, 0x07B4, 0x07B7, 0x07B8, 0x07B9, 0x07BE, 0x07BF, 0x077A, 0x07CF}; /** * Dell device types to run */ static guint8 enclosure_whitelist [] = { 0x03, /* desktop */ 0x04, /* low profile desktop */ 0x06, /* mini tower */ 0x07, /* tower */ 0x08, /* portable */ 0x09, /* laptop */ 0x0A, /* notebook */ 0x0D, /* AIO */ 0x1E, /* tablet */ 0x1F, /* convertible */ 0x21, /* IoT gateway */ 0x22, /* embedded PC */}; /** * System blacklist on older libsmbios */ static guint16 system_blacklist [] = { 0x071E, /* latitude 5414 */ 0x07A8, /* latitude 5580 */ 0x077A, /* xps 9365 */ }; /** * Systems containing host MST device */ static guint16 systems_host_mst [] = { 0x062d, /* Latitude E7250 */ 0x062e, /* Latitude E7450 */ 0x062a, /* Latitude E5250 */ 0x062b, /* Latitude E5450 */ 0x062c, /* Latitude E5550 */ 0x06db, /* Latitude E7270 */ 0x06dc, /* Latitude E7470 */ 0x06dd, /* Latitude E5270 */ 0x06de, /* Latitude E5470 */ 0x06df, /* Latitude E5570 */ 0x06e0, /* Precision 3510 */ 0x071d, /* Latitude Rugged 7214 */ 0x071e, /* Latitude Rugged 5414 */ 0x071c, /* Latitude Rugged 7414 */}; static void _fwup_resource_iter_free (fwup_resource_iter *iter) { fwup_resource_iter_destroy (&iter); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (fwup_resource_iter, _fwup_resource_iter_free); static guint16 fu_dell_get_system_id (FuPlugin *plugin) { const gchar *system_id_str = NULL; guint16 system_id = 0; gchar *endptr = NULL; system_id_str = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_SKU); if (system_id_str != NULL) system_id = g_ascii_strtoull (system_id_str, &endptr, 16); if (system_id == 0 || endptr == system_id_str) system_id = (guint16) sysinfo_get_dell_system_id (); return system_id; } static gboolean fu_dell_host_mst_supported (FuPlugin *plugin) { guint16 system_id; system_id = fu_dell_get_system_id (plugin); if (system_id == 0) return FALSE; for (guint i = 0; i < G_N_ELEMENTS (systems_host_mst); i++) if (systems_host_mst[i] == system_id) return TRUE; return FALSE; } static gboolean fu_dell_supported (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); GBytes *de_table = NULL; GBytes *enclosure = NULL; guint16 system_id = 0; const guint8 *value; gsize len; /* make sure that Dell SMBIOS methods are available */ de_table = fu_plugin_get_smbios_data (plugin, 0xDE); if (de_table == NULL) return FALSE; value = g_bytes_get_data (de_table, &len); if (len == 0) return FALSE; if (*value != 0xDE) return FALSE; /* skip blacklisted hw on libsmbios 2.3 or less */ if (data->libsmbios_major <= 2 && data->libsmbios_minor <= 3) { system_id = fu_dell_get_system_id (plugin); if (system_id == 0) return FALSE; for (guint i = 0; i < G_N_ELEMENTS (system_blacklist); i++) { if (system_blacklist[i] == system_id) return FALSE; } } /* only run on intended Dell hw types */ enclosure = fu_plugin_get_smbios_data (plugin, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS); if (enclosure == NULL) return FALSE; value = g_bytes_get_data (enclosure, &len); if (len == 0) return FALSE; for (guint i = 0; i < G_N_ELEMENTS (enclosure_whitelist); i++) { if (enclosure_whitelist[i] == value[0]) return TRUE; } return FALSE; } static gboolean fu_plugin_dell_match_dock_component (const gchar *query_str, efi_guid_t *guid_out, const gchar **name_out) { const DOCK_DESCRIPTION list[] = { {WD15_EC_GUID, WD15_EC_STR, EC_DESC}, {TB16_EC_GUID, TB16_EC_STR, EC_DESC}, {WD15_PC1_GUID, WD15_PC1_STR, PC1_DESC}, {TB16_PC1_GUID, TB16_PC1_STR, PC1_DESC}, {TB16_PC2_GUID, TB16_PC2_STR, PC2_DESC}, {TBT_CBL_GUID, TBT_CBL_STR, TBT_CBL_DESC}, {UNIV_CBL_GUID, UNIV_CBL_STR, UNIV_CBL_DESC}, {LEGACY_CBL_GUID, LEGACY_CBL_STR, LEGACY_CBL_DESC}, }; for (guint i = 0; i < G_N_ELEMENTS (list); i++) { if (g_strcmp0 (query_str, list[i].query) == 0) { memcpy (guid_out, &list[i].guid, sizeof (efi_guid_t)); *name_out = list[i].desc; return TRUE; } } return FALSE; } void fu_plugin_dell_inject_fake_data (FuPlugin *plugin, guint32 *output, guint16 vid, guint16 pid, guint8 *buf, gboolean can_switch_modes) { FuPluginData *data = fu_plugin_get_data (plugin); if (!data->smi_obj->fake_smbios) return; for (guint i = 0; i < 4; i++) data->smi_obj->output[i] = output[i]; data->fake_vid = vid; data->fake_pid = pid; data->smi_obj->fake_buffer = buf; data->can_switch_modes = TRUE; } static AsVersionParseFlag fu_plugin_dell_get_version_format (FuPlugin *plugin) { const gchar *content; const gchar *quirk; content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER); if (content == NULL) return AS_VERSION_PARSE_FLAG_USE_TRIPLET; /* any quirks match */ quirk = fu_plugin_lookup_quirk_by_id (plugin, FU_QUIRKS_UEFI_VERSION_FORMAT, content); if (g_strcmp0 (quirk, "none") == 0) return AS_VERSION_PARSE_FLAG_NONE; /* fall back */ return AS_VERSION_PARSE_FLAG_USE_TRIPLET; } static gchar * fu_plugin_get_dock_key (FuPlugin *plugin, GUsbDevice *device, const gchar *guid) { FuPluginData *data = fu_plugin_get_data (plugin); const gchar* platform_id; if (data->smi_obj->fake_smbios) platform_id = "fake"; else platform_id = g_usb_device_get_platform_id (device); return g_strdup_printf ("%s_%s", platform_id, guid); } static gboolean fu_plugin_dell_capsule_supported (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); return data->smi_obj->fake_smbios || data->capsule_supported; } static gboolean fu_plugin_dock_node (FuPlugin *plugin, GUsbDevice *device, guint8 type, const efi_guid_t *guid_raw, const gchar *component_desc, const gchar *version) { const gchar *dock_type; g_autofree gchar *dock_id = NULL; g_autofree gchar *guid_str = NULL; g_autofree gchar *dock_key = NULL; g_autofree gchar *dock_name = NULL; g_autoptr(FuDevice) dev = NULL; dock_type = fu_dell_get_dock_type (type); if (dock_type == NULL) { g_debug ("Unknown dock type %d", type); return FALSE; } guid_str = g_strdup ("00000000-0000-0000-0000-000000000000"); if (efi_guid_to_str (guid_raw, &guid_str) < 0) { g_debug ("Failed to convert GUID."); return FALSE; } dock_key = fu_plugin_get_dock_key (plugin, device, guid_str); if (fu_plugin_cache_lookup (plugin, dock_key) != NULL) { g_debug ("%s is already registered.", dock_key); return FALSE; } dev = fu_device_new (); dock_id = g_strdup_printf ("DELL-%s" G_GUINT64_FORMAT, guid_str); dock_name = g_strdup_printf ("Dell %s %s", dock_type, component_desc); fu_device_set_id (dev, dock_id); fu_device_set_vendor (dev, "Dell Inc."); fu_device_set_name (dev, dock_name); if (type == DOCK_TYPE_TB16) { fu_device_set_summary (dev, "A Thunderbolt™ 3 docking station"); } else if (type == DOCK_TYPE_WD15) { fu_device_set_summary (dev, "A USB type-C docking station"); } fu_device_add_icon (dev, "computer"); fu_device_add_guid (dev, guid_str); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC); if (version != NULL) { fu_device_set_version (dev, version); if (fu_plugin_dell_capsule_supported (plugin)) { fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT); } } fu_plugin_device_add (plugin, dev); fu_plugin_cache_add (plugin, dock_key, dev); return TRUE; } void fu_plugin_dell_device_added_cb (GUsbContext *ctx, GUsbDevice *device, FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); AsVersionParseFlag parse_flags; guint16 pid; guint16 vid; const gchar *query_str; const gchar *component_name = NULL; DOCK_UNION buf; DOCK_INFO *dock_info; efi_guid_t guid_raw; efi_guid_t tmpguid; gboolean old_ec = FALSE; /* don't look up immediately if a dock is connected as that would mean a SMI on every USB device that showed up on the system */ if (!data->smi_obj->fake_smbios) { vid = g_usb_device_get_vid (device); pid = g_usb_device_get_pid (device); } else { vid = data->fake_vid; pid = data->fake_pid; } /* we're going to match on the Realtek NIC in the dock */ if (vid != DOCK_NIC_VID || pid != DOCK_NIC_PID) return; buf.buf = NULL; if (!fu_dell_query_dock (data->smi_obj, &buf)) { g_debug ("No dock detected."); return; } if (buf.record->dock_info_header.dir_version != 1) { g_debug ("Dock info header version unknown: %d", buf.record->dock_info_header.dir_version); return; } dock_info = &buf.record->dock_info; g_debug ("Dock description: %s", dock_info->dock_description); /* Note: fw package version is deprecated, look at components instead */ g_debug ("Dock flash pkg ver: 0x%x", dock_info->flash_pkg_version); if (dock_info->flash_pkg_version == 0x00ffffff) g_debug ("WARNING: dock flash package version invalid"); g_debug ("Dock cable type: %" G_GUINT32_FORMAT, dock_info->cable_type); g_debug ("Dock location: %d", dock_info->location); g_debug ("Dock component count: %d", dock_info->component_count); parse_flags = fu_plugin_dell_get_version_format (plugin); for (guint i = 0; i < dock_info->component_count; i++) { g_autofree gchar *fw_str = NULL; if (i >= MAX_COMPONENTS) { g_debug ("Too many components. Invalid: #%u", i); break; } g_debug ("Dock component %u: %s (version 0x%x)", i, dock_info->components[i].description, dock_info->components[i].fw_version); query_str = g_strrstr (dock_info->components[i].description, "Query "); if (query_str == NULL) { g_debug ("Invalid dock component request"); return; } if (!fu_plugin_dell_match_dock_component (query_str + 6, &guid_raw, &component_name)) { g_debug ("Unable to match dock component %s", query_str); return; } /* dock EC hasn't been updated for first time */ if (dock_info->flash_pkg_version == 0x00ffffff) { old_ec = TRUE; dock_info->flash_pkg_version = 0; continue; } /* if invalid version, don't mark device for updates */ else if (dock_info->components[i].fw_version == 0 || dock_info->components[i].fw_version == 0xffffffff) { old_ec = TRUE; continue; } fw_str = as_utils_version_from_uint32 (dock_info->components[i].fw_version, parse_flags); if (!fu_plugin_dock_node (plugin, device, buf.record->dock_info_header.dock_type, &guid_raw, component_name, fw_str)) { g_debug ("Failed to create %s", component_name); return; } } /* if an old EC or invalid EC version found, create updatable parent */ if (old_ec) { g_autofree gchar *fw_str = NULL; tmpguid = DOCK_FLASH_GUID; fw_str = as_utils_version_from_uint32 (dock_info->flash_pkg_version, parse_flags); if (!fu_plugin_dock_node (plugin, device, buf.record->dock_info_header.dock_type, &tmpguid, "", fw_str)) { g_debug ("Failed to create top dock node"); return; } } #if defined (HAVE_SYNAPTICS) fu_plugin_request_recoldplug (plugin); #endif } void fu_plugin_dell_device_removed_cb (GUsbContext *ctx, GUsbDevice *device, FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); const efi_guid_t guids[] = { WD15_EC_GUID, TB16_EC_GUID, TB16_PC2_GUID, TB16_PC1_GUID, WD15_PC1_GUID, LEGACY_CBL_GUID, UNIV_CBL_GUID, TBT_CBL_GUID, DOCK_FLASH_GUID}; const efi_guid_t *guid_raw; guint16 pid; guint16 vid; FuDevice *dev = NULL; if (!data->smi_obj->fake_smbios) { vid = g_usb_device_get_vid (device); pid = g_usb_device_get_pid (device); } else { vid = data->fake_vid; pid = data->fake_pid; } /* we're going to match on the Realtek NIC in the dock */ if (vid != DOCK_NIC_VID || pid != DOCK_NIC_PID) return; /* remove any components already in database? */ for (guint i = 0; i < G_N_ELEMENTS (guids); i++) { g_autofree gchar *dock_key = NULL; g_autofree gchar *guid_str = NULL; guid_raw = &guids[i]; guid_str = g_strdup ("00000000-0000-0000-0000-000000000000"); efi_guid_to_str (guid_raw, &guid_str); dock_key = fu_plugin_get_dock_key (plugin, device, guid_str); dev = fu_plugin_cache_lookup (plugin, dock_key); if (dev != NULL) { fu_plugin_device_remove (plugin, dev); fu_plugin_cache_remove (plugin, dock_key); } } #if defined (HAVE_SYNAPTICS) fu_plugin_request_recoldplug (plugin); #endif } gboolean fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error) { GBytes *de_table = NULL; const gchar *tmp = NULL; const guint16 *completion_code; gsize len; de_table = fu_plugin_get_smbios_data (plugin, 0xDE); completion_code = g_bytes_get_data (de_table, &len); if (len < 8) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "ERROR: Unable to read results of %s: %" G_GSIZE_FORMAT " < 8", fu_device_get_name (device), len); return FALSE; } /* look at byte offset 0x06 for identifier meaning completion code */ if (completion_code[3] == DELL_SUCCESS) { fu_device_set_update_state (device, FWUPD_UPDATE_STATE_SUCCESS); } else { fu_device_set_update_state (device, FWUPD_UPDATE_STATE_FAILED); switch (completion_code[3]) { case DELL_CONSISTENCY_FAIL: tmp = "The image failed one or more consistency checks."; break; case DELL_FLASH_MEMORY_FAIL: tmp = "The BIOS could not access the flash-memory device."; break; case DELL_FLASH_NOT_READY: tmp = "The flash-memory device was not ready when an erase was attempted."; break; case DELL_FLASH_DISABLED: tmp = "Flash programming is currently disabled on the system, or the voltage is low."; break; case DELL_BATTERY_MISSING: tmp = "A battery must be installed for the operation to complete."; break; case DELL_BATTERY_DEAD: tmp = "A fully-charged battery must be present for the operation to complete."; break; case DELL_AC_MISSING: tmp = "An external power adapter must be connected for the operation to complete."; break; case DELL_CANT_SET_12V: tmp = "The 12V required to program the flash-memory could not be set."; break; case DELL_CANT_UNSET_12V: tmp = "The 12V required to program the flash-memory could not be removed."; break; case DELL_FAILURE_BLOCK_ERASE : tmp = "A flash-memory failure occurred during a block-erase operation."; break; case DELL_GENERAL_FAILURE: tmp = "A general failure occurred during the flash programming."; break; case DELL_DATA_MISCOMPARE: tmp = "A data miscompare error occurred during the flash programming."; break; case DELL_IMAGE_MISSING: tmp = "The image could not be found in memory, i.e. the header could not be located."; break; case DELL_DID_NOTHING: tmp = "No update operation has been performed on the system."; break; default: break; } if (tmp != NULL) fu_device_set_update_error (device, tmp); } return TRUE; } gboolean fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); const gchar *tpm_mode; const gchar *tpm_mode_alt; guint16 system_id = 0; gboolean can_switch_modes = FALSE; g_autofree gchar *pretty_tpm_name_alt = NULL; g_autofree gchar *pretty_tpm_name = NULL; g_autofree gchar *tpm_guid_raw_alt = NULL; g_autofree gchar *tpm_guid_alt = NULL; g_autofree gchar *tpm_guid = NULL; g_autofree gchar *tpm_guid_raw = NULL; g_autofree gchar *tpm_id_alt = NULL; g_autofree gchar *tpm_id = NULL; g_autofree gchar *version_str = NULL; struct tpm_status *out = NULL; g_autoptr (FuDevice) dev_alt = NULL; g_autoptr (FuDevice) dev = NULL; const gchar *product_name = NULL; fu_dell_clear_smi (data->smi_obj); out = (struct tpm_status *) data->smi_obj->output; /* execute TPM Status Query */ data->smi_obj->input[0] = DACI_FLASH_ARG_TPM; if (!fu_dell_execute_simple_smi (data->smi_obj, DACI_FLASH_INTERFACE_CLASS, DACI_FLASH_INTERFACE_SELECT)) return FALSE; if (out->ret != 0) { g_debug ("Failed to query system for TPM information: " "(%" G_GUINT32_FORMAT ")", out->ret); return FALSE; } /* HW version is output in second /input/ arg * it may be relevant as next gen TPM is enabled */ g_debug ("TPM HW version: 0x%x", data->smi_obj->input[1]); g_debug ("TPM Status: 0x%x", out->status); /* test TPM enabled (Bit 0) */ if (!(out->status & TPM_EN_MASK)) { g_debug ("TPM not enabled (%x)", out->status); return FALSE; } /* test TPM mode to determine current mode */ if (((out->status & TPM_TYPE_MASK) >> 8) == TPM_1_2_MODE) { tpm_mode = "1.2"; tpm_mode_alt = "2.0"; } else if (((out->status & TPM_TYPE_MASK) >> 8) == TPM_2_0_MODE) { tpm_mode = "2.0"; tpm_mode_alt = "1.2"; } else { g_debug ("Unable to determine TPM mode"); return FALSE; } system_id = fu_dell_get_system_id (plugin); if (data->smi_obj->fake_smbios) can_switch_modes = data->can_switch_modes; else if (system_id == 0) return FALSE; for (guint i = 0; i < G_N_ELEMENTS (tpm_switch_whitelist); i++) { if (tpm_switch_whitelist[i] == system_id) { can_switch_modes = TRUE; } } tpm_guid_raw = g_strdup_printf ("%04x-%s", system_id, tpm_mode); tpm_guid = as_utils_guid_from_string (tpm_guid_raw); tpm_id = g_strdup_printf ("DELL-%s" G_GUINT64_FORMAT, tpm_guid); tpm_guid_raw_alt = g_strdup_printf ("%04x-%s", system_id, tpm_mode_alt); tpm_guid_alt = as_utils_guid_from_string (tpm_guid_raw_alt); tpm_id_alt = g_strdup_printf ("DELL-%s" G_GUINT64_FORMAT, tpm_guid_alt); g_debug ("Creating primary TPM GUID %s and secondary TPM GUID %s", tpm_guid_raw, tpm_guid_raw_alt); version_str = as_utils_version_from_uint32 (out->fw_version, AS_VERSION_PARSE_FLAG_NONE); /* make it clear that the TPM is a discrete device of the product */ if (!data->smi_obj->fake_smbios) { product_name = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME); } pretty_tpm_name = g_strdup_printf ("%s TPM %s", product_name, tpm_mode); pretty_tpm_name_alt = g_strdup_printf ("%s TPM %s", product_name, tpm_mode_alt); /* build Standard device nodes */ dev = fu_device_new (); fu_device_set_id (dev, tpm_id); fu_device_add_guid (dev, tpm_guid); fu_device_set_vendor (dev, "Dell Inc."); fu_device_set_name (dev, pretty_tpm_name); fu_device_set_summary (dev, "Platform TPM device"); fu_device_set_version (dev, version_str); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC); fu_device_add_icon (dev, "computer"); if ((out->status & TPM_OWN_MASK) == 0 && out->flashes_left > 0) { if (fu_plugin_dell_capsule_supported (plugin)) { fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT); } fu_device_set_flashes_left (dev, out->flashes_left); } else { g_debug ("%s updating disabled due to TPM ownership", pretty_tpm_name); } fu_plugin_device_add (plugin, dev); /* build alternate device node */ if (can_switch_modes) { dev_alt = fu_device_new (); fu_device_set_id (dev_alt, tpm_id_alt); fu_device_add_guid (dev_alt, tpm_guid_alt); fu_device_set_vendor (dev, "Dell Inc."); fu_device_set_name (dev_alt, pretty_tpm_name_alt); fu_device_set_summary (dev_alt, "Alternate mode for platform TPM device"); fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_INTERNAL); fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_REQUIRE_AC); fu_device_add_flag (dev_alt, FWUPD_DEVICE_FLAG_LOCKED); fu_device_add_icon (dev_alt, "computer"); fu_device_set_alternate (dev_alt, dev); /* If TPM is not owned and at least 1 flash left allow mode switching * * Mode switching is turned on by setting flashes left on alternate * device. */ if ((out->status & TPM_OWN_MASK) == 0 && out->flashes_left > 0) { fu_device_set_flashes_left (dev_alt, out->flashes_left); } else { g_debug ("%s mode switch disabled due to TPM ownership", pretty_tpm_name); } fu_plugin_device_add (plugin, dev_alt); } else g_debug ("System %04x does not offer TPM modeswitching", system_id); return TRUE; } gboolean fu_plugin_unlock (FuPlugin *plugin, FuDevice *device, GError **error) { FuDevice *device_alt = NULL; FwupdDeviceFlags device_flags_alt = 0; guint flashes_left = 0; guint flashes_left_alt = 0; /* for unlocking TPM1.2 <-> TPM2.0 switching */ g_debug ("Unlocking upgrades for: %s (%s)", fu_device_get_name (device), fu_device_get_id (device)); device_alt = fu_device_get_alternate (device); if (!device_alt) return FALSE; g_debug ("Preventing upgrades for: %s (%s)", fu_device_get_name (device_alt), fu_device_get_id (device_alt)); flashes_left = fu_device_get_flashes_left (device); flashes_left_alt = fu_device_get_flashes_left (device_alt); if (flashes_left == 0) { /* flashes left == 0 on both means no flashes left */ if (flashes_left_alt == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "ERROR: %s has no flashes left.", fu_device_get_name (device)); /* flashes left == 0 on just unlocking device is ownership */ } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "ERROR: %s is currently OWNED. " "Ownership must be removed to switch modes.", fu_device_get_name (device_alt)); } return FALSE; } /* clone the info from real device but prevent it from being flashed */ device_flags_alt = fu_device_get_flags (device_alt); fu_device_set_flags (device, device_flags_alt); fu_device_set_flags (device_alt, device_flags_alt & ~FWUPD_DEVICE_FLAG_UPDATABLE); /* make sure that this unlocked device can be updated */ fu_device_set_version (device, "0.0.0.0"); return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr (fwup_resource_iter) iter = NULL; fwup_resource *re = NULL; const gchar *name = NULL; gint rc; guint flashes_left; const gchar *guidstr = NULL; efi_guid_t guid; /* test the flash counter * - devices with 0 left at setup aren't allowed offline updates * - devices greater than 0 should show a warning when near 0 */ flashes_left = fu_device_get_flashes_left (device); if (flashes_left > 0) { name = fu_device_get_name (device); g_debug ("%s has %u flashes left", name, flashes_left); if ((flags & FWUPD_INSTALL_FLAG_FORCE) == 0 && flashes_left <= 2) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "WARNING: %s only has %u flashes left. " "See https://github.com/hughsie/fwupd/wiki/Dell-TPM:-flashes-left for more information.", name, flashes_left); return FALSE; } } if (data->smi_obj->fake_smbios) return TRUE; /* perform the update */ g_debug ("Performing capsule update"); /* Stuff the payload into a different GUID * - with fwup 0.5 this uses the ESRT GUID * - with fwup 0.6 this uses the payload's GUID * it's preferable to use payload GUID to avoid * a corner case scenario of UEFI BIOS and non-ESRT * update happening at same time */ fwup_resource_iter_create (&iter); fwup_resource_iter_next (iter, &re); guidstr = fu_device_get_guid_default (device); rc = efi_str_to_guid (guidstr, &guid); if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to convert guid to string"); return FALSE; } rc = fwup_set_guid (iter, &re, &guid); if (rc < 0 || re == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to update GUID %s", strerror (rc)); return FALSE; } /* NOTE: if there are problems with this working, adjust the * GUID in the capsule header to match something in ESRT. * This won't actually cause any bad behavior because the real * payload GUID is extracted later on. */ fu_device_set_status (device, FWUPD_STATUS_SCHEDULING); rc = fwup_set_up_update_with_buf (re, 0, g_bytes_get_data (blob_fw, NULL), g_bytes_get_size (blob_fw)); if (rc < 0) { g_autoptr(GString) err_string = g_string_new ("Dell firmware update failed:\n"); rc = 1; for (int i = 0; rc > 0; i++) { char *filename = NULL; char *function = NULL; char *message = NULL; int line = 0; int err = 0; rc = efi_error_get (i, &filename, &function, &line, &message, &err); if (rc <= 0) break; g_string_append_printf (err_string, "{error #%d} %s:%d %s(): %s: %s \n", i, filename, line, function, message, strerror(err)); } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "%s", err_string->str); return FALSE; } return TRUE; } void fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) { /* thunderbolt plugin */ if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") == 0 && fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) { /* fix VID/DID of safe mode devices */ if (fu_device_get_metadata_boolean (device, FU_DEVICE_METADATA_TBT_IS_SAFE_MODE)) { g_autofree gchar *vendor_id = NULL; g_autofree gchar *device_id = NULL; guint16 system_id = 0; vendor_id = g_strdup ("TBT:0x00D4"); system_id = fu_dell_get_system_id (plugin); if (system_id == 0) return; /* the kernel returns lowercase in sysfs, need to match it */ device_id = g_strdup_printf ("TBT-%04x%04x", 0x00d4u, (unsigned) system_id); fu_device_set_vendor_id (device, vendor_id); fu_device_add_guid (device, device_id); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); } } } static gboolean fu_dell_toggle_flash (FuPlugin *plugin, FuDevice *device, gboolean enable, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); gboolean has_host = fu_dell_host_mst_supported (plugin); gboolean has_dock; guint32 dock_location; const gchar *tmp; if (device) { if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)) return TRUE; tmp = fu_device_get_plugin (device); if (g_strcmp0 (tmp, "synapticsmst") != 0) return TRUE; g_debug ("preparing/cleaning update for %s", tmp); } /* Dock MST Hub */ has_dock = fu_dell_detect_dock (data->smi_obj, &dock_location); if (has_dock) { if (!fu_dell_toggle_dock_mode (data->smi_obj, enable, dock_location, error)) g_debug ("unable to change dock to %d", enable); else g_debug ("Toggled dock mode to %d", enable); } /* System MST hub */ if (has_host) { if (!fu_dell_toggle_host_mode (data->smi_obj, MST_GPIO_GUID, enable)) g_debug ("Unable to toggle MST hub GPIO to %d", enable); else g_debug ("Toggled MST hub GPIO to %d", enable); } #if defined (HAVE_SYNAPTICS) /* set a delay to allow OS response to settling the GPIO change */ if (enable && device == NULL && (has_dock || has_host)) fu_plugin_set_coldplug_delay (plugin, DELL_FLASH_MODE_DELAY * 1000); #endif return TRUE; } gboolean fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error) { return fu_dell_toggle_flash (plugin, device, TRUE, error); } gboolean fu_plugin_update_cleanup (FuPlugin *plugin, FuDevice *device, GError **error) { return fu_dell_toggle_flash (plugin, device , FALSE, error); } gboolean fu_plugin_coldplug_prepare (FuPlugin *plugin, GError **error) { return fu_dell_toggle_flash (plugin, NULL, TRUE, error); } gboolean fu_plugin_coldplug_cleanup (FuPlugin *plugin, GError **error) { return fu_dell_toggle_flash (plugin, NULL, FALSE, error); } void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); g_autofree gchar *tmp = NULL; data->libsmbios_major = smbios_get_library_version_major(); data->libsmbios_minor = smbios_get_library_version_minor(); g_debug ("Using libsmbios %u.%u", data->libsmbios_major, data->libsmbios_minor); tmp = g_strdup_printf ("%u.%u", data->libsmbios_major, data->libsmbios_minor); fu_plugin_add_report_metadata (plugin, "LibsmbiosVersion", tmp); data->smi_obj = g_malloc0 (sizeof (FuDellSmiObj)); if (g_getenv ("FWUPD_DELL_VERBOSE") != NULL) g_setenv ("LIBSMBIOS_C_DEBUG_OUTPUT_ALL", "1", TRUE); if (fu_dell_supported (plugin)) data->smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS); data->smi_obj->fake_smbios = FALSE; if (g_getenv ("FWUPD_DELL_FAKE_SMBIOS") != NULL) data->smi_obj->fake_smbios = TRUE; } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); if (data->smi_obj->smi) dell_smi_obj_free (data->smi_obj->smi); g_free(data->smi_obj); } gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); GUsbContext *usb_ctx = fu_plugin_get_usb_context (plugin); gint uefi_supported; if (data->smi_obj->fake_smbios) { g_debug ("Called with fake SMBIOS implementation. " "We're ignoring test for SBMIOS table and ESRT. " "Individual calls will need to be properly staged."); return TRUE; } if (!fu_dell_supported (plugin)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Firmware updating not supported"); return FALSE; } if (data->smi_obj->smi == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to initialize libsmbios library"); return FALSE; } /* If ESRT is not turned on, fwupd will have already created an * unlock device (if compiled with support). * * Once unlocked, that will enable flashing capsules here too. * * that means we should only look for supported = 1 */ uefi_supported = fwup_supported (); data->capsule_supported = (uefi_supported == 1); if (!data->capsule_supported) { g_debug ("UEFI capsule firmware updating not supported (%x)", (guint) uefi_supported); } if (usb_ctx != NULL) { g_signal_connect (usb_ctx, "device-added", G_CALLBACK (fu_plugin_dell_device_added_cb), plugin); g_signal_connect (usb_ctx, "device-removed", G_CALLBACK (fu_plugin_dell_device_removed_cb), plugin); } return TRUE; } static gboolean fu_plugin_dell_coldplug (FuPlugin *plugin, GError **error) { /* look for switchable TPM */ if (!fu_plugin_dell_detect_tpm (plugin, error)) g_debug ("No switchable TPM detected"); return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { return fu_plugin_dell_coldplug (plugin, error); } gboolean fu_plugin_recoldplug (FuPlugin *plugin, GError **error) { return fu_plugin_dell_coldplug (plugin, error); } fwupd-1.0.6/plugins/dell/fu-plugin-dell.h000066400000000000000000000037721325145456600202650ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Mario Limonciello * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_PLUGIN_DELL_H #define __FU_PLUGIN_DELL_H #include #include "fu-plugin.h" #include "fu-dell-smi.h" struct FuPluginData { FuDellSmiObj *smi_obj; guint16 fake_vid; guint16 fake_pid; gboolean can_switch_modes; gboolean capsule_supported; guint libsmbios_major; guint libsmbios_minor; }; void fu_plugin_dell_inject_fake_data (FuPlugin *plugin, guint32 *output, guint16 vid, guint16 pid, guint8 *buf, gboolean can_switch_modes); gboolean fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error); void fu_plugin_dell_device_added_cb (GUsbContext *ctx, GUsbDevice *device, FuPlugin *plugin); void fu_plugin_dell_device_removed_cb (GUsbContext *ctx, GUsbDevice *device, FuPlugin *plugin); /* These are nodes that will indicate information about * the TPM status */ struct tpm_status { guint32 ret; guint32 fw_version; guint32 status; guint32 flashes_left; }; #define TPM_EN_MASK 0x0001 #define TPM_OWN_MASK 0x0004 #define TPM_TYPE_MASK 0x0F00 #define TPM_1_2_MODE 0x0001 #define TPM_2_0_MODE 0x0002 #endif /* __FU_PLUGIN_DELL_H */ fwupd-1.0.6/plugins/dell/fu-self-test.c000066400000000000000000000346371325145456600177560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "fu-plugin-private.h" #include "fu-plugin-dell.h" static void _plugin_device_added_cb (FuPlugin *plugin, FuDevice *device, gpointer user_data) { FuDevice **dev = (FuDevice **) user_data; g_set_object (dev, device); } static void fu_plugin_dell_tpm_func (void) { gboolean ret; struct tpm_status tpm_out; FuDevice *device_alt = NULL; g_autoptr(GError) error = NULL; g_autoptr(FuDevice) device = NULL; g_autoptr(FuPlugin) plugin = NULL; memset (&tpm_out, 0x0, sizeof(tpm_out)); g_setenv ("FWUPD_DELL_FAKE_SMBIOS", "1", FALSE); plugin = fu_plugin_new (); ret = fu_plugin_open (plugin, PLUGINBUILDDIR "/libfu_plugin_dell.so", &error); g_assert_no_error (error); g_assert (ret); ret = fu_plugin_runner_startup (plugin, &error); g_assert_no_error (error); g_assert (ret); ret = fu_plugin_runner_coldplug(plugin, &error); g_signal_connect (plugin, "device-added", G_CALLBACK (_plugin_device_added_cb), &device); g_assert_no_error (error); g_assert (ret); /* inject fake data (no TPM) */ tpm_out.ret = -2; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &tpm_out, 0, 0, NULL, FALSE); ret = fu_plugin_dell_detect_tpm (plugin, &error); g_assert_no_error (error); g_assert (!ret); /* inject fake data: * - that is out of flashes * - no ownership * - TPM 1.2 * dev will be the locked 2.0, alt will be the orig 1.2 */ tpm_out.ret = 0; tpm_out.fw_version = 0; tpm_out.status = TPM_EN_MASK | (TPM_1_2_MODE << 8); tpm_out.flashes_left = 0; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &tpm_out, 0, 0, NULL, TRUE); ret = fu_plugin_dell_detect_tpm (plugin, &error); device_alt = fu_device_get_alternate (device); g_assert_no_error (error); g_assert (ret); g_assert (device != NULL); g_assert (device_alt != NULL); /* make sure 2.0 is locked */ g_assert_true (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_LOCKED)); /* make sure not allowed to flash 1.2 */ g_assert_false (fu_device_has_flag (device_alt, FWUPD_DEVICE_FLAG_UPDATABLE)); /* try to unlock 2.0 */ ret = fu_plugin_runner_unlock (plugin, device, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED); g_assert (!ret); g_clear_error (&error); /* cleanup */ fu_plugin_device_remove (plugin, device_alt); fu_plugin_device_remove (plugin, device); g_clear_object (&device); /* inject fake data: * - that hasflashes * - owned * - TPM 1.2 * dev will be the locked 2.0, alt will be the orig 1.2 */ tpm_out.status = TPM_EN_MASK | TPM_OWN_MASK | (TPM_1_2_MODE << 8); tpm_out.flashes_left = 125; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &tpm_out, 0, 0, NULL, TRUE); ret = fu_plugin_dell_detect_tpm (plugin, &error); device_alt = fu_device_get_alternate (device); g_assert_no_error (error); g_assert (ret); g_assert (device != NULL); g_assert (device_alt != NULL); /* make sure not allowed to flash 1.2 */ g_assert_false (fu_device_has_flag (device_alt, FWUPD_DEVICE_FLAG_UPDATABLE)); /* try to unlock 2.0 */ ret = fu_plugin_runner_unlock (plugin, device, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED); g_assert (!ret); g_clear_error (&error); /* cleanup */ fu_plugin_device_remove (plugin, device_alt); fu_plugin_device_remove (plugin, device); g_clear_object (&device); /* inject fake data: * - that has flashes * - not owned * - TPM 1.2 * dev will be the locked 2.0, alt will be the orig 1.2 */ tpm_out.status = TPM_EN_MASK | (TPM_1_2_MODE << 8); tpm_out.flashes_left = 125; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &tpm_out, 0, 0, NULL, TRUE); ret = fu_plugin_dell_detect_tpm (plugin, &error); device_alt = fu_device_get_alternate (device); g_assert_no_error (error); g_assert (ret); g_assert (device != NULL); g_assert (device_alt != NULL); /* make sure allowed to flash 1.2 but not 2.0 */ g_assert_true (fu_device_has_flag (device_alt, FWUPD_DEVICE_FLAG_UPDATABLE)); g_assert_false (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)); /* try to unlock 2.0 */ ret = fu_plugin_runner_unlock (plugin, device, &error); g_assert_no_error (error); g_assert (ret); /* make sure no longer allowed to flash 1.2 but can flash 2.0 */ g_assert_false (fu_device_has_flag (device_alt, FWUPD_DEVICE_FLAG_UPDATABLE)); g_assert_true (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)); /* cleanup */ fu_plugin_device_remove (plugin, device_alt); fu_plugin_device_remove (plugin, device); g_clear_object (&device); /* inject fake data: * - that has 1 flash left * - not owned * - TPM 2.0 * dev will be the locked 1.2, alt will be the orig 2.0 */ tpm_out.status = TPM_EN_MASK | (TPM_2_0_MODE << 8); tpm_out.flashes_left = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &tpm_out, 0, 0, NULL, TRUE); ret = fu_plugin_dell_detect_tpm (plugin, &error); device_alt = fu_device_get_alternate (device); g_assert_no_error (error); g_assert (ret); g_assert (device != NULL); g_assert (device_alt != NULL); /* make sure allowed to flash 2.0 but not 1.2 */ g_assert_true (fu_device_has_flag (device_alt, FWUPD_DEVICE_FLAG_UPDATABLE)); g_assert_false (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)); /* With one flash left we need an override */ ret = fu_plugin_runner_update (plugin, device_alt, NULL, NULL, FWUPD_INSTALL_FLAG_NONE, &error); g_assert (!ret); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED); g_clear_error (&error); /* test override */ ret = fu_plugin_runner_update (plugin, device_alt, NULL, NULL, FWUPD_INSTALL_FLAG_FORCE, &error); g_assert (ret); g_assert_no_error (error); /* cleanup */ fu_plugin_device_remove (plugin, device_alt); fu_plugin_device_remove (plugin, device); g_clear_object (&device); } static void fu_plugin_dell_dock_func (void) { gboolean ret; guint32 out[4] = { 0x0, 0x0, 0x0, 0x0 }; DOCK_UNION buf; DOCK_INFO *dock_info; g_autoptr(GError) error = NULL; g_autoptr(FuDevice) device = NULL; g_autoptr(FuPlugin) plugin = NULL; g_setenv ("FWUPD_DELL_FAKE_SMBIOS", "1", FALSE); plugin = fu_plugin_new (); ret = fu_plugin_open (plugin, PLUGINBUILDDIR "/libfu_plugin_dell.so", &error); g_assert_no_error (error); g_assert (ret); ret = fu_plugin_runner_startup (plugin, &error); g_assert_no_error (error); g_assert (ret); g_signal_connect (plugin, "device-added", G_CALLBACK (_plugin_device_added_cb), &device); ret = fu_plugin_runner_coldplug (plugin, &error); g_assert_no_error (error); g_assert (ret); /* make sure bad device doesn't trigger this */ fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, 0x1234, 0x4321, NULL, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device == NULL); /* inject a USB dongle matching correct VID/PID */ out[0] = 0; out[1] = 0; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, NULL, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device == NULL); /* inject valid TB16 dock w/ invalid flash pkg version */ buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD)); dock_info = &buf.record->dock_info; buf.record->dock_info_header.dir_version = 1; buf.record->dock_info_header.dock_type = DOCK_TYPE_TB16; memcpy (dock_info->dock_description, "BME_Dock", 8); dock_info->flash_pkg_version = 0x00ffffff; dock_info->cable_type = CABLE_TYPE_TBT; dock_info->location = 2; dock_info->component_count = 4; dock_info->components[0].fw_version = 0x00ffffff; memcpy (dock_info->components[0].description, "Dock1,EC,MIPS32,BME_Dock,0 :Query 2 0 2 1 0", 43); dock_info->components[1].fw_version = 0x10201; memcpy (dock_info->components[1].description, "Dock1,PC,TI,BME_Dock,0 :Query 2 1 0 1 0", 39); dock_info->components[2].fw_version = 0x10201; memcpy (dock_info->components[2].description, "Dock1,PC,TI,BME_Dock,1 :Query 2 1 0 1 1", 39); dock_info->components[3].fw_version = 0x00ffffff; memcpy (dock_info->components[3].description, "Dock1,Cable,Cyp,TBT_Cable,0 :Query 2 2 2 3 0", 44); out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, buf.buf, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device != NULL); g_clear_object (&device); g_free (buf.record); fu_plugin_dell_device_removed_cb (NULL, NULL, plugin); /* inject valid TB16 dock w/ older system EC */ buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD)); dock_info = &buf.record->dock_info; buf.record->dock_info_header.dir_version = 1; buf.record->dock_info_header.dock_type = DOCK_TYPE_TB16; memcpy (dock_info->dock_description, "BME_Dock", 8); dock_info->flash_pkg_version = 0x43; dock_info->cable_type = CABLE_TYPE_TBT; dock_info->location = 2; dock_info->component_count = 4; dock_info->components[0].fw_version = 0xffffffff; memcpy (dock_info->components[0].description, "Dock1,EC,MIPS32,BME_Dock,0 :Query 2 0 2 1 0", 43); dock_info->components[1].fw_version = 0x10211; memcpy (dock_info->components[1].description, "Dock1,PC,TI,BME_Dock,0 :Query 2 1 0 1 0", 39); dock_info->components[2].fw_version = 0x10212; memcpy (dock_info->components[2].description, "Dock1,PC,TI,BME_Dock,1 :Query 2 1 0 1 1", 39); dock_info->components[3].fw_version = 0xffffffff; memcpy (dock_info->components[3].description, "Dock1,Cable,Cyp,TBT_Cable,0 :Query 2 2 2 3 0", 44); out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, buf.buf, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device != NULL); g_clear_object (&device); g_free (buf.record); fu_plugin_dell_device_removed_cb (NULL, NULL, plugin); /* inject valid WD15 dock w/ invalid flash pkg version */ buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD)); dock_info = &buf.record->dock_info; buf.record->dock_info_header.dir_version = 1; buf.record->dock_info_header.dock_type = DOCK_TYPE_WD15; memcpy (dock_info->dock_description, "IE_Dock", 7); dock_info->flash_pkg_version = 0x00ffffff; dock_info->cable_type = CABLE_TYPE_LEGACY; dock_info->location = 2; dock_info->component_count = 3; dock_info->components[0].fw_version = 0x00ffffff; memcpy (dock_info->components[0].description, "Dock1,EC,MIPS32,IE_Dock,0 :Query 2 0 2 2 0", 42); dock_info->components[1].fw_version = 0x00ffffff; memcpy (dock_info->components[1].description, "Dock1,PC,TI,IE_Dock,0 :Query 2 1 0 2 0", 38); dock_info->components[2].fw_version = 0x00ffffff; memcpy (dock_info->components[2].description, "Dock1,Cable,Cyp,IE_Cable,0 :Query 2 2 2 1 0", 43); out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, buf.buf, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device != NULL); g_clear_object (&device); g_free (buf.record); fu_plugin_dell_device_removed_cb (NULL, NULL, plugin); /* inject valid WD15 dock w/ older system EC */ buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD)); dock_info = &buf.record->dock_info; buf.record->dock_info_header.dir_version = 1; buf.record->dock_info_header.dock_type = DOCK_TYPE_WD15; memcpy (dock_info->dock_description, "IE_Dock", 7); dock_info->flash_pkg_version = 0x43; dock_info->cable_type = CABLE_TYPE_LEGACY; dock_info->location = 2; dock_info->component_count = 3; dock_info->components[0].fw_version = 0xffffffff; memcpy (dock_info->components[0].description, "Dock1,EC,MIPS32,IE_Dock,0 :Query 2 0 2 2 0", 42); dock_info->components[1].fw_version = 0x10108; memcpy (dock_info->components[1].description, "Dock1,PC,TI,IE_Dock,0 :Query 2 1 0 2 0", 38); dock_info->components[2].fw_version = 0xffffffff; memcpy (dock_info->components[2].description, "Dock1,Cable,Cyp,IE_Cable,0 :Query 2 2 2 1 0", 43); out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, buf.buf, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device != NULL); g_clear_object (&device); g_free (buf.record); fu_plugin_dell_device_removed_cb (NULL, NULL, plugin); /* inject an invalid future dock */ buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD)); dock_info = &buf.record->dock_info; buf.record->dock_info_header.dir_version = 1; buf.record->dock_info_header.dock_type = 50; memcpy (dock_info->dock_description, "Future!", 8); dock_info->flash_pkg_version = 0x00ffffff; dock_info->cable_type = CABLE_TYPE_UNIV; dock_info->location = 2; dock_info->component_count = 1; dock_info->components[0].fw_version = 0x00ffffff; memcpy (dock_info->components[0].description, "Dock1,EC,MIPS32,FUT_Dock,0 :Query 2 0 2 2 0", 43); out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, (guint32 *) &out, DOCK_NIC_VID, DOCK_NIC_PID, buf.buf, FALSE); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device == NULL); g_free (buf.record); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_assert_cmpint (g_mkdir_with_parents ("/tmp/fwupd-self-test/var/lib/fwupd", 0755), ==, 0); /* tests go here */ g_test_add_func ("/fwupd/plugin{dell:tpm}", fu_plugin_dell_tpm_func); g_test_add_func ("/fwupd/plugin{dell:dock}", fu_plugin_dell_dock_func); return g_test_run (); } fwupd-1.0.6/plugins/dell/meson.build000066400000000000000000000024761325145456600174320ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginDell"'] install_data(['dell.quirk'], install_dir: join_paths(datadir, 'fwupd', 'quirks.d') ) shared_module('fu_plugin_dell', sources : [ 'fu-plugin-dell.c', 'fu-dell-smi.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', ], dependencies : [ plugin_deps, efivar, libsmbios_c, fwup, ], ) if get_option('tests') cargs += '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"' cargs += '-DPLUGINBUILDDIR="' + meson.current_build_dir() + '"' e = executable( 'dell-self-test', sources : [ 'fu-self-test.c', 'fu-dell-smi.c', 'fu-plugin-dell.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, efivar, fwup, sqlite, gudev, libsmbios_c, valgrind, ], link_with : [ fwupd, libfwupdprivate, ], c_args : [ cargs, '-DLOCALSTATEDIR="/tmp/fwupd-self-test/var"', ], ) test('dell-self-test', e) endif fwupd-1.0.6/plugins/dfu/000077500000000000000000000000001325145456600151155ustar00rootroot00000000000000fwupd-1.0.6/plugins/dfu/README.md000066400000000000000000000002521325145456600163730ustar00rootroot00000000000000DFU Support =========== Introduction ------------ Device Firmware Update is a standard that allows USB devices to be easily and safely updated by any operating system. fwupd-1.0.6/plugins/dfu/contrib/000077500000000000000000000000001325145456600165555ustar00rootroot00000000000000fwupd-1.0.6/plugins/dfu/contrib/parse-avrdude-conf.py000077500000000000000000000125401325145456600226210ustar00rootroot00000000000000#!/usr/bin/env python3 """ This parses avrdude.conf and generates quirks for fwupd """ # pylint: disable=wrong-import-position,pointless-string-statement """ Licensed under the GNU General Public License Version 2 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . """ import sys from difflib import SequenceMatcher # finds a part using the ID def _find_part_by_id(parts, part_id): for part in parts: if 'id' not in part: continue if part['id'] == part_id: return part return None # finds a memory layout for a part, climbing up the tree to the parent if reqd. def _find_mem_layout(parts, part): if 'memory-application' in part: memory_flash = part['memory-application'] if memory_flash: return memory_flash #look at the parent if 'parent' in part: parent = _find_part_by_id(parts, part['parent']) if parent: return _find_mem_layout(parts, parent) print('no parent ', part['parent'], 'found for', part['id']) return None # parses the weird syntax of avrdude.conf and makes lots of nested dictionaries def _parse_parts(fn_source): print("reading", fn_source) part = None memory_id = None parts = [] for line in open(fn_source).readlines(): # try to clean up crazy syntax line = line.replace('\n', '') if line.endswith(';'): line = line[:-1] # ignore blank lines line = line.rstrip() if not line: continue # count how many spaces deep this is lvl = 0 for char in line: if char != ' ': break lvl = lvl + 1 # ignore comments line = line.strip() if line[0] == '#': continue # level 0 of hell if lvl == 0: if line.startswith('part'): memory_id = None part = {} parts.append(part) if line.startswith('part parent '): part['parent'] = line[13:].replace('"', '') continue # level 4 of hell if lvl == 4: if line.startswith('memory'): memory_id = 'memory-' + line[7:].replace('"', '') part[memory_id] = {} continue split = line.split('=') if len(split) != 2: print('ignoring', line) continue part[split[0].strip()] = split[1].strip().replace('"', '') continue # level 8 of hell if lvl == 8: if memory_id: split = line.split('=') if len(split) != 2: continue memory = part[memory_id] memory[split[0].strip()] = split[1].strip() continue return parts def _get_longest_substring(s1, s2): match = SequenceMatcher(None, s1, s2).find_longest_match(0, len(s1), 0, len(s2)) return s2[match.b: match.b + match.size] # writes important data to the quirks file def _write_quirks(parts, fn_destination): outp = [] results = {} for part in parts: # ignore meta parts with deprecated names if 'desc' not in part: continue if 'signature' not in part: continue # find the layout mem_part = _find_mem_layout(parts, part) if not mem_part: print("no memory layout for", part['desc']) continue if not 'size' in mem_part: print("no memory size for", part['desc']) continue if mem_part['size'].startswith('0x'): size = int(mem_part['size'], 16) else: size = int(mem_part['size'], 10) # output the line for the quirk chip_id = '0x' + part['signature'].replace('0x', '').replace(' ', '') mem_layout = '@Flash/0x0/1*%.0iKg' % int(size / 1024) # merge duplicate quirks if chip_id in results: result = results[chip_id] result['desc'] = _get_longest_substring(result['desc'], part['desc']) else: result = {} result['desc'] = part['desc'] result['size'] = size result['mem_layout'] = mem_layout results[chip_id] = result for chip_id in results: result = results[chip_id] outp.append('# ' + result['desc'] + ' [USER] USER=0x%x' % result['size'] + '\n') outp.append(chip_id + '=' + result['mem_layout'] + '\n\n') # write file print("writing", fn_destination) open(fn_destination, 'w').writelines(outp) if __name__ == '__main__': if len(sys.argv) != 3: print("USAGE: %s avrdude.conf tmp.quirk" % sys.argv[0]) sys.exit(1) all_parts = _parse_parts(sys.argv[1]) _write_quirks(all_parts, sys.argv[2]) fwupd-1.0.6/plugins/dfu/dfu-chunked.c000066400000000000000000000121411325145456600174550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 20157 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "dfu-chunked.h" /** * dfu_chunked_packet_new: * @idx: the packet number * @page: the hardware memory page * @address: the address *within* the page * @data: the data * @data_sz: size of @data_sz * * Creates a new packet of chunked data. * * Return value: (transfer full): a #DfuChunkedPacket **/ DfuChunkedPacket * dfu_chunked_packet_new (guint32 idx, guint32 page, guint32 address, const guint8 *data, guint32 data_sz) { DfuChunkedPacket *item = g_new0 (DfuChunkedPacket, 1); item->idx = idx; item->page = page; item->address = address; item->data = data; item->data_sz = data_sz; return item; } /** * dfu_chunked_packet_to_string: * @item: a #DfuChunkedPacket * * Converts the chunked packet to a string representation. * * Return value: (transfer full): A string **/ gchar * dfu_chunked_packet_to_string (DfuChunkedPacket *item) { g_autoptr(GString) str = g_string_new (NULL); if (item->data != NULL) { for (guint32 i = 0; i < item->data_sz; i++) { gchar tmp = (gchar) item->data[i]; if (tmp == 0x00) break; g_string_append_c (str, g_ascii_isalnum (tmp) ? tmp : '?'); } } return g_strdup_printf ("#%02" G_GUINT32_FORMAT ": page:%02x " "addr:%04x len:%02" G_GUINT32_FORMAT " %s", item->idx, (guint) item->page, (guint) item->address, item->data_sz, str->str); } /** * dfu_chunked_to_string: * @segments: (element-type DfuChunkedPacket): array of packets * * Converts all the chunked packets in an array to a string representation. * * Return value: (transfer full): A string **/ gchar * dfu_chunked_to_string (GPtrArray *segments) { GString *str = g_string_new (NULL); for (guint i = 0; i < segments->len; i++) { DfuChunkedPacket *item = g_ptr_array_index (segments, i); g_autofree gchar *tmp = dfu_chunked_packet_to_string (item); g_string_append_printf (str, "%s\n", tmp); } return g_string_free (str, FALSE); } /** * dfu_chunked_new: * @data: a linear blob of memory, or %NULL * @data_sz: size of @data_sz * @addr_start: the hardware address offset, or 0 * @page_sz: the hardware page size, or 0 * @packet_sz: the transfer size, or 0 * * Chunks a linear blob of memory into packets, ensuring each packet does not * cross a package boundary and is less that a specific transfer size. * * Return value: (element-type DfuChunkedPacket): array of packets **/ GPtrArray * dfu_chunked_new (const guint8 *data, guint32 data_sz, guint32 addr_start, guint32 page_sz, guint32 packet_sz) { GPtrArray *segments = NULL; guint32 page_old = G_MAXUINT32; guint32 idx; guint32 last_flush = 0; g_return_val_if_fail (data_sz > 0, NULL); segments = g_ptr_array_new_with_free_func (g_free); for (idx = 1; idx < data_sz; idx++) { guint32 page = 0; if (page_sz > 0) page = (addr_start + idx) / page_sz; if (page_old == G_MAXUINT32) { page_old = page; } else if (page != page_old) { const guint8 *data_offset = data != NULL ? data + last_flush : 0x0; guint32 address_offset = addr_start + last_flush; if (page_sz > 0) address_offset %= page_sz; g_ptr_array_add (segments, dfu_chunked_packet_new (segments->len, page_old, address_offset, data_offset, idx - last_flush)); last_flush = idx; page_old = page; continue; } if (packet_sz > 0 && idx - last_flush >= packet_sz) { const guint8 *data_offset = data != NULL ? data + last_flush : 0x0; guint32 address_offset = addr_start + last_flush; if (page_sz > 0) address_offset %= page_sz; g_ptr_array_add (segments, dfu_chunked_packet_new (segments->len, page, address_offset, data_offset, idx - last_flush)); last_flush = idx; continue; } } if (last_flush != idx) { const guint8 *data_offset = data != NULL ? data + last_flush : 0x0; guint32 address_offset = addr_start + last_flush; guint32 page = 0; if (page_sz > 0) { address_offset %= page_sz; page = (addr_start + (idx - 1)) / page_sz; } g_ptr_array_add (segments, dfu_chunked_packet_new (segments->len, page, address_offset, data_offset, data_sz - last_flush)); } return segments; } fwupd-1.0.6/plugins/dfu/dfu-chunked.h000066400000000000000000000032061325145456600174640ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_CHUNKED_H #define __DFU_CHUNKED_H #include #include G_BEGIN_DECLS typedef struct { guint32 idx; guint32 page; guint32 address; const guint8 *data; guint32 data_sz; } DfuChunkedPacket; DfuChunkedPacket *dfu_chunked_packet_new (guint32 idx, guint32 page, guint32 address, const guint8 *data, guint32 data_sz); gchar *dfu_chunked_packet_to_string (DfuChunkedPacket *item); gchar *dfu_chunked_to_string (GPtrArray *chunked); GPtrArray *dfu_chunked_new (const guint8 *data, guint32 data_sz, guint32 addr_start, guint32 page_sz, guint32 packet_sz); G_END_DECLS #endif /* __DFU_CHUNKED_H */ fwupd-1.0.6/plugins/dfu/dfu-cipher-xtea.c000066400000000000000000000135551325145456600202570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fu-common.h" #include "dfu-cipher-xtea.h" #include "fwupd-error.h" #define XTEA_DELTA 0x9e3779b9 #define XTEA_NUM_ROUNDS 32 static void dfu_cipher_buf_to_uint32 (const guint8 *buf, guint buflen, guint32 *array) { for (guint i = 0; i < buflen / 4; i++) array[i] = fu_common_read_uint32 (&buf[i * 4], G_LITTLE_ENDIAN); } static void dfu_cipher_uint32_to_buf (guint8 *buf, guint buflen, const guint32 *array) { for (guint i = 0; i < buflen / 4; i++) fu_common_write_uint32 (&buf[i * 4], array[i], G_LITTLE_ENDIAN); } static gboolean dfu_tool_parse_xtea_key (const gchar *key, guint32 *keys, GError **error) { gsize key_len; /* too long */ key_len = strlen (key); if (key_len > 32) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Key string too long at %" G_GSIZE_FORMAT " chars, max 16", key_len); return FALSE; } /* parse 4x32b values or generate a hash */ if (key_len == 32) { for (guint8 i = 0; i < 4; i++) { gchar buf[] = "xxxxxxxx"; gchar *endptr; guint64 tmp; /* copy to 4-char buf (with NUL) */ memcpy (buf, key + i*8, 8); tmp = g_ascii_strtoull (buf, &endptr, 16); if (endptr && endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Failed to parse key '%s'", key); return FALSE; } keys[3-i] = (guint32) tmp; } } else { gsize buf_len = 16; guint8 buf[16]; g_autoptr(GChecksum) csum = NULL; csum = g_checksum_new (G_CHECKSUM_MD5); g_checksum_update (csum, (const guchar *) key, (gssize) key_len); g_checksum_get_digest (csum, buf, &buf_len); g_assert (buf_len == 16); dfu_cipher_buf_to_uint32 (buf, buf_len, keys); } /* success */ g_debug ("using XTEA key %04x%04x%04x%04x", keys[3], keys[2], keys[1], keys[0]); return TRUE; } /** * dfu_cipher_decrypt_xtea: (skip) * @key: a XTEA key * @data: data to parse * @length: length of @data * @error: a #GError, or %NULL * * Decrypt a buffer using XTEA. * * Returns: %TRUE for success **/ gboolean dfu_cipher_decrypt_xtea (const gchar *key, guint8 *data, guint32 length, GError **error) { guint32 sum; guint32 v0; guint32 v1; guint32 chunks = length / 4; guint32 keys[4]; g_autofree guint32 *tmp = NULL; /* sanity check */ if (length < 8) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "8 bytes data required, got %" G_GUINT32_FORMAT, length); return FALSE; } if (length % 4 != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT, length); return FALSE; } /* parse key */ if (!dfu_tool_parse_xtea_key (key, keys, error)) return FALSE; /* allocate a buffer that can be addressed in 4-byte chunks */ tmp = g_new0 (guint32, chunks); dfu_cipher_buf_to_uint32 (data, length, tmp); /* process buffer using XTEA keys */ for (guint j = 0; j < chunks; j += 2) { v0 = tmp[j]; v1 = tmp[j+1]; sum = XTEA_DELTA * XTEA_NUM_ROUNDS; for (guint8 i = 0; i < XTEA_NUM_ROUNDS; i++) { v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]); sum -= XTEA_DELTA; v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]); } tmp[j] = v0; tmp[j+1] = v1; } /* copy the temp buffer back to data */ dfu_cipher_uint32_to_buf (data, length, tmp); return TRUE; } /** * dfu_cipher_encrypt_xtea: (skip) * @key: a XTEA key * @data: data to parse * @length: length of @data * @error: a #GError, or %NULL * * Encrypt a buffer using XTEA. * * Returns: %TRUE for success **/ gboolean dfu_cipher_encrypt_xtea (const gchar *key, guint8 *data, guint32 length, GError **error) { guint32 sum; guint32 v0; guint32 v1; guint32 chunks = length / 4; guint32 keys[4]; g_autofree guint32 *tmp = NULL; /* sanity check */ if (length < 8) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "8 bytes data required, got %" G_GUINT32_FORMAT, length); return FALSE; } if (length % 4 != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Multiples of 4 bytes required, got %" G_GUINT32_FORMAT, length); return FALSE; } /* parse key */ if (!dfu_tool_parse_xtea_key (key, keys, error)) return FALSE; /* allocate a buffer that can be addressed in 4-byte chunks */ tmp = g_new0 (guint32, chunks); dfu_cipher_buf_to_uint32 (data, length, tmp); /* process buffer using XTEA keys */ for (guint j = 0; j < chunks; j += 2) { sum = 0; v0 = tmp[j]; v1 = tmp[j+1]; for (guint8 i = 0; i < XTEA_NUM_ROUNDS; i++) { v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + keys[sum & 3]); sum += XTEA_DELTA; v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + keys[(sum >> 11) & 3]); } tmp[j] = v0; tmp[j+1] = v1; } /* copy the temp buffer back to data */ dfu_cipher_uint32_to_buf (data, length, tmp); return TRUE; } fwupd-1.0.6/plugins/dfu/dfu-cipher-xtea.h000066400000000000000000000025451325145456600202610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_XTEA_H #define __DFU_FORMAT_XTEA_H #include #include G_BEGIN_DECLS gboolean dfu_cipher_encrypt_xtea (const gchar *key, guint8 *data, guint32 length, GError **error); gboolean dfu_cipher_decrypt_xtea (const gchar *key, guint8 *data, guint32 length, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_XTEA_H */ fwupd-1.0.6/plugins/dfu/dfu-common.c000066400000000000000000000154671325145456600173420ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-common * @short_description: Common functions for DFU * * These helper objects allow converting from enum values to strings. */ #include "config.h" #include #include "dfu-common.h" /** * dfu_state_to_string: * @state: a #DfuState, e.g. %DFU_STATE_DFU_MANIFEST * * Converts an enumerated value to a string. * * Return value: a string **/ const gchar * dfu_state_to_string (DfuState state) { if (state == DFU_STATE_APP_IDLE) return "appIDLE"; if (state == DFU_STATE_APP_DETACH) return "appDETACH"; if (state == DFU_STATE_DFU_IDLE) return "dfuIDLE"; if (state == DFU_STATE_DFU_DNLOAD_SYNC) return "dfuDNLOAD-SYNC"; if (state == DFU_STATE_DFU_DNBUSY) return "dfuDNBUSY"; if (state == DFU_STATE_DFU_DNLOAD_IDLE) return "dfuDNLOAD-IDLE"; if (state == DFU_STATE_DFU_MANIFEST_SYNC) return "dfuMANIFEST-SYNC"; if (state == DFU_STATE_DFU_MANIFEST) return "dfuMANIFEST"; if (state == DFU_STATE_DFU_MANIFEST_WAIT_RESET) return "dfuMANIFEST-WAIT-RESET"; if (state == DFU_STATE_DFU_UPLOAD_IDLE) return "dfuUPLOAD-IDLE"; if (state == DFU_STATE_DFU_ERROR) return "dfuERROR"; return NULL; } /** * dfu_status_to_string: * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE * * Converts an enumerated value to a string. * * Return value: a string **/ const gchar * dfu_status_to_string (DfuStatus status) { if (status == DFU_STATUS_OK) return "OK"; if (status == DFU_STATUS_ERR_TARGET) return "errTARGET"; if (status == DFU_STATUS_ERR_FILE) return "errFILE"; if (status == DFU_STATUS_ERR_WRITE) return "errwrite"; if (status == DFU_STATUS_ERR_ERASE) return "errERASE"; if (status == DFU_STATUS_ERR_CHECK_ERASED) return "errCHECK_ERASED"; if (status == DFU_STATUS_ERR_PROG) return "errPROG"; if (status == DFU_STATUS_ERR_VERIFY) return "errVERIFY"; if (status == DFU_STATUS_ERR_ADDRESS) return "errADDRESS"; if (status == DFU_STATUS_ERR_NOTDONE) return "errNOTDONE"; if (status == DFU_STATUS_ERR_FIRMWARE) return "errFIRMWARE"; if (status == DFU_STATUS_ERR_VENDOR) return "errVENDOR"; if (status == DFU_STATUS_ERR_USBR) return "errUSBR"; if (status == DFU_STATUS_ERR_POR) return "errPOR"; if (status == DFU_STATUS_ERR_UNKNOWN) return "errUNKNOWN"; if (status == DFU_STATUS_ERR_STALLDPKT) return "errSTALLDPKT"; return NULL; } /** * dfu_cipher_kind_to_string: * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA * * Converts an enumerated value to a string. * * Return value: a string **/ const gchar * dfu_cipher_kind_to_string (DfuCipherKind cipher_kind) { if (cipher_kind == DFU_CIPHER_KIND_NONE) return "none"; if (cipher_kind == DFU_CIPHER_KIND_XTEA) return "xtea"; if (cipher_kind == DFU_CIPHER_KIND_RSA) return "rsa"; return NULL; } /** * dfu_version_to_string: * @version: a #DfuVersion, e.g. %DFU_VERSION_DFU_1_1 * * Converts an enumerated value to a string. * * Return value: a string **/ const gchar * dfu_version_to_string (DfuVersion version) { if (version == DFU_VERSION_DFU_1_0) return "1.0"; if (version == DFU_VERSION_DFU_1_1) return "1.1"; if (version == DFU_VERSION_DFUSE) return "DfuSe"; if (version == DFU_VERSION_ATMEL_AVR) return "AtmelAVR"; return NULL; } /** * dfu_utils_bytes_join_array: * @chunks: (element-kind GBytes): bytes * * Creates a monolithic block of memory from an array of #GBytes. * * Return value: (transfer full): a new GBytes **/ GBytes * dfu_utils_bytes_join_array (GPtrArray *chunks) { gsize total_size = 0; guint32 offset = 0; guint8 *buffer; /* get the size of all the chunks */ for (guint i = 0; i < chunks->len; i++) { GBytes *chunk_tmp = g_ptr_array_index (chunks, i); total_size += g_bytes_get_size (chunk_tmp); } /* copy them into a buffer */ buffer = g_malloc0 (total_size); for (guint i = 0; i < chunks->len; i++) { const guint8 *chunk_data; gsize chunk_size = 0; GBytes *chunk_tmp = g_ptr_array_index (chunks, i); chunk_data = g_bytes_get_data (chunk_tmp, &chunk_size); if (chunk_size == 0) continue; memcpy (buffer + offset, chunk_data, chunk_size); offset += chunk_size; } return g_bytes_new_take (buffer, total_size); } /** * dfu_utils_bytes_is_empty: * @bytes: a #GBytes * * Checks if a byte array are just empty (0xff) bytes. * * Return value: %TRUE if @bytes is empty **/ gboolean dfu_utils_bytes_is_empty (GBytes *bytes) { gsize sz = 0; const guint8 *buf = g_bytes_get_data (bytes, &sz); for (gsize i = 0; i < sz; i++) { if (buf[i] != 0xff) return FALSE; } return TRUE; } /** * dfu_utils_buffer_parse_uint8: * @data: a string * * Parses a base 16 number from a string. * * The string MUST be at least 2 bytes long as this function cannot check the * length of @data. Checking the size must be done in the caller. * * Return value: A parsed value, or 0 for error **/ guint8 dfu_utils_buffer_parse_uint8 (const gchar *data) { gchar buffer[3]; memcpy (buffer, data, 2); buffer[2] = '\0'; return (guint8) g_ascii_strtoull (buffer, NULL, 16); } /** * dfu_utils_buffer_parse_uint16: * @data: a string * * Parses a base 16 number from a string. * * The string MUST be at least 4 bytes long as this function cannot check the * length of @data. Checking the size must be done in the caller. * * Return value: A parsed value, or 0 for error **/ guint16 dfu_utils_buffer_parse_uint16 (const gchar *data) { gchar buffer[5]; memcpy (buffer, data, 4); buffer[4] = '\0'; return (guint16) g_ascii_strtoull (buffer, NULL, 16); } /** * dfu_utils_buffer_parse_uint32: * @data: a string * * Parses a base 16 number from a string. * * The string MUST be at least 8 bytes long as this function cannot check the * length of @data. Checking the size must be done in the caller. * * Return value: A parsed value, or 0 for error **/ guint32 dfu_utils_buffer_parse_uint32 (const gchar *data) { gchar buffer[9]; memcpy (buffer, data, 8); buffer[8] = '\0'; return (guint32) g_ascii_strtoull (buffer, NULL, 16); } fwupd-1.0.6/plugins/dfu/dfu-common.h000066400000000000000000000136131325145456600173360ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_COMMON_H #define __DFU_COMMON_H #include #include G_BEGIN_DECLS /** * DfuRequest: * @DFU_REQUEST_DETACH: Detach * @DFU_REQUEST_DNLOAD: Download host-to-device * @DFU_REQUEST_UPLOAD: Upload device-to-host * @DFU_REQUEST_GETSTATUS: Get the device status * @DFU_REQUEST_CLRSTATUS: Clear the device status * @DFU_REQUEST_GETSTATE: Get the last set state * @DFU_REQUEST_ABORT: Abort the current transfer * * The DFU request kinds. **/ typedef enum { DFU_REQUEST_DETACH = 0x00, DFU_REQUEST_DNLOAD = 0x01, DFU_REQUEST_UPLOAD = 0x02, DFU_REQUEST_GETSTATUS = 0x03, DFU_REQUEST_CLRSTATUS = 0x04, DFU_REQUEST_GETSTATE = 0x05, DFU_REQUEST_ABORT = 0x06, /*< private >*/ DFU_REQUEST_LAST } DfuRequest; /** * DfuStatus: * @DFU_STATUS_OK: No error condition is present * @DFU_STATUS_ERR_TARGET: File is not targeted for use by this device * @DFU_STATUS_ERR_FILE: File is for this device but fails a verification test * @DFU_STATUS_ERR_WRITE: Device is unable to write memory * @DFU_STATUS_ERR_ERASE: Memory erase function failed * @DFU_STATUS_ERR_CHECK_ERASED: Memory erase check failed * @DFU_STATUS_ERR_PROG: Program memory function failed * @DFU_STATUS_ERR_VERIFY: Programmed memory failed verification * @DFU_STATUS_ERR_ADDRESS: Cannot program memory due to received address that isout of range * @DFU_STATUS_ERR_NOTDONE: Received DFU_DNLOAD with wLength = 0 but data is incomplete * @DFU_STATUS_ERR_FIRMWARE: Device firmware is corrupt * @DFU_STATUS_ERR_VENDOR: iString indicates a vendor-specific error * @DFU_STATUS_ERR_USBR: Device detected unexpected USB reset signaling * @DFU_STATUS_ERR_POR: Device detected unexpected power on reset * @DFU_STATUS_ERR_UNKNOWN: Something unexpected went wrong * @DFU_STATUS_ERR_STALLDPKT: Device stalled an unexpected request * * The status enumerated kind. **/ typedef enum { DFU_STATUS_OK = 0x00, DFU_STATUS_ERR_TARGET = 0x01, DFU_STATUS_ERR_FILE = 0x02, DFU_STATUS_ERR_WRITE = 0x03, DFU_STATUS_ERR_ERASE = 0x04, DFU_STATUS_ERR_CHECK_ERASED = 0x05, DFU_STATUS_ERR_PROG = 0x06, DFU_STATUS_ERR_VERIFY = 0x07, DFU_STATUS_ERR_ADDRESS = 0x08, DFU_STATUS_ERR_NOTDONE = 0x09, DFU_STATUS_ERR_FIRMWARE = 0x0a, DFU_STATUS_ERR_VENDOR = 0x0b, DFU_STATUS_ERR_USBR = 0x0c, DFU_STATUS_ERR_POR = 0x0d, DFU_STATUS_ERR_UNKNOWN = 0x0e, DFU_STATUS_ERR_STALLDPKT = 0x0f, /*< private >*/ DFU_STATUS_LAST } DfuStatus; /** * DfuState: * @DFU_STATE_APP_IDLE: State 0 * @DFU_STATE_APP_DETACH: State 1 * @DFU_STATE_DFU_IDLE: State 2 * @DFU_STATE_DFU_DNLOAD_SYNC: State 3 * @DFU_STATE_DFU_DNBUSY: State 4 * @DFU_STATE_DFU_DNLOAD_IDLE: State 5 * @DFU_STATE_DFU_MANIFEST_SYNC: State 6 * @DFU_STATE_DFU_MANIFEST: State 7 * @DFU_STATE_DFU_MANIFEST_WAIT_RESET: State 8 * @DFU_STATE_DFU_UPLOAD_IDLE: State 9 * @DFU_STATE_DFU_ERROR: State 10 * * The state enumerated kind. **/ typedef enum { DFU_STATE_APP_IDLE = 0x00, DFU_STATE_APP_DETACH = 0x01, DFU_STATE_DFU_IDLE = 0x02, DFU_STATE_DFU_DNLOAD_SYNC = 0x03, DFU_STATE_DFU_DNBUSY = 0x04, DFU_STATE_DFU_DNLOAD_IDLE = 0x05, DFU_STATE_DFU_MANIFEST_SYNC = 0x06, DFU_STATE_DFU_MANIFEST = 0x07, DFU_STATE_DFU_MANIFEST_WAIT_RESET = 0x08, DFU_STATE_DFU_UPLOAD_IDLE = 0x09, DFU_STATE_DFU_ERROR = 0x0a, /*< private >*/ DFU_STATE_LAST } DfuState; /** * DfuCipherKind: * @DFU_CIPHER_KIND_NONE: No cipher detected * @DFU_CIPHER_KIND_XTEA: XTEA cipher detected * @DFU_CIPHER_KIND_RSA: RSA cipher detected * * The type of cipher used for transfering the firmware. **/ typedef enum { DFU_CIPHER_KIND_NONE, DFU_CIPHER_KIND_XTEA, DFU_CIPHER_KIND_RSA, /*< private >*/ DFU_CIPHER_KIND_LAST } DfuCipherKind; /** * DfuVersion: * @DFU_VERSION_UNKNOWN: Format unknown * @DFU_VERSION_DFU_1_0: DFU 1.0 * @DFU_VERSION_DFU_1_1: DFU 1.1 * @DFU_VERSION_DFUSE: DfuSe * @DFU_VERSION_ATMEL_AVR: Atmel AVR * * The known versions of the DFU standard in BCD format. **/ typedef enum { DFU_VERSION_UNKNOWN = 0, DFU_VERSION_DFU_1_0 = 0x0100, DFU_VERSION_DFU_1_1 = 0x0110, DFU_VERSION_DFUSE = 0x011a, /* defined by ST */ DFU_VERSION_ATMEL_AVR = 0xff01, /* made up */ /*< private >*/ DFU_VERSION_LAST } DfuVersion; #define DFU_METADATA_KEY_LICENSE "License" #define DFU_METADATA_KEY_COPYRIGHT "Copyright" #define DFU_METADATA_KEY_CIPHER_KIND "CipherKind" const gchar *dfu_state_to_string (DfuState state); const gchar *dfu_status_to_string (DfuStatus status); const gchar *dfu_cipher_kind_to_string (DfuCipherKind cipher_kind); const gchar *dfu_version_to_string (DfuVersion version); /* helpers */ GBytes *dfu_utils_bytes_join_array (GPtrArray *chunks); gboolean dfu_utils_bytes_is_empty (GBytes *bytes); guint8 dfu_utils_buffer_parse_uint8 (const gchar *data); guint16 dfu_utils_buffer_parse_uint16 (const gchar *data); guint32 dfu_utils_buffer_parse_uint32 (const gchar *data); G_END_DECLS #endif /* __DFU_COMMON_H */ fwupd-1.0.6/plugins/dfu/dfu-device-private.h000066400000000000000000000030121325145456600207450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_DEVICE_PRIVATE_H #define __DFU_DEVICE_PRIVATE_H #include #include #include #include "fu-quirks.h" #include "dfu-device.h" G_BEGIN_DECLS void dfu_device_error_fixup (DfuDevice *device, GError **error); guint dfu_device_get_download_timeout (DfuDevice *device); gchar *dfu_device_get_quirks_as_string (DfuDevice *device); gchar *dfu_device_get_attributes_as_string (DfuDevice *device); gboolean dfu_device_ensure_interface (DfuDevice *device, GError **error); G_END_DECLS #endif /* __DFU_DEVICE_PRIVATE_H */ fwupd-1.0.6/plugins/dfu/dfu-device.c000066400000000000000000001633451325145456600173100ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-device * @short_description: Object representing a DFU-capable device * * This object allows two things: * * - Downloading from the host to the device, optionally with * verification using a DFU or DfuSe firmware file. * * - Uploading from the device to the host to a DFU or DfuSe firmware * file. The file format is chosen automatically, with DfuSe being * chosen if the device contains more than one target. * * See also: #DfuTarget, #DfuFirmware */ #include "config.h" #include #include "dfu-common.h" #include "dfu-device-private.h" #include "dfu-target-avr.h" #include "dfu-target-private.h" #include "dfu-target-stm.h" #include "fu-device-locker.h" #include "fwupd-error.h" static void dfu_device_finalize (GObject *object); typedef struct { DfuDeviceAttributes attributes; DfuDeviceQuirks quirks; DfuState state; DfuStatus status; GPtrArray *targets; GUsbContext *usb_context; gboolean done_upload_or_download; gboolean claimed_interface; gchar *chip_id; guint16 version; guint16 runtime_pid; guint16 runtime_vid; guint16 runtime_release; guint16 transfer_size; guint8 iface_number; guint dnload_timeout; guint timeout_ms; } DfuDevicePrivate; enum { SIGNAL_STATUS_CHANGED, SIGNAL_STATE_CHANGED, SIGNAL_LAST }; static guint signals [SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (DfuDevice, dfu_device, FU_TYPE_USB_DEVICE) #define GET_PRIVATE(o) (dfu_device_get_instance_private (o)) static gboolean dfu_device_open (FuUsbDevice *device, GError **error); static gboolean dfu_device_close (FuUsbDevice *device, GError **error); static gboolean dfu_device_probe (FuUsbDevice *device, GError **error); static void dfu_device_class_init (DfuDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); klass_usb_device->open = dfu_device_open; klass_usb_device->close = dfu_device_close; klass_usb_device->probe = dfu_device_probe; /** * DfuDevice::status-changed: * @device: the #DfuDevice instance that emitted the signal * @status: the new #DfuStatus * * The ::status-changed signal is emitted when the status changes. **/ signals [SIGNAL_STATUS_CHANGED] = g_signal_new ("status-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DfuDeviceClass, status_changed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); /** * DfuDevice::state-changed: * @device: the #DfuDevice instance that emitted the signal * @state: the new #DfuState * * The ::state-changed signal is emitted when the state changes. **/ signals [SIGNAL_STATE_CHANGED] = g_signal_new ("state-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DfuDeviceClass, state_changed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); object_class->finalize = dfu_device_finalize; } static void dfu_device_init (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); priv->iface_number = 0xff; priv->runtime_pid = 0xffff; priv->runtime_vid = 0xffff; priv->runtime_release = 0xffff; priv->state = DFU_STATE_APP_IDLE; priv->status = DFU_STATUS_OK; priv->targets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->timeout_ms = 1500; priv->transfer_size = 64; } /** * dfu_device_get_transfer_size: * @device: a #GUsbDevice * * Gets the transfer size in bytes. * * Return value: packet size, or 0 for unknown **/ guint16 dfu_device_get_transfer_size (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return priv->transfer_size; } /** * dfu_device_get_version: * @device: a #GUsbDevice * * Gets the DFU specification version supported by the device. * * Return value: integer, or 0 for unknown, e.g. %DFU_VERSION_DFU_1_1 **/ guint16 dfu_device_get_version (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return priv->version; } /** * dfu_device_get_download_timeout: * @device: a #GUsbDevice * * Gets the download timeout in ms. * * Return value: delay, or 0 for unknown **/ guint dfu_device_get_download_timeout (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0); return priv->dnload_timeout; } /** * dfu_device_set_transfer_size: * @device: a #GUsbDevice * @transfer_size: maximum packet size * * Sets the transfer size in bytes. **/ void dfu_device_set_transfer_size (DfuDevice *device, guint16 transfer_size) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (DFU_IS_DEVICE (device)); priv->transfer_size = transfer_size; } static void dfu_device_finalize (GObject *object) { DfuDevice *device = DFU_DEVICE (object); DfuDevicePrivate *priv = GET_PRIVATE (device); if (priv->usb_context != NULL) g_object_unref (priv->usb_context); g_free (priv->chip_id); g_ptr_array_unref (priv->targets); G_OBJECT_CLASS (dfu_device_parent_class)->finalize (object); } typedef struct __attribute__((packed)) { guint8 bLength; guint8 bDescriptorType; guint8 bmAttributes; guint16 wDetachTimeOut; guint16 wTransferSize; guint16 bcdDFUVersion; } DfuFuncDescriptor; static gboolean dfu_device_parse_iface_data (DfuDevice *device, GBytes *iface_data, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); DfuFuncDescriptor desc; const guint8 *buf; gsize sz; /* parse the functional descriptor */ buf = g_bytes_get_data (iface_data, &sz); if (sz == sizeof(DfuFuncDescriptor)) { memcpy (&desc, buf, sz); } else if (sz == sizeof(DfuFuncDescriptor) - 2) { g_warning ("truncated DFU interface data, no bcdDFUVersion"); memcpy (&desc, buf, sz); desc.bcdDFUVersion = DFU_VERSION_DFU_1_1; } else { g_autoptr(GString) bufstr = g_string_new (NULL); for (gsize i = 0; i < sz; i++) g_string_append_printf (bufstr, "%02x ", buf[i]); if (bufstr->len > 0) g_string_truncate (bufstr, bufstr->len - 1); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "interface found, but not the correct length for " "functional data: %" G_GSIZE_FORMAT " bytes: %s", sz, bufstr->str); return FALSE; } /* check sanity */ if (desc.bLength != sz) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "DFU interface data has incorrect length: 0x%02x", desc.bLength); return FALSE; } /* get transfer size and version */ priv->transfer_size = GUINT16_FROM_LE (desc.wTransferSize); priv->version = GUINT16_FROM_LE (desc.bcdDFUVersion); /* ST-specific */ if (priv->version == DFU_VERSION_DFUSE && desc.bmAttributes & DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE) priv->transfer_size = 0x1000; /* get attributes about the DFU operation */ priv->attributes = desc.bmAttributes; return TRUE; } static void dfu_device_guess_state_from_iface (DfuDevice *device, GUsbInterface *iface) { DfuDevicePrivate *priv = GET_PRIVATE (device); /* some devices use the wrong interface */ if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_FORCE_DFU_MODE)) { g_debug ("quirking device into DFU mode"); priv->state = DFU_STATE_DFU_IDLE; return; } /* runtime */ if (g_usb_interface_get_protocol (iface) == 0x01) { priv->state = DFU_STATE_APP_IDLE; return; } /* DFU */ if (g_usb_interface_get_protocol (iface) == 0x02) { priv->state = DFU_STATE_DFU_IDLE; return; } g_warning ("unable to guess initial device state from interface %u", g_usb_interface_get_protocol (iface)); } static gboolean dfu_device_add_targets (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); FuQuirks *system_quirks = fu_device_get_quirks (FU_DEVICE (device)); g_autoptr(GPtrArray) ifaces = NULL; /* add all DFU-capable targets */ ifaces = g_usb_device_get_interfaces (usb_device, error); if (ifaces == NULL) return FALSE; g_ptr_array_set_size (priv->targets, 0); for (guint i = 0; i < ifaces->len; i++) { GBytes *iface_data = NULL; DfuTarget *target; const gchar *quirk_str; g_autoptr(GError) error_local = NULL; GUsbInterface *iface = g_ptr_array_index (ifaces, i); /* some devices don't use the right class and subclass */ if (!dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_USE_ANY_INTERFACE)) { if (g_usb_interface_get_class (iface) != G_USB_DEVICE_CLASS_APPLICATION_SPECIFIC) continue; if (g_usb_interface_get_subclass (iface) != 0x01) continue; } /* parse any interface data */ iface_data = g_usb_interface_get_extra (iface); if (g_bytes_get_size (iface_data) > 0) { if (!dfu_device_parse_iface_data (device, iface_data, &error_local)) { g_warning ("failed to parse interface data: %s", error_local->message); continue; } } else { priv->attributes |= DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD | DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD; } /* fix up the version */ quirk_str = fu_quirks_lookup_by_usb_device (system_quirks, FU_QUIRKS_DFU_FORCE_VERSION, usb_device); if (quirk_str != NULL && strlen (quirk_str) == 4) priv->version = dfu_utils_buffer_parse_uint16 (quirk_str); if (priv->version == DFU_VERSION_DFU_1_0 || priv->version == DFU_VERSION_DFU_1_1) { g_debug ("DFU v1.1"); } else if (priv->version == DFU_VERSION_ATMEL_AVR) { g_debug ("AVR-DFU support"); priv->version = DFU_VERSION_ATMEL_AVR; } else if (priv->version == DFU_VERSION_DFUSE) { g_debug ("STM-DFU support"); } else if (priv->version == 0x0101) { g_debug ("DFU v1.1 assumed"); priv->version = DFU_VERSION_DFU_1_1; } else { g_warning ("DFU version 0x%04x invalid, v1.1 assumed", priv->version); priv->version = DFU_VERSION_DFU_1_1; } /* fix up the transfer size */ if (priv->transfer_size == 0xffff) { priv->transfer_size = 0x0400; g_debug ("DFU transfer size unspecified, guessing"); } if (priv->transfer_size > 0x0000) { g_debug ("using DFU transfer size 0x%04x bytes", priv->transfer_size); } else { g_warning ("DFU transfer size invalid, using default"); priv->transfer_size = 64; } /* create a target of the required type */ switch (priv->version) { case DFU_VERSION_DFUSE: target = dfu_target_stm_new (); break; case DFU_VERSION_ATMEL_AVR: target = dfu_target_avr_new (); break; default: target = dfu_target_new (); break; } dfu_target_set_device (target, device); dfu_target_set_alt_idx (target, g_usb_interface_get_index (iface)); dfu_target_set_alt_setting (target, g_usb_interface_get_alternate (iface)); /* add target */ priv->iface_number = g_usb_interface_get_number (iface); g_ptr_array_add (priv->targets, target); dfu_device_guess_state_from_iface (device, iface); } /* save for reset */ if (priv->state == DFU_STATE_APP_IDLE || (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE)) { priv->runtime_vid = g_usb_device_get_vid (usb_device); priv->runtime_pid = g_usb_device_get_pid (usb_device); priv->runtime_release = g_usb_device_get_release (usb_device); } /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) { if (priv->targets->len == 0) { g_debug ("no DFU runtime, so faking device"); priv->state = DFU_STATE_APP_IDLE; priv->iface_number = 0xff; priv->runtime_vid = g_usb_device_get_vid (usb_device); priv->runtime_pid = g_usb_device_get_pid (usb_device); priv->runtime_release = g_usb_device_get_release (usb_device); priv->attributes = DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD | DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD; } return TRUE; } /* no targets */ if (priv->targets->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no DFU interfaces"); return FALSE; } /* the device upload is broken */ if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_UPLOAD) priv->attributes &= ~DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD; return TRUE; } /** * dfu_device_has_quirk: (skip) * @device: A #DfuDevice * @quirk: A #DfuDeviceQuirks * * Returns if a device has a specific quirk * * Return value: %TRUE if the device has this quirk **/ gboolean dfu_device_has_quirk (DfuDevice *device, DfuDeviceQuirks quirk) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0); return (priv->quirks & quirk) > 0; } /** * dfu_device_can_upload: * @device: a #GUsbDevice * * Gets if the device can upload. * * Return value: %TRUE if the device can upload from device to host **/ gboolean dfu_device_can_upload (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD) > 0; } /** * dfu_device_can_download: * @device: a #GUsbDevice * * Gets if the device can download. * * Return value: %TRUE if the device can download from host to device **/ gboolean dfu_device_can_download (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); return (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD) > 0; } /** * dfu_device_set_timeout: * @device: a #DfuDevice * @timeout_ms: the timeout in ms * * Sets the USB timeout to use when contacting the USB device. **/ void dfu_device_set_timeout (DfuDevice *device, guint timeout_ms) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (DFU_IS_DEVICE (device)); priv->timeout_ms = timeout_ms; } /** * dfu_device_is_runtime: * @device: a #GUsbDevice * * Gets the device mode. * * Return value: %TRUE if the device is in a runtime state **/ gboolean dfu_device_is_runtime (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); if (priv->state == DFU_STATE_APP_IDLE || priv->state == DFU_STATE_APP_DETACH) return TRUE; return FALSE; } /** * dfu_device_get_timeout: * @device: a #GUsbDevice * * Gets the device timeout. * * Return value: enumerated timeout in ms **/ guint dfu_device_get_timeout (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0); return priv->timeout_ms; } /** * dfu_device_get_state: * @device: a #GUsbDevice * * Gets the device state. * * Return value: enumerated state, e.g. %DFU_STATE_DFU_UPLOAD_IDLE **/ DfuState dfu_device_get_state (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0); return priv->state; } /** * dfu_device_get_status: * @device: a #GUsbDevice * * Gets the device status. * * Return value: enumerated status, e.g. %DFU_STATUS_ERR_ADDRESS **/ DfuStatus dfu_device_get_status (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0); return priv->status; } /** * dfu_device_has_attribute: (skip) * @device: A #DfuDevice * @attribute: A #DfuDeviceAttributes, e.g. %DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD * * Returns if an attribute set for the device. * * Return value: %TRUE if the attribute is set **/ gboolean dfu_device_has_attribute (DfuDevice *device, DfuDeviceAttributes attribute) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0x0); return (priv->attributes & attribute) > 0; } /** * dfu_device_remove_attribute: (skip) * @device: A #DfuDevice * @attribute: A #DfuDeviceAttributes, e.g. %DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD * * Removes an attribute from the device. **/ void dfu_device_remove_attribute (DfuDevice *device, DfuDeviceAttributes attribute) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (DFU_IS_DEVICE (device)); priv->attributes &= ~attribute; } static void dfu_device_set_quirks_from_string (DfuDevice *device, const gchar *str) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_auto(GStrv) split = g_strsplit (str, "|", -1); for (guint i = 0; split[i] != NULL; i++) { if (g_strcmp0 (split[i], "ignore-polltimeout") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT; continue; } if (g_strcmp0 (split[i], "force-dfu-mode") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_FORCE_DFU_MODE; continue; } if (g_strcmp0 (split[i], "no-pid-change") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_NO_PID_CHANGE; continue; } if (g_strcmp0 (split[i], "no-get-status-upload") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD; continue; } if (g_strcmp0 (split[i], "no-dfu-runtime") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_NO_DFU_RUNTIME; continue; } if (g_strcmp0 (split[i], "attach-upload-download") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD; continue; } if (g_strcmp0 (split[i], "ignore-runtime") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_RUNTIME; continue; } if (g_strcmp0 (split[i], "action-required") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_ACTION_REQUIRED; continue; } if (g_strcmp0 (split[i], "ignore-upload") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_IGNORE_UPLOAD; continue; } if (g_strcmp0 (split[i], "attach-extra-reset") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_ATTACH_EXTRA_RESET; continue; } if (g_strcmp0 (split[i], "use-any-interface") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_USE_ANY_INTERFACE; continue; } if (g_strcmp0 (split[i], "legacy-protocol") == 0) { priv->quirks |= DFU_DEVICE_QUIRK_LEGACY_PROTOCOL; continue; } } } static void dfu_device_apply_quirks (DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); FuQuirks *system_quirks = fu_device_get_quirks (FU_DEVICE (device)); if (system_quirks != NULL && usb_device != NULL) { const gchar *quirk_str; quirk_str = fu_quirks_lookup_by_usb_device (system_quirks, FU_QUIRKS_DFU, usb_device); if (quirk_str != NULL) dfu_device_set_quirks_from_string (device, quirk_str); } else { g_warning ("no system quirk information"); } } void dfu_device_set_usb_context (DfuDevice *device, GUsbContext *quirks) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_set_object (&priv->usb_context, quirks); } GUsbContext * dfu_device_get_usb_context (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); return priv->usb_context; } /** * dfu_device_new: * * Creates a new DFU device object. * * Return value: a new #DfuDevice **/ DfuDevice * dfu_device_new (GUsbDevice *usb_device) { DfuDevice *device; device = g_object_new (DFU_TYPE_DEVICE, "usb-device", usb_device, NULL); return device; } /** * dfu_device_get_targets: * @device: a #DfuDevice * * Gets all the targets for this device. * * Return value: (transfer none) (element-type DfuTarget): #DfuTarget, or %NULL **/ GPtrArray * dfu_device_get_targets (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), NULL); return priv->targets; } /** * dfu_device_get_target_by_alt_setting: * @device: a #DfuDevice * @alt_setting: the setting used to find * @error: a #GError, or %NULL * * Gets a target with a specific alternative setting. * * Return value: (transfer full): a #DfuTarget, or %NULL **/ DfuTarget * dfu_device_get_target_by_alt_setting (DfuDevice *device, guint8 alt_setting, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find by ID */ for (guint i = 0; i < priv->targets->len; i++) { DfuTarget *target = g_ptr_array_index (priv->targets, i); if (dfu_target_get_alt_setting (target) == alt_setting) return g_object_ref (target); } /* failed */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "No target with alt-setting %i", alt_setting); return NULL; } /** * dfu_device_get_target_by_alt_name: * @device: a #DfuDevice * @alt_name: the name used to find * @error: a #GError, or %NULL * * Gets a target with a specific alternative name. * * Return value: (transfer full): a #DfuTarget, or %NULL **/ DfuTarget * dfu_device_get_target_by_alt_name (DfuDevice *device, const gchar *alt_name, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* find by ID */ for (guint i = 0; i < priv->targets->len; i++) { DfuTarget *target = g_ptr_array_index (priv->targets, i); if (g_strcmp0 (dfu_target_get_alt_name (target, NULL), alt_name) == 0) return g_object_ref (target); } /* failed */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "No target with alt-name %s", alt_name); return NULL; } /** * dfu_device_get_platform_id: * @device: a #DfuDevice * * Gets the platform ID which normally corresponds to the port in some way. * * Return value: string or %NULL **/ const gchar * dfu_device_get_platform_id (DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_return_val_if_fail (DFU_IS_DEVICE (device), NULL); return g_usb_device_get_platform_id (usb_device); } /** * dfu_device_get_runtime_vid: * @device: a #DfuDevice * * Gets the runtime vendor ID. * * Return value: vendor ID, or 0xffff for unknown **/ guint16 dfu_device_get_runtime_vid (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return priv->runtime_vid; } /** * dfu_device_get_runtime_pid: * @device: a #DfuDevice * * Gets the runtime product ID. * * Return value: product ID, or 0xffff for unknown **/ guint16 dfu_device_get_runtime_pid (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return priv->runtime_pid; } /** * dfu_device_get_runtime_release: * @device: a #DfuDevice * * Gets the runtime release number in BCD format. * * Return value: release number, or 0xffff for unknown **/ guint16 dfu_device_get_runtime_release (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return priv->runtime_release; } /** * dfu_device_get_vid: * @device: a #DfuDevice * * Gets the present vendor ID. * * Return value: vendor ID, or 0xffff for unknown **/ guint16 dfu_device_get_vid (DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return g_usb_device_get_vid (usb_device); } /** * dfu_device_get_pid: * @device: a #DfuDevice * * Gets the present product ID. * * Return value: product ID, or 0xffff for unknown **/ guint16 dfu_device_get_pid (DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return g_usb_device_get_pid (usb_device); } /** * dfu_device_get_release: * @device: a #DfuDevice * * Gets the present release number in BCD format. * * Return value: release number, or 0xffff for unknown **/ guint16 dfu_device_get_release (DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xffff); return g_usb_device_get_release (usb_device); } const gchar * dfu_device_get_chip_id (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), NULL); return priv->chip_id; } void dfu_device_set_chip_id (DfuDevice *device, const gchar *chip_id) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_if_fail (DFU_IS_DEVICE (device)); g_debug ("chip ID set to: %s", chip_id); priv->chip_id = g_strdup (chip_id); } static void dfu_device_set_state (DfuDevice *device, DfuState state) { DfuDevicePrivate *priv = GET_PRIVATE (device); if (priv->state == state) return; priv->state = state; g_signal_emit (device, signals[SIGNAL_STATE_CHANGED], 0, state); } static void dfu_device_set_status (DfuDevice *device, DfuStatus status) { DfuDevicePrivate *priv = GET_PRIVATE (device); if (priv->status == status) return; priv->status = status; g_signal_emit (device, signals[SIGNAL_STATUS_CHANGED], 0, status); } gboolean dfu_device_ensure_interface (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; /* already done */ if (priv->claimed_interface) return TRUE; /* nothing set */ if (priv->iface_number == 0xff) return TRUE; /* claim, without detaching kernel driver */ if (!g_usb_device_claim_interface (usb_device, (gint) priv->iface_number, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot claim interface %i: %s", priv->iface_number, error_local->message); return FALSE; } /* success */ priv->claimed_interface = TRUE; return TRUE; } /** * dfu_device_refresh_and_clear: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Refreshes the cached properties on the DFU device. If there are any transers * in progress thay are cancelled, and if there are any pending errors they are * cancelled. * * Return value: %TRUE for success **/ gboolean dfu_device_refresh_and_clear (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); if (!dfu_device_refresh (device, error)) return FALSE; switch (priv->state) { case DFU_STATE_DFU_UPLOAD_IDLE: case DFU_STATE_DFU_DNLOAD_IDLE: case DFU_STATE_DFU_DNLOAD_SYNC: g_debug ("aborting transfer %s", dfu_status_to_string (priv->status)); if (!dfu_device_abort (device, error)) return FALSE; break; case DFU_STATE_DFU_ERROR: g_debug ("clearing error %s", dfu_status_to_string (priv->status)); if (!dfu_device_clear_status (device, error)) return FALSE; break; default: break; } return TRUE; } /** * dfu_device_refresh: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Refreshes the cached properties on the DFU device. * * Return value: %TRUE for success **/ gboolean dfu_device_refresh (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); gsize actual_length = 0; guint8 buf[6]; g_autoptr(GError) error_local = NULL; g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to refresh: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) return TRUE; /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return FALSE; if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_GETSTATUS, 0, priv->iface_number, buf, sizeof(buf), &actual_length, priv->timeout_ms, NULL, /* cancellable */ &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot get device state: %s", error_local->message); return FALSE; } if (actual_length != 6) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "cannot get device status, invalid size: %04x", (guint) actual_length); return FALSE; } /* some devices use the wrong state value */ if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_FORCE_DFU_MODE)) { g_debug ("quirking device into DFU mode"); dfu_device_set_state (device, DFU_STATE_DFU_IDLE); } else { dfu_device_set_state (device, buf[4]); } /* status or state changed */ dfu_device_set_status (device, buf[0]); if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT)) { priv->dnload_timeout = 5; } else { priv->dnload_timeout = buf[1] + (((guint32) buf[2]) << 8) + (((guint32) buf[3]) << 16); } g_debug ("refreshed status=%s and state=%s (dnload=%u)", dfu_status_to_string (priv->status), dfu_state_to_string (priv->state), priv->dnload_timeout); return TRUE; } static guint8 _g_usb_device_get_interface_for_class (GUsbDevice *dev, guint8 intf_class, GError **error) { g_autoptr(GPtrArray) intfs = NULL; intfs = g_usb_device_get_interfaces (dev, error); if (intfs == NULL) return 0xff; for (guint i = 0; i < intfs->len; i++) { GUsbInterface *intf = g_ptr_array_index (intfs, i); if (g_usb_interface_get_class (intf) == intf_class) return g_usb_interface_get_number (intf); } return 0xff; } /** * dfu_device_detach: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Detaches the device putting it into DFU-mode. * * Return value: %TRUE for success **/ gboolean dfu_device_detach (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); FuQuirks *system_quirks = fu_device_get_quirks (FU_DEVICE (device)); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); const guint16 timeout_reset_ms = 1000; const gchar *quirk_str; g_autoptr(GError) error_local = NULL; g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already in DFU mode */ if (!dfu_device_is_runtime (device)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Already in DFU mode; state is %s", dfu_state_to_string (priv->state)); return FALSE; } /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to detach: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } /* handle Jabra devices that need a magic HID packet */ quirk_str = fu_quirks_lookup_by_usb_device (system_quirks, FU_QUIRKS_DFU_JABRA_DETACH, usb_device); if (quirk_str != NULL) { guint8 adr = 0x00; guint8 rep = 0x00; guint8 iface_hid; g_autofree guint8 *buf = g_malloc0 (33); g_autoptr(GError) error_jabra = NULL; /* parse string and create magic packet */ if (strlen (quirk_str) != 4) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "unsupported jabra quirk format: '%s'", quirk_str); return FALSE; } rep = dfu_utils_buffer_parse_uint8 (quirk_str + 0); adr = dfu_utils_buffer_parse_uint8 (quirk_str + 2); buf[0] = rep; buf[1] = adr; buf[2] = 0x00; buf[3] = 0x01; buf[4] = 0x85; buf[5] = 0x07; /* detach the HID interface from the kernel driver */ iface_hid = _g_usb_device_get_interface_for_class (usb_device, G_USB_DEVICE_CLASS_HID, &error_local); if (iface_hid == 0xff) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot find HID interface: %s", error_local->message); return FALSE; } g_debug ("claiming interface 0x%02x", iface_hid); if (!g_usb_device_claim_interface (usb_device, (gint) iface_hid, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot claim interface 0x%02x: %s", iface_hid, error_local->message); return FALSE; } /* send magic to device */ if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, 0x09, 0x0200 | rep, 0x0003, buf, 33, NULL, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, NULL, /* cancellable */ &error_jabra)) { g_debug ("whilst sending magic: %s, ignoring", error_jabra->message); } /* wait for device to re-appear */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_RESTART); if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* wait 10 seconds for DFU mode to settle */ g_debug ("waiting for Jabra device to settle..."); fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_BUSY); g_usleep (10 * G_USEC_PER_SEC); /* hacky workaround until Jabra has a plugin */ usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); } /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) return TRUE; /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return FALSE; /* inform UI there's going to be a detach:attach */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_RESTART); if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_DETACH, timeout_reset_ms, priv->iface_number, NULL, 0, NULL, priv->timeout_ms, NULL, /* cancellable */ &error_local)) { /* some devices just reboot and stall the endpoint :/ */ if (g_error_matches (error_local, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_NOT_SUPPORTED) || g_error_matches (error_local, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_FAILED)) { g_debug ("ignoring while detaching: %s", error_local->message); } else { /* refresh the error code */ dfu_device_error_fixup (device, &error_local); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot detach device: %s", error_local->message); return FALSE; } } /* do a host reset */ if ((priv->attributes & DFU_DEVICE_ATTRIBUTE_WILL_DETACH) == 0) { g_debug ("doing device reset as host will not self-reset"); if (!dfu_device_reset (device, error)) return FALSE; } /* success */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); return TRUE; } /** * dfu_device_abort: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Aborts any upload or download in progress. * * Return value: %TRUE for success **/ gboolean dfu_device_abort (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to abort: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported as no DFU runtime"); return FALSE; } /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return FALSE; if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_ABORT, 0, priv->iface_number, NULL, 0, NULL, priv->timeout_ms, NULL, /* cancellable */ &error_local)) { /* refresh the error code */ dfu_device_error_fixup (device, &error_local); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot abort device: %s", error_local->message); return FALSE; } return TRUE; } /** * dfu_device_clear_status: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Clears any error status on the DFU device. * * Return value: %TRUE for success **/ gboolean dfu_device_clear_status (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to clear status: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported as no DFU runtime"); return FALSE; } /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return FALSE; if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_CLRSTATUS, 0, priv->iface_number, NULL, 0, NULL, priv->timeout_ms, NULL, /* cancellable */ &error_local)) { /* refresh the error code */ dfu_device_error_fixup (device, &error_local); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot clear status on the device: %s", error_local->message); return FALSE; } return TRUE; } /** * dfu_device_get_interface: * @device: a #DfuDevice * * Gets the interface number. **/ guint8 dfu_device_get_interface (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (DFU_IS_DEVICE (device), 0xff); return priv->iface_number; } /** * dfu_device_open: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Opens a DFU-capable device. * * Return value: %TRUE for success **/ static gboolean dfu_device_open (FuUsbDevice *device, GError **error) { DfuDevice *self = DFU_DEVICE (device); DfuDevicePrivate *priv = GET_PRIVATE (self); GPtrArray *targets = dfu_device_get_targets (self); g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* the device has no DFU runtime, so cheat */ if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) { priv->state = DFU_STATE_APP_IDLE; priv->status = DFU_STATUS_OK; } /* set up target ready for use */ for (guint j = 0; j < targets->len; j++) { DfuTarget *target = g_ptr_array_index (targets, j); if (!dfu_target_setup (target, error)) return FALSE; } /* success */ return TRUE; } /** * dfu_device_close: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Closes a DFU device. * * Return value: %TRUE for success **/ static gboolean dfu_device_close (FuUsbDevice *device, GError **error) { DfuDevice *self = DFU_DEVICE (device); DfuDevicePrivate *priv = GET_PRIVATE (self); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); /* release interface */ if (priv->claimed_interface) { g_usb_device_release_interface (usb_device, (gint) priv->iface_number, 0, NULL); priv->claimed_interface = FALSE; } return TRUE; } static gboolean dfu_device_probe (FuUsbDevice *device, GError **error) { DfuDevice *self = DFU_DEVICE (device); DfuDevicePrivate *priv = GET_PRIVATE (self); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); /* set the quirks for this new device */ priv->quirks = DFU_DEVICE_QUIRK_NONE; dfu_device_apply_quirks (self); /* add all the targets */ if (!dfu_device_add_targets (self, error)) { g_prefix_error (error, "%04x:%04x is not supported: ", g_usb_device_get_vid (usb_device), g_usb_device_get_pid (usb_device)); return FALSE; } /* check capabilities */ if (dfu_device_can_download (self)) { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_remove_delay (FU_DEVICE (device), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE); } /* needs a manual action */ if (dfu_device_has_quirk (self, DFU_DEVICE_QUIRK_ACTION_REQUIRED)) { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); } /* success */ return TRUE; } /** * dfu_device_wait_for_replug: * @device: a #DfuDevice * @timeout: the maximum amount of time to wait * @error: a #GError, or %NULL * * Waits for a DFU device to disconnect and reconnect. * This does rely on a #GUsbContext being set up before this is called. * * Return value: %TRUE for success **/ gboolean dfu_device_wait_for_replug (DfuDevice *device, guint timeout, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GUsbDevice) usb_device2 = NULL; /* close */ fu_usb_device_close (FU_USB_DEVICE (device), NULL); /* watch the device disappear and re-appear */ usb_device2 = g_usb_context_wait_for_replug (priv->usb_context, usb_device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error); if (usb_device2 == NULL) return FALSE; /* re-open with new device set */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); fu_usb_device_set_dev (FU_USB_DEVICE (device), usb_device2); if (!fu_usb_device_open (FU_USB_DEVICE (device), error)) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; /* success */ return TRUE; } /** * dfu_device_reset: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Resets the USB device. * * Return value: %TRUE for success **/ gboolean dfu_device_reset (DfuDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(GError) error_local = NULL; g_autoptr(GTimer) timer = g_timer_new (); g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to reset: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } if (!g_usb_device_reset (usb_device, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot reset USB device: %s [%i]", error_local->message, error_local->code); return FALSE; } g_debug ("reset took %.2lfms", g_timer_elapsed (timer, NULL) * 1000); return TRUE; } /** * dfu_device_attach: * @device: a #DfuDevice * @error: a #GError, or %NULL * * Move device from DFU mode to runtime. * * Return value: %TRUE for success **/ gboolean dfu_device_attach (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(DfuTarget) target = NULL; g_return_val_if_fail (DFU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already in runtime mode */ if (dfu_device_is_runtime (device)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Already in application runtime mode"); return FALSE; } /* inform UI there's going to be a re-attach */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_RESTART); /* handle m-stack DFU bootloaders */ if (!priv->done_upload_or_download && (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD) > 0) { g_autoptr(GBytes) chunk = NULL; g_autoptr(DfuTarget) target_zero = NULL; g_debug ("doing dummy upload to work around m-stack quirk"); target_zero = dfu_device_get_target_by_alt_setting (device, 0, error); if (target_zero == NULL) return FALSE; chunk = dfu_target_upload_chunk (target_zero, 0, 0, error); if (chunk == NULL) return FALSE; } /* get default target */ target = dfu_device_get_target_by_alt_setting (device, 0, error); if (target == NULL) return FALSE; /* normal DFU mode just needs a bus reset */ if (!dfu_target_attach (target, error)) return FALSE; /* some devices need yet another reset */ if (dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_ATTACH_EXTRA_RESET)) { if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; if (!dfu_device_reset (device, error)) return FALSE; } /* success */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); return TRUE; } static void dfu_device_percentage_cb (DfuTarget *target, guint percentage, DfuDevice *device) { fu_device_set_progress (FU_DEVICE (device), percentage); } static void dfu_device_action_cb (DfuTarget *target, FwupdStatus action, DfuDevice *device) { fu_device_set_status (FU_DEVICE (device), action); } /** * dfu_device_upload: * @device: a #DfuDevice * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY * @error: a #GError, or %NULL * * Uploads firmware from the target to the host. * * Return value: (transfer full): the uploaded firmware, or %NULL for error **/ DfuFirmware * dfu_device_upload (DfuDevice *device, DfuTargetTransferFlags flags, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(DfuFirmware) firmware = NULL; /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to upload: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return NULL; } /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return NULL; /* create ahead of time */ firmware = dfu_firmware_new (); dfu_firmware_set_vid (firmware, priv->runtime_vid); dfu_firmware_set_pid (firmware, priv->runtime_pid); dfu_firmware_set_release (firmware, 0xffff); /* upload from each target */ for (guint i = 0; i < priv->targets->len; i++) { DfuTarget *target; const gchar *alt_name; gulong id1; gulong id2; g_autoptr(DfuImage) image = NULL; /* upload to target and proxy signals */ target = g_ptr_array_index (priv->targets, i); /* ignore some target types */ alt_name = dfu_target_get_alt_name_for_display (target, NULL); if (g_strcmp0 (alt_name, "Option Bytes") == 0) { g_debug ("ignoring target %s", alt_name); continue; } id1 = g_signal_connect (target, "percentage-changed", G_CALLBACK (dfu_device_percentage_cb), device); id2 = g_signal_connect (target, "action-changed", G_CALLBACK (dfu_device_action_cb), device); image = dfu_target_upload (target, DFU_TARGET_TRANSFER_FLAG_NONE, error); g_signal_handler_disconnect (target, id1); g_signal_handler_disconnect (target, id2); if (image == NULL) return NULL; dfu_firmware_add_image (firmware, image); } /* do not do the dummy upload for quirked devices */ priv->done_upload_or_download = TRUE; /* choose the most appropriate type */ if (priv->targets->len > 1) { g_debug ("switching to DefuSe automatically"); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE); } else { dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU); } /* success */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); return g_object_ref (firmware); } static gboolean dfu_device_id_compatible (guint16 id_file, guint16 id_runtime, guint16 id_dev) { /* file doesn't specify */ if (id_file == 0xffff) return TRUE; /* runtime matches */ if (id_runtime != 0xffff && id_file == id_runtime) return TRUE; /* bootloader matches */ if (id_dev != 0xffff && id_file == id_dev) return TRUE; /* nothing */ return FALSE; } /** * dfu_device_download: * @device: a #DfuDevice * @firmware: a #DfuFirmware * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY * @error: a #GError, or %NULL * * Downloads firmware from the host to the target, optionally verifying * the transfer. * * Return value: %TRUE for success **/ gboolean dfu_device_download (DfuDevice *device, DfuFirmware *firmware, DfuTargetTransferFlags flags, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); GPtrArray *images; GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); gboolean ret; /* no backing USB device */ if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to download: no GUsbDevice for %s", dfu_device_get_platform_id (device)); return FALSE; } /* ensure interface is claimed */ if (!dfu_device_ensure_interface (device, error)) return FALSE; /* do we allow wildcard VID:PID matches */ if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID) == 0) { if (dfu_firmware_get_vid (firmware) == 0xffff) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "firmware vendor ID not specified"); return FALSE; } } if ((flags & DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID) == 0) { if (dfu_firmware_get_pid (firmware) == 0xffff) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "firmware product ID not specified"); return FALSE; } } /* check vendor matches */ if (priv->runtime_vid != 0xffff) { if (!dfu_device_id_compatible (dfu_firmware_get_vid (firmware), priv->runtime_vid, dfu_device_get_vid (device))) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "vendor ID incorrect, expected 0x%04x " "got 0x%04x and 0x%04x\n", dfu_firmware_get_vid (firmware), priv->runtime_vid, dfu_device_get_vid (device)); return FALSE; } } /* check product matches */ if (priv->runtime_pid != 0xffff) { if (!dfu_device_id_compatible (dfu_firmware_get_pid (firmware), priv->runtime_pid, dfu_device_get_pid (device))) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "product ID incorrect, expected 0x%04x " "got 0x%04x and 0x%04x", dfu_firmware_get_pid (firmware), priv->runtime_pid, dfu_device_get_pid (device)); return FALSE; } } /* download each target */ images = dfu_firmware_get_images (firmware); if (images->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no images in firmware file"); return FALSE; } for (guint i = 0; i < images->len; i++) { DfuCipherKind cipher_fw; DfuCipherKind cipher_target; DfuImage *image; DfuTargetTransferFlags flags_local = DFU_TARGET_TRANSFER_FLAG_NONE; const gchar *alt_name; gulong id1; gulong id2; g_autoptr(DfuTarget) target_tmp = NULL; g_autoptr(GError) error_local = NULL; image = g_ptr_array_index (images, i); target_tmp = dfu_device_get_target_by_alt_setting (device, dfu_image_get_alt_setting (image), error); if (target_tmp == NULL) return FALSE; /* we don't actually need to print this, but it makes sure the * target is setup prior to doing the cipher checks */ alt_name = dfu_target_get_alt_name (target_tmp, &error_local); if (alt_name == NULL) { if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND)) { alt_name = "unknown"; } else { g_propagate_error (error, g_steal_pointer (&error_local)); return FALSE; } } g_debug ("downloading to target: %s", alt_name); /* check we're flashing a compatible firmware */ cipher_target = dfu_target_get_cipher_kind (target_tmp); cipher_fw = dfu_firmware_get_cipher_kind (firmware); if ((flags & DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER) == 0) { if (cipher_fw != DFU_CIPHER_KIND_NONE && cipher_target == DFU_CIPHER_KIND_NONE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Device is only accepting " "unsigned firmware, not %s", dfu_cipher_kind_to_string (cipher_fw)); return FALSE; } if (cipher_fw == DFU_CIPHER_KIND_NONE && cipher_target != DFU_CIPHER_KIND_NONE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Device is only accepting " "firmware with %s cipher kind", dfu_cipher_kind_to_string (cipher_target)); return FALSE; } } /* download onto target */ if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY) flags_local = DFU_TARGET_TRANSFER_FLAG_VERIFY; if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW) flags_local |= DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC; id1 = g_signal_connect (target_tmp, "percentage-changed", G_CALLBACK (dfu_device_percentage_cb), device); id2 = g_signal_connect (target_tmp, "action-changed", G_CALLBACK (dfu_device_action_cb), device); ret = dfu_target_download (target_tmp, image, flags_local, error); g_signal_handler_disconnect (target_tmp, id1); g_signal_handler_disconnect (target_tmp, id2); if (!ret) return FALSE; } /* do not do the dummy upload for quirked devices */ priv->done_upload_or_download = TRUE; /* success */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); return TRUE; } void dfu_device_error_fixup (DfuDevice *device, GError **error) { DfuDevicePrivate *priv = GET_PRIVATE (device); /* sad panda */ if (error == NULL) return; /* not the right error to query */ if (!g_error_matches (*error, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_NOT_SUPPORTED)) return; /* get the status */ if (!dfu_device_refresh (device, NULL)) return; /* not in an error state */ if (priv->state != DFU_STATE_DFU_ERROR) return; /* prefix the error */ switch (priv->status) { case DFU_STATUS_OK: /* ignore */ break; case DFU_STATUS_ERR_VENDOR: g_prefix_error (error, "read protection is active: "); break; default: g_prefix_error (error, "[%s,%s]: ", dfu_state_to_string (priv->state), dfu_status_to_string (priv->status)); break; } } /** * dfu_device_get_quirks_as_string: (skip) * @device: a #DfuDevice * * Gets a string describing the quirks set for a device. * * Return value: string, or %NULL for no quirks **/ gchar * dfu_device_get_quirks_as_string (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); GString *str; /* just append to a string */ str = g_string_new (""); if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT) g_string_append_printf (str, "ignore-polltimeout|"); if (priv->quirks & DFU_DEVICE_QUIRK_FORCE_DFU_MODE) g_string_append_printf (str, "force-dfu-mode|"); if (priv->quirks & DFU_DEVICE_QUIRK_NO_PID_CHANGE) g_string_append_printf (str, "no-pid-change|"); if (priv->quirks & DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD) g_string_append_printf (str, "no-get-status-upload|"); if (priv->quirks & DFU_DEVICE_QUIRK_NO_DFU_RUNTIME) g_string_append_printf (str, "no-dfu-runtime|"); if (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD) g_string_append_printf (str, "attach-upload-download|"); if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_RUNTIME) g_string_append_printf (str, "ignore-runtime|"); if (priv->quirks & DFU_DEVICE_QUIRK_ACTION_REQUIRED) g_string_append_printf (str, "action-required|"); if (priv->quirks & DFU_DEVICE_QUIRK_IGNORE_UPLOAD) g_string_append_printf (str, "ignore-upload|"); if (priv->quirks & DFU_DEVICE_QUIRK_ATTACH_EXTRA_RESET) g_string_append_printf (str, "attach-extra-reset|"); if (priv->quirks & DFU_DEVICE_QUIRK_USE_ANY_INTERFACE) g_string_append_printf (str, "use-any-interface|"); if (priv->quirks & DFU_DEVICE_QUIRK_LEGACY_PROTOCOL) g_string_append_printf (str, "legacy-protocol|"); /* a well behaved device */ if (str->len == 0) { g_string_free (str, TRUE); return NULL; } /* remove trailing pipe */ g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } /** * dfu_device_get_attributes_as_string: (skip) * @device: a #DfuDevice * * Gets a string describing the attributes for a device. * * Return value: a string, possibly empty **/ gchar * dfu_device_get_attributes_as_string (DfuDevice *device) { DfuDevicePrivate *priv = GET_PRIVATE (device); GString *str; /* just append to a string */ str = g_string_new (""); if (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD) g_string_append_printf (str, "can-download|"); if (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD) g_string_append_printf (str, "can-upload|"); if (priv->attributes & DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL) g_string_append_printf (str, "manifest-tol|"); if (priv->attributes & DFU_DEVICE_ATTRIBUTE_WILL_DETACH) g_string_append_printf (str, "will-detach|"); if (priv->attributes & DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE) g_string_append_printf (str, "can-accelerate|"); /* remove trailing pipe */ g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } fwupd-1.0.6/plugins/dfu/dfu-device.h000066400000000000000000000157751325145456600173200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_DEVICE_H #define __DFU_DEVICE_H #include #include #include #include "fu-usb-device.h" #include "dfu-common.h" #include "dfu-target.h" #include "dfu-firmware.h" G_BEGIN_DECLS #define DFU_TYPE_DEVICE (dfu_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuDevice, dfu_device, DFU, DEVICE, FuUsbDevice) /** * DfuDeviceQuirks: * @DFU_DEVICE_QUIRK_NONE: No device quirks * @DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT: Ignore the device download timeout * @DFU_DEVICE_QUIRK_FORCE_DFU_MODE: Force DFU mode * @DFU_DEVICE_QUIRK_USE_ANY_INTERFACE: Use any interface for DFU * @DFU_DEVICE_QUIRK_NO_PID_CHANGE: Accept the same VID:PID when changing modes * @DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD: Do not do GetStatus when uploading * @DFU_DEVICE_QUIRK_NO_DFU_RUNTIME: No DFU runtime interface is provided * @DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD: An upload or download is required for attach * @DFU_DEVICE_QUIRK_IGNORE_RUNTIME: Device has broken DFU runtime support * @DFU_DEVICE_QUIRK_ACTION_REQUIRED: User has to do something manually, e.g. press a button * @DFU_DEVICE_QUIRK_IGNORE_UPLOAD: Uploading from the device is broken * @DFU_DEVICE_QUIRK_ATTACH_EXTRA_RESET: Device needs resetting twice for attach * @DFU_DEVICE_QUIRK_LEGACY_PROTOCOL: Use a legacy protocol version * * The workarounds for different devices. **/ typedef enum { DFU_DEVICE_QUIRK_NONE = 0, DFU_DEVICE_QUIRK_IGNORE_POLLTIMEOUT = (1 << 0), DFU_DEVICE_QUIRK_FORCE_DFU_MODE = (1 << 1), DFU_DEVICE_QUIRK_USE_ANY_INTERFACE = (1 << 2), DFU_DEVICE_QUIRK_NO_PID_CHANGE = (1 << 4), DFU_DEVICE_QUIRK_NO_GET_STATUS_UPLOAD = (1 << 5), DFU_DEVICE_QUIRK_NO_DFU_RUNTIME = (1 << 6), DFU_DEVICE_QUIRK_ATTACH_UPLOAD_DOWNLOAD = (1 << 7), DFU_DEVICE_QUIRK_IGNORE_RUNTIME = (1 << 8), DFU_DEVICE_QUIRK_ACTION_REQUIRED = (1 << 9), DFU_DEVICE_QUIRK_IGNORE_UPLOAD = (1 << 10), DFU_DEVICE_QUIRK_ATTACH_EXTRA_RESET = (1 << 11), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL = (1 << 12), /*< private >*/ DFU_DEVICE_QUIRK_LAST } DfuDeviceQuirks; /** * DfuDeviceAttributes: * @DFU_DEVICE_ATTRIBUTE_NONE: No attributes set * @DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD: Can download from host->device * @DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD: Can upload from device->host * @DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL: Can answer GetStatus in manifest * @DFU_DEVICE_ATTRIBUTE_WILL_DETACH: Will self-detach * @DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE: Use a larger transfer size for speed * * The device DFU attributes. **/ typedef enum { DFU_DEVICE_ATTRIBUTE_NONE = 0, DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD = (1 << 0), DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD = (1 << 1), DFU_DEVICE_ATTRIBUTE_MANIFEST_TOL = (1 << 2), DFU_DEVICE_ATTRIBUTE_WILL_DETACH = (1 << 3), DFU_DEVICE_ATTRIBUTE_CAN_ACCELERATE = (1 << 7), /*< private >*/ DFU_DEVICE_ATTRIBUTE_LAST } DfuDeviceAttributes; struct _DfuDeviceClass { FuUsbDeviceClass parent_class; void (*status_changed) (DfuDevice *device, DfuStatus status); void (*state_changed) (DfuDevice *device, DfuState state); void (*percentage_changed) (DfuDevice *device, guint percentage); void (*action_changed) (DfuDevice *device, FwupdStatus action); }; DfuDevice *dfu_device_new (GUsbDevice *usb_device); const gchar *dfu_device_get_platform_id (DfuDevice *device); GPtrArray *dfu_device_get_targets (DfuDevice *device); DfuTarget *dfu_device_get_target_by_alt_setting (DfuDevice *device, guint8 alt_setting, GError **error); DfuTarget *dfu_device_get_target_by_alt_name (DfuDevice *device, const gchar *alt_name, GError **error); const gchar *dfu_device_get_chip_id (DfuDevice *device); void dfu_device_set_chip_id (DfuDevice *device, const gchar *chip_id); guint16 dfu_device_get_runtime_vid (DfuDevice *device); guint16 dfu_device_get_runtime_pid (DfuDevice *device); guint16 dfu_device_get_runtime_release (DfuDevice *device); guint16 dfu_device_get_vid (DfuDevice *device); guint16 dfu_device_get_pid (DfuDevice *device); guint16 dfu_device_get_release (DfuDevice *device); gboolean dfu_device_reset (DfuDevice *device, GError **error); gboolean dfu_device_attach (DfuDevice *device, GError **error); gboolean dfu_device_wait_for_replug (DfuDevice *device, guint timeout, GError **error); DfuFirmware *dfu_device_upload (DfuDevice *device, DfuTargetTransferFlags flags, GError **error); gboolean dfu_device_download (DfuDevice *device, DfuFirmware *firmware, DfuTargetTransferFlags flags, GError **error); gboolean dfu_device_refresh (DfuDevice *device, GError **error); gboolean dfu_device_refresh_and_clear (DfuDevice *device, GError **error); gboolean dfu_device_detach (DfuDevice *device, GError **error); gboolean dfu_device_abort (DfuDevice *device, GError **error); gboolean dfu_device_clear_status (DfuDevice *device, GError **error); guint8 dfu_device_get_interface (DfuDevice *device); gboolean dfu_device_is_runtime (DfuDevice *device); DfuState dfu_device_get_state (DfuDevice *device); DfuStatus dfu_device_get_status (DfuDevice *device); guint16 dfu_device_get_transfer_size (DfuDevice *device); guint16 dfu_device_get_version (DfuDevice *device); guint dfu_device_get_timeout (DfuDevice *device); gboolean dfu_device_can_upload (DfuDevice *device); gboolean dfu_device_can_download (DfuDevice *device); gboolean dfu_device_has_attribute (DfuDevice *device, DfuDeviceAttributes attribute); void dfu_device_remove_attribute (DfuDevice *device, DfuDeviceAttributes attribute); gboolean dfu_device_has_quirk (DfuDevice *device, DfuDeviceQuirks quirk); void dfu_device_set_transfer_size (DfuDevice *device, guint16 transfer_size); void dfu_device_set_timeout (DfuDevice *device, guint timeout_ms); void dfu_device_set_usb_context (DfuDevice *device, GUsbContext *quirks); GUsbContext *dfu_device_get_usb_context (DfuDevice *device); G_END_DECLS #endif /* __DFU_DEVICE_H */ fwupd-1.0.6/plugins/dfu/dfu-element.c000066400000000000000000000143671325145456600175010ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-element * @short_description: Object representing a binary element * * This object represents an binary blob of data at a specific address. * * This allows relocatable data segments to be stored in different * locations on the device itself. * * See also: #DfuImage, #DfuFirmware */ #include "config.h" #include #include #include "dfu-common.h" #include "dfu-element.h" static void dfu_element_finalize (GObject *object); typedef struct { GBytes *contents; guint32 target_size; guint32 address; guint8 padding_value; } DfuElementPrivate; G_DEFINE_TYPE_WITH_PRIVATE (DfuElement, dfu_element, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_element_get_instance_private (o)) static void dfu_element_class_init (DfuElementClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = dfu_element_finalize; } static void dfu_element_init (DfuElement *element) { } static void dfu_element_finalize (GObject *object) { DfuElement *element = DFU_ELEMENT (object); DfuElementPrivate *priv = GET_PRIVATE (element); if (priv->contents != NULL) g_bytes_unref (priv->contents); G_OBJECT_CLASS (dfu_element_parent_class)->finalize (object); } /** * dfu_element_new: * * Creates a new DFU element object. * * Return value: a new #DfuElement **/ DfuElement * dfu_element_new (void) { DfuElement *element; element = g_object_new (DFU_TYPE_ELEMENT, NULL); return element; } /** * dfu_element_get_contents: * @element: a #DfuElement * * Gets the element data. * * Return value: (transfer none): element data **/ GBytes * dfu_element_get_contents (DfuElement *element) { DfuElementPrivate *priv = GET_PRIVATE (element); g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL); return priv->contents; } /** * dfu_element_get_address: * @element: a #DfuElement * * Gets the offset address of the element. * * Return value: memory offset value, or 0x00 for unset **/ guint32 dfu_element_get_address (DfuElement *element) { DfuElementPrivate *priv = GET_PRIVATE (element); g_return_val_if_fail (DFU_IS_ELEMENT (element), 0x00); return priv->address; } /** * dfu_element_set_contents: * @element: a #DfuElement * @contents: element data * * Sets the element data. **/ void dfu_element_set_contents (DfuElement *element, GBytes *contents) { DfuElementPrivate *priv = GET_PRIVATE (element); g_return_if_fail (DFU_IS_ELEMENT (element)); g_return_if_fail (contents != NULL); if (priv->contents == contents) return; if (priv->contents != NULL) g_bytes_unref (priv->contents); priv->contents = g_bytes_ref (contents); } /** * dfu_element_set_address: * @element: a #DfuElement * @address: memory offset value * * Sets the offset address of the element. **/ void dfu_element_set_address (DfuElement *element, guint32 address) { DfuElementPrivate *priv = GET_PRIVATE (element); g_return_if_fail (DFU_IS_ELEMENT (element)); priv->address = address; } /** * dfu_element_to_string: * @element: a #DfuElement * * Returns a string representaiton of the object. * * Return value: NULL terminated string, or %NULL for invalid **/ gchar * dfu_element_to_string (DfuElement *element) { DfuElementPrivate *priv = GET_PRIVATE (element); GString *str; g_return_val_if_fail (DFU_IS_ELEMENT (element), NULL); str = g_string_new (""); g_string_append_printf (str, "address: 0x%02x\n", priv->address); if (priv->target_size > 0) { g_string_append_printf (str, "target: 0x%04x\n", priv->target_size); } if (priv->contents != NULL) { g_string_append_printf (str, "contents: 0x%04x\n", (guint32) g_bytes_get_size (priv->contents)); } g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } /** * dfu_element_set_padding_value: * @element: a #DfuElement * @padding_value: char value, typically 0x00 or 0xff * * Sets a the value of the padding byte to be used in the function * dfu_element_set_target_size(). **/ void dfu_element_set_padding_value (DfuElement *element, guint8 padding_value) { DfuElementPrivate *priv = GET_PRIVATE (element); g_return_if_fail (DFU_IS_ELEMENT (element)); priv->padding_value = padding_value; } /** * dfu_element_set_target_size: * @element: a #DfuElement * @target_size: size in bytes * * Sets a target size for the element. If the prepared element is smaller * than this then it will be padded up to the required size. * * If a padding byte other than 0x00 is required then the function * dfu_element_set_padding_value() should be used before this function is * called. **/ void dfu_element_set_target_size (DfuElement *element, guint32 target_size) { DfuElementPrivate *priv = GET_PRIVATE (element); const guint8 *data; gsize length; guint8 *buf; g_return_if_fail (DFU_IS_ELEMENT (element)); /* save for dump */ priv->target_size = target_size; /* no need to pad */ if (priv->contents == NULL) return; if (g_bytes_get_size (priv->contents) >= target_size) return; /* reallocate and pad */ data = g_bytes_get_data (priv->contents, &length); buf = g_malloc0 (target_size); g_assert (buf != NULL); memcpy (buf, data, length); /* set the pading value */ if (priv->padding_value != 0x00) { memset (buf + length, priv->padding_value, target_size - length); } /* replace */ g_bytes_unref (priv->contents); priv->contents = g_bytes_new_take (buf, target_size); } fwupd-1.0.6/plugins/dfu/dfu-element.h000066400000000000000000000034601325145456600174760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_ELEMENT_H #define __DFU_ELEMENT_H #include #include G_BEGIN_DECLS #define DFU_TYPE_ELEMENT (dfu_element_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuElement, dfu_element, DFU, ELEMENT, GObject) struct _DfuElementClass { GObjectClass parent_class; }; DfuElement *dfu_element_new (void); GBytes *dfu_element_get_contents (DfuElement *element); guint32 dfu_element_get_address (DfuElement *element); void dfu_element_set_contents (DfuElement *element, GBytes *contents); void dfu_element_set_address (DfuElement *element, guint32 address); void dfu_element_set_target_size (DfuElement *element, guint32 target_size); void dfu_element_set_padding_value (DfuElement *element, guint8 padding_value); gchar *dfu_element_to_string (DfuElement *element); G_END_DECLS #endif /* __DFU_ELEMENT_H */ fwupd-1.0.6/plugins/dfu/dfu-firmware.c000066400000000000000000000474451325145456600176670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-firmware * @short_description: Object representing a DFU or DfuSe firmware file * * This object allows reading and writing firmware files either in * raw, DFU or DfuSe formats. * * A #DfuFirmware can be made up of several #DfuImages, although * typically there is only one. * * See also: #DfuImage */ #include "config.h" #include #include #include #include "dfu-common.h" #include "dfu-firmware.h" #include "dfu-format-dfu.h" #include "dfu-format-ihex.h" #include "dfu-format-raw.h" #include "dfu-image.h" #include "fwupd-error.h" static void dfu_firmware_finalize (GObject *object); typedef struct { GHashTable *metadata; GPtrArray *images; guint16 vid; guint16 pid; guint16 release; DfuCipherKind cipher_kind; DfuFirmwareFormat format; } DfuFirmwarePrivate; G_DEFINE_TYPE_WITH_PRIVATE (DfuFirmware, dfu_firmware, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_firmware_get_instance_private (o)) static void dfu_firmware_class_init (DfuFirmwareClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = dfu_firmware_finalize; } static void dfu_firmware_init (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); priv->vid = 0xffff; priv->pid = 0xffff; priv->release = 0xffff; priv->images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static void dfu_firmware_finalize (GObject *object) { DfuFirmware *firmware = DFU_FIRMWARE (object); DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_ptr_array_unref (priv->images); g_hash_table_destroy (priv->metadata); G_OBJECT_CLASS (dfu_firmware_parent_class)->finalize (object); } /** * dfu_firmware_new: * * Creates a new DFU firmware object. * * Return value: a new #DfuFirmware **/ DfuFirmware * dfu_firmware_new (void) { DfuFirmware *firmware; firmware = g_object_new (DFU_TYPE_FIRMWARE, NULL); return firmware; } /** * dfu_firmware_get_image: * @firmware: a #DfuFirmware * @alt_setting: an alternative setting, typically 0x00 * * Gets an image from the firmware file. * * Return value: (transfer none): a #DfuImage, or %NULL for not found **/ DfuImage * dfu_firmware_get_image (DfuFirmware *firmware, guint8 alt_setting) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); /* find correct image */ for (guint i = 0; i < priv->images->len; i++) { DfuImage *im = g_ptr_array_index (priv->images, i); if (dfu_image_get_alt_setting (im) == alt_setting) return im; } return NULL; } /** * dfu_firmware_get_image_by_name: * @firmware: a #DfuFirmware * @name: an alternative setting name * * Gets an image from the firmware file. * * Return value: (transfer none): a #DfuImage, or %NULL for not found **/ DfuImage * dfu_firmware_get_image_by_name (DfuFirmware *firmware, const gchar *name) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); /* find correct image */ for (guint i = 0; i < priv->images->len; i++) { DfuImage *im = g_ptr_array_index (priv->images, i); if (g_strcmp0 (dfu_image_get_name (im), name) == 0) return im; } return NULL; } /** * dfu_firmware_get_image_default: * @firmware: a #DfuFirmware * * Gets the default image from the firmware file. * * Return value: (transfer none): a #DfuImage, or %NULL for not found **/ DfuImage * dfu_firmware_get_image_default (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); if (priv->images->len == 0) return NULL; return g_ptr_array_index (priv->images, 0); } /** * dfu_firmware_get_images: * @firmware: a #DfuFirmware * * Gets all the images contained in this firmware file. * * Return value: (transfer none) (element-type DfuImage): list of images **/ GPtrArray * dfu_firmware_get_images (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); return priv->images; } /** * dfu_firmware_get_size: * @firmware: a #DfuFirmware * * Gets the size of all the images in the firmware. * * This only returns actual data that would be sent to the device and * does not include any padding. * * Return value: a integer value, or 0 if there are no images. **/ guint32 dfu_firmware_get_size (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); guint32 length = 0; g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0); for (guint i = 0; i < priv->images->len; i++) { DfuImage *image = g_ptr_array_index (priv->images, i); length += dfu_image_get_size (image); } return length; } /** * dfu_firmware_add_image: * @firmware: a #DfuFirmware * @image: a #DfuImage * * Adds an image to the list of images. **/ void dfu_firmware_add_image (DfuFirmware *firmware, DfuImage *image) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); g_return_if_fail (DFU_IS_IMAGE (image)); g_ptr_array_add (priv->images, g_object_ref (image)); } /** * dfu_firmware_get_vid: * @firmware: a #DfuFirmware * * Gets the vendor ID. * * Return value: a vendor ID, or 0xffff for unset **/ guint16 dfu_firmware_get_vid (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff); return priv->vid; } /** * dfu_firmware_get_pid: * @firmware: a #DfuFirmware * * Gets the product ID. * * Return value: a product ID, or 0xffff for unset **/ guint16 dfu_firmware_get_pid (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff); return priv->pid; } /** * dfu_firmware_get_release: * @firmware: a #DfuFirmware * * Gets the device ID. * * Return value: a device ID, or 0xffff for unset **/ guint16 dfu_firmware_get_release (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff); return priv->release; } /** * dfu_firmware_get_format: * @firmware: a #DfuFirmware * * Gets the DFU version. * * Return value: a version, or 0x0 for unset **/ guint16 dfu_firmware_get_format (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0xffff); return priv->format; } /** * dfu_firmware_set_vid: * @firmware: a #DfuFirmware * @vid: vendor ID, or 0xffff for unset * * Sets the vendor ID. **/ void dfu_firmware_set_vid (DfuFirmware *firmware, guint16 vid) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); priv->vid = vid; } /** * dfu_firmware_set_pid: * @firmware: a #DfuFirmware * @pid: product ID, or 0xffff for unset * * Sets the product ID. **/ void dfu_firmware_set_pid (DfuFirmware *firmware, guint16 pid) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); priv->pid = pid; } /** * dfu_firmware_set_release: * @firmware: a #DfuFirmware * @release: device ID, or 0xffff for unset * * Sets the device ID. **/ void dfu_firmware_set_release (DfuFirmware *firmware, guint16 release) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); priv->release = release; } /** * dfu_firmware_set_format: * @firmware: a #DfuFirmware * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE * * Sets the DFU version in BCD format. **/ void dfu_firmware_set_format (DfuFirmware *firmware, DfuFirmwareFormat format) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); priv->format = format; } /** * dfu_firmware_parse_data: * @firmware: a #DfuFirmware * @bytes: raw firmware data * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST * @error: a #GError, or %NULL * * Parses firmware data which may have an optional DFU suffix. * * Return value: %TRUE for success **/ gboolean dfu_firmware_parse_data (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE); g_return_val_if_fail (bytes != NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* set defaults */ priv->vid = 0xffff; priv->pid = 0xffff; priv->release = 0xffff; /* try to get format if not already set */ if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN) priv->format = dfu_firmware_detect_ihex (bytes); if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN) priv->format = dfu_firmware_detect_dfu (bytes); if (priv->format == DFU_FIRMWARE_FORMAT_UNKNOWN) priv->format = dfu_firmware_detect_raw (bytes); /* handled easily */ switch (priv->format) { case DFU_FIRMWARE_FORMAT_INTEL_HEX: if (!dfu_firmware_from_ihex (firmware, bytes, flags, error)) return FALSE; break; case DFU_FIRMWARE_FORMAT_DFU: case DFU_FIRMWARE_FORMAT_DFUSE: if (!dfu_firmware_from_dfu (firmware, bytes, flags, error)) return FALSE; break; default: if (!dfu_firmware_from_raw (firmware, bytes, flags, error)) return FALSE; break; } return TRUE; } /** * dfu_firmware_parse_file: * @firmware: a #DfuFirmware * @file: a #GFile to load and parse * @flags: optional flags, e.g. %DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST * @error: a #GError, or %NULL * * Parses a DFU firmware, which may contain an optional footer. * * Return value: %TRUE for success **/ gboolean dfu_firmware_parse_file (DfuFirmware *firmware, GFile *file, DfuFirmwareParseFlags flags, GError **error) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); gchar *contents = NULL; gsize length = 0; g_autofree gchar *basename = NULL; g_autoptr(GBytes) bytes = NULL; g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE); g_return_val_if_fail (G_IS_FILE (file), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* guess cipher kind based on file extension */ basename = g_file_get_basename (file); if (g_str_has_suffix (basename, ".xdfu")) priv->cipher_kind = DFU_CIPHER_KIND_XTEA; if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error)) return FALSE; bytes = g_bytes_new_take (contents, length); return dfu_firmware_parse_data (firmware, bytes, flags, error); } /** * dfu_firmware_get_metadata: * @firmware: a #DfuFirmware * @key: metadata string key * * Gets metadata from the store with a specific key. * * Return value: the metadata value, or %NULL for unset **/ const gchar * dfu_firmware_get_metadata (DfuFirmware *firmware, const gchar *key) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); return g_hash_table_lookup (priv->metadata, key); } /** * dfu_firmware_get_metadata_table: * @firmware: a #DfuFirmware * * Gets all metadata from the store. * * Return value: (transfer none): the metadata hash table **/ GHashTable * dfu_firmware_get_metadata_table (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); return priv->metadata; } /** * dfu_firmware_set_metadata: * @firmware: a #DfuFirmware * @key: metadata string key * @value: metadata string value * * Sets a metadata value with a specific key. **/ void dfu_firmware_set_metadata (DfuFirmware *firmware, const gchar *key, const gchar *value) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_debug ("adding metadata %s=%s", key, value); g_hash_table_insert (priv->metadata, g_strdup (key), g_strdup (value)); } /** * dfu_firmware_remove_metadata: * @firmware: a #DfuFirmware * @key: metadata string key * * Removes a metadata item from the store **/ void dfu_firmware_remove_metadata (DfuFirmware *firmware, const gchar *key) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_debug ("removing metadata %s", key); g_hash_table_remove (priv->metadata, key); } static gboolean dfu_firmware_check_acceptable_for_format (DfuFirmware *firmware, GError **error) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); /* always okay */ if (priv->images->len <= 1) return TRUE; if (priv->format == DFU_FIRMWARE_FORMAT_DFUSE) return TRUE; /* one is usual, and 2 is okay if one image is the signature */ if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX) { if (priv->images->len == 2 && dfu_firmware_get_image_by_name (firmware, "signature") != NULL) return TRUE; } /* unsupported */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "multiple images (%u) not supported for %s", priv->images->len, dfu_firmware_format_to_string (priv->format)); return TRUE; } /** * dfu_firmware_write_data: * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Writes DFU data to a data blob with a DFU-specific footer. * * Return value: (transfer none): firmware data **/ GBytes * dfu_firmware_write_data (DfuFirmware *firmware, GError **error) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* at least one image */ if (priv->images == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "no image data to write"); return NULL; } /* does the format support this many images */ if (!dfu_firmware_check_acceptable_for_format (firmware, error)) return NULL; /* raw */ if (priv->format == DFU_FIRMWARE_FORMAT_RAW) return dfu_firmware_to_raw (firmware, error); /* DFU or DfuSe*/ if (priv->format == DFU_FIRMWARE_FORMAT_DFU || priv->format == DFU_FIRMWARE_FORMAT_DFUSE) return dfu_firmware_to_dfu (firmware, error); /* Intel HEX */ if (priv->format == DFU_FIRMWARE_FORMAT_INTEL_HEX) return dfu_firmware_to_ihex (firmware, error); /* invalid */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid format for write (0x%04x)", priv->format); return NULL; } /** * dfu_firmware_write_file: * @firmware: a #DfuFirmware * @file: a #GFile * @error: a #GError, or %NULL * * Writes a DFU firmware with the optional footer. * * Return value: %TRUE for success **/ gboolean dfu_firmware_write_file (DfuFirmware *firmware, GFile *file, GError **error) { const guint8 *data; gsize length = 0; g_autoptr(GBytes) bytes = NULL; g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), FALSE); g_return_val_if_fail (G_IS_FILE (file), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* get blob */ bytes = dfu_firmware_write_data (firmware, error); if (bytes == NULL) return FALSE; /* save to firmware */ data = g_bytes_get_data (bytes, &length); return g_file_replace_contents (file, (const gchar *) data, length, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL, /* cancellable */ error); } static gchar * _bcd_version_from_uint16 (guint16 val) { #if AS_CHECK_VERSION(0,7,3) return as_utils_version_from_uint16 (val, AS_VERSION_PARSE_FLAG_USE_BCD); #else guint maj = ((val >> 12) & 0x0f) * 10 + ((val >> 8) & 0x0f); guint min = ((val >> 4) & 0x0f) * 10 + (val & 0x0f); return g_strdup_printf ("%u.%u", maj, min); #endif } /** * dfu_firmware_to_string: * @firmware: a #DfuFirmware * * Returns a string representaiton of the object. * * Return value: NULL terminated string, or %NULL for invalid **/ gchar * dfu_firmware_to_string (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); DfuImage *image; GString *str; g_autofree gchar *release_str = NULL; g_autoptr(GList) keys = NULL; g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), NULL); release_str = _bcd_version_from_uint16 (priv->release); str = g_string_new (""); g_string_append_printf (str, "vid: 0x%04x\n", priv->vid); g_string_append_printf (str, "pid: 0x%04x\n", priv->pid); g_string_append_printf (str, "release: 0x%04x [%s]\n", priv->release, release_str); g_string_append_printf (str, "format: %s [0x%04x]\n", dfu_firmware_format_to_string (priv->format), priv->format); g_string_append_printf (str, "cipher: %s\n", dfu_cipher_kind_to_string (priv->cipher_kind)); /* print metadata */ keys = g_hash_table_get_keys (priv->metadata); for (GList *l = keys; l != NULL; l = l->next) { const gchar *key = l->data; const gchar *value; value = g_hash_table_lookup (priv->metadata, key); g_string_append_printf (str, "metadata: %s=%s\n", key, value); } /* print images */ for (guint i = 0; i < priv->images->len; i++) { g_autofree gchar *tmp = NULL; image = g_ptr_array_index (priv->images, i); tmp = dfu_image_to_string (image); g_string_append_printf (str, "= IMAGE %u =\n", i); g_string_append_printf (str, "%s\n", tmp); } g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } /** * dfu_firmware_format_to_string: * @format: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFU * * Returns a string representaiton of the format. * * Return value: NULL terminated string, or %NULL for invalid **/ const gchar * dfu_firmware_format_to_string (DfuFirmwareFormat format) { if (format == DFU_FIRMWARE_FORMAT_RAW) return "raw"; if (format == DFU_FIRMWARE_FORMAT_DFU) return "dfu"; if (format == DFU_FIRMWARE_FORMAT_DFUSE) return "dfuse"; if (format == DFU_FIRMWARE_FORMAT_INTEL_HEX) return "ihex"; return NULL; } /** * dfu_firmware_format_from_string: * @format: a format string, e.g. `dfuse` * * Returns an enumerated version of the format. * * Return value: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_DFUSE **/ DfuFirmwareFormat dfu_firmware_format_from_string (const gchar *format) { if (g_strcmp0 (format, "raw") == 0) return DFU_FIRMWARE_FORMAT_RAW; if (g_strcmp0 (format, "dfu") == 0) return DFU_FIRMWARE_FORMAT_DFU; if (g_strcmp0 (format, "dfuse") == 0) return DFU_FIRMWARE_FORMAT_DFUSE; if (g_strcmp0 (format, "ihex") == 0) return DFU_FIRMWARE_FORMAT_INTEL_HEX; return DFU_FIRMWARE_FORMAT_UNKNOWN; } /** * dfu_firmware_get_cipher_kind: * @firmware: a #DfuFirmware * * Returns the kind of cipher used by the firmware file. * * NOTE: this value is based on a heuristic, and may not be accurate. * The value %DFU_CIPHER_KIND_NONE will be returned when the cipher * is not recognised. * * Return value: NULL terminated string, or %NULL for invalid **/ DfuCipherKind dfu_firmware_get_cipher_kind (DfuFirmware *firmware) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_val_if_fail (DFU_IS_FIRMWARE (firmware), 0); return priv->cipher_kind; } /** * dfu_firmware_set_cipher_kind: * @firmware: a #DfuFirmware * @cipher_kind: a #DfuCipherKind, e.g. %DFU_CIPHER_KIND_XTEA * * Sets the kind of cipher used by the firmware file. **/ void dfu_firmware_set_cipher_kind (DfuFirmware *firmware, DfuCipherKind cipher_kind) { DfuFirmwarePrivate *priv = GET_PRIVATE (firmware); g_return_if_fail (DFU_IS_FIRMWARE (firmware)); priv->cipher_kind = cipher_kind; } fwupd-1.0.6/plugins/dfu/dfu-firmware.h000066400000000000000000000112061325145456600176560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FIRMWARE_H #define __DFU_FIRMWARE_H #include #include #include "dfu-common.h" #include "dfu-image.h" G_BEGIN_DECLS #define DFU_TYPE_FIRMWARE (dfu_firmware_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuFirmware, dfu_firmware, DFU, FIRMWARE, GObject) struct _DfuFirmwareClass { GObjectClass parent_class; }; /** * DfuFirmwareParseFlags: * @DFU_FIRMWARE_PARSE_FLAG_NONE: No flags set * @DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST: Do not verify the CRC * @DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST: Do not verify the DFU version * @DFU_FIRMWARE_PARSE_FLAG_NO_METADATA: Do not read the metadata table * * The optional flags used for parsing. **/ typedef enum { DFU_FIRMWARE_PARSE_FLAG_NONE = 0, DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST = (1 << 0), DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST = (1 << 1), DFU_FIRMWARE_PARSE_FLAG_NO_METADATA = (1 << 2), /*< private >*/ DFU_FIRMWARE_PARSE_FLAG_LAST } DfuFirmwareParseFlags; /** * DfuFirmwareFormat: * @DFU_FIRMWARE_FORMAT_UNKNOWN: Format unknown * @DFU_FIRMWARE_FORMAT_RAW: Raw format * @DFU_FIRMWARE_FORMAT_DFU: DFU footer * @DFU_FIRMWARE_FORMAT_DFUSE: DfuSe header * @DFU_FIRMWARE_FORMAT_INTEL_HEX: Intel HEX * * The known versions of the DFU standard in BCD format. **/ typedef enum { DFU_FIRMWARE_FORMAT_UNKNOWN, DFU_FIRMWARE_FORMAT_RAW, DFU_FIRMWARE_FORMAT_DFU, DFU_FIRMWARE_FORMAT_DFUSE, DFU_FIRMWARE_FORMAT_INTEL_HEX, /*< private >*/ DFU_FIRMWARE_FORMAT_LAST } DfuFirmwareFormat; DfuFirmware *dfu_firmware_new (void); const gchar *dfu_firmware_format_to_string (DfuFirmwareFormat format); DfuFirmwareFormat dfu_firmware_format_from_string(const gchar *format); DfuImage *dfu_firmware_get_image (DfuFirmware *firmware, guint8 alt_setting); DfuImage *dfu_firmware_get_image_by_name (DfuFirmware *firmware, const gchar *name); DfuImage *dfu_firmware_get_image_default (DfuFirmware *firmware); GPtrArray *dfu_firmware_get_images (DfuFirmware *firmware); guint16 dfu_firmware_get_vid (DfuFirmware *firmware); guint16 dfu_firmware_get_pid (DfuFirmware *firmware); guint16 dfu_firmware_get_release (DfuFirmware *firmware); guint16 dfu_firmware_get_format (DfuFirmware *firmware); guint32 dfu_firmware_get_size (DfuFirmware *firmware); DfuCipherKind dfu_firmware_get_cipher_kind (DfuFirmware *firmware); void dfu_firmware_add_image (DfuFirmware *firmware, DfuImage *image); void dfu_firmware_set_vid (DfuFirmware *firmware, guint16 vid); void dfu_firmware_set_pid (DfuFirmware *firmware, guint16 pid); void dfu_firmware_set_release (DfuFirmware *firmware, guint16 release); void dfu_firmware_set_format (DfuFirmware *firmware, DfuFirmwareFormat format); void dfu_firmware_set_cipher_kind (DfuFirmware *firmware, DfuCipherKind cipher_kind); gboolean dfu_firmware_parse_data (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); gboolean dfu_firmware_parse_file (DfuFirmware *firmware, GFile *file, DfuFirmwareParseFlags flags, GError **error); GBytes *dfu_firmware_write_data (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_write_file (DfuFirmware *firmware, GFile *file, GError **error); gchar *dfu_firmware_to_string (DfuFirmware *firmware); GHashTable *dfu_firmware_get_metadata_table(DfuFirmware *firmware); const gchar *dfu_firmware_get_metadata (DfuFirmware *firmware, const gchar *key); void dfu_firmware_set_metadata (DfuFirmware *firmware, const gchar *key, const gchar *value); void dfu_firmware_remove_metadata (DfuFirmware *firmware, const gchar *key); G_END_DECLS #endif /* __DFU_FIRMWARE_H */ fwupd-1.0.6/plugins/dfu/dfu-format-dfu.c000066400000000000000000000266141325145456600201120ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "dfu-element.h" #include "dfu-format-dfu.h" #include "dfu-format-metadata.h" #include "dfu-format-dfuse.h" #include "dfu-format-raw.h" #include "dfu-image.h" #include "fwupd-error.h" typedef struct __attribute__((packed)) { guint16 release; guint16 pid; guint16 vid; guint16 ver; guint8 sig[3]; guint8 len; guint32 crc; } DfuFirmwareFooter; /** * dfu_firmware_detect_dfu: (skip) * @bytes: data to parse * * Attempts to sniff the data and work out the firmware format * * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW **/ DfuFirmwareFormat dfu_firmware_detect_dfu (GBytes *bytes) { DfuFirmwareFooter *ftr; guint8 *data; gsize len; /* check data size */ data = (guint8 *) g_bytes_get_data (bytes, &len); if (len < 16) return DFU_FIRMWARE_FORMAT_UNKNOWN; /* check for DFU signature */ ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)]; if (memcmp (ftr->sig, "UFD", 3) != 0) return DFU_FIRMWARE_FORMAT_UNKNOWN; /* check versions */ switch (GUINT16_FROM_LE (ftr->ver)) { case DFU_VERSION_DFU_1_0: case DFU_VERSION_DFU_1_1: return DFU_FIRMWARE_FORMAT_DFU; case DFU_VERSION_DFUSE: return DFU_FIRMWARE_FORMAT_DFUSE; default: break; } return DFU_FIRMWARE_FORMAT_UNKNOWN; } static guint32 _crctbl[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; static guint32 dfu_firmware_generate_crc32 (const guint8 *data, gsize length) { guint32 accum = 0xffffffff; for (guint i = 0; i < length; i++) accum = _crctbl[(accum^data[i]) & 0xff] ^ (accum >> 8); return accum; } /** * dfu_firmware_from_dfu: (skip) * @firmware: a #DfuFirmware * @bytes: data to parse * @flags: some #DfuFirmwareParseFlags * @error: a #GError, or %NULL * * Unpacks into a firmware object from dfu data. * * Returns: %TRUE for success **/ gboolean dfu_firmware_from_dfu (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { DfuFirmwareFooter *ftr; const gchar *cipher_str; gsize len; guint32 crc; guint32 crc_new; guint8 *data; g_autoptr(GBytes) contents = NULL; /* check data size */ data = (guint8 *) g_bytes_get_data (bytes, &len); if (len < 16) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "size check failed, too small"); return FALSE; } /* check for DFU signature */ ftr = (DfuFirmwareFooter *) &data[len - sizeof(DfuFirmwareFooter)]; if (memcmp (ftr->sig, "UFD", 3) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "no DFU signature"); return FALSE; } /* check version */ if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST) == 0) { if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFU && dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "version check failed, got %04x", dfu_firmware_get_format (firmware)); return FALSE; } } /* verify the checksum */ crc = GUINT32_FROM_LE (ftr->crc); if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) { crc_new = dfu_firmware_generate_crc32 (data, len - 4); if (crc != crc_new) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "CRC failed, expected %04x, got %04x", crc_new, GUINT32_FROM_LE (ftr->crc)); return FALSE; } } /* set from footer */ dfu_firmware_set_vid (firmware, GUINT16_FROM_LE (ftr->vid)); dfu_firmware_set_pid (firmware, GUINT16_FROM_LE (ftr->pid)); dfu_firmware_set_release (firmware, GUINT16_FROM_LE (ftr->release)); /* check reported length */ if (ftr->len > len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "reported firmware size %04x larger than file %04x", (guint) ftr->len, (guint) len); return FALSE; } /* parse the optional metadata segment */ if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_METADATA) == 0) { gsize offset = len - ftr->len; g_autoptr(GBytes) md = g_bytes_new (&data[offset], ftr->len); if (!dfu_firmware_from_metadata (firmware, md, flags, error)) return FALSE; } /* set this automatically */ cipher_str = dfu_firmware_get_metadata (firmware, DFU_METADATA_KEY_CIPHER_KIND); if (cipher_str != NULL) { if (g_strcmp0 (cipher_str, "XTEA") == 0) dfu_firmware_set_cipher_kind (firmware, DFU_CIPHER_KIND_XTEA); else g_warning ("Unknown CipherKind: %s", cipher_str); } /* parse DfuSe prefix */ contents = g_bytes_new_from_bytes (bytes, 0, len - ftr->len); if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) return dfu_firmware_from_dfuse (firmware, contents, flags, error); /* just copy old-plain DFU file */ return dfu_firmware_from_raw (firmware, contents, flags, error); } static DfuVersion dfu_convert_version (DfuFirmwareFormat format) { if (format == DFU_FIRMWARE_FORMAT_DFU) return DFU_VERSION_DFU_1_0; if (format == DFU_FIRMWARE_FORMAT_DFUSE) return DFU_VERSION_DFUSE; return DFU_VERSION_UNKNOWN; } static GBytes * dfu_firmware_add_footer (DfuFirmware *firmware, GBytes *contents, GError **error) { DfuFirmwareFooter *ftr; const guint8 *data_bin; const guint8 *data_md; gsize length_bin = 0; gsize length_md = 0; guint32 crc_new; guint8 *buf; g_autoptr(GBytes) metadata_table = NULL; /* get any file metadata */ metadata_table = dfu_firmware_to_metadata (firmware, error); if (metadata_table == NULL) return NULL; data_md = g_bytes_get_data (metadata_table, &length_md); /* add the raw firmware data */ data_bin = g_bytes_get_data (contents, &length_bin); buf = g_malloc0 (length_bin + length_md + 0x10); memcpy (buf + 0, data_bin, length_bin); /* add the metadata table */ memcpy (buf + length_bin, data_md, length_md); /* set up LE footer */ ftr = (DfuFirmwareFooter *) (buf + length_bin + length_md); ftr->release = GUINT16_TO_LE (dfu_firmware_get_release (firmware)); ftr->pid = GUINT16_TO_LE (dfu_firmware_get_pid (firmware)); ftr->vid = GUINT16_TO_LE (dfu_firmware_get_vid (firmware)); ftr->ver = GUINT16_TO_LE (dfu_convert_version (dfu_firmware_get_format (firmware))); ftr->len = (guint8) (sizeof (DfuFirmwareFooter) + length_md); memcpy(ftr->sig, "UFD", 3); crc_new = dfu_firmware_generate_crc32 (buf, length_bin + length_md + 12); ftr->crc = GUINT32_TO_LE (crc_new); /* return all data */ return g_bytes_new_take (buf, length_bin + length_md + 0x10); } /** * dfu_firmware_to_dfu: (skip) * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Packs dfu firmware * * Returns: (transfer full): the packed data **/ GBytes * dfu_firmware_to_dfu (DfuFirmware *firmware, GError **error) { /* plain DFU */ if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFU) { GBytes *contents; DfuElement *element; DfuImage *image; image = dfu_firmware_get_image_default (firmware); g_assert (image != NULL); element = dfu_image_get_element (image, 0); if (element == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no firmware element data to write"); return NULL; } contents = dfu_element_get_contents (element); return dfu_firmware_add_footer (firmware, contents, error); } /* DfuSe */ if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) { g_autoptr(GBytes) contents = NULL; contents = dfu_firmware_to_dfuse (firmware, error); if (contents == NULL) return NULL; return dfu_firmware_add_footer (firmware, contents, error); } g_assert_not_reached (); return NULL; } fwupd-1.0.6/plugins/dfu/dfu-format-dfu.h000066400000000000000000000026301325145456600201070ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_DFU_H #define __DFU_FORMAT_DFU_H #include #include #include "dfu-firmware.h" G_BEGIN_DECLS DfuFirmwareFormat dfu_firmware_detect_dfu (GBytes *bytes); GBytes *dfu_firmware_to_dfu (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_from_dfu (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_DFU_H */ fwupd-1.0.6/plugins/dfu/dfu-format-dfuse.c000066400000000000000000000246311325145456600204370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "dfu-element.h" #include "dfu-format-dfuse.h" #include "dfu-image.h" #include "fwupd-error.h" /* DfuSe element header */ typedef struct __attribute__((packed)) { guint32 address; guint32 size; } DfuSeElementPrefix; /** * dfu_element_from_dfuse: (skip) * @data: data buffer * @length: length of @data we can access * @consumed: (out): the number of bytes we consued * @error: a #GError, or %NULL * * Unpacks an element from DfuSe data. * * Returns: a #DfuElement, or %NULL for error **/ static DfuElement * dfu_element_from_dfuse (const guint8 *data, guint32 length, guint32 *consumed, GError **error) { DfuElement *element = NULL; DfuSeElementPrefix *el = (DfuSeElementPrefix *) data; guint32 size; g_autoptr(GBytes) contents = NULL; g_assert_cmpint(sizeof(DfuSeElementPrefix), ==, 8); /* check input buffer size */ if (length < sizeof(DfuSeElementPrefix)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid element data size %u", (guint32) length); return NULL; } /* check size */ size = GUINT32_FROM_LE (el->size); if (size + sizeof(DfuSeElementPrefix) > length) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid element size %u, only %u bytes left", size, (guint32) (length - sizeof(DfuSeElementPrefix))); return NULL; } /* create new element */ element = dfu_element_new (); dfu_element_set_address (element, GUINT32_FROM_LE (el->address)); contents = g_bytes_new (data + sizeof(DfuSeElementPrefix), size); dfu_element_set_contents (element, contents); /* return size */ if (consumed != NULL) *consumed = (guint32) sizeof(DfuSeElementPrefix) + size; return element; } /** * dfu_element_to_dfuse: (skip) * @element: a #DfuElement * * Packs a DfuSe element. * * Returns: (transfer full): the packed data **/ static GBytes * dfu_element_to_dfuse (DfuElement *element) { DfuSeElementPrefix *el; const guint8 *data; gsize length; guint8 *buf; data = g_bytes_get_data (dfu_element_get_contents (element), &length); buf = g_malloc0 (length + sizeof (DfuSeElementPrefix)); el = (DfuSeElementPrefix *) buf; el->address = GUINT32_TO_LE (dfu_element_get_address (element)); el->size = GUINT32_TO_LE (length); memcpy (buf + sizeof (DfuSeElementPrefix), data, length); return g_bytes_new_take (buf, length + sizeof (DfuSeElementPrefix)); } /* DfuSe image header */ typedef struct __attribute__((packed)) { guint8 sig[6]; guint8 alt_setting; guint32 target_named; gchar target_name[255]; guint32 target_size; guint32 elements; } DfuSeImagePrefix; /** * dfu_image_from_dfuse: (skip) * @data: data buffer * @length: length of @data we can access * @consumed: (out): the number of bytes we consued * @error: a #GError, or %NULL * * Unpacks an image from DfuSe data. * * Returns: a #DfuImage, or %NULL for error **/ static DfuImage * dfu_image_from_dfuse (const guint8 *data, guint32 length, guint32 *consumed, GError **error) { DfuSeImagePrefix *im; guint32 elements; guint32 offset = sizeof(DfuSeImagePrefix); g_autoptr(DfuImage) image = NULL; g_assert_cmpint(sizeof(DfuSeImagePrefix), ==, 274); /* check input buffer size */ if (length < sizeof(DfuSeImagePrefix)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid image data size %u", (guint32) length); return NULL; } /* verify image signature */ im = (DfuSeImagePrefix *) data; if (memcmp (im->sig, "Target", 6) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid DfuSe target signature"); return NULL; } /* create new image */ image = dfu_image_new (); dfu_image_set_alt_setting (image, im->alt_setting); if (GUINT32_FROM_LE (im->target_named) == 0x01) dfu_image_set_name (image, im->target_name); /* parse elements */ length -= offset; elements = GUINT32_FROM_LE (im->elements); for (guint j = 0; j < elements; j++) { guint32 consumed_local; g_autoptr(DfuElement) element = NULL; element = dfu_element_from_dfuse (data + offset, length, &consumed_local, error); if (element == NULL) return NULL; dfu_image_add_element (image, element); offset += consumed_local; length -= consumed_local; } /* return size */ if (consumed != NULL) *consumed = offset; return g_object_ref (image); } /** * dfu_image_to_dfuse: (skip) * @image: a #DfuImage * * Packs a DfuSe image * * Returns: (transfer full): the packed data **/ static GBytes * dfu_image_to_dfuse (DfuImage *image) { DfuSeImagePrefix *im; GPtrArray *elements; guint32 length_total = 0; guint32 offset = sizeof (DfuSeImagePrefix); guint8 *buf; g_autoptr(GPtrArray) element_array = NULL; /* get total size */ element_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); elements = dfu_image_get_elements (image); for (guint i = 0; i < elements->len; i++) { DfuElement *element = g_ptr_array_index (elements, i); GBytes *bytes = dfu_element_to_dfuse (element); g_ptr_array_add (element_array, bytes); length_total += (guint32) g_bytes_get_size (bytes); } /* add prefix */ buf = g_malloc0 (length_total + sizeof (DfuSeImagePrefix)); im = (DfuSeImagePrefix *) buf; memcpy (im->sig, "Target", 6); im->alt_setting = dfu_image_get_alt_setting (image); if (dfu_image_get_name (image) != NULL) { im->target_named = GUINT32_TO_LE (0x01); memcpy (im->target_name, dfu_image_get_name (image), 255); } im->target_size = GUINT32_TO_LE (length_total); im->elements = GUINT32_TO_LE (elements->len); /* copy data */ for (guint i = 0; i < element_array->len; i++) { gsize length; GBytes *bytes = g_ptr_array_index (element_array, i); const guint8 *data = g_bytes_get_data (bytes, &length); memcpy (buf + offset, data, length); offset += (guint32) length; } return g_bytes_new_take (buf, length_total + sizeof (DfuSeImagePrefix)); } /* DfuSe header */ typedef struct __attribute__((packed)) { guint8 sig[5]; guint8 ver; guint32 image_size; guint8 targets; } DfuSePrefix; /** * dfu_firmware_to_dfuse: (skip) * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Packs a DfuSe firmware * * Returns: (transfer full): the packed data **/ GBytes * dfu_firmware_to_dfuse (DfuFirmware *firmware, GError **error) { DfuSePrefix *prefix; GPtrArray *images; guint32 image_size_total = 0; guint32 offset = sizeof (DfuSePrefix); g_autofree guint8 *buf = NULL; g_autoptr(GPtrArray) dfuse_images = NULL; /* get all the image data */ dfuse_images = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); images = dfu_firmware_get_images (firmware); for (guint i = 0; i < images->len; i++) { DfuImage *im = g_ptr_array_index (images, i); GBytes *contents; contents = dfu_image_to_dfuse (im); image_size_total += (guint32) g_bytes_get_size (contents); g_ptr_array_add (dfuse_images, contents); } g_debug ("image_size_total: %" G_GUINT32_FORMAT, image_size_total); buf = g_malloc0 (sizeof (DfuSePrefix) + image_size_total); /* DfuSe header */ prefix = (DfuSePrefix *) buf; memcpy (prefix->sig, "DfuSe", 5); prefix->ver = 0x01; prefix->image_size = GUINT32_TO_LE (offset + image_size_total); if (images->len > G_MAXUINT8) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "too many (%u) images to write DfuSe file", images->len); return NULL; } prefix->targets = (guint8) images->len; /* copy images */ for (guint i = 0; i < dfuse_images->len; i++) { GBytes *contents = g_ptr_array_index (dfuse_images, i); gsize length; const guint8 *data; data = g_bytes_get_data (contents, &length); memcpy (buf + offset, data, length); offset += (guint32) length; } /* return blob */ return g_bytes_new (buf, sizeof (DfuSePrefix) + image_size_total); } /** * dfu_firmware_from_dfuse: (skip) * @firmware: a #DfuFirmware * @bytes: data to parse * @flags: some #DfuFirmwareParseFlags * @error: a #GError, or %NULL * * Unpacks into a firmware object from DfuSe data. * * Returns: %TRUE for success **/ gboolean dfu_firmware_from_dfuse (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { DfuSePrefix *prefix; gsize len; guint32 offset = sizeof(DfuSePrefix); guint8 *data; /* check the prefix (BE) */ data = (guint8 *) g_bytes_get_data (bytes, &len); prefix = (DfuSePrefix *) data; if (memcmp (prefix->sig, "DfuSe", 5) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid DfuSe prefix"); return FALSE; } /* check the version */ if (prefix->ver != 0x01) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid DfuSe version, got %02x", prefix->ver); return FALSE; } /* check image size */ if (GUINT32_FROM_LE (prefix->image_size) != len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid DfuSe image size, " "got %" G_GUINT32_FORMAT ", " "expected %" G_GSIZE_FORMAT, GUINT32_FROM_LE (prefix->image_size), len); return FALSE; } /* parse the image targets */ len -= sizeof(DfuSePrefix); for (guint i = 0; i < prefix->targets; i++) { guint consumed; g_autoptr(DfuImage) image = NULL; image = dfu_image_from_dfuse (data + offset, (guint32) len, &consumed, error); if (image == NULL) return FALSE; dfu_firmware_add_image (firmware, image); offset += consumed; len -= consumed; } return TRUE; } fwupd-1.0.6/plugins/dfu/dfu-format-dfuse.h000066400000000000000000000026471325145456600204470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_DFUSE_H #define __DFU_FORMAT_DFUSE_H #include #include #include "dfu-firmware.h" G_BEGIN_DECLS DfuFirmwareFormat dfu_firmware_detect_dfuse (GBytes *bytes); GBytes *dfu_firmware_to_dfuse (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_from_dfuse (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_DFUSE_H */ fwupd-1.0.6/plugins/dfu/dfu-format-ihex.c000066400000000000000000000267061325145456600202730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fu-common.h" #include "dfu-element.h" #include "dfu-firmware.h" #include "dfu-format-ihex.h" #include "dfu-image.h" #include "fwupd-error.h" /** * dfu_firmware_detect_ihex: (skip) * @bytes: data to parse * * Attempts to sniff the data and work out the firmware format * * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW **/ DfuFirmwareFormat dfu_firmware_detect_ihex (GBytes *bytes) { guint8 *data; gsize len; data = (guint8 *) g_bytes_get_data (bytes, &len); if (len < 12) return DFU_FIRMWARE_FORMAT_UNKNOWN; if (data[0] != ':') return DFU_FIRMWARE_FORMAT_UNKNOWN; return DFU_FIRMWARE_FORMAT_INTEL_HEX; } #define DFU_INHX32_RECORD_TYPE_DATA 0x00 #define DFU_INHX32_RECORD_TYPE_EOF 0x01 #define DFU_INHX32_RECORD_TYPE_EXTENDED_SEGMENT 0x02 #define DFU_INHX32_RECORD_TYPE_START_SEGMENT 0x03 #define DFU_INHX32_RECORD_TYPE_EXTENDED 0x04 #define DFU_INHX32_RECORD_TYPE_ADDR32 0x05 #define DFU_INHX32_RECORD_TYPE_SIGNATURE 0xfd /** * dfu_firmware_from_ihex: (skip) * @firmware: a #DfuFirmware * @bytes: data to parse * @flags: some #DfuFirmwareParseFlags * @error: a #GError, or %NULL * * Unpacks into a firmware object from raw data. * * Returns: %TRUE for success **/ gboolean dfu_firmware_from_ihex (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { const gchar *in_buffer; gboolean got_eof = FALSE; gsize len_in; guint16 addr_high = 0; guint16 addr_low = 0; guint32 addr32 = 0; guint32 addr32_last = 0; guint32 element_address = 0; guint8 checksum; guint8 data_tmp; guint8 len_tmp; guint8 type; guint end; guint offset = 0; g_autoptr(DfuElement) element = NULL; g_autoptr(DfuImage) image = NULL; g_autoptr(GBytes) contents = NULL; g_autoptr(GString) string = NULL; g_autoptr(GString) signature = g_string_new (NULL); g_return_val_if_fail (bytes != NULL, FALSE); /* create element */ image = dfu_image_new (); dfu_image_set_name (image, "ihex"); element = dfu_element_new (); /* parse records */ in_buffer = g_bytes_get_data (bytes, &len_in); string = g_string_new (""); while (offset < len_in) { /* check starting token */ if (in_buffer[offset] != ':') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid starting token, got %c at %x", in_buffer[offset], offset); return FALSE; } /* check there's enough data for the smallest possible record */ if (offset + 12 > (guint) len_in) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "record incomplete at %u, length %u", offset, (guint) len_in); return FALSE; } /* length, 16-bit address, type */ len_tmp = dfu_utils_buffer_parse_uint8 (in_buffer + offset + 1); addr_low = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 3); type = dfu_utils_buffer_parse_uint8 (in_buffer + offset + 7); /* position of checksum */ end = offset + 9 + len_tmp * 2; if (end > (guint) len_in) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "checksum > file length: %u", end); return FALSE; } /* verify checksum */ if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) { checksum = 0; for (guint i = offset + 1; i < end + 2; i += 2) { data_tmp = dfu_utils_buffer_parse_uint8 (in_buffer + i); checksum += data_tmp; } if (checksum != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid record checksum at 0x%04x " "to 0x%04x, got 0x%02x", offset, end, checksum); return FALSE; } } /* process different record types */ switch (type) { case DFU_INHX32_RECORD_TYPE_DATA: /* if not contiguous with previous record */ if ((addr_high + addr_low) != addr32) { if (addr32 == 0x0) { g_debug ("base address %08x", addr_low); dfu_element_set_address (element, addr_low); } addr32 = ((guint32) addr_high << 16) + addr_low; if (element_address == 0x0) element_address = addr32; } /* does not make sense */ if (addr32 < addr32_last) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid address 0x%x, last was 0x%x", (guint) addr32, (guint) addr32_last); return FALSE; } /* parse bytes from line */ g_debug ("writing data 0x%08x", (guint32) addr32); for (guint i = offset + 9; i < end; i += 2) { /* any holes in the hex record */ guint32 len_hole = addr32 - addr32_last; if (addr32_last > 0x0 && len_hole > 1) { for (guint j = 1; j < len_hole; j++) { g_debug ("filling address 0x%08x", addr32_last + j); /* although 0xff might be clearer, * we can't write 0xffff to pic14 */ g_string_append_c (string, 0x00); } } /* write into buf */ data_tmp = dfu_utils_buffer_parse_uint8 (in_buffer + i); g_string_append_c (string, (gchar) data_tmp); addr32_last = addr32++; } break; case DFU_INHX32_RECORD_TYPE_EOF: if (got_eof) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "duplicate EOF, perhaps " "corrupt file"); return FALSE; } got_eof = TRUE; break; case DFU_INHX32_RECORD_TYPE_EXTENDED: addr_high = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 9); addr32 = ((guint32) addr_high << 16) + addr_low; break; case DFU_INHX32_RECORD_TYPE_ADDR32: addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 9); break; case DFU_INHX32_RECORD_TYPE_EXTENDED_SEGMENT: /* segment base address, so ~1Mb addressable */ addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 9) * 16; break; case DFU_INHX32_RECORD_TYPE_START_SEGMENT: /* initial content of the CS:IP registers */ addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 9); break; case DFU_INHX32_RECORD_TYPE_SIGNATURE: for (guint i = offset + 9; i < end; i += 2) { guint8 tmp_c = dfu_utils_buffer_parse_uint8 (in_buffer + i); g_string_append_c (signature, tmp_c); } break; default: /* vendors sneak in nonstandard sections past the EOF */ if (got_eof) break; g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid ihex record type %i", type); return FALSE; } /* ignore any line return */ offset = end + 2; for (; offset < len_in; offset++) { if (in_buffer[offset] != '\n' && in_buffer[offset] != '\r') break; } } /* no EOF */ if (!got_eof) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no EOF, perhaps truncated file"); return FALSE; } /* add single image */ contents = g_bytes_new (string->str, string->len); dfu_element_set_contents (element, contents); dfu_element_set_address (element, element_address); dfu_image_add_element (image, element); dfu_firmware_add_image (firmware, image); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX); /* add optional signature */ if (signature->len > 0) { g_autoptr(DfuElement) element_sig = dfu_element_new (); g_autoptr(DfuImage) image_sig = dfu_image_new (); g_autoptr(GBytes) data = g_bytes_new_static (signature->str, signature->len); dfu_element_set_contents (element_sig, data); dfu_image_add_element (image_sig, element_sig); dfu_image_set_name (image_sig, "signature"); dfu_firmware_add_image (firmware, image_sig); } return TRUE; } static void dfu_firmware_ihex_emit_chunk (GString *str, guint16 address, guint8 record_type, const guint8 *data, gsize sz) { guint8 checksum = 0x00; g_string_append_printf (str, ":%02X%04X%02X", (guint) sz, (guint) address, (guint) record_type); for (gsize j = 0; j < sz; j++) g_string_append_printf (str, "%02X", data[j]); checksum = (guint8) sz; checksum += (guint8) ((address & 0xff00) >> 8); checksum += (guint8) (address & 0xff); checksum += record_type; for (gsize j = 0; j < sz; j++) checksum += data[j]; g_string_append_printf (str, "%02X\n", (guint) (((~checksum) + 0x01) & 0xff)); } static void dfu_firmware_to_ihex_bytes (GString *str, guint8 record_type, guint32 address, GBytes *contents) { const guint8 *data; const guint chunk_size = 16; gsize len; guint32 address_offset_last = 0x0; /* get number of chunks */ data = g_bytes_get_data (contents, &len); for (gsize i = 0; i < len; i += chunk_size) { guint32 address_tmp = address + i; guint32 address_offset = (address_tmp >> 16) & 0xffff; gsize chunk_len = MIN (len - i, 16); /* need to offset */ if (address_offset != address_offset_last) { guint8 buf[2]; fu_common_write_uint16 (buf, address_offset, G_BIG_ENDIAN); dfu_firmware_ihex_emit_chunk (str, 0x0, DFU_INHX32_RECORD_TYPE_EXTENDED, buf, 2); address_offset_last = address_offset; } address_tmp &= 0xffff; dfu_firmware_ihex_emit_chunk (str, address_tmp, record_type, data + i, chunk_len); } } static gboolean dfu_firmware_to_ihex_element (DfuElement *element, GString *str, guint8 record_type, GError **error) { GBytes *contents = dfu_element_get_contents (element); dfu_firmware_to_ihex_bytes (str, record_type, dfu_element_get_address (element), contents); return TRUE; } static gboolean dfu_firmware_to_ihex_image (DfuImage *image, GString *str, GError **error) { GPtrArray *elements; guint8 record_type = DFU_INHX32_RECORD_TYPE_DATA; if (g_strcmp0 (dfu_image_get_name (image), "signature") == 0) record_type = DFU_INHX32_RECORD_TYPE_SIGNATURE; elements = dfu_image_get_elements (image); for (guint i = 0; i < elements->len; i++) { DfuElement *element = g_ptr_array_index (elements, i); if (!dfu_firmware_to_ihex_element (element, str, record_type, error)) return FALSE; } return TRUE; } /** * dfu_firmware_to_ihex: (skip) * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Packs a IHEX firmware * * Returns: (transfer full): the packed data **/ GBytes * dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error) { GPtrArray *images; g_autoptr(GString) str = NULL; /* write all the element data */ str = g_string_new (""); images = dfu_firmware_get_images (firmware); for (guint i = 0; i < images->len; i++) { DfuImage *image = g_ptr_array_index (images, i); if (!dfu_firmware_to_ihex_image (image, str, error)) return NULL; } /* add EOF */ dfu_firmware_ihex_emit_chunk (str, 0x0, DFU_INHX32_RECORD_TYPE_EOF, NULL, 0); return g_bytes_new (str->str, str->len); } fwupd-1.0.6/plugins/dfu/dfu-format-ihex.h000066400000000000000000000026361325145456600202740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_IHEX_H #define __DFU_FORMAT_IHEX_H #include #include #include "dfu-firmware.h" G_BEGIN_DECLS DfuFirmwareFormat dfu_firmware_detect_ihex (GBytes *bytes); GBytes *dfu_firmware_to_ihex (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_from_ihex (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_IHEX_H */ fwupd-1.0.6/plugins/dfu/dfu-format-metadata.c000066400000000000000000000126171325145456600211120ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "dfu-element.h" #include "dfu-format-metadata.h" #include "dfu-image.h" #include "fwupd-error.h" /** * dfu_firmware_from_metadata: (skip) * @firmware: a #DfuFirmware * @bytes: data to parse * @flags: some #DfuFirmwareParseFlags * @error: a #GError, or %NULL * * Unpacks into a firmware object from metadata data. * * The representation in memory is as follows: * * uint16 signature='MD' * uint8 number_of_keys * uint8 number_of_keys * uint8 key(n)_length * ... key(n) (no NUL) * uint8 value(n)_length * ... value(n) (no NUL) * * Returns: %TRUE for success **/ gboolean dfu_firmware_from_metadata (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { const guint8 *data; gsize data_length; guint idx = 2; guint kvlen; guint number_keys; /* not big enough */ data = g_bytes_get_data (bytes, &data_length); if (data_length <= 0x10) return TRUE; /* signature invalid */ if (memcmp (data, "MD", 2) != 0) return TRUE; /* parse key=value store */ number_keys = data[idx++]; for (guint i = 0; i < number_keys; i++) { g_autofree gchar *key = NULL; g_autofree gchar *value = NULL; /* parse key */ kvlen = data[idx++]; if (kvlen > 233) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "metadata table corrupt, key=%u", kvlen); return FALSE; } if (idx + kvlen + 0x10 > data_length) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "metadata table corrupt, k-kvlen=%u", kvlen); return FALSE; } key = g_strndup ((const gchar *) data + idx, kvlen); idx += kvlen; /* parse value */ kvlen = data[idx++]; if (kvlen > 233) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "metadata table corrupt, value=%u", kvlen); return FALSE; } if (idx + kvlen + 0x10 > data_length) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "metadata table corrupt, v-kvlen=%u", kvlen); return FALSE; } value = g_strndup ((const gchar *) data + idx, kvlen); idx += kvlen; dfu_firmware_set_metadata (firmware, key, value); } return TRUE; } /** * dfu_firmware_to_metadata: (skip) * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Packs metadata firmware * * Returns: (transfer full): the packed data **/ GBytes * dfu_firmware_to_metadata (DfuFirmware *firmware, GError **error) { GHashTable *metadata; guint8 mdbuf[239]; guint idx = 0; guint number_keys; g_autoptr(GList) keys = NULL; /* no metadata */ metadata = dfu_firmware_get_metadata_table (firmware); if (g_hash_table_size (metadata) == 0) return g_bytes_new (NULL, 0); /* check the number of keys */ keys = g_hash_table_get_keys (metadata); number_keys = g_list_length (keys); if (number_keys > 59) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "too many metadata keys (%u)", number_keys); return NULL; } /* write the signature */ mdbuf[idx++] = 'M'; mdbuf[idx++] = 'D'; mdbuf[idx++] = (guint8) number_keys; for (GList *l = keys; l != NULL; l = l->next) { const gchar *key; const gchar *value; guint key_len; guint value_len; /* check key and value length */ key = l->data; key_len = (guint) strlen (key); if (key_len > 233) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "metdata key too long: %s", key); return NULL; } value = g_hash_table_lookup (metadata, key); value_len = (guint) strlen (value); if (value_len > 233) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "value too long: %s", value); return NULL; } /* do we still have space? */ if (idx + key_len + value_len + 2 > sizeof(mdbuf)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not enough space in metadata table, " "already used %u bytes", idx); return NULL; } /* write the key */ mdbuf[idx++] = (guint8) key_len; memcpy(mdbuf + idx, key, key_len); idx += key_len; /* write the value */ mdbuf[idx++] = (guint8) value_len; memcpy(mdbuf + idx, value, value_len); idx += value_len; } g_debug ("metadata table was %u/%" G_GSIZE_FORMAT " bytes", idx, sizeof(mdbuf)); return g_bytes_new (mdbuf, idx); } fwupd-1.0.6/plugins/dfu/dfu-format-metadata.h000066400000000000000000000025661325145456600211210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_METADATA_H #define __DFU_FORMAT_METADATA_H #include #include #include "dfu-firmware.h" G_BEGIN_DECLS GBytes *dfu_firmware_to_metadata (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_from_metadata (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_METADATA_H */ fwupd-1.0.6/plugins/dfu/dfu-format-raw.c000066400000000000000000000055231325145456600201210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "dfu-element.h" #include "dfu-format-raw.h" #include "dfu-image.h" #include "fwupd-error.h" /** * dfu_firmware_detect_raw: (skip) * @bytes: data to parse * * Attempts to sniff the data and work out the firmware format * * Returns: a #DfuFirmwareFormat, e.g. %DFU_FIRMWARE_FORMAT_RAW **/ DfuFirmwareFormat dfu_firmware_detect_raw (GBytes *bytes) { return DFU_FIRMWARE_FORMAT_RAW; } /** * dfu_firmware_from_raw: (skip) * @firmware: a #DfuFirmware * @bytes: data to parse * @flags: some #DfuFirmwareParseFlags * @error: a #GError, or %NULL * * Unpacks into a firmware object from raw data. * * Returns: %TRUE for success **/ gboolean dfu_firmware_from_raw (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error) { g_autoptr(DfuElement) element = NULL; g_autoptr(DfuImage) image = NULL; image = dfu_image_new (); element = dfu_element_new (); dfu_element_set_contents (element, bytes); dfu_image_add_element (image, element); dfu_firmware_add_image (firmware, image); return TRUE; } /** * dfu_firmware_to_raw: (skip) * @firmware: a #DfuFirmware * @error: a #GError, or %NULL * * Packs raw firmware * * Returns: (transfer full): the packed data **/ GBytes * dfu_firmware_to_raw (DfuFirmware *firmware, GError **error) { DfuElement *element; DfuImage *image; GBytes *contents; image = dfu_firmware_get_image_default (firmware); if (image == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no firmware image data to write"); return NULL; } element = dfu_image_get_element (image, 0); if (element == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no firmware element data to write"); return NULL; } contents = dfu_element_get_contents (element); return g_bytes_ref (contents); } fwupd-1.0.6/plugins/dfu/dfu-format-raw.h000066400000000000000000000026301325145456600201220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_FORMAT_RAW_H #define __DFU_FORMAT_RAW_H #include #include #include "dfu-firmware.h" G_BEGIN_DECLS DfuFirmwareFormat dfu_firmware_detect_raw (GBytes *bytes); GBytes *dfu_firmware_to_raw (DfuFirmware *firmware, GError **error); gboolean dfu_firmware_from_raw (DfuFirmware *firmware, GBytes *bytes, DfuFirmwareParseFlags flags, GError **error); G_END_DECLS #endif /* __DFU_FORMAT_RAW_H */ fwupd-1.0.6/plugins/dfu/dfu-image.c000066400000000000000000000161761325145456600171320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-image * @short_description: Object representing a a firmware image * * A #DfuImage is typically made up of several #DfuElements, although * typically there will only be one. * * See also: #DfuElement */ #include "config.h" #include #include #include "dfu-common.h" #include "dfu-element.h" #include "dfu-image.h" static void dfu_image_finalize (GObject *object); typedef struct { GPtrArray *elements; gchar name[255]; guint8 alt_setting; } DfuImagePrivate; G_DEFINE_TYPE_WITH_PRIVATE (DfuImage, dfu_image, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_image_get_instance_private (o)) static void dfu_image_class_init (DfuImageClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = dfu_image_finalize; } static void dfu_image_init (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); priv->elements = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); memset (priv->name, 0x00, 255); } static void dfu_image_finalize (GObject *object) { DfuImage *image = DFU_IMAGE (object); DfuImagePrivate *priv = GET_PRIVATE (image); g_ptr_array_unref (priv->elements); G_OBJECT_CLASS (dfu_image_parent_class)->finalize (object); } /** * dfu_image_new: * * Creates a new DFU image object. * * Return value: a new #DfuImage **/ DfuImage * dfu_image_new (void) { DfuImage *image; image = g_object_new (DFU_TYPE_IMAGE, NULL); return image; } /** * dfu_image_get_elements: * @image: a #DfuImage * * Gets the element data. * * Return value: (transfer none) (element-type DfuElement): element data **/ GPtrArray * dfu_image_get_elements (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); return priv->elements; } /** * dfu_image_get_element: * @image: a #DfuImage * @idx: an array index * * Gets the element. * * Return value: (transfer none): element data, or %NULL for invalid **/ DfuElement * dfu_image_get_element (DfuImage *image, guint8 idx) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); if (idx >= priv->elements->len) return NULL; return g_ptr_array_index (priv->elements, idx); } /** * dfu_image_get_element_default: * @image: a #DfuImage * * Gets the default element. * * Return value: (transfer none): element data, or %NULL for invalid **/ DfuElement * dfu_image_get_element_default (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); if (priv->elements->len == 0) return NULL; return g_ptr_array_index (priv->elements, 0); } /** * dfu_image_get_alt_setting: * @image: a #DfuImage * * Gets the alternate setting. * * Return value: integer, or 0x00 for unset **/ guint8 dfu_image_get_alt_setting (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_val_if_fail (DFU_IS_IMAGE (image), 0xff); return priv->alt_setting; } /** * dfu_image_get_name: * @image: a #DfuImage * * Gets the target name. * * Return value: a string, or %NULL for unset **/ const gchar * dfu_image_get_name (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); return priv->name; } /** * dfu_image_get_size: * @image: a #DfuImage * * Gets the size of all the elements in the image. * * This only returns actual data that would be sent to the device and * does not include any padding. * * Return value: a integer value, or 0 if there are no elements. **/ guint32 dfu_image_get_size (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); guint32 length = 0; g_return_val_if_fail (DFU_IS_IMAGE (image), 0); for (guint i = 0; i < priv->elements->len; i++) { DfuElement *element = g_ptr_array_index (priv->elements, i); length += (guint32) g_bytes_get_size (dfu_element_get_contents (element)); } return length; } /** * dfu_image_add_element: * @image: a #DfuImage * @element: a #DfuElement * * Adds an element to the image. **/ void dfu_image_add_element (DfuImage *image, DfuElement *element) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_if_fail (DFU_IS_IMAGE (image)); g_return_if_fail (DFU_IS_ELEMENT (element)); g_ptr_array_add (priv->elements, g_object_ref (element)); } /** * dfu_image_set_alt_setting: * @image: a #DfuImage * @alt_setting: vendor ID, or 0xffff for unset * * Sets the vendor ID. **/ void dfu_image_set_alt_setting (DfuImage *image, guint8 alt_setting) { DfuImagePrivate *priv = GET_PRIVATE (image); g_return_if_fail (DFU_IS_IMAGE (image)); priv->alt_setting = alt_setting; } /** * dfu_image_set_name: * @image: a #DfuImage * @name: a target string, or %NULL * * Sets the target name. **/ void dfu_image_set_name (DfuImage *image, const gchar *name) { guint16 sz; DfuImagePrivate *priv = GET_PRIVATE (image); g_return_if_fail (DFU_IS_IMAGE (image)); /* this is a hard limit in DfuSe */ memset (priv->name, 0x00, 0xff); if (name != NULL) { sz = MIN ((guint16) strlen (name), 0xff - 1); memcpy (priv->name, name, sz); } /* copy junk data in self tests for 1:1 copies */ if (name != NULL && G_UNLIKELY (g_getenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME") != NULL)) memcpy (priv->name, name, 0xff); } /** * dfu_image_to_string: * @image: a #DfuImage * * Returns a string representaiton of the object. * * Return value: NULL terminated string, or %NULL for invalid **/ gchar * dfu_image_to_string (DfuImage *image) { DfuImagePrivate *priv = GET_PRIVATE (image); GString *str; g_return_val_if_fail (DFU_IS_IMAGE (image), NULL); str = g_string_new (""); g_string_append_printf (str, "alt_setting: 0x%02x\n", priv->alt_setting); if (priv->name[0] != '\0') g_string_append_printf (str, "name: %s\n", priv->name); g_string_append_printf (str, "elements: 0x%02x\n", priv->elements->len); /* add elements */ for (guint i = 0; i < priv->elements->len; i++) { DfuElement *element = g_ptr_array_index (priv->elements, i); g_autofree gchar *tmp = NULL; tmp = dfu_element_to_string (element); g_string_append_printf (str, "== ELEMENT %u ==\n", i); g_string_append_printf (str, "%s\n", tmp); } g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } fwupd-1.0.6/plugins/dfu/dfu-image.h000066400000000000000000000036521325145456600171320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_IMAGE_H #define __DFU_IMAGE_H #include #include #include "dfu-element.h" G_BEGIN_DECLS #define DFU_TYPE_IMAGE (dfu_image_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuImage, dfu_image, DFU, IMAGE, GObject) struct _DfuImageClass { GObjectClass parent_class; }; DfuImage *dfu_image_new (void); GPtrArray *dfu_image_get_elements (DfuImage *image); DfuElement *dfu_image_get_element (DfuImage *image, guint8 idx); DfuElement *dfu_image_get_element_default (DfuImage *image); guint8 dfu_image_get_alt_setting (DfuImage *image); const gchar *dfu_image_get_name (DfuImage *image); guint32 dfu_image_get_size (DfuImage *image); void dfu_image_add_element (DfuImage *image, DfuElement *element); void dfu_image_set_alt_setting (DfuImage *image, guint8 alt_setting); void dfu_image_set_name (DfuImage *image, const gchar *name); gchar *dfu_image_to_string (DfuImage *image); G_END_DECLS #endif /* __DFU_IMAGE_H */ fwupd-1.0.6/plugins/dfu/dfu-patch.c000066400000000000000000000416671325145456600171520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-patch * @short_description: Object representing a binary patch * * This object represents an binary patch that can be applied on a firmware * image. The patch itself is made up of chunks of data that have an offset * and that can replace the data to upgrade the firmware. * * Note: this is one way operation -- the patch can only be used to go forwards * and also cannot be used to truncate the existing image. * * See also: #DfuImage, #DfuFirmware */ #include "config.h" #include #include #include "dfu-common.h" #include "dfu-patch.h" #include "fwupd-error.h" static void dfu_patch_finalize (GObject *object); typedef struct __attribute__((packed)) { guint32 off; guint32 sz; guint32 flags; } DfuPatchChunkHeader; typedef struct __attribute__((packed)) { guint8 signature[4]; /* 'DfuP' */ guint8 reserved[4]; guint8 checksum_old[20]; /* SHA1 */ guint8 checksum_new[20]; /* SHA1 */ } DfuPatchFileHeader; typedef struct { GBytes *checksum_old; GBytes *checksum_new; GPtrArray *chunks; /* of DfuPatchChunk */ } DfuPatchPrivate; typedef struct { guint32 off; GBytes *blob; } DfuPatchChunk; G_DEFINE_TYPE_WITH_PRIVATE (DfuPatch, dfu_patch, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_patch_get_instance_private (o)) static void dfu_patch_class_init (DfuPatchClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = dfu_patch_finalize; } static void dfu_patch_chunk_free (DfuPatchChunk *chunk) { g_bytes_unref (chunk->blob); g_free (chunk); } static void dfu_patch_init (DfuPatch *self) { DfuPatchPrivate *priv = GET_PRIVATE (self); priv->chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_patch_chunk_free); } static void dfu_patch_finalize (GObject *object) { DfuPatch *self = DFU_PATCH (object); DfuPatchPrivate *priv = GET_PRIVATE (self); if (priv->checksum_old != NULL) g_bytes_unref (priv->checksum_old); if (priv->checksum_new != NULL) g_bytes_unref (priv->checksum_new); g_ptr_array_unref (priv->chunks); G_OBJECT_CLASS (dfu_patch_parent_class)->finalize (object); } /** * dfu_patch_export: * @self: a #DfuPatch * @error: a #GError, or %NULL * * Converts the patch to a binary blob that can be stored as a file. * * Return value: (transfer full): blob **/ GBytes * dfu_patch_export (DfuPatch *self, GError **error) { DfuPatchPrivate *priv = GET_PRIVATE (self); gsize addr; gsize sz; guint8 *data; g_return_val_if_fail (DFU_IS_PATCH (self), NULL); /* check we have something to write */ if (priv->chunks->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no chunks to process"); return NULL; } /* calculate the size of the new blob */ sz = sizeof(DfuPatchFileHeader); for (guint i = 0; i < priv->chunks->len; i++) { DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i); sz += sizeof(DfuPatchChunkHeader) + g_bytes_get_size (chunk->blob); } g_debug ("blob size is %" G_GSIZE_FORMAT, sz); /* actually allocate and fill in the blob */ data = g_malloc0 (sz); memcpy (data, "DfuP", 4); /* add checksums */ if (priv->checksum_old != NULL) { gsize csum_sz = 0; const guint8 *csum_data = g_bytes_get_data (priv->checksum_old, &csum_sz); memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old), csum_data, csum_sz); } if (priv->checksum_new != NULL) { gsize csum_sz = 0; const guint8 *csum_data = g_bytes_get_data (priv->checksum_new, &csum_sz); memcpy (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new), csum_data, csum_sz); } addr = sizeof(DfuPatchFileHeader); for (guint i = 0; i < priv->chunks->len; i++) { DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i); DfuPatchChunkHeader chunkhdr; gsize sz_tmp = 0; const guint8 *data_new = g_bytes_get_data (chunk->blob, &sz_tmp); /* build chunk header and append data */ chunkhdr.off = GUINT32_TO_LE (chunk->off); chunkhdr.sz = GUINT32_TO_LE (sz_tmp); chunkhdr.flags = 0; memcpy (data + addr, &chunkhdr, sizeof(DfuPatchChunkHeader)); memcpy (data + addr + sizeof(DfuPatchChunkHeader), data_new, sz_tmp); /* move up after the copied data */ addr += sizeof(DfuPatchChunkHeader) + sz_tmp; } return g_bytes_new_take (data, sz); } /** * dfu_patch_import: * @self: a #DfuPatch * @blob: patch data * @error: a #GError, or %NULL * * Creates a patch from a serialized patch, possibly from a file. * * Return value: %TRUE on success **/ gboolean dfu_patch_import (DfuPatch *self, GBytes *blob, GError **error) { DfuPatchPrivate *priv = GET_PRIVATE (self); const guint8 *data; gsize sz = 0; guint32 off; g_return_val_if_fail (DFU_IS_PATCH (self), FALSE); g_return_val_if_fail (blob != NULL, FALSE); /* cannot reuse object */ if (priv->chunks->len > 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "patch has already been loaded"); return FALSE; } /* check minimum size */ data = g_bytes_get_data (blob, &sz); if (sz < sizeof(DfuPatchFileHeader) + sizeof(DfuPatchChunkHeader) + 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "file is too small"); return FALSE; } /* check header */ if (memcmp (data, "DfuP", 4) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "header signature is not correct"); return FALSE; } /* get checksums */ priv->checksum_old = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_old), 20); priv->checksum_new = g_bytes_new (data + G_STRUCT_OFFSET(DfuPatchFileHeader,checksum_new), 20); /* look for each chunk */ off = sizeof(DfuPatchFileHeader); while (off < (guint32) sz) { DfuPatchChunkHeader *chunkhdr = (DfuPatchChunkHeader *) (data + off); DfuPatchChunk *chunk; guint32 chunk_sz = GUINT32_FROM_LE (chunkhdr->sz); guint32 chunk_off = GUINT32_FROM_LE (chunkhdr->off); /* check chunk size, assuming it can overflow */ if (chunk_sz > sz || off + chunk_sz > sz) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "chunk offset 0x%04x outsize file size 0x%04x", (guint) (off + chunk_sz), (guint) sz); return FALSE; } chunk = g_new0 (DfuPatchChunk, 1); chunk->off = chunk_off; chunk->blob = g_bytes_new_from_bytes (blob, off + sizeof(DfuPatchChunkHeader), chunk_sz); g_ptr_array_add (priv->chunks, chunk); off += sizeof(DfuPatchChunkHeader) + chunk_sz; } /* check we finished properly */ if (off != sz) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "blob chunk sizes did not sum to total"); return FALSE; } /* success */ return TRUE; } static GBytes * dfu_patch_calculate_checksum (GBytes *blob) { const guchar *data; gsize digest_len = 20; gsize sz = 0; guint8 *buf = g_malloc0 (digest_len); g_autoptr(GChecksum) csum = NULL; csum = g_checksum_new (G_CHECKSUM_SHA1); data = g_bytes_get_data (blob, &sz); g_checksum_update (csum, data, (gssize) sz); g_checksum_get_digest (csum, buf, &digest_len); return g_bytes_new_take (buf, digest_len); } typedef struct { guint32 diff_start; guint32 diff_end; GBytes *blob; /* no ref */ } DfuPatchCreateHelper; static void dfu_patch_flush (DfuPatch *self, DfuPatchCreateHelper *helper) { DfuPatchChunk *chunk; DfuPatchPrivate *priv = GET_PRIVATE (self); if (helper->diff_end == 0xffff) return; g_debug ("add chunk @0x%04x (len %" G_GUINT32_FORMAT ")", (guint) helper->diff_start, helper->diff_end - helper->diff_start + 1); chunk = g_new0 (DfuPatchChunk, 1); chunk->off = helper->diff_start; chunk->blob = g_bytes_new_from_bytes (helper->blob, chunk->off, helper->diff_end - helper->diff_start + 1); g_ptr_array_add (priv->chunks, chunk); helper->diff_end = 0xffff; } /** * dfu_patch_create: * @self: a #DfuPatch * @blob1: a #GBytes, typically the old firmware image * @blob2: a #GBytes, typically the new firmware image * @error: a #GError, or %NULL * * Creates a patch from two blobs of memory. * * The blobs should ideally be the same size. If @blob2 is has grown in size * the binary diff will still work but the algorithm will probably not perform * well unless the majority of data has just been appended. * * As an additional constrainst, @blob2 cannot be smaller than @blob1, i.e. * the firmware cannot be truncated by this format. * * Return value: %TRUE on success **/ gboolean dfu_patch_create (DfuPatch *self, GBytes *blob1, GBytes *blob2, GError **error) { DfuPatchPrivate *priv = GET_PRIVATE (self); DfuPatchCreateHelper helper; const guint8 *data1; const guint8 *data2; gsize sz1 = 0; gsize sz2 = 0; guint32 same_sz = 0; g_return_val_if_fail (DFU_IS_PATCH (self), FALSE); g_return_val_if_fail (blob1 != NULL, FALSE); g_return_val_if_fail (blob2 != NULL, FALSE); /* are the blobs the same */ if (g_bytes_equal (blob1, blob2)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "old and new binaries are the same"); return FALSE; } /* cannot reuse object */ if (priv->chunks->len > 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "patch has already been loaded"); return FALSE; } /* get the hash of the old firmware file */ priv->checksum_old = dfu_patch_calculate_checksum (blob1); priv->checksum_new = dfu_patch_calculate_checksum (blob2); /* get the raw data, and ensure they are the same size */ data1 = g_bytes_get_data (blob1, &sz1); data2 = g_bytes_get_data (blob2, &sz2); if (sz1 > sz2) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "firmware binary cannot go down, got " "%" G_GSIZE_FORMAT " and %" G_GSIZE_FORMAT, sz1, sz2); return FALSE; } if (sz1 == sz2) { g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz1); } else { g_debug ("binary growing from: %" G_GSIZE_FORMAT " to %" G_GSIZE_FORMAT, sz1, sz2); } /* start the dumb comparison algorithm */ helper.diff_start = 0; helper.diff_end = 0xffff; helper.blob = blob2; for (gsize i = 0; i < sz1 || i < sz2; i++) { if (i < sz1 && i < sz2 && data1[i] == data2[i]) { /* if we got enough the same, dump what is pending */ if (++same_sz > sizeof(DfuPatchChunkHeader) * 2) dfu_patch_flush (self, &helper); continue; } if (helper.diff_end == 0xffff) helper.diff_start = (guint32) i; helper.diff_end = (guint32) i; same_sz = 0; } dfu_patch_flush (self, &helper); return TRUE; } static gchar * _g_bytes_to_string (GBytes *blob) { gsize sz = 0; const guint8 *data = g_bytes_get_data (blob, &sz); GString *str = g_string_new (NULL); for (gsize i = 0; i < sz; i++) g_string_append_printf (str, "%02x", (guint) data[i]); return g_string_free (str, FALSE); } /** * dfu_patch_get_checksum_old: * @self: a #DfuPatch * * Get the checksum for the old firmware image. * * Return value: A #GBytes, or %NULL if nothing has been loaded. **/ GBytes * dfu_patch_get_checksum_old (DfuPatch *self) { DfuPatchPrivate *priv = GET_PRIVATE (self); return priv->checksum_old; } /** * dfu_patch_get_checksum_new: * @self: a #DfuPatch * * Get the checksum for the new firmware image. * * Return value: A #GBytes, or %NULL if nothing has been loaded. **/ GBytes * dfu_patch_get_checksum_new (DfuPatch *self) { DfuPatchPrivate *priv = GET_PRIVATE (self); return priv->checksum_new; } /** * dfu_patch_apply: * @self: a #DfuPatch * @blob: a #GBytes, typically the old firmware image * @flags: a #DfuPatchApplyFlags, e.g. %DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM * @error: a #GError, or %NULL * * Apply the currently loaded patch to a new firmware image. * * Return value: A #GBytes, typically saved as the new firmware file **/ GBytes * dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError **error) { DfuPatchPrivate *priv = GET_PRIVATE (self); const guint8 *data_old; gsize sz; gsize sz_max = 0; g_autofree guint8 *data_new = NULL; g_autoptr(GBytes) blob_checksum_new = NULL; g_autoptr(GBytes) blob_checksum = NULL; g_autoptr(GBytes) blob_new = NULL; /* not loaded yet */ if (priv->chunks->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no patches loaded"); return NULL; } /* get the hash of the old firmware file */ blob_checksum = dfu_patch_calculate_checksum (blob); if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 && !g_bytes_equal (blob_checksum, priv->checksum_old)) { g_autofree gchar *actual = _g_bytes_to_string (blob_checksum); g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_old); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "checksum for source did not match, expected %s, got %s", expect, actual); return NULL; } /* get the size of the new image size */ for (guint i = 0; i < priv->chunks->len; i++) { DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i); gsize chunk_sz = g_bytes_get_size (chunk->blob); if (chunk->off + chunk_sz > sz_max) sz_max = chunk->off + chunk_sz; } /* first, copy the data buffer */ data_old = g_bytes_get_data (blob, &sz); if (sz_max < sz) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "binary patch cannot truncate binary"); return NULL; } if (sz == sz_max) { g_debug ("binary staying same size: %" G_GSIZE_FORMAT, sz); } else { g_debug ("binary growing from: %" G_GSIZE_FORMAT " to %" G_GSIZE_FORMAT, sz, sz_max); } data_new = g_malloc0 (sz_max); memcpy (data_new, data_old, sz_max); for (guint i = 0; i < priv->chunks->len; i++) { DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i); const guint8 *chunk_data; gsize chunk_sz; /* bigger than the total size */ chunk_data = g_bytes_get_data (chunk->blob, &chunk_sz); if (chunk->off + chunk_sz > sz_max) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot apply chunk as larger than max size"); return NULL; } /* apply one chunk */ g_debug ("applying chunk %u/%u @0x%04x (length %" G_GSIZE_FORMAT ")", i + 1, priv->chunks->len, chunk->off, chunk_sz); memcpy (data_new + chunk->off, chunk_data, chunk_sz); } /* check we got the desired hash */ blob_new = g_bytes_new (data_new, sz_max); blob_checksum_new = dfu_patch_calculate_checksum (blob_new); if ((flags & DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM) == 0 && !g_bytes_equal (blob_checksum_new, priv->checksum_new)) { g_autofree gchar *actual = _g_bytes_to_string (blob_checksum_new); g_autofree gchar *expect = _g_bytes_to_string (priv->checksum_new); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "checksum for result did not match, expected %s, got %s", expect, actual); return NULL; } /* success */ return g_steal_pointer (&blob_new); } /** * dfu_patch_to_string: * @self: a #DfuPatch * * Returns a string representaiton of the object. * * Return value: NULL terminated string, or %NULL for invalid **/ gchar * dfu_patch_to_string (DfuPatch *self) { DfuPatchPrivate *priv = GET_PRIVATE (self); GString *str = g_string_new (NULL); g_autofree gchar *checksum_old = NULL; g_autofree gchar *checksum_new = NULL; g_return_val_if_fail (DFU_IS_PATCH (self), NULL); /* add checksums */ checksum_old = _g_bytes_to_string (priv->checksum_old); g_string_append_printf (str, "checksum-old: %s\n", checksum_old); checksum_new = _g_bytes_to_string (priv->checksum_new); g_string_append_printf (str, "checksum-new: %s\n", checksum_new); /* add chunks */ for (guint i = 0; i < priv->chunks->len; i++) { DfuPatchChunk *chunk = g_ptr_array_index (priv->chunks, i); g_string_append_printf (str, "chunk #%02u 0x%04x, length %" G_GSIZE_FORMAT "\n", i, chunk->off, g_bytes_get_size (chunk->blob)); } g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } /** * dfu_patch_new: * * Creates a new DFU patch object. * * Return value: a new #DfuPatch **/ DfuPatch * dfu_patch_new (void) { DfuPatch *self; self = g_object_new (DFU_TYPE_PATCH, NULL); return self; } fwupd-1.0.6/plugins/dfu/dfu-patch.h000066400000000000000000000042651325145456600171500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_PATCH_H #define __DFU_PATCH_H #include #include G_BEGIN_DECLS #define DFU_TYPE_PATCH (dfu_patch_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuPatch, dfu_patch, DFU, PATCH, GObject) struct _DfuPatchClass { GObjectClass parent_class; }; /** * DfuPatchApplyFlags: * @DFU_PATCH_APPLY_FLAG_NONE: No flags set * @DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM: Do not check the checksum * * The optional flags used for applying a patch. **/ typedef enum { DFU_PATCH_APPLY_FLAG_NONE = 0, DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM = (1 << 0), /*< private >*/ DFU_PATCH_APPLY_FLAG_LAST } DfuPatchApplyFlags; DfuPatch *dfu_patch_new (void); gchar *dfu_patch_to_string (DfuPatch *self); GBytes *dfu_patch_export (DfuPatch *self, GError **error); gboolean dfu_patch_import (DfuPatch *self, GBytes *blob, GError **error); gboolean dfu_patch_create (DfuPatch *self, GBytes *blob1, GBytes *blob2, GError **error); GBytes *dfu_patch_apply (DfuPatch *self, GBytes *blob, DfuPatchApplyFlags flags, GError **error); GBytes *dfu_patch_get_checksum_old (DfuPatch *self); GBytes *dfu_patch_get_checksum_new (DfuPatch *self); G_END_DECLS #endif /* __DFU_PATCH_H */ fwupd-1.0.6/plugins/dfu/dfu-sector-private.h000066400000000000000000000023661325145456600210200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_SECTOR_PRIVATE_H #define __DFU_SECTOR_PRIVATE_H #include "dfu-sector.h" G_BEGIN_DECLS DfuSector *dfu_sector_new (guint32 address, guint32 size, guint32 size_left, guint16 zone, guint16 number, DfuSectorCap cap); G_END_DECLS #endif /* __DFU_SECTOR_PRIVATE_H */ fwupd-1.0.6/plugins/dfu/dfu-sector.c000066400000000000000000000141451325145456600173410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-sector * @short_description: Object representing a sector on a chip * * This object represents an sector of memory at a specific address on the * device itself. * * This allows relocatable data segments to be stored in different * locations on the device itself. * * You can think of these objects as flash segments on devices, where a * complete block can be erased and then written to. * * See also: #DfuElement */ #include "config.h" #include #include #include "dfu-common.h" #include "dfu-sector-private.h" typedef struct { guint32 address; guint32 size; guint32 size_left; guint16 zone; guint16 number; DfuSectorCap cap; } DfuSectorPrivate; G_DEFINE_TYPE_WITH_PRIVATE (DfuSector, dfu_sector, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_sector_get_instance_private (o)) static void dfu_sector_class_init (DfuSectorClass *klass) { } static void dfu_sector_init (DfuSector *sector) { } /** * dfu_sector_new: (skip) * address: the address for the sector * size: the size of this sector * size_left: the size of the rest of the sector * zone: the zone of memory the setor belongs * number: the sector number in the zone * cap: the #DfuSectorCap * * Creates a new DFU sector object. * * Return value: a new #DfuSector **/ DfuSector * dfu_sector_new (guint32 address, guint32 size, guint32 size_left, guint16 zone, guint16 number, DfuSectorCap cap) { DfuSectorPrivate *priv; DfuSector *sector; sector = g_object_new (DFU_TYPE_SECTOR, NULL); priv = GET_PRIVATE (sector); priv->address = address; priv->size = size; priv->size_left = size_left; priv->zone = zone; priv->number = number; priv->cap = cap; return sector; } /** * dfu_sector_get_address: * @sector: a #DfuSector * * Gets the alternate setting. * * Return value: integer, or 0x00 for unset **/ guint32 dfu_sector_get_address (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return priv->address; } /** * dfu_sector_get_size: * @sector: a #DfuSector * * Gets the sector size. * * Return value: integer, or 0x00 for unset **/ guint32 dfu_sector_get_size (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return priv->size; } /** * dfu_sector_get_size_left: * @sector: a #DfuSector * * Gets the size of the rest of the sector. * * Return value: integer, or 0x00 for unset **/ guint32 dfu_sector_get_size_left (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return priv->size_left; } /** * dfu_sector_get_zone: * @sector: a #DfuSector * * Gets the sector zone number. * * Return value: integer, or 0x00 for unset **/ guint16 dfu_sector_get_zone (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return priv->zone; } /** * dfu_sector_get_number: * @sector: a #DfuSector * * Gets the sector index number. * * Return value: integer, or 0x00 for unset **/ guint16 dfu_sector_get_number (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return priv->number; } /** * dfu_sector_get_id: * @sector: a #DfuSector * * Gets the sector ID which is a combination of the zone and sector number. * You can use this number to check if the segment is the 'same' as the last * written or read sector. * * Return value: integer ID, or 0x00 for unset **/ guint32 dfu_sector_get_id (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), 0x00); return (((guint32) priv->zone) << 16) | priv->number; } /** * dfu_sector_has_cap: * @sector: a #DfuSector * @cap: a #DfuSectorCap, e.g. %DFU_SECTOR_CAP_ERASEABLE * * Finds out if the sector has the required capability. * * Return value: %TRUE if the sector has the capabilily **/ gboolean dfu_sector_has_cap (DfuSector *sector, DfuSectorCap cap) { DfuSectorPrivate *priv = GET_PRIVATE (sector); g_return_val_if_fail (DFU_IS_SECTOR (sector), FALSE); return (priv->cap & cap) > 0; } static gchar * dfu_sector_cap_to_string (DfuSectorCap cap) { GString *str = g_string_new (NULL); if (cap & DFU_SECTOR_CAP_READABLE) g_string_append (str, "R"); if (cap & DFU_SECTOR_CAP_ERASEABLE) g_string_append (str, "E"); if (cap & DFU_SECTOR_CAP_WRITEABLE) g_string_append (str, "W"); return g_string_free (str, FALSE); } /** * dfu_sector_to_string: * @sector: a #DfuSector * * Returns a string representaiton of the object. * * Return value: NULL terminated string, or %NULL for invalid **/ gchar * dfu_sector_to_string (DfuSector *sector) { DfuSectorPrivate *priv = GET_PRIVATE (sector); GString *str; g_autofree gchar *caps_str = NULL; g_return_val_if_fail (DFU_IS_SECTOR (sector), NULL); str = g_string_new (""); caps_str = dfu_sector_cap_to_string (priv->cap); g_string_append_printf (str, "Zone:%i, Sec#:%i, Addr:0x%08x, " "Size:0x%04x, Caps:0x%01x [%s]", priv->zone, priv->number, priv->address, priv->size, priv->cap, caps_str); return g_string_free (str, FALSE); } fwupd-1.0.6/plugins/dfu/dfu-sector.h000066400000000000000000000042511325145456600173430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_SECTOR_H #define __DFU_SECTOR_H #include #include G_BEGIN_DECLS #define DFU_TYPE_SECTOR (dfu_sector_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuSector, dfu_sector, DFU, SECTOR, GObject) struct _DfuSectorClass { GObjectClass parent_class; }; /** * DfuSectorCap: * @DFU_SECTOR_CAP_NONE: No operations possible * @DFU_SECTOR_CAP_READABLE: Sector can be read * @DFU_SECTOR_CAP_WRITEABLE: Sector can be written * @DFU_SECTOR_CAP_ERASEABLE: Sector can be erased * * The flags indicating what the sector can do. **/ typedef enum { DFU_SECTOR_CAP_NONE = 0, DFU_SECTOR_CAP_READABLE = 1 << 0, DFU_SECTOR_CAP_WRITEABLE = 1 << 1, DFU_SECTOR_CAP_ERASEABLE = 1 << 2, /*< private >*/ DFU_SECTOR_CAP_LAST } DfuSectorCap; guint32 dfu_sector_get_id (DfuSector *sector); guint32 dfu_sector_get_address (DfuSector *sector); guint32 dfu_sector_get_size (DfuSector *sector); guint32 dfu_sector_get_size_left (DfuSector *sector); guint16 dfu_sector_get_zone (DfuSector *sector); guint16 dfu_sector_get_number (DfuSector *sector); gboolean dfu_sector_has_cap (DfuSector *sector, DfuSectorCap cap); gchar *dfu_sector_to_string (DfuSector *sector); G_END_DECLS #endif /* __DFU_SECTOR_H */ fwupd-1.0.6/plugins/dfu/dfu-self-test.c000066400000000000000000000721411325145456600177500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "dfu-chunked.h" #include "dfu-cipher-xtea.h" #include "dfu-common.h" #include "dfu-device-private.h" #include "dfu-firmware.h" #include "dfu-patch.h" #include "dfu-sector-private.h" #include "dfu-target-private.h" #include "fu-test.h" #include "fwupd-error.h" static gchar * dfu_test_get_filename (const gchar *filename) { gchar *tmp; char full_tmp[PATH_MAX]; g_autofree gchar *path = NULL; path = g_build_filename (TESTDATADIR, filename, NULL); tmp = realpath (path, full_tmp); if (tmp == NULL) return NULL; return g_strdup (full_tmp); } static gchar * _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2) { const guint8 *data1; const guint8 *data2; gsize length1; gsize length2; data1 = g_bytes_get_data (bytes1, &length1); data2 = g_bytes_get_data (bytes2, &length2); /* not the same length */ if (length1 != length2) { return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, " "expected %" G_GSIZE_FORMAT, length1, length2); } /* return 00 01 02 03 */ for (guint i = 0; i < length1; i++) { if (data1[i] != data2[i]) { return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x", data1[i], data2[i], i); } } return NULL; } static void dfu_cipher_xtea_func (void) { gboolean ret; guint8 buf[] = { 'H', 'i', 'y', 'a', 'D', 'a', 'v', 'e' }; g_autoptr(GError) error = NULL; ret = dfu_cipher_encrypt_xtea ("test", buf, sizeof(buf), &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (buf[0], ==, 128); g_assert_cmpint (buf[1], ==, 220); g_assert_cmpint (buf[2], ==, 23); g_assert_cmpint (buf[3], ==, 55); g_assert_cmpint (buf[4], ==, 201); g_assert_cmpint (buf[5], ==, 207); g_assert_cmpint (buf[6], ==, 182); g_assert_cmpint (buf[7], ==, 177); ret = dfu_cipher_decrypt_xtea ("test", buf, sizeof(buf), &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (buf[0], ==, 'H'); g_assert_cmpint (buf[1], ==, 'i'); g_assert_cmpint (buf[2], ==, 'y'); g_assert_cmpint (buf[3], ==, 'a'); g_assert_cmpint (buf[4], ==, 'D'); g_assert_cmpint (buf[5], ==, 'a'); g_assert_cmpint (buf[6], ==, 'v'); g_assert_cmpint (buf[7], ==, 'e'); } static void dfu_firmware_xdfu_func (void) { gboolean ret; g_autofree gchar *fn = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file = NULL; fn = dfu_test_get_filename ("example.xdfu"); g_assert (fn != NULL); firmware = dfu_firmware_new (); file = g_file_new_for_path (fn); ret = dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_XTEA); } static void dfu_enums_func (void) { for (guint i = 0; i < DFU_STATE_LAST; i++) g_assert_cmpstr (dfu_state_to_string (i), !=, NULL); for (guint i = 0; i < DFU_STATUS_LAST; i++) g_assert_cmpstr (dfu_status_to_string (i), !=, NULL); } static GBytes * dfu_self_test_get_bytes_for_file (GFile *file, GError **error) { gchar *contents = NULL; gsize length = 0; if (!g_file_load_contents (file, NULL, &contents, &length, NULL, error)) return NULL; return g_bytes_new_take (contents, length); } static void dfu_firmware_raw_func (void) { DfuElement *element; DfuImage *image_tmp; GBytes *no_suffix_contents; gchar buf[256]; gboolean ret; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(GBytes) roundtrip = NULL; g_autoptr(GError) error = NULL; /* set up some dummy data */ for (guint i = 0; i < 256; i++) buf[i] = (gchar) i; fw = g_bytes_new_static (buf, 256); /* load a non DFU firmware */ firmware = dfu_firmware_new (); ret = dfu_firmware_parse_data (firmware, fw, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0xffff); g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xffff); g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff); g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_RAW); g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE); image_tmp = dfu_firmware_get_image (firmware, 0xfe); g_assert (image_tmp == NULL); image_tmp = dfu_firmware_get_image (firmware, 0); g_assert (image_tmp != NULL); g_assert_cmpint (dfu_image_get_size (image_tmp), ==, 256); element = dfu_image_get_element (image_tmp, 0); g_assert (element != NULL); no_suffix_contents = dfu_element_get_contents (element); g_assert (no_suffix_contents != NULL); g_assert_cmpint (g_bytes_compare (no_suffix_contents, fw), ==, 0); /* can we roundtrip without adding data */ roundtrip = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (roundtrip != NULL); g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, fw), ==, NULL); } static void dfu_firmware_dfu_func (void) { gchar buf[256]; gboolean ret; g_autofree gchar *filename = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(DfuImage) image = NULL; g_autoptr(DfuElement) element = NULL; g_autoptr(GBytes) data = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(GBytes) roundtrip_orig = NULL; g_autoptr(GBytes) roundtrip = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file = NULL; /* set up some dummy data */ for (guint i = 0; i < 256; i++) buf[i] = (gchar) i; fw = g_bytes_new_static (buf, 256); /* write DFU format */ firmware = dfu_firmware_new (); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU); dfu_firmware_set_vid (firmware, 0x1234); dfu_firmware_set_pid (firmware, 0x5678); dfu_firmware_set_release (firmware, 0xfedc); image = dfu_image_new (); element = dfu_element_new (); dfu_element_set_contents (element, fw); dfu_image_add_element (image, element); dfu_firmware_add_image (firmware, image); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256); data = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (data != NULL); /* can we load it again? */ g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0); ret = dfu_firmware_parse_data (firmware, data, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1234); g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x5678); g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xfedc); g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 256); /* load a real firmware */ filename = dfu_test_get_filename ("kiibohd.dfu.bin"); g_assert (filename != NULL); file = g_file_new_for_path (filename); g_ptr_array_set_size (dfu_firmware_get_images (firmware), 0); ret = dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x1c11); g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0xb007); g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0xffff); g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFU); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x8eB4); g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE); /* can we roundtrip without loosing data */ roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error); g_assert_no_error (error); g_assert (roundtrip_orig != NULL); roundtrip = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (roundtrip != NULL); g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL); } static void dfu_firmware_dfuse_func (void) { gboolean ret; g_autofree gchar *filename = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GBytes) roundtrip_orig = NULL; g_autoptr(GBytes) roundtrip = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file = NULL; /* load a DeFUse firmware */ g_setenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME", "", FALSE); filename = dfu_test_get_filename ("dev_VRBRAIN.dfu"); g_assert (filename != NULL); file = g_file_new_for_path (filename); firmware = dfu_firmware_new (); ret = dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_vid (firmware), ==, 0x0483); g_assert_cmpint (dfu_firmware_get_pid (firmware), ==, 0x0000); g_assert_cmpint (dfu_firmware_get_release (firmware), ==, 0x0000); g_assert_cmpint (dfu_firmware_get_format (firmware), ==, DFU_FIRMWARE_FORMAT_DFUSE); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 0x168d5); g_assert_cmpint (dfu_firmware_get_cipher_kind (firmware), ==, DFU_CIPHER_KIND_NONE); /* can we roundtrip without loosing data */ roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error); g_assert_no_error (error); g_assert (roundtrip_orig != NULL); roundtrip = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (roundtrip != NULL); // g_file_set_contents ("/tmp/1.bin", // g_bytes_get_data (roundtrip, NULL), // g_bytes_get_size (roundtrip), NULL); g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL); /* use usual image name copying */ g_unsetenv ("DFU_SELF_TEST_IMAGE_MEMCPY_NAME"); } static void dfu_firmware_metadata_func (void) { gboolean ret; g_autofree gchar *filename = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GBytes) roundtrip_orig = NULL; g_autoptr(GBytes) roundtrip = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file = NULL; /* load a DFU firmware with a metadata table */ filename = dfu_test_get_filename ("metadata.dfu"); g_assert (filename != NULL); file = g_file_new_for_path (filename); firmware = dfu_firmware_new (); ret = dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 6); g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "key"), ==, "value"); g_assert_cmpstr (dfu_firmware_get_metadata (firmware, "???"), ==, NULL); /* can we roundtrip without loosing data */ roundtrip_orig = dfu_self_test_get_bytes_for_file (file, &error); g_assert_no_error (error); g_assert (roundtrip_orig != NULL); roundtrip = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (roundtrip != NULL); g_assert_cmpstr (_g_bytes_compare_verbose (roundtrip, roundtrip_orig), ==, NULL); } static void dfu_firmware_intel_hex_offset_func (void) { DfuElement *element_verify; DfuImage *image_verify; const guint8 *data; gboolean ret; gsize len; g_autofree gchar *str = NULL; g_autoptr(DfuElement) element = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(DfuFirmware) firmware_verify = NULL; g_autoptr(DfuImage) image = NULL; g_autoptr(GBytes) data_bin = NULL; g_autoptr(GBytes) data_dummy = NULL; g_autoptr(GError) error = NULL; /* add a 4 byte image in high memory */ element = dfu_element_new (); data_dummy = g_bytes_new_static ("foo", 4); dfu_element_set_address (element, 0x80000000); dfu_element_set_contents (element, data_dummy); image = dfu_image_new (); dfu_image_add_element (image, element); firmware = dfu_firmware_new (); dfu_firmware_add_image (firmware, image); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX); data_bin = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (data_bin != NULL); data = g_bytes_get_data (data_bin, &len); str = g_strndup ((const gchar *) data, len); g_assert_cmpstr (str, ==, ":0200000480007A\n" ":04000000666F6F00B8\n" ":00000001FF\n"); /* check we can load it too */ firmware_verify = dfu_firmware_new (); ret = dfu_firmware_parse_data (firmware_verify, data_bin, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); image_verify = dfu_firmware_get_image_default (firmware_verify); g_assert (image_verify != NULL); element_verify = dfu_image_get_element_default (image); g_assert (element_verify != NULL); g_assert_cmpint (dfu_element_get_address (element_verify), ==, 0x80000000); g_assert_cmpint (g_bytes_get_size (dfu_element_get_contents (element_verify)), ==, 0x4); } static void dfu_firmware_intel_hex_func (void) { const guint8 *data; gboolean ret; gsize len; g_autofree gchar *filename_hex = NULL; g_autofree gchar *filename_ref = NULL; g_autofree gchar *str = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GBytes) data_bin2 = NULL; g_autoptr(GBytes) data_bin = NULL; g_autoptr(GBytes) data_hex = NULL; g_autoptr(GBytes) data_ref = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file_bin = NULL; g_autoptr(GFile) file_hex = NULL; /* load a Intel hex32 file */ filename_hex = dfu_test_get_filename ("firmware.hex"); g_assert (filename_hex != NULL); file_hex = g_file_new_for_path (filename_hex); firmware = dfu_firmware_new (); ret = dfu_firmware_parse_file (firmware, file_hex, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 136); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW); data_bin = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (data_bin != NULL); /* did we match the reference file? */ filename_ref = dfu_test_get_filename ("firmware.bin"); g_assert (filename_ref != NULL); file_bin = g_file_new_for_path (filename_ref); data_ref = dfu_self_test_get_bytes_for_file (file_bin, &error); g_assert_no_error (error); g_assert (data_ref != NULL); g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_ref), ==, NULL); /* export a ihex file (which will be slightly different due to * non-continous regions being expanded */ dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_INTEL_HEX); data_hex = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (data_hex != NULL); data = g_bytes_get_data (data_hex, &len); str = g_strndup ((const gchar *) data, len); g_assert_cmpstr (str, ==, ":104000003DEF20F000000000FACF01F0FBCF02F0FE\n" ":10401000E9CF03F0EACF04F0E1CF05F0E2CF06F0FC\n" ":10402000D9CF07F0DACF08F0F3CF09F0F4CF0AF0D8\n" ":10403000F6CF0BF0F7CF0CF0F8CF0DF0F5CF0EF078\n" ":104040000EC0F5FF0DC0F8FF0CC0F7FF0BC0F6FF68\n" ":104050000AC0F4FF09C0F3FF08C0DAFF07C0D9FFA8\n" ":1040600006C0E2FF05C0E1FF04C0EAFF03C0E9FFAC\n" ":1040700002C0FBFF01C0FAFF11003FEF20F000017A\n" ":0840800042EF20F03DEF20F0BB\n" ":00000001FF\n"); /* do we match the binary file again */ dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_RAW); data_bin2 = dfu_firmware_write_data (firmware, &error); g_assert_no_error (error); g_assert (data_bin2 != NULL); g_assert_cmpstr (_g_bytes_compare_verbose (data_bin, data_bin2), ==, NULL); } static void dfu_firmware_intel_hex_signed_func (void) { DfuElement *element; DfuImage *image; GBytes *data_sig; const guint8 *data; gboolean ret; gsize len; g_autofree gchar *filename_hex = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) file_hex = NULL; /* load a Intel hex32 file */ filename_hex = dfu_test_get_filename ("firmware.shex"); g_assert (filename_hex != NULL); file_hex = g_file_new_for_path (filename_hex); firmware = dfu_firmware_new (); ret = dfu_firmware_parse_file (firmware, file_hex, DFU_FIRMWARE_PARSE_FLAG_NONE, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_firmware_get_size (firmware), ==, 144); /* get the signed image element */ image = dfu_firmware_get_image_by_name (firmware, "signature"); g_assert (image != NULL); element = dfu_image_get_element_default (image); data_sig = dfu_element_get_contents (element); g_assert (data_sig != NULL); data = g_bytes_get_data (data_sig, &len); g_assert_cmpint (len, ==, 8); g_assert (data != NULL); } static gchar * dfu_target_sectors_to_string (DfuTarget *target) { GPtrArray *sectors; GString *str; str = g_string_new (""); sectors = dfu_target_get_sectors (target); for (guint i = 0; i < sectors->len; i++) { DfuSector *sector = g_ptr_array_index (sectors, i); g_autofree gchar *tmp = dfu_sector_to_string (sector); g_string_append_printf (str, "%s\n", tmp); } if (str->len > 0) g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } static void dfu_target_dfuse_func (void) { gboolean ret; gchar *tmp; g_autoptr(DfuTarget) target = NULL; g_autoptr(GError) error = NULL; /* NULL */ target = g_object_new (DFU_TYPE_TARGET, NULL); ret = dfu_target_parse_sectors (target, NULL, &error); g_assert_no_error (error); g_assert (ret); tmp = dfu_target_sectors_to_string (target); g_assert_cmpstr (tmp, ==, ""); g_free (tmp); /* no addresses */ ret = dfu_target_parse_sectors (target, "@Flash3", &error); g_assert_no_error (error); g_assert (ret); tmp = dfu_target_sectors_to_string (target); g_assert_cmpstr (tmp, ==, ""); g_free (tmp); /* one sector, no space */ ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/2*001Ka", &error); g_assert_no_error (error); g_assert (ret); tmp = dfu_target_sectors_to_string (target); ret = fu_test_compare_lines (tmp, "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n" "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]", &error); g_assert_no_error (error); g_assert (ret); g_free (tmp); /* multiple sectors */ ret = dfu_target_parse_sectors (target, "@Flash1 /0x08000000/2*001Ka,4*001Kg", &error); g_assert_no_error (error); g_assert (ret); tmp = dfu_target_sectors_to_string (target); ret = fu_test_compare_lines (tmp, "Zone:0, Sec#:0, Addr:0x08000000, Size:0x0400, Caps:0x1 [R]\n" "Zone:0, Sec#:0, Addr:0x08000400, Size:0x0400, Caps:0x1 [R]\n" "Zone:0, Sec#:1, Addr:0x08000800, Size:0x0400, Caps:0x7 [REW]\n" "Zone:0, Sec#:1, Addr:0x08000c00, Size:0x0400, Caps:0x7 [REW]\n" "Zone:0, Sec#:1, Addr:0x08001000, Size:0x0400, Caps:0x7 [REW]\n" "Zone:0, Sec#:1, Addr:0x08001400, Size:0x0400, Caps:0x7 [REW]", &error); g_assert_no_error (error); g_assert (ret); g_free (tmp); /* non-contiguous */ ret = dfu_target_parse_sectors (target, "@Flash2 /0xF000/4*100Ba/0xE000/3*8Kg/0x80000/2*24Kg", &error); g_assert_no_error (error); g_assert (ret); tmp = dfu_target_sectors_to_string (target); ret = fu_test_compare_lines (tmp, "Zone:0, Sec#:0, Addr:0x0000f000, Size:0x0064, Caps:0x1 [R]\n" "Zone:0, Sec#:0, Addr:0x0000f064, Size:0x0064, Caps:0x1 [R]\n" "Zone:0, Sec#:0, Addr:0x0000f0c8, Size:0x0064, Caps:0x1 [R]\n" "Zone:0, Sec#:0, Addr:0x0000f12c, Size:0x0064, Caps:0x1 [R]\n" "Zone:1, Sec#:0, Addr:0x0000e000, Size:0x2000, Caps:0x7 [REW]\n" "Zone:1, Sec#:0, Addr:0x00010000, Size:0x2000, Caps:0x7 [REW]\n" "Zone:1, Sec#:0, Addr:0x00012000, Size:0x2000, Caps:0x7 [REW]\n" "Zone:2, Sec#:0, Addr:0x00080000, Size:0x6000, Caps:0x7 [REW]\n" "Zone:2, Sec#:0, Addr:0x00086000, Size:0x6000, Caps:0x7 [REW]", &error); g_assert_no_error (error); g_assert (ret); g_free (tmp); /* invalid */ ret = dfu_target_parse_sectors (target, "Flash", NULL); g_assert (ret); ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000", NULL); g_assert (!ret); ret = dfu_target_parse_sectors (target, "@Internal Flash /0x08000000/12*001a", NULL); g_assert (!ret); /* indicate a cipher being used */ g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_NONE); ret = dfu_target_parse_sectors (target, "@Flash|XTEA", &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpint (dfu_target_get_cipher_kind (target), ==, DFU_CIPHER_KIND_XTEA); } static gboolean dfu_patch_create_from_strings (DfuPatch *patch, const gchar *dold, const gchar *dnew, GError **error) { guint32 sz1 = strlen (dold); guint32 sz2 = strlen (dnew); g_autoptr(GBytes) blob1 = g_bytes_new (dold, sz1); g_autoptr(GBytes) blob2 = g_bytes_new (dnew, sz2); g_debug ("compare:\n%s\n%s", dold, dnew); return dfu_patch_create (patch, blob1, blob2, error); } static void dfu_patch_merges_func (void) { const guint8 *data; gboolean ret; gsize sz; g_autoptr(DfuPatch) patch = dfu_patch_new (); g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; /* check merges happen */ ret = dfu_patch_create_from_strings (patch, "XXX", "YXY", &error); g_assert_no_error (error); g_assert (ret); blob = dfu_patch_export (patch, &error); g_assert_no_error (error); g_assert (ret); data = g_bytes_get_data (blob, &sz); g_assert_cmpint (data[0x00], ==, 'D'); g_assert_cmpint (data[0x01], ==, 'f'); g_assert_cmpint (data[0x02], ==, 'u'); g_assert_cmpint (data[0x03], ==, 'P'); g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */ g_assert_cmpint (data[0x05], ==, 0x00); g_assert_cmpint (data[0x06], ==, 0x00); g_assert_cmpint (data[0x07], ==, 0x00); g_assert_cmpint (data[0x08 + 0x28], ==, 0x00); /* chunk1, offset */ g_assert_cmpint (data[0x09 + 0x28], ==, 0x00); g_assert_cmpint (data[0x0a + 0x28], ==, 0x00); g_assert_cmpint (data[0x0b + 0x28], ==, 0x00); g_assert_cmpint (data[0x0c + 0x28], ==, 0x03); /* chunk1, size */ g_assert_cmpint (data[0x0d + 0x28], ==, 0x00); g_assert_cmpint (data[0x0e + 0x28], ==, 0x00); g_assert_cmpint (data[0x0f + 0x28], ==, 0x00); g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */ g_assert_cmpint (data[0x11 + 0x28], ==, 0x00); g_assert_cmpint (data[0x12 + 0x28], ==, 0x00); g_assert_cmpint (data[0x13 + 0x28], ==, 0x00); g_assert_cmpint (data[0x14 + 0x28], ==, 'Y'); g_assert_cmpint (data[0x15 + 0x28], ==, 'X'); g_assert_cmpint (data[0x16 + 0x28], ==, 'Y'); g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 3 /* data */); } static void dfu_patch_apply_func (void) { gboolean ret; g_autoptr(DfuPatch) patch = dfu_patch_new (); g_autoptr(GBytes) blob_new2 = NULL; g_autoptr(GBytes) blob_new3 = NULL; g_autoptr(GBytes) blob_new4 = NULL; g_autoptr(GBytes) blob_new = NULL; g_autoptr(GBytes) blob_old = NULL; g_autoptr(GBytes) blob_wrong = NULL; g_autoptr(GError) error = NULL; /* create a patch */ blob_old = g_bytes_new_static ("helloworldhelloworldhelloworldhelloworld", 40); blob_new = g_bytes_new_static ("XelloXorldhelloworldhelloworldhelloworlXXX", 42); ret = dfu_patch_create (patch, blob_old, blob_new, &error); g_assert_no_error (error); g_assert (ret); /* apply the patch */ blob_new2 = dfu_patch_apply (patch, blob_old, DFU_PATCH_APPLY_FLAG_NONE, &error); g_assert_no_error (error); g_assert (blob_new2 != NULL); g_assert_cmpint (g_bytes_compare (blob_new, blob_new2), ==, 0); /* check we force the patch to an unrelated blob */ blob_wrong = g_bytes_new_static ("wrongwrongwrongwrongwrongwrongwrongwrong", 40); blob_new3 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM, &error); g_assert_no_error (error); g_assert (blob_new3 != NULL); /* check we can't apply the patch to an unrelated blob */ blob_new4 = dfu_patch_apply (patch, blob_wrong, DFU_PATCH_APPLY_FLAG_NONE, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (blob_new4 == NULL); } static void dfu_patch_func (void) { const guint8 *data; gboolean ret; gsize sz; g_autoptr(DfuPatch) patch = dfu_patch_new (); g_autoptr(DfuPatch) patch2 = dfu_patch_new (); g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; g_autofree gchar *serialized_str = NULL; /* create binary diff */ ret = dfu_patch_create_from_strings (patch, "XXX", "XYY", &error); g_assert_no_error (error); g_assert (ret); /* check we can serialize this object to a blob */ blob = dfu_patch_export (patch, &error); g_assert_no_error (error); g_assert (ret); data = g_bytes_get_data (blob, &sz); g_assert_cmpint (data[0x00], ==, 'D'); g_assert_cmpint (data[0x01], ==, 'f'); g_assert_cmpint (data[0x02], ==, 'u'); g_assert_cmpint (data[0x03], ==, 'P'); g_assert_cmpint (data[0x04], ==, 0x00); /* reserved */ g_assert_cmpint (data[0x05], ==, 0x00); g_assert_cmpint (data[0x06], ==, 0x00); g_assert_cmpint (data[0x07], ==, 0x00); g_assert_cmpint (data[0x08 + 0x28], ==, 0x01); /* chunk1, offset */ g_assert_cmpint (data[0x09 + 0x28], ==, 0x00); g_assert_cmpint (data[0x0a + 0x28], ==, 0x00); g_assert_cmpint (data[0x0b + 0x28], ==, 0x00); g_assert_cmpint (data[0x0c + 0x28], ==, 0x02); /* chunk1, size */ g_assert_cmpint (data[0x0d + 0x28], ==, 0x00); g_assert_cmpint (data[0x0e + 0x28], ==, 0x00); g_assert_cmpint (data[0x0f + 0x28], ==, 0x00); g_assert_cmpint (data[0x10 + 0x28], ==, 0x00); /* reserved */ g_assert_cmpint (data[0x11 + 0x28], ==, 0x00); g_assert_cmpint (data[0x12 + 0x28], ==, 0x00); g_assert_cmpint (data[0x13 + 0x28], ==, 0x00); g_assert_cmpint (data[0x14 + 0x28], ==, 'Y'); g_assert_cmpint (data[0x15 + 0x28], ==, 'Y'); g_assert_cmpint (sz, ==, 48 /* hdr */ + 12 /* chunk */ + 2 /* data */); /* try to load it from the serialized blob */ ret = dfu_patch_import (patch2, blob, &error); g_assert_no_error (error); g_assert (ret); serialized_str = dfu_patch_to_string (patch2); g_debug ("serialized blob %s", serialized_str); } static void dfu_chunked_func (void) { g_autofree gchar *chunked1_str = NULL; g_autofree gchar *chunked2_str = NULL; g_autofree gchar *chunked3_str = NULL; g_autofree gchar *chunked4_str = NULL; g_autoptr(GPtrArray) chunked1 = NULL; g_autoptr(GPtrArray) chunked2 = NULL; g_autoptr(GPtrArray) chunked3 = NULL; g_autoptr(GPtrArray) chunked4 = NULL; chunked3 = dfu_chunked_new ((const guint8 *) "123456", 6, 0x0, 3, 3); chunked3_str = dfu_chunked_to_string (chunked3); g_print ("\n%s", chunked3_str); g_assert_cmpstr (chunked3_str, ==, "#00: page:00 addr:0000 len:03 123\n" "#01: page:01 addr:0000 len:03 456\n"); chunked4 = dfu_chunked_new ((const guint8 *) "123456", 6, 0x4, 4, 4); chunked4_str = dfu_chunked_to_string (chunked4); g_print ("\n%s", chunked4_str); g_assert_cmpstr (chunked4_str, ==, "#00: page:01 addr:0000 len:04 1234\n" "#01: page:02 addr:0000 len:02 56\n"); chunked1 = dfu_chunked_new ((const guint8 *) "0123456789abcdef", 16, 0x0, 10, 4); chunked1_str = dfu_chunked_to_string (chunked1); g_print ("\n%s", chunked1_str); g_assert_cmpstr (chunked1_str, ==, "#00: page:00 addr:0000 len:04 0123\n" "#01: page:00 addr:0004 len:04 4567\n" "#02: page:00 addr:0008 len:02 89\n" "#03: page:01 addr:0000 len:04 abcd\n" "#04: page:01 addr:0004 len:02 ef\n"); chunked2 = dfu_chunked_new ((const guint8 *) "XXXXXXYYYYYYZZZZZZ", 18, 0x0, 6, 4); chunked2_str = dfu_chunked_to_string (chunked2); g_print ("\n%s", chunked2_str); g_assert_cmpstr (chunked2_str, ==, "#00: page:00 addr:0000 len:04 XXXX\n" "#01: page:00 addr:0004 len:02 XX\n" "#02: page:01 addr:0000 len:04 YYYY\n" "#03: page:01 addr:0004 len:02 YY\n" "#04: page:02 addr:0000 len:04 ZZZZ\n" "#05: page:02 addr:0004 len:02 ZZ\n"); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); /* log everything */ g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); /* tests go here */ g_test_add_func ("/dfu/chunked", dfu_chunked_func); g_test_add_func ("/dfu/patch", dfu_patch_func); g_test_add_func ("/dfu/patch{merges}", dfu_patch_merges_func); g_test_add_func ("/dfu/patch{apply}", dfu_patch_apply_func); g_test_add_func ("/dfu/enums", dfu_enums_func); g_test_add_func ("/dfu/target(DfuSe}", dfu_target_dfuse_func); g_test_add_func ("/dfu/cipher{xtea}", dfu_cipher_xtea_func); g_test_add_func ("/dfu/firmware{raw}", dfu_firmware_raw_func); g_test_add_func ("/dfu/firmware{dfu}", dfu_firmware_dfu_func); g_test_add_func ("/dfu/firmware{dfuse}", dfu_firmware_dfuse_func); g_test_add_func ("/dfu/firmware{xdfu}", dfu_firmware_xdfu_func); g_test_add_func ("/dfu/firmware{metadata}", dfu_firmware_metadata_func); g_test_add_func ("/dfu/firmware{intel-hex-offset}", dfu_firmware_intel_hex_offset_func); g_test_add_func ("/dfu/firmware{intel-hex}", dfu_firmware_intel_hex_func); g_test_add_func ("/dfu/firmware{intel-hex-signed}", dfu_firmware_intel_hex_signed_func); return g_test_run (); } fwupd-1.0.6/plugins/dfu/dfu-target-avr.c000066400000000000000000000543341325145456600201220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "dfu-chunked.h" #include "dfu-common.h" #include "dfu-sector.h" #include "dfu-target-avr.h" #include "dfu-target-private.h" #include "dfu-device-private.h" #include "fwupd-error.h" typedef struct { guint32 device_id; } DfuTargetAvrPrivate; G_DEFINE_TYPE_WITH_PRIVATE (DfuTargetAvr, dfu_target_avr, DFU_TYPE_TARGET) #define GET_PRIVATE(o) (dfu_target_avr_get_instance_private (o)) /* ATMEL AVR version of DFU: * http://www.atmel.com/Images/doc7618.pdf */ #define DFU_AVR_CMD_PROG_START 0x01 #define DFU_AVR_CMD_DISPLAY_DATA 0x03 #define DFU_AVR_CMD_WRITE_COMMAND 0x04 #define DFU_AVR_CMD_READ_COMMAND 0x05 #define DFU_AVR_CMD_CHANGE_BASE_ADDR 0x06 /* Atmel AVR32 version of DFU: * http://www.atmel.com/images/doc32131.pdf */ #define DFU_AVR32_GROUP_SELECT 0x06 /** SELECT */ #define DFU_AVR32_CMD_SELECT_MEMORY 0x03 #define DFU_AVR32_MEMORY_UNIT 0x00 #define DFU_AVR32_MEMORY_PAGE 0x01 #define DFU_AVR32_MEMORY_UNIT_FLASH 0x00 #define DFU_AVR32_MEMORY_UNIT_EEPROM 0x01 #define DFU_AVR32_MEMORY_UNIT_SECURITY 0x02 #define DFU_AVR32_MEMORY_UNIT_CONFIGURATION 0x03 #define DFU_AVR32_MEMORY_UNIT_BOOTLOADER 0x04 #define DFU_AVR32_MEMORY_UNIT_SIGNATURE 0x05 #define DFU_AVR32_MEMORY_UNIT_USER 0x06 #define DFU_AVR32_GROUP_DOWNLOAD 0x01 /** DOWNLOAD */ #define DFU_AVR32_CMD_PROGRAM_START 0x00 #define DFU_AVR32_GROUP_UPLOAD 0x03 /** UPLOAD */ #define DFU_AVR32_CMD_READ_MEMORY 0x00 #define DFU_AVR32_CMD_BLANK_CHECK 0x01 #define DFU_AVR32_GROUP_EXEC 0x04 /** EXEC */ #define DFU_AVR32_CMD_ERASE 0x00 #define DFU_AVR32_ERASE_EVERYTHING 0xff #define DFU_AVR32_CMD_START_APPLI 0x03 #define DFU_AVR32_START_APPLI_RESET 0x00 #define DFU_AVR32_START_APPLI_NO_RESET 0x01 #define ATMEL_64KB_PAGE 0x10000 #define ATMEL_MAX_TRANSFER_SIZE 0x0400 #define ATMEL_AVR_CONTROL_BLOCK_SIZE 32 #define ATMEL_AVR32_CONTROL_BLOCK_SIZE 64 #define ATMEL_MANUFACTURER_CODE1 0x58 #define ATMEL_MANUFACTURER_CODE2 0x1e static gboolean dfu_target_avr_mass_erase (DfuTarget *target, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[3]; /* this takes a long time on some devices */ dfu_device_set_timeout (dfu_target_get_device (target), 5000); /* format buffer */ buf[0] = DFU_AVR32_GROUP_EXEC; buf[1] = DFU_AVR32_CMD_ERASE; buf[2] = 0xff; data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("mass erasing"); dfu_target_set_action (target, FWUPD_STATUS_DEVICE_ERASE); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot mass-erase: "); return FALSE; } dfu_target_set_action (target, FWUPD_STATUS_IDLE); return TRUE; } static gboolean dfu_target_avr_attach (DfuTarget *target, GError **error) { guint8 buf[3]; g_autoptr(GBytes) data_empty = NULL; g_autoptr(GBytes) data_in = NULL; g_autoptr(GError) error_local = NULL; /* format buffer */ buf[0] = DFU_AVR32_GROUP_EXEC; buf[1] = DFU_AVR32_CMD_START_APPLI; buf[2] = DFU_AVR32_START_APPLI_RESET; data_in = g_bytes_new_static (buf, sizeof(buf)); if (!dfu_target_download_chunk (target, 0, data_in, &error_local)) { if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_debug ("ignoring as device rebooting: %s", error_local->message); return TRUE; } g_prefix_error (error, "cannot start application reset attach: "); return FALSE; } /* do zero-sized download to initiate the reset */ data_empty = g_bytes_new (NULL, 0); if (!dfu_target_download_chunk (target, 0, data_empty, &error_local)) { if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_debug ("ignoring as device rebooting: %s", error_local->message); return TRUE; } g_prefix_error (error, "cannot initiate reset for attach: "); return FALSE; } /* success */ return TRUE; } /** * dfu_target_avr_select_memory_unit: * @target: a #DfuTarget * @memory_unit: a unit, e.g. %DFU_AVR32_MEMORY_UNIT_FLASH * @error: a #GError, or %NULL * * Selects the memory unit for the device. * * Return value: %TRUE for success **/ static gboolean dfu_target_avr_select_memory_unit (DfuTarget *target, guint8 memory_unit, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[4]; /* check legacy protocol quirk */ if (dfu_device_has_quirk (dfu_target_get_device (target), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL)) { g_debug ("ignoring select memory unit as legacy protocol"); return TRUE; } /* format buffer */ buf[0] = DFU_AVR32_GROUP_SELECT; buf[1] = DFU_AVR32_CMD_SELECT_MEMORY; buf[2] = DFU_AVR32_MEMORY_UNIT; buf[3] = memory_unit; data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("selecting memory unit 0x%02x", (guint) memory_unit); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot select memory unit: "); return FALSE; } return TRUE; } /** * dfu_target_avr_select_memory_page: * @target: a #DfuTarget * @memory_page: an address * @error: a #GError, or %NULL * * Selects the memory page for the AVR device. * * Return value: %TRUE for success **/ static gboolean dfu_target_avr_select_memory_page (DfuTarget *target, guint16 memory_page, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[4]; /* check page not too large for protocol */ if (memory_page > 0xff) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot select memory page:0x%02x " "with FLIP protocol version 1", memory_page); return FALSE; } /* format buffer */ buf[0] = DFU_AVR_CMD_CHANGE_BASE_ADDR; buf[1] = 0x03; buf[2] = 0x00; buf[3] = memory_page & 0xff; data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("selecting memory page 0x%01x", (guint) memory_page); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot select memory page: "); return FALSE; } return TRUE; } /** * dfu_target_avr32_select_memory_page: * @target: a #DfuTarget * @memory_page: an address * @error: a #GError, or %NULL * * Selects the memory page for the AVR32 device. * * Return value: %TRUE for success **/ static gboolean dfu_target_avr32_select_memory_page (DfuTarget *target, guint16 memory_page, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[5]; /* format buffer */ buf[0] = DFU_AVR32_GROUP_SELECT; buf[1] = DFU_AVR32_CMD_SELECT_MEMORY; buf[2] = DFU_AVR32_MEMORY_PAGE; fu_common_write_uint16 (&buf[3], memory_page, G_BIG_ENDIAN); data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("selecting memory page 0x%02x", (guint) memory_page); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot select memory page: "); return FALSE; } return TRUE; } /** * dfu_target_avr_read_memory * @target: a #DfuTarget * @addr_start: an address * @addr_end: an address * @error: a #GError, or %NULL * * Reads flash data from the device. * * Return value: %TRUE for success **/ static gboolean dfu_target_avr_read_memory (DfuTarget *target, guint16 addr_start, guint16 addr_end, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[6]; /* format buffer */ buf[0] = DFU_AVR32_GROUP_UPLOAD; buf[1] = DFU_AVR32_CMD_READ_MEMORY; fu_common_write_uint16 (&buf[2], addr_start, G_BIG_ENDIAN); fu_common_write_uint16 (&buf[4], addr_end, G_BIG_ENDIAN); data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("reading memory from 0x%04x to 0x%04x", (guint) addr_start, (guint) addr_end); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot read memory 0x%04x to 0x%04x: ", (guint) addr_start, (guint) addr_end); return FALSE; } return TRUE; } /** * dfu_target_avr_read_command: * @target: a #DfuTarget * @memory_unit: a unit, e.g. %DFU_AVR32_MEMORY_UNIT_FLASH * @error: a #GError, or %NULL * * Performs a read operation on the device. * * Return value: %TRUE for success **/ static gboolean dfu_target_avr_read_command (DfuTarget *target, guint8 page, guint8 addr, GError **error) { g_autoptr(GBytes) data_in = NULL; guint8 buf[3]; /* format buffer */ buf[0] = DFU_AVR_CMD_READ_COMMAND; buf[1] = page; buf[2] = addr; data_in = g_bytes_new_static (buf, sizeof(buf)); g_debug ("read command page:0x%02x addr:0x%02x", (guint) page, (guint) addr); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot read command page: "); return FALSE; } return TRUE; } /** * dfu_target_avr32_get_chip_signature: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Gets the chip signature for the AVR32 device. * * Return value: a 4-byte %GBytes object for success, else %NULL **/ static GBytes * dfu_target_avr32_get_chip_signature (DfuTarget *target, GError **error) { /* select unit, and request 4 bytes */ if (!dfu_target_avr_select_memory_unit (target, DFU_AVR32_MEMORY_UNIT_SIGNATURE, error)) return NULL; if (!dfu_target_avr32_select_memory_page (target, 0x00, error)) return NULL; if (!dfu_target_avr_read_memory (target, 0x00, 0x03, error)) return NULL; /* get data back */ return dfu_target_upload_chunk (target, 0x00, 0, error); } /** * dfu_target_avr_get_chip_signature: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Gets the chip signature for the AVR device. * * Return value: a 4-byte %GBytes object for success, else %NULL **/ static GBytes * dfu_target_avr_get_chip_signature (DfuTarget *target, GError **error) { struct { guint8 page; guint addr; } signature_locations[] = { { 0x01, 0x30 }, { 0x01, 0x31 }, { 0x01, 0x60 }, { 0x01, 0x61 }, { 0xff, 0xff } }; g_autoptr(GPtrArray) chunks = NULL; /* we have to request this one byte at a time */ chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); for (guint i = 0; signature_locations[i].page != 0xff; i++) { g_autoptr(GBytes) chunk_byte = NULL; /* request a single byte */ if (!dfu_target_avr_read_command (target, signature_locations[i].page, signature_locations[i].addr, error)) return NULL; /* get data back */ chunk_byte = dfu_target_upload_chunk (target, 0x00, 0x01, error); if (chunk_byte == NULL) return NULL; if (g_bytes_get_size (chunk_byte) != 1) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot read signature memory page:0x%02x " "addr:0x%02x, got 0x%02x bytes", (guint) signature_locations[i].page, (guint) signature_locations[i].addr, (guint) g_bytes_get_size (chunk_byte)); return NULL; } g_ptr_array_add (chunks, g_steal_pointer (&chunk_byte)); } return dfu_utils_bytes_join_array (chunks); } static gboolean dfu_target_avr_setup (DfuTarget *target, GError **error) { DfuDevice *device; DfuTargetAvr *target_avr = DFU_TARGET_AVR (target); DfuTargetAvrPrivate *priv = GET_PRIVATE (target_avr); const gchar *quirk_str; const guint8 *buf; gsize sz; guint32 device_id_be; g_autofree gchar *chip_id = NULL; g_autoptr(GBytes) chunk_sig = NULL; /* already done */ if (priv->device_id > 0x0) return TRUE; /* different methods for AVR vs. AVR32 */ if (dfu_device_has_quirk (dfu_target_get_device (target), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL)) { chunk_sig = dfu_target_avr_get_chip_signature (target, error); if (chunk_sig == NULL) return FALSE; } else { chunk_sig = dfu_target_avr32_get_chip_signature (target, error); if (chunk_sig == NULL) return FALSE; } /* get data back */ buf = g_bytes_get_data (chunk_sig, &sz); if (sz != 4) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot read config memory, got 0x%02x bytes", (guint) sz); return FALSE; } memcpy (&device_id_be, buf, 4); priv->device_id = GINT32_FROM_BE (device_id_be); if (buf[0] == ATMEL_MANUFACTURER_CODE1) { chip_id = g_strdup_printf ("0x%08x", (guint) priv->device_id); } else if (buf[0] == ATMEL_MANUFACTURER_CODE2) { chip_id = g_strdup_printf ("0x%06x", (guint) priv->device_id >> 8); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot read config vendor, got 0x%08x, " "expected 0x%02x or 0x%02x", (guint) priv->device_id, (guint) ATMEL_MANUFACTURER_CODE1, (guint) ATMEL_MANUFACTURER_CODE2); return FALSE; } /* set the alt-name using the device ID */ dfu_device_set_chip_id (dfu_target_get_device (target), chip_id); device = dfu_target_get_device (target); quirk_str = fu_quirks_lookup_by_id (fu_device_get_quirks (FU_DEVICE (device)), FU_QUIRKS_DFU_AVR_CHIP_ID, chip_id); if (quirk_str == NULL) { dfu_device_remove_attribute (dfu_target_get_device (target), DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD); dfu_device_remove_attribute (dfu_target_get_device (target), DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "DeviceID %s is not supported", chip_id); return FALSE; } dfu_target_set_alt_name (target, quirk_str); return TRUE; } static gboolean dfu_target_avr_download_element (DfuTarget *target, DfuElement *element, DfuTargetTransferFlags flags, GError **error) { DfuSector *sector; GBytes *blob; const guint8 *data; gsize header_sz = ATMEL_AVR32_CONTROL_BLOCK_SIZE; guint16 page_last = G_MAXUINT16; guint32 address; guint32 address_offset = 0x0; g_autoptr(GPtrArray) packets = NULL; const guint8 footer[] = { 0x00, 0x00, 0x00, 0x00, /* CRC */ 16, /* len */ 'D', 'F', 'U', /* signature */ 0x01, 0x10, /* version */ 0xff, 0xff, /* vendor ID */ 0xff, 0xff, /* product ID */ 0xff, 0xff }; /* release */ /* select a memory and erase everything */ if (!dfu_target_avr_select_memory_unit (target, dfu_target_get_alt_setting (target), error)) return FALSE; if (!dfu_target_avr_mass_erase (target, error)) return FALSE; /* verify the element isn't larger than the target size */ blob = dfu_element_get_contents (element); sector = dfu_target_get_sector_default (target); if (sector == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no sector defined for target"); return FALSE; } address = dfu_element_get_address (element) & ~0x80000000; if (address < dfu_sector_get_address (sector)) { address_offset = dfu_sector_get_address (sector) - address; g_warning ("firmware element starts at 0x%x but sector " "starts at 0x%x, so offsetting by 0x%x (bootloader?)", (guint) address, (guint) dfu_sector_get_address (sector), (guint) address_offset); } if (g_bytes_get_size (blob) + address_offset > dfu_sector_get_size (sector)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "element was larger than sector size: 0x%x", (guint) dfu_sector_get_size (sector)); return FALSE; } /* the original AVR protocol uses a half-size control block */ if (dfu_device_has_quirk (dfu_target_get_device (target), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL)) { header_sz = ATMEL_AVR_CONTROL_BLOCK_SIZE; } /* chunk up the memory space into pages */ data = g_bytes_get_data (blob, NULL); packets = dfu_chunked_new (data + address_offset, g_bytes_get_size (blob) - address_offset, dfu_sector_get_address (sector), ATMEL_64KB_PAGE, ATMEL_MAX_TRANSFER_SIZE); /* update UI */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_WRITE); /* process each chunk */ for (guint i = 0; i < packets->len; i++) { const DfuChunkedPacket *packet = g_ptr_array_index (packets, i); g_autofree guint8 *buf = NULL; g_autoptr(GBytes) chunk_tmp = NULL; /* select page if required */ if (packet->page != page_last) { if (dfu_device_has_quirk (dfu_target_get_device (target), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL)) { if (!dfu_target_avr_select_memory_page (target, packet->page, error)) return FALSE; } else { if (!dfu_target_avr32_select_memory_page (target, packet->page, error)) return FALSE; } page_last = packet->page; } /* create packet with header and footer */ buf = g_malloc0 (packet->data_sz + header_sz + sizeof(footer)); buf[0] = DFU_AVR32_GROUP_DOWNLOAD; buf[1] = DFU_AVR32_CMD_PROGRAM_START; fu_common_write_uint16 (&buf[2], packet->address, G_BIG_ENDIAN); fu_common_write_uint16 (&buf[4], packet->address + packet->data_sz - 1, G_BIG_ENDIAN); memcpy (&buf[header_sz], packet->data, packet->data_sz); memcpy (&buf[header_sz + packet->data_sz], footer, sizeof(footer)); /* download data */ chunk_tmp = g_bytes_new_static (buf, packet->data_sz + header_sz + sizeof(footer)); g_debug ("sending %" G_GSIZE_FORMAT " bytes to the hardware", g_bytes_get_size (chunk_tmp)); if (!dfu_target_download_chunk (target, i, chunk_tmp, error)) return FALSE; /* update UI */ dfu_target_set_percentage (target, i + 1, packets->len); } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); return TRUE; } static DfuElement * dfu_target_avr_upload_element (DfuTarget *target, guint32 address, gsize expected_size, gsize maximum_size, GError **error) { guint16 page_last = G_MAXUINT16; guint chunk_valid = G_MAXUINT; g_autoptr(DfuElement) element = NULL; g_autoptr(GBytes) contents = NULL; g_autoptr(GBytes) contents_truncated = NULL; g_autoptr(GPtrArray) packets = NULL; g_autoptr(GPtrArray) chunks = NULL; DfuSector *sector; /* select unit */ if (!dfu_target_avr_select_memory_unit (target, dfu_target_get_alt_setting (target), error)) return NULL; /* verify the element isn't lower than the flash area */ sector = dfu_target_get_sector_default (target); if (sector == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no sector defined for target"); return NULL; } if (address < dfu_sector_get_address (sector)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "cannot read from below sector start"); return NULL; } /* the flash starts at 0x80000000, but is indexed from zero */ address &= ~0x80000000; /* chunk up the memory space into pages */ packets = dfu_chunked_new (NULL, maximum_size, address, ATMEL_64KB_PAGE, ATMEL_MAX_TRANSFER_SIZE); /* update UI */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_READ); /* process each chunk */ chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); for (guint i = 0; i < packets->len; i++) { GBytes *chunk_tmp = NULL; const DfuChunkedPacket *packet = g_ptr_array_index (packets, i); /* select page if required */ if (packet->page != page_last) { if (dfu_device_has_quirk (dfu_target_get_device (target), DFU_DEVICE_QUIRK_LEGACY_PROTOCOL)) { if (!dfu_target_avr_select_memory_page (target, packet->page, error)) return NULL; } else { if (!dfu_target_avr32_select_memory_page (target, packet->page, error)) return NULL; } page_last = packet->page; } /* prepare to read */ if (!dfu_target_avr_read_memory (target, packet->address, packet->address + packet->data_sz - 1, error)) return NULL; /* upload data */ g_debug ("requesting %i bytes from the hardware", ATMEL_MAX_TRANSFER_SIZE); chunk_tmp = dfu_target_upload_chunk (target, i, ATMEL_MAX_TRANSFER_SIZE, error); if (chunk_tmp == NULL) return NULL; g_ptr_array_add (chunks, chunk_tmp); /* this page has valid data */ if (!dfu_utils_bytes_is_empty (chunk_tmp)) { g_debug ("chunk %u has data (page %" G_GUINT32_FORMAT ")", i, packet->page); chunk_valid = i; } else { g_debug ("chunk %u is empty", i); } /* update UI */ dfu_target_set_percentage (target, i + 1, packets->len); } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* truncate the image if any sectors are empty, i.e. all 0xff */ if (chunk_valid == G_MAXUINT) { g_debug ("all %u chunks are empty", chunks->len); g_ptr_array_set_size (chunks, 0); } else if (chunks->len != chunk_valid + 1) { g_debug ("truncating chunks from %u to %u", chunks->len, chunk_valid + 1); g_ptr_array_set_size (chunks, chunk_valid + 1); } /* create element of required size */ contents = dfu_utils_bytes_join_array (chunks); if (expected_size > 0 && g_bytes_get_size (contents) > expected_size) { contents_truncated = g_bytes_new_from_bytes (contents, 0x0, expected_size); } else { contents_truncated = g_bytes_ref (contents); } element = dfu_element_new (); dfu_element_set_address (element, address | 0x80000000); /* flash */ dfu_element_set_contents (element, contents_truncated); return g_steal_pointer (&element); } static void dfu_target_avr_init (DfuTargetAvr *target_avr) { } static void dfu_target_avr_class_init (DfuTargetAvrClass *klass) { DfuTargetClass *klass_target = DFU_TARGET_CLASS (klass); klass_target->setup = dfu_target_avr_setup; klass_target->attach = dfu_target_avr_attach; klass_target->mass_erase = dfu_target_avr_mass_erase; klass_target->upload_element = dfu_target_avr_upload_element; klass_target->download_element = dfu_target_avr_download_element; } DfuTarget * dfu_target_avr_new (void) { DfuTarget *target; target = g_object_new (DFU_TYPE_TARGET_AVR, NULL); return target; } fwupd-1.0.6/plugins/dfu/dfu-target-avr.h000066400000000000000000000025531325145456600201230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_TARGET_AVR_H #define __DFU_TARGET_AVR_H #include #include #include "dfu-target.h" G_BEGIN_DECLS #define DFU_TYPE_TARGET_AVR (dfu_target_avr_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuTargetAvr, dfu_target_avr, DFU, TARGET_AVR, DfuTarget) struct _DfuTargetAvrClass { DfuTargetClass parent_class; }; DfuTarget *dfu_target_avr_new (void); G_END_DECLS #endif /* __DFU_TARGET_AVR_H */ fwupd-1.0.6/plugins/dfu/dfu-target-private.h000066400000000000000000000050011325145456600207740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_TARGET_PRIVATE_H #define __DFU_TARGET_PRIVATE_H #include #include "dfu-device.h" #include "dfu-target.h" #include "dfu-sector.h" G_BEGIN_DECLS DfuTarget *dfu_target_new (void); GBytes *dfu_target_upload_chunk (DfuTarget *target, guint16 index, gsize buf_sz, GError **error); gboolean dfu_target_download_chunk (DfuTarget *target, guint16 index, GBytes *bytes, GError **error); gboolean dfu_target_attach (DfuTarget *target, GError **error); void dfu_target_set_alt_idx (DfuTarget *target, guint8 alt_idx); void dfu_target_set_alt_setting (DfuTarget *target, guint8 alt_setting); /* for the other implementations */ void dfu_target_set_action (DfuTarget *target, FwupdStatus action); void dfu_target_set_percentage_raw (DfuTarget *target, guint percentage); void dfu_target_set_percentage (DfuTarget *target, guint value, guint total); void dfu_target_set_alt_name (DfuTarget *target, const gchar *alt_name); void dfu_target_set_device (DfuTarget *target, DfuDevice *device); DfuDevice *dfu_target_get_device (DfuTarget *target); gboolean dfu_target_check_status (DfuTarget *target, GError **error); DfuSector *dfu_target_get_sector_for_addr (DfuTarget *target, guint32 addr); /* export this just for the self tests */ gboolean dfu_target_parse_sectors (DfuTarget *target, const gchar *alt_name, GError **error); G_END_DECLS #endif /* __DFU_TARGET_PRIVATE_H */ fwupd-1.0.6/plugins/dfu/dfu-target-stm.c000066400000000000000000000277031325145456600201350ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "dfu-chunked.h" #include "dfu-common.h" #include "dfu-sector.h" #include "dfu-target-stm.h" #include "dfu-target-private.h" #include "fwupd-error.h" G_DEFINE_TYPE (DfuTargetStm, dfu_target_stm, DFU_TYPE_TARGET) /* STMicroelectronics STM32 version of DFU: * www.st.com/resource/en/application_note/cd00264379.pdf */ #define DFU_STM_CMD_GET_COMMAND 0x00 #define DFU_STM_CMD_SET_ADDRESS_POINTER 0x21 #define DFU_STM_CMD_ERASE 0x41 #define DFU_STM_CMD_READ_UNPROTECT 0x92 static gboolean dfu_target_stm_attach (DfuTarget *target, GError **error) { g_autoptr(GBytes) bytes_tmp = g_bytes_new (NULL, 0); return dfu_target_download_chunk (target, 2, bytes_tmp, error); } static gboolean dfu_target_stm_mass_erase (DfuTarget *target, GError **error) { GBytes *data_in; guint8 buf[1]; /* format buffer */ buf[0] = DFU_STM_CMD_ERASE; data_in = g_bytes_new_static (buf, sizeof(buf)); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot mass-erase: "); return FALSE; } /* 2nd check required to get error code */ return dfu_target_check_status (target, error); } /** * dfu_target_stm_set_address: * @target: a #DfuTarget * @address: memory address * @error: a #GError, or %NULL * * Sets the address used for the next download or upload request. * * Return value: %TRUE for success **/ static gboolean dfu_target_stm_set_address (DfuTarget *target, guint32 address, GError **error) { GBytes *data_in; guint8 buf[5]; /* format buffer */ buf[0] = DFU_STM_CMD_SET_ADDRESS_POINTER; memcpy (buf + 1, &address, 4); data_in = g_bytes_new_static (buf, sizeof(buf)); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot set address 0x%x: ", address); return FALSE; } /* 2nd check required to get error code */ g_debug ("doing actual check status"); return dfu_target_check_status (target, error); } static DfuElement * dfu_target_stm_upload_element (DfuTarget *target, guint32 address, gsize expected_size, gsize maximum_size, GError **error) { DfuDevice *device = dfu_target_get_device (target); DfuSector *sector; DfuElement *element = NULL; GBytes *chunk_tmp; guint32 offset = address; guint percentage_size = expected_size > 0 ? expected_size : maximum_size; gsize total_size = 0; guint16 transfer_size = dfu_device_get_transfer_size (device); g_autoptr(GBytes) contents = NULL; g_autoptr(GBytes) contents_truncated = NULL; g_autoptr(GPtrArray) chunks = NULL; /* for DfuSe devices we need to handle the address manually */ sector = dfu_target_get_sector_for_addr (target, offset); if (sector == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no memory sector at 0x%04x", (guint) offset); return NULL; } g_debug ("using sector %u for read of %x", dfu_sector_get_id (sector), offset); if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_READABLE)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "memory sector at 0x%04x is not readble", (guint) offset); return NULL; } /* update UI */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_READ); /* manually set the sector address */ g_debug ("setting DfuSe address to 0x%04x", (guint) offset); if (!dfu_target_stm_set_address (target, offset, error)) return NULL; /* abort back to IDLE */ if (!dfu_device_abort (device, error)) return NULL; /* get all the chunks from the hardware */ chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); for (guint16 idx = 0; idx < G_MAXUINT16; idx++) { guint32 chunk_size; /* read chunk of data -- ST uses wBlockNum=0 for DfuSe commands * and wBlockNum=1 is reserved */ chunk_tmp = dfu_target_upload_chunk (target, idx + 2, 0, /* device transfer size */ error); if (chunk_tmp == NULL) return NULL; /* add to array */ chunk_size = (guint32) g_bytes_get_size (chunk_tmp); g_debug ("got #%04x chunk @0x%x of size %" G_GUINT32_FORMAT, idx, offset, chunk_size); g_ptr_array_add (chunks, chunk_tmp); total_size += chunk_size; offset += chunk_size; /* update UI */ if (chunk_size > 0) dfu_target_set_percentage (target, total_size, percentage_size); /* detect short write as EOF */ if (chunk_size < transfer_size) break; /* more data than we needed */ if (maximum_size > 0 && total_size > maximum_size) break; } /* abort back to IDLE */ if (!dfu_device_abort (device, error)) return NULL; /* check final size */ if (expected_size > 0) { if (total_size < expected_size) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid size, got %" G_GSIZE_FORMAT ", " "expected %" G_GSIZE_FORMAT , total_size, expected_size); return NULL; } } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* create new image */ contents = dfu_utils_bytes_join_array (chunks); if (expected_size > 0) contents_truncated = g_bytes_new_from_bytes (contents, 0, expected_size); else contents_truncated = g_bytes_ref (contents); element = dfu_element_new (); dfu_element_set_contents (element, contents_truncated); dfu_element_set_address (element, address); return element; } /** * dfu_target_stm_erase_address: * @target: a #DfuTarget * @address: memory address * @error: a #GError, or %NULL * * Erases a memory sector at a given address. * * Return value: %TRUE for success **/ static gboolean dfu_target_stm_erase_address (DfuTarget *target, guint32 address, GError **error) { GBytes *data_in; guint8 buf[5]; /* format buffer */ buf[0] = DFU_STM_CMD_ERASE; memcpy (buf + 1, &address, 4); data_in = g_bytes_new_static (buf, sizeof(buf)); if (!dfu_target_download_chunk (target, 0, data_in, error)) { g_prefix_error (error, "cannot erase address 0x%x: ", address); return FALSE; } /* 2nd check required to get error code */ g_debug ("doing actual check status"); return dfu_target_check_status (target, error); } static gboolean dfu_target_stm_download_element (DfuTarget *target, DfuElement *element, DfuTargetTransferFlags flags, GError **error) { DfuDevice *device = dfu_target_get_device (target); DfuSector *sector; GBytes *bytes; guint nr_chunks; guint zone_last = G_MAXUINT; guint16 transfer_size = dfu_device_get_transfer_size (device); g_autoptr(GPtrArray) sectors_array = NULL; g_autoptr(GHashTable) sectors_hash = NULL; /* round up as we have to transfer incomplete blocks */ bytes = dfu_element_get_contents (element); nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) / (gdouble) transfer_size); if (nr_chunks == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "zero-length firmware"); return FALSE; } /* 1st pass: work out which sectors need erasing */ sectors_array = g_ptr_array_new (); sectors_hash = g_hash_table_new (g_direct_hash, g_direct_equal); for (guint i = 0; i < nr_chunks; i++) { guint32 offset_dev; /* for DfuSe devices we need to handle the erase and setting * the sectory address manually */ offset_dev = dfu_element_get_address (element) + (i * transfer_size); sector = dfu_target_get_sector_for_addr (target, offset_dev); if (sector == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no memory sector at 0x%04x", (guint) offset_dev); return FALSE; } if (!dfu_sector_has_cap (sector, DFU_SECTOR_CAP_WRITEABLE)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "memory sector at 0x%04x is not writable", (guint) offset_dev); return FALSE; } /* if it's erasable and not yet blanked */ if (dfu_sector_has_cap (sector, DFU_SECTOR_CAP_ERASEABLE) && g_hash_table_lookup (sectors_hash, sector) == NULL) { g_hash_table_insert (sectors_hash, sector, GINT_TO_POINTER (1)); g_ptr_array_add (sectors_array, sector); g_debug ("marking sector 0x%04x-%04x to be erased", dfu_sector_get_address (sector), dfu_sector_get_address (sector) + dfu_sector_get_size (sector)); } } /* 2nd pass: actually erase sectors */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_ERASE); for (guint i = 0; i < sectors_array->len; i++) { sector = g_ptr_array_index (sectors_array, i); g_debug ("erasing sector at 0x%04x", dfu_sector_get_address (sector)); if (!dfu_target_stm_erase_address (target, dfu_sector_get_address (sector), error)) return FALSE; dfu_target_set_percentage (target, i + 1, sectors_array->len); } dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* 3rd pass: write data */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_WRITE); for (guint i = 0; i < nr_chunks; i++) { gsize length; guint32 offset; guint32 offset_dev; g_autoptr(GBytes) bytes_tmp = NULL; /* caclulate the offset into the element data */ offset = i * transfer_size; offset_dev = dfu_element_get_address (element) + offset; /* for DfuSe devices we need to set the address manually */ sector = dfu_target_get_sector_for_addr (target, offset_dev); g_assert (sector != NULL); /* manually set the sector address */ if (dfu_sector_get_zone (sector) != zone_last) { g_debug ("setting address to 0x%04x", (guint) offset_dev); if (!dfu_target_stm_set_address (target, (guint32) offset_dev, error)) return FALSE; zone_last = dfu_sector_get_zone (sector); } /* we have to write one final zero-sized chunk for EOF */ length = g_bytes_get_size (bytes) - offset; if (length > transfer_size) length = transfer_size; bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length); g_debug ("writing sector at 0x%04x (0x%" G_GSIZE_FORMAT ")", offset_dev, g_bytes_get_size (bytes_tmp)); /* ST uses wBlockNum=0 for DfuSe commands and wBlockNum=1 is reserved */ if (!dfu_target_download_chunk (target, (guint8) (i + 2), bytes_tmp, error)) return FALSE; /* getting the status moves the state machine to DNLOAD-IDLE */ if (!dfu_target_check_status (target, error)) return FALSE; /* update UI */ dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes)); } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* success */ return TRUE; } static void dfu_target_stm_init (DfuTargetStm *target_stm) { } static void dfu_target_stm_class_init (DfuTargetStmClass *klass) { DfuTargetClass *klass_target = DFU_TARGET_CLASS (klass); klass_target->attach = dfu_target_stm_attach; klass_target->mass_erase = dfu_target_stm_mass_erase; klass_target->upload_element = dfu_target_stm_upload_element; klass_target->download_element = dfu_target_stm_download_element; } DfuTarget * dfu_target_stm_new (void) { DfuTarget *target; target = g_object_new (DFU_TYPE_TARGET_STM, NULL); return target; } fwupd-1.0.6/plugins/dfu/dfu-target-stm.h000066400000000000000000000025531325145456600201360ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_TARGET_STM_H #define __DFU_TARGET_STM_H #include #include #include "dfu-target.h" G_BEGIN_DECLS #define DFU_TYPE_TARGET_STM (dfu_target_stm_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuTargetStm, dfu_target_stm, DFU, TARGET_STM, DfuTarget) struct _DfuTargetStmClass { DfuTargetClass parent_class; }; DfuTarget *dfu_target_stm_new (void); G_END_DECLS #endif /* __DFU_TARGET_STM_H */ fwupd-1.0.6/plugins/dfu/dfu-target.c000066400000000000000000001114561325145456600173330ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:dfu-target * @short_description: Object representing a DFU-capable target * * This object allows uploading and downloading an image onto a * specific DFU-capable target. * * You only need to use this in preference to #DfuDevice if you only * want to update one target on the device. Most users will want to * update all the targets on the device at the same time. * * See also: #DfuDevice, #DfuImage */ #include "config.h" #include #include #include "dfu-common.h" #include "dfu-device-private.h" #include "dfu-sector-private.h" #include "dfu-target-private.h" #include "fwupd-error.h" static void dfu_target_finalize (GObject *object); typedef struct { DfuDevice *device; /* not refcounted */ DfuCipherKind cipher_kind; gboolean done_setup; guint8 alt_setting; guint8 alt_idx; gchar *alt_name; gchar *alt_name_for_display; GPtrArray *sectors; /* of DfuSector */ guint old_percentage; FwupdStatus old_action; } DfuTargetPrivate; enum { SIGNAL_PERCENTAGE_CHANGED, SIGNAL_ACTION_CHANGED, SIGNAL_LAST }; static guint signals [SIGNAL_LAST] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (DfuTarget, dfu_target, G_TYPE_OBJECT) #define GET_PRIVATE(o) (dfu_target_get_instance_private (o)) static void dfu_target_class_init (DfuTargetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); /** * DfuTarget::percentage-changed: * @device: the #DfuTarget instance that emitted the signal * @percentage: the new percentage * * The ::percentage-changed signal is emitted when the percentage changes. **/ signals [SIGNAL_PERCENTAGE_CHANGED] = g_signal_new ("percentage-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DfuTargetClass, percentage_changed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); /** * DfuTarget::action-changed: * @device: the #DfuTarget instance that emitted the signal * @action: the new FwupdStatus * * The ::action-changed signal is emitted when the high level action changes. **/ signals [SIGNAL_ACTION_CHANGED] = g_signal_new ("action-changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (DfuTargetClass, action_changed), NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); object_class->finalize = dfu_target_finalize; } static void dfu_target_init (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); priv->sectors = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); priv->old_percentage = G_MAXUINT; priv->old_action = FWUPD_STATUS_IDLE; } static void dfu_target_finalize (GObject *object) { DfuTarget *target = DFU_TARGET (object); DfuTargetPrivate *priv = GET_PRIVATE (target); g_free (priv->alt_name); g_free (priv->alt_name_for_display); g_ptr_array_unref (priv->sectors); /* we no longer care */ if (priv->device != NULL) { g_object_remove_weak_pointer (G_OBJECT (priv->device), (gpointer *) &priv->device); } G_OBJECT_CLASS (dfu_target_parent_class)->finalize (object); } static gchar * dfu_target_sectors_to_string (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); GString *str = g_string_new (""); for (guint i = 0; i < priv->sectors->len; i++) { DfuSector *sector = g_ptr_array_index (priv->sectors, i); g_autofree gchar *tmp = dfu_sector_to_string (sector); g_string_append_printf (str, "%s\n", tmp); } if (str->len > 0) g_string_truncate (str, str->len - 1); return g_string_free (str, FALSE); } DfuSector * dfu_target_get_sector_for_addr (DfuTarget *target, guint32 addr) { DfuTargetPrivate *priv = GET_PRIVATE (target); for (guint i = 0; i < priv->sectors->len; i++) { DfuSector *sector = g_ptr_array_index (priv->sectors, i); if (addr < dfu_sector_get_address (sector)) continue; if (addr > dfu_sector_get_address (sector) + dfu_sector_get_size (sector)) continue; return sector; } return NULL; } static gboolean dfu_target_parse_sector (DfuTarget *target, const gchar *dfuse_sector_id, guint32 *addr, guint16 zone, guint16 number, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuSectorCap cap = DFU_SECTOR_CAP_NONE; gchar *tmp; guint32 addr_offset = 0; guint64 nr_sectors; guint64 sector_size; /* parse # of sectors */ nr_sectors = g_ascii_strtoull (dfuse_sector_id, &tmp, 10); if (nr_sectors > 999) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid number of sectors: %s", dfuse_sector_id); return FALSE; } /* check this is the delimiter */ if (tmp[0] != '*') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid sector ID: %s", dfuse_sector_id); return FALSE; } /* parse sector size */ sector_size = g_ascii_strtoull (tmp + 1, &tmp, 10); if (sector_size > 999) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid sector size: %s", dfuse_sector_id); return FALSE; } /* get multiplier */ switch (tmp[0]) { case 'B': /* byte */ case ' ': /* byte, ST reference bootloader :/ */ break; case 'K': /* Kilo */ sector_size *= 0x400; break; case 'M': /* Mega */ sector_size *= 0x100000 ; break; default: g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid sector multiplier: %s", tmp); return FALSE; } /* get sector type */ switch (tmp[1]) { case 'a': cap = DFU_SECTOR_CAP_READABLE; break; case 'b': cap = DFU_SECTOR_CAP_ERASEABLE; break; case 'c': cap = DFU_SECTOR_CAP_READABLE | DFU_SECTOR_CAP_ERASEABLE; break; case 'd': cap = DFU_SECTOR_CAP_WRITEABLE; break; case 'e': cap = DFU_SECTOR_CAP_READABLE | DFU_SECTOR_CAP_WRITEABLE; break; case 'f': cap = DFU_SECTOR_CAP_ERASEABLE | DFU_SECTOR_CAP_WRITEABLE; break; case 'g': cap = DFU_SECTOR_CAP_READABLE | DFU_SECTOR_CAP_ERASEABLE | DFU_SECTOR_CAP_WRITEABLE; break; default: g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid sector type: %s", tmp); return FALSE; } /* add all the sectors */ for (guint i = 0; i < nr_sectors; i++) { DfuSector *sector; sector = dfu_sector_new (*addr + addr_offset, (guint32) sector_size, (guint32) ((nr_sectors * sector_size) - addr_offset), zone, number, cap); g_ptr_array_add (priv->sectors, sector); addr_offset += dfu_sector_get_size (sector); } /* update for next sector */ *addr += addr_offset; return TRUE; } gboolean dfu_target_parse_sectors (DfuTarget *target, const gchar *alt_name, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_autofree gchar *str_debug = NULL; g_auto(GStrv) zones = NULL; /* not set */ if (alt_name == NULL) return TRUE; /* do we have any hint for the cipher */ if (g_strstr_len (alt_name, -1, "|XTEA") != NULL) priv->cipher_kind = DFU_CIPHER_KIND_XTEA; /* From the Neo Freerunner */ if (g_str_has_prefix (alt_name, "RAM 0x")) { DfuSector *sector; guint64 addr_tmp; addr_tmp = g_ascii_strtoull (alt_name + 6, NULL, 16); if (addr_tmp == 0 || addr_tmp > G_MAXUINT32) return FALSE; g_debug ("RAM description, so parsing"); sector = dfu_sector_new ((guint32) addr_tmp, 0x0, /* size */ 0x0, /* size_left */ 0x0, /* zone */ 0x0, /* number */ DFU_SECTOR_CAP_READABLE | DFU_SECTOR_CAP_WRITEABLE); g_ptr_array_add (priv->sectors, sector); } /* not a DfuSe alternative name */ if (alt_name[0] != '@') return TRUE; /* clear any existing zones */ g_ptr_array_set_size (priv->sectors, 0); /* parse zones */ zones = g_strsplit (alt_name, "/", -1); g_free (priv->alt_name_for_display); priv->alt_name_for_display = g_strdup (g_strchomp (zones[0] + 1)); for (guint i = 1; zones[i] != NULL; i += 2) { guint32 addr; guint64 addr_tmp; g_auto(GStrv) sectors = NULL; /* parse address */ if (!g_str_has_prefix (zones[i], "0x")) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No sector address"); return FALSE; } addr_tmp = g_ascii_strtoull (zones[i] + 2, NULL, 16); if (addr_tmp > G_MAXUINT32) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Sector address too large"); return FALSE; } addr = (guint32) addr_tmp; /* no sectors?! */ if (zones[i+1] == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No sector section"); return FALSE; } /* parse sectors */ sectors = g_strsplit (zones[i+1], ",", -1); for (guint16 j = 0; sectors[j] != NULL; j++) { if (!dfu_target_parse_sector (target, sectors[j], &addr, (i - 1) / 2, j, error)) { g_prefix_error (error, "Failed to parse: '%s': ", sectors[j]); return FALSE; } } } /* success */ str_debug = dfu_target_sectors_to_string (target); g_debug ("%s", str_debug); return TRUE; } /** * dfu_target_new: (skip) * * Creates a new DFU target, which represents an alt-setting on a * DFU-capable device. * * Return value: a #DfuTarget **/ DfuTarget * dfu_target_new (void) { DfuTarget *target; target = g_object_new (DFU_TYPE_TARGET, NULL); return target; } /** * dfu_target_get_sectors: * @target: a #GUsbDevice * * Gets the sectors exported by the target. * * Return value: (transfer none) (element-type DfuSector): sectors **/ GPtrArray * dfu_target_get_sectors (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), NULL); return priv->sectors; } /** * dfu_target_get_sector_default: * @target: a #GUsbDevice * * Gets the default (first) sector exported by the target. * * Return value: (transfer none): a #DfuSector, or %NULL **/ DfuSector * dfu_target_get_sector_default (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), NULL); if (priv->sectors->len == 0) return NULL; return DFU_SECTOR (g_ptr_array_index (priv->sectors, 0)); } /** * dfu_target_status_to_error_msg: * @status: a #DfuStatus, e.g. %DFU_STATUS_ERR_ERASE * * Converts an enumerated value to an error description. * * Return value: a string **/ static const gchar * dfu_target_status_to_error_msg (DfuStatus status) { if (status == DFU_STATUS_OK) return "No error condition is present"; if (status == DFU_STATUS_ERR_TARGET) return "Firmware is not for designed this device"; if (status == DFU_STATUS_ERR_FILE) return "Firmware is for this device but fails verification"; if (status == DFU_STATUS_ERR_WRITE) return "Device is unable to write memory"; if (status == DFU_STATUS_ERR_ERASE) return "Memory erase function failed"; if (status == DFU_STATUS_ERR_CHECK_ERASED) return "Memory erase check failed"; if (status == DFU_STATUS_ERR_PROG) return "Program memory function failed"; if (status == DFU_STATUS_ERR_VERIFY) return "Programmed memory failed verification"; if (status == DFU_STATUS_ERR_ADDRESS) return "Cannot program memory due to address out of range"; if (status == DFU_STATUS_ERR_NOTDONE) return "Received zero-length download but data is incomplete"; if (status == DFU_STATUS_ERR_FIRMWARE) return "Device firmware is corrupt"; if (status == DFU_STATUS_ERR_VENDOR) return "Vendor-specific error"; if (status == DFU_STATUS_ERR_USBR) return "Device detected unexpected USB reset signaling"; if (status == DFU_STATUS_ERR_POR) return "Device detected unexpected power on reset"; if (status == DFU_STATUS_ERR_UNKNOWN) return "Something unexpected went wrong"; if (status == DFU_STATUS_ERR_STALLDPKT) return "Device stalled an unexpected request"; return NULL; } gboolean dfu_target_check_status (DfuTarget *target, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuStatus status; /* get the status */ if (!dfu_device_refresh (priv->device, error)) return FALSE; /* wait for dfuDNBUSY to not be set */ if (dfu_device_get_version (priv->device) == DFU_VERSION_DFUSE) { while (dfu_device_get_state (priv->device) == DFU_STATE_DFU_DNBUSY) { g_debug ("waiting for DFU_STATE_DFU_DNBUSY to clear"); g_usleep (dfu_device_get_download_timeout (priv->device) * 1000); if (!dfu_device_refresh (priv->device, error)) return FALSE; } } /* not in an error state */ if (dfu_device_get_state (priv->device) != DFU_STATE_DFU_ERROR) return TRUE; /* STM32-specific long errors */ status = dfu_device_get_status (priv->device); if (dfu_device_get_version (priv->device) == DFU_VERSION_DFUSE) { if (status == DFU_STATUS_ERR_VENDOR) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Read protection is active"); return FALSE; } if (status == DFU_STATUS_ERR_TARGET) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Address is wrong or unsupported"); return FALSE; } } /* use a proper error description */ g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, dfu_target_status_to_error_msg (status)); return FALSE; } /** * dfu_target_use_alt_setting: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Opens a DFU-capable target. * * Return value: %TRUE for success **/ static gboolean dfu_target_use_alt_setting (DfuTarget *target, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (priv->device)); g_autoptr(GError) error_local = NULL; g_return_val_if_fail (DFU_IS_TARGET (target), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* ensure interface is claimed */ if (!dfu_device_ensure_interface (priv->device, error)) return FALSE; /* use the correct setting */ if (!dfu_device_is_runtime (priv->device)) { if (!g_usb_device_set_interface_alt (usb_device, (gint) dfu_device_get_interface (priv->device), (gint) priv->alt_setting, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot set alternate setting 0x%02x on interface %i: %s", priv->alt_setting, dfu_device_get_interface (priv->device), error_local->message); return FALSE; } } return TRUE; } void dfu_target_set_alt_name (DfuTarget *target, const gchar *alt_name) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_free (priv->alt_name); priv->alt_name = g_strdup (alt_name); } void dfu_target_set_device (DfuTarget *target, DfuDevice *device) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_set_object (&priv->device, device); /* if we try to ref the target and destroy the device */ g_object_add_weak_pointer (G_OBJECT (priv->device), (gpointer *) &priv->device); } /** * dfu_target_setup: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Opens a DFU-capable target. * * Return value: %TRUE for success **/ gboolean dfu_target_setup (DfuTarget *target, GError **error) { DfuTargetClass *klass = DFU_TARGET_GET_CLASS (target); DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already done */ if (priv->done_setup) return TRUE; /* superclassed */ if (klass->setup != NULL) { if (!klass->setup (target, error)) return FALSE; } /* get string */ if (priv->alt_idx != 0x00 && priv->alt_name == NULL) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (priv->device)); priv->alt_name = g_usb_device_get_string_descriptor (usb_device, priv->alt_idx, NULL); } /* parse the DfuSe format according to UM0424 */ if (!dfu_target_parse_sectors (target, priv->alt_name, error)) return FALSE; /* add a dummy entry */ if (priv->sectors->len == 0) { DfuSector *sector; sector = dfu_sector_new (0x0, /* addr */ 0x0, /* size */ 0x0, /* size_left */ 0x0, /* zone */ 0x0, /* number */ DFU_SECTOR_CAP_READABLE | DFU_SECTOR_CAP_WRITEABLE); g_debug ("no UM0424 sector description in %s", priv->alt_name); g_ptr_array_add (priv->sectors, sector); } priv->done_setup = TRUE; return TRUE; } /** * dfu_target_mass_erase: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Mass erases the device clearing all SRAM and EEPROM memory. * * IMPORTANT: This only works on STM32 devices from ST and AVR32 devices from Atmel. * * Return value: %TRUE for success **/ gboolean dfu_target_mass_erase (DfuTarget *target, GError **error) { DfuTargetClass *klass = DFU_TARGET_GET_CLASS (target); if (!dfu_target_setup (target, error)) return FALSE; if (klass->mass_erase == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "mass erase not supported"); return FALSE; } return klass->mass_erase (target, error); } gboolean dfu_target_download_chunk (DfuTarget *target, guint16 index, GBytes *bytes, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (priv->device)); g_autoptr(GError) error_local = NULL; gsize actual_length; /* low level packet debugging */ if (g_getenv ("FWUPD_DFU_VERBOSE") != NULL) { gsize sz = 0; const guint8 *data = g_bytes_get_data (bytes, &sz); for (gsize i = 0; i < sz; i++) g_print ("Message: m[%" G_GSIZE_FORMAT "] = 0x%02x\n", i, (guint) data[i]); } if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_DNLOAD, index, dfu_device_get_interface (priv->device), (guint8 *) g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), &actual_length, dfu_device_get_timeout (priv->device), NULL, &error_local)) { /* refresh the error code */ dfu_device_error_fixup (priv->device, &error_local); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot download data: %s", error_local->message); return FALSE; } /* for STM32 devices, the action only occurs when we do GetStatus */ if (dfu_device_get_version (priv->device) == DFU_VERSION_DFUSE) { if (!dfu_device_refresh (priv->device, error)) return FALSE; } /* wait for the device to write contents to the EEPROM */ if (g_bytes_get_size (bytes) == 0 && dfu_device_get_download_timeout (priv->device) > 0) { dfu_target_set_action (target, FWUPD_STATUS_IDLE); dfu_target_set_action (target, FWUPD_STATUS_DEVICE_BUSY); } if (dfu_device_get_download_timeout (priv->device) > 0) { g_debug ("sleeping for %ums…", dfu_device_get_download_timeout (priv->device)); g_usleep (dfu_device_get_download_timeout (priv->device) * 1000); } /* find out if the write was successful */ if (!dfu_device_refresh (priv->device, error)) return FALSE; g_assert (actual_length == g_bytes_get_size (bytes)); return TRUE; } GBytes * dfu_target_upload_chunk (DfuTarget *target, guint16 index, gsize buf_sz, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (priv->device)); g_autoptr(GError) error_local = NULL; guint8 *buf; gsize actual_length; /* unset */ if (buf_sz == 0) buf_sz = (gsize) dfu_device_get_transfer_size (priv->device); buf = g_new0 (guint8, buf_sz); if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, DFU_REQUEST_UPLOAD, index, dfu_device_get_interface (priv->device), buf, buf_sz, &actual_length, dfu_device_get_timeout (priv->device), NULL, &error_local)) { /* refresh the error code */ dfu_device_error_fixup (priv->device, &error_local); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "cannot upload data: %s", error_local->message); return NULL; } /* low level packet debugging */ if (g_getenv ("FWUPD_DFU_VERBOSE") != NULL) { for (gsize i = 0; i < actual_length; i++) g_print ("Message: r[%" G_GSIZE_FORMAT "] = 0x%02x\n", i, (guint) buf[i]); } return g_bytes_new_take (buf, actual_length); } void dfu_target_set_alt_idx (DfuTarget *target, guint8 alt_idx) { DfuTargetPrivate *priv = GET_PRIVATE (target); priv->alt_idx = alt_idx; } void dfu_target_set_alt_setting (DfuTarget *target, guint8 alt_setting) { DfuTargetPrivate *priv = GET_PRIVATE (target); priv->alt_setting = alt_setting; } void dfu_target_set_action (DfuTarget *target, FwupdStatus action) { DfuTargetPrivate *priv = GET_PRIVATE (target); /* unchanged */ if (priv->old_action == action) return; if (priv->old_action != FWUPD_STATUS_IDLE && action != FWUPD_STATUS_IDLE) { g_debug ("ignoring action %s as %s already set and not idle", fwupd_status_to_string (action), fwupd_status_to_string (priv->old_action)); return; } g_debug ("setting action %s", fwupd_status_to_string (action)); g_signal_emit (target, signals[SIGNAL_ACTION_CHANGED], 0, action); priv->old_action = action; } DfuDevice * dfu_target_get_device (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); return priv->device; } void dfu_target_set_percentage_raw (DfuTarget *target, guint percentage) { DfuTargetPrivate *priv = GET_PRIVATE (target); if (percentage == priv->old_percentage) return; g_debug ("setting percentage %u%% of %s", percentage, fwupd_status_to_string (priv->old_action)); g_signal_emit (target, signals[SIGNAL_PERCENTAGE_CHANGED], 0, percentage); priv->old_percentage = percentage; } void dfu_target_set_percentage (DfuTarget *target, guint value, guint total) { guint percentage; g_return_if_fail (total > 0); percentage = (value * 100) / total; if (percentage >= 100) return; dfu_target_set_percentage_raw (target, percentage); } gboolean dfu_target_attach (DfuTarget *target, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuTargetClass *klass = DFU_TARGET_GET_CLASS (target); /* ensure populated */ if (!dfu_target_setup (target, error)) return FALSE; /* implemented as part of a superclass */ if (klass->attach != NULL) return klass->attach (target, error); /* normal DFU mode just needs a bus reset */ return dfu_device_reset (priv->device, error); } static DfuElement * dfu_target_upload_element_dfu (DfuTarget *target, guint32 address, gsize expected_size, gsize maximum_size, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuElement *element = NULL; GBytes *chunk_tmp; guint32 offset = 0; guint percentage_size = expected_size > 0 ? expected_size : maximum_size; gsize total_size = 0; guint16 transfer_size = dfu_device_get_transfer_size (priv->device); g_autoptr(GBytes) contents = NULL; g_autoptr(GPtrArray) chunks = NULL; /* update UI */ dfu_target_set_action (target, FWUPD_STATUS_DEVICE_READ); /* get all the chunks from the hardware */ chunks = g_ptr_array_new_with_free_func ((GDestroyNotify) g_bytes_unref); for (guint16 idx = 0; idx < G_MAXUINT16; idx++) { guint32 chunk_size; /* read chunk of data */ chunk_tmp = dfu_target_upload_chunk (target, idx, 0, /* device transfer size */ error); if (chunk_tmp == NULL) return NULL; /* keep a sum of all the chunks */ chunk_size = (guint32) g_bytes_get_size (chunk_tmp); total_size += chunk_size; offset += chunk_size; /* add to array */ g_debug ("got #%04x chunk of size %" G_GUINT32_FORMAT, idx, chunk_size); g_ptr_array_add (chunks, chunk_tmp); /* update UI */ if (chunk_size > 0) dfu_target_set_percentage (target, total_size, percentage_size); /* detect short write as EOF */ if (chunk_size < transfer_size) break; } /* check final size */ if (expected_size > 0) { if (total_size != expected_size) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid size, got %" G_GSIZE_FORMAT ", " "expected %" G_GSIZE_FORMAT , total_size, expected_size); return NULL; } } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* create new image */ contents = dfu_utils_bytes_join_array (chunks); element = dfu_element_new (); dfu_element_set_contents (element, contents); return element; } static DfuElement * dfu_target_upload_element (DfuTarget *target, guint32 address, gsize expected_size, gsize maximum_size, GError **error) { DfuTargetClass *klass = DFU_TARGET_GET_CLASS (target); /* implemented as part of a superclass */ if (klass->upload_element != NULL) { return klass->upload_element (target, address, expected_size, maximum_size, error); } return dfu_target_upload_element_dfu (target, address, expected_size, maximum_size, error); } static guint32 dfu_target_get_size_of_zone (DfuTarget *target, guint16 zone) { DfuTargetPrivate *priv = GET_PRIVATE (target); guint32 len = 0; for (guint i = 0; i < priv->sectors->len; i++) { DfuSector *sector = g_ptr_array_index (priv->sectors, i); if (dfu_sector_get_zone (sector) != zone) continue; len += dfu_sector_get_size (sector); } return len; } /** * dfu_target_upload: * @target: a #DfuTarget * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY * @error: a #GError, or %NULL * * Uploads firmware from the target to the host. * * Return value: (transfer full): the uploaded image, or %NULL for error **/ DfuImage * dfu_target_upload (DfuTarget *target, DfuTargetTransferFlags flags, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuSector *sector; guint16 zone_cur; guint32 zone_size = 0; guint32 zone_last = G_MAXUINT; g_autoptr(DfuImage) image = NULL; g_return_val_if_fail (DFU_IS_TARGET (target), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* ensure populated */ if (!dfu_target_setup (target, error)) return NULL; /* can the target do this? */ if (!dfu_device_can_upload (priv->device)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "target cannot do uploading"); return NULL; } /* use correct alt */ if (!dfu_target_use_alt_setting (target, error)) return NULL; /* no open?! */ if (priv->sectors->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no sectors defined for target"); return NULL; } /* create a new image */ image = dfu_image_new (); dfu_image_set_name (image, priv->alt_name); dfu_image_set_alt_setting (image, priv->alt_setting); /* get all the sectors for the device */ for (guint i = 0; i < priv->sectors->len; i++) { g_autoptr(DfuElement) element = NULL; /* only upload to the start of any zone:sector */ sector = g_ptr_array_index (priv->sectors, i); zone_cur = dfu_sector_get_zone (sector); if (zone_cur == zone_last) continue; /* get the size of the entire continous zone */ zone_size = dfu_target_get_size_of_zone (target, zone_cur); zone_last = zone_cur; /* get the first element from the hardware */ g_debug ("starting upload from 0x%08x (0x%04x)", dfu_sector_get_address (sector), zone_size); element = dfu_target_upload_element (target, dfu_sector_get_address (sector), 0, /* expected */ zone_size, /* maximum */ error); if (element == NULL) return NULL; /* this element was uploaded okay */ dfu_image_add_element (image, element); } /* success */ return g_object_ref (image); } static gchar * _g_bytes_compare_verbose (GBytes *bytes1, GBytes *bytes2) { const guint8 *data1; const guint8 *data2; gsize length1; gsize length2; data1 = g_bytes_get_data (bytes1, &length1); data2 = g_bytes_get_data (bytes2, &length2); /* not the same length */ if (length1 != length2) { return g_strdup_printf ("got %" G_GSIZE_FORMAT " bytes, " "expected %" G_GSIZE_FORMAT, length1, length2); } /* return 00 01 02 03 */ for (guint i = 0; i < length1; i++) { if (data1[i] != data2[i]) { return g_strdup_printf ("got 0x%02x, expected 0x%02x @ 0x%04x", data1[i], data2[i], i); } } return NULL; } static gboolean dfu_target_download_element_dfu (DfuTarget *target, DfuElement *element, DfuTargetTransferFlags flags, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); GBytes *bytes; guint16 nr_chunks; guint16 transfer_size = dfu_device_get_transfer_size (priv->device); /* round up as we have to transfer incomplete blocks */ bytes = dfu_element_get_contents (element); nr_chunks = (guint) ceil ((gdouble) g_bytes_get_size (bytes) / (gdouble) transfer_size); if (nr_chunks == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "zero-length firmware"); return FALSE; } dfu_target_set_action (target, FWUPD_STATUS_DEVICE_WRITE); for (guint16 i = 0; i < nr_chunks + 1; i++) { gsize length; guint32 offset; g_autoptr(GBytes) bytes_tmp = NULL; /* caclulate the offset into the element data */ offset = i * transfer_size; /* we have to write one final zero-sized chunk for EOF */ if (i < nr_chunks) { length = g_bytes_get_size (bytes) - offset; if (length > transfer_size) length = transfer_size; bytes_tmp = g_bytes_new_from_bytes (bytes, offset, length); } else { bytes_tmp = g_bytes_new (NULL, 0); } g_debug ("writing #%04x chunk of size %" G_GSIZE_FORMAT, i, g_bytes_get_size (bytes_tmp)); if (!dfu_target_download_chunk (target, i, bytes_tmp, error)) return FALSE; /* update UI */ dfu_target_set_percentage (target, offset, g_bytes_get_size (bytes)); } /* done */ dfu_target_set_percentage_raw (target, 100); dfu_target_set_action (target, FWUPD_STATUS_IDLE); /* success */ return TRUE; } static gboolean dfu_target_download_element (DfuTarget *target, DfuElement *element, DfuTargetTransferFlags flags, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); DfuTargetClass *klass = DFU_TARGET_GET_CLASS (target); /* implemented as part of a superclass */ if (klass->download_element != NULL) { if (!klass->download_element (target, element, flags, error)) return FALSE; } else { if (!dfu_target_download_element_dfu (target, element, flags, error)) return FALSE; } /* verify */ if (flags & DFU_TARGET_TRANSFER_FLAG_VERIFY && dfu_device_has_attribute (priv->device, DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD)) { GBytes *bytes; GBytes *bytes_tmp; g_autoptr(DfuElement) element_tmp = NULL; dfu_target_set_action (target, FWUPD_STATUS_DEVICE_VERIFY); bytes = dfu_element_get_contents (element); element_tmp = dfu_target_upload_element (target, dfu_element_get_address (element), g_bytes_get_size (bytes), g_bytes_get_size (bytes), error); if (element_tmp == NULL) return FALSE; bytes_tmp = dfu_element_get_contents (element_tmp); if (g_bytes_compare (bytes_tmp, bytes) != 0) { g_autofree gchar *bytes_cmp_str = NULL; bytes_cmp_str = _g_bytes_compare_verbose (bytes_tmp, bytes); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "verify failed: %s", bytes_cmp_str); return FALSE; } dfu_target_set_action (target, FWUPD_STATUS_IDLE); } return TRUE; } /** * dfu_target_download: * @target: a #DfuTarget * @image: a #DfuImage * @flags: flags to use, e.g. %DFU_TARGET_TRANSFER_FLAG_VERIFY * @error: a #GError, or %NULL * * Downloads firmware from the host to the target, optionally verifying * the transfer. * * Return value: %TRUE for success **/ gboolean dfu_target_download (DfuTarget *target, DfuImage *image, DfuTargetTransferFlags flags, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); GPtrArray *elements; gboolean ret; g_return_val_if_fail (DFU_IS_TARGET (target), FALSE); g_return_val_if_fail (DFU_IS_IMAGE (image), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* ensure populated */ if (!dfu_target_setup (target, error)) return FALSE; /* can the target do this? */ if (!dfu_device_can_download (priv->device)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "target cannot do downloading"); return FALSE; } /* use correct alt */ if (!dfu_target_use_alt_setting (target, error)) return FALSE; /* download all elements in the image to the device */ elements = dfu_image_get_elements (image); if (elements->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no image elements"); return FALSE; } for (guint i = 0; i < elements->len; i++) { DfuElement *element = dfu_image_get_element (image, (guint8) i); g_debug ("downloading element at 0x%04x", dfu_element_get_address (element)); /* auto-detect missing firmware address -- this assumes * that the first target is the main program memory and that * there is only one element in the firmware file */ if (flags & DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC && dfu_element_get_address (element) == 0x0 && elements->len == 1 && priv->sectors->len > 0) { DfuSector *sector = g_ptr_array_index (priv->sectors, 0); g_debug ("fixing up firmware address from 0x0 to 0x%x", dfu_sector_get_address (sector)); dfu_element_set_address (element, dfu_sector_get_address (sector)); } /* download to device */ ret = dfu_target_download_element (target, element, flags, error); if (!ret) return FALSE; } /* success */ return TRUE; } /** * dfu_target_get_alt_setting: * @target: a #DfuTarget * * Gets the alternate setting to use for this interface. * * Return value: the alternative setting, typically zero **/ guint8 dfu_target_get_alt_setting (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), 0xff); return priv->alt_setting; } /** * dfu_target_get_alt_name: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Gets the alternate setting name to use for this interface. * * Return value: the alternative setting name, typically %NULL **/ const gchar * dfu_target_get_alt_name (DfuTarget *target, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), NULL); /* ensure populated */ if (!dfu_target_setup (target, error)) return NULL; /* nothing */ if (priv->alt_name == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no alt-name"); return NULL; } return priv->alt_name; } /** * dfu_target_get_alt_name_for_display: * @target: a #DfuTarget * @error: a #GError, or %NULL * * Gets the alternate setting name to use for this interface that can be * shown on the display. * * Return value: the alternative setting name **/ const gchar * dfu_target_get_alt_name_for_display (DfuTarget *target, GError **error) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), NULL); /* ensure populated */ if (!dfu_target_setup (target, error)) return NULL; /* nothing */ if (priv->alt_name_for_display == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no alt-name for display"); return NULL; } return priv->alt_name_for_display; } /** * dfu_target_get_cipher_kind: * @target: a #DfuTarget * * Gets the cipher used for data sent to this interface. * * Return value: the cipher, typically %DFU_CIPHER_KIND_NONE **/ DfuCipherKind dfu_target_get_cipher_kind (DfuTarget *target) { DfuTargetPrivate *priv = GET_PRIVATE (target); g_return_val_if_fail (DFU_IS_TARGET (target), 0); return priv->cipher_kind; } fwupd-1.0.6/plugins/dfu/dfu-target.h000066400000000000000000000075171325145456600173420ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __DFU_TARGET_H #define __DFU_TARGET_H #include #include #include #include "dfu-common.h" #include "dfu-image.h" #include "dfu-sector.h" #include "fwupd-enums.h" G_BEGIN_DECLS #define DFU_TYPE_TARGET (dfu_target_get_type ()) G_DECLARE_DERIVABLE_TYPE (DfuTarget, dfu_target, DFU, TARGET, GUsbDevice) /** * DfuTargetTransferFlags: * @DFU_TARGET_TRANSFER_FLAG_NONE: No flags set * @DFU_TARGET_TRANSFER_FLAG_VERIFY: Verify the download once complete * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID: Allow downloading images with wildcard VIDs * @DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID: Allow downloading images with wildcard PIDs * @DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER: Allow any cipher kinds to be downloaded * @DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC: Automatically detect the address to use * * The optional flags used for transfering firmware. **/ typedef enum { DFU_TARGET_TRANSFER_FLAG_NONE = 0, DFU_TARGET_TRANSFER_FLAG_VERIFY = (1 << 0), DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID = (1 << 4), DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID = (1 << 5), DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER = (1 << 6), DFU_TARGET_TRANSFER_FLAG_ADDR_HEURISTIC = (1 << 7), /*< private >*/ DFU_TARGET_TRANSFER_FLAG_LAST } DfuTargetTransferFlags; struct _DfuTargetClass { GUsbDeviceClass parent_class; void (*percentage_changed) (DfuTarget *target, guint percentage); void (*action_changed) (DfuTarget *target, FwupdStatus action); gboolean (*setup) (DfuTarget *target, GError **error); gboolean (*attach) (DfuTarget *target, GError **error); gboolean (*detach) (DfuTarget *target, GError **error); gboolean (*mass_erase) (DfuTarget *target, GError **error); DfuElement *(*upload_element) (DfuTarget *target, guint32 address, gsize expected_size, gsize maximum_size, GError **error); gboolean (*download_element) (DfuTarget *target, DfuElement *element, DfuTargetTransferFlags flags, GError **error); }; GPtrArray *dfu_target_get_sectors (DfuTarget *target); DfuSector *dfu_target_get_sector_default (DfuTarget *target); guint8 dfu_target_get_alt_setting (DfuTarget *target); const gchar *dfu_target_get_alt_name (DfuTarget *target, GError **error); const gchar *dfu_target_get_alt_name_for_display (DfuTarget *target, GError **error); DfuImage *dfu_target_upload (DfuTarget *target, DfuTargetTransferFlags flags, GError **error); gboolean dfu_target_setup (DfuTarget *target, GError **error); gboolean dfu_target_download (DfuTarget *target, DfuImage *image, DfuTargetTransferFlags flags, GError **error); gboolean dfu_target_mass_erase (DfuTarget *target, GError **error); DfuCipherKind dfu_target_get_cipher_kind (DfuTarget *target); G_END_DECLS #endif /* __DFU_TARGET_H */ fwupd-1.0.6/plugins/dfu/dfu-tool.c000066400000000000000000002067511325145456600170250ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "dfu-cipher-xtea.h" #include "dfu-device-private.h" #include "dfu-patch.h" #include "dfu-sector.h" #include "fu-device-locker.h" #include "fu-progressbar.h" #include "fwupd-error.h" typedef struct { GCancellable *cancellable; GPtrArray *cmd_array; gboolean force; gchar *device_vid_pid; guint16 transfer_size; FuProgressbar *progressbar; FuQuirks *quirks; } DfuToolPrivate; static void dfu_tool_print_indent (const gchar *title, const gchar *message, guint indent) { for (gsize i = 0; i < indent; i++) g_print (" "); g_print ("%s:", title); for (gsize i = strlen (title) + indent; i < 15; i++) g_print (" "); g_print ("%s\n", message); } static void dfu_tool_private_free (DfuToolPrivate *priv) { if (priv == NULL) return; g_free (priv->device_vid_pid); g_object_unref (priv->cancellable); g_object_unref (priv->quirks); if (priv->cmd_array != NULL) g_ptr_array_unref (priv->cmd_array); g_free (priv); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(DfuToolPrivate, dfu_tool_private_free) typedef gboolean (*FuUtilPrivateCb) (DfuToolPrivate *util, gchar **values, GError **error); typedef struct { gchar *name; gchar *arguments; gchar *description; FuUtilPrivateCb callback; } FuUtilItem; static void dfu_tool_item_free (FuUtilItem *item) { g_free (item->name); g_free (item->arguments); g_free (item->description); g_free (item); } static gint dfu_tool_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2) { return g_strcmp0 ((*item1)->name, (*item2)->name); } static void dfu_tool_add (GPtrArray *array, const gchar *name, const gchar *arguments, const gchar *description, FuUtilPrivateCb callback) { g_auto(GStrv) names = NULL; g_return_if_fail (name != NULL); g_return_if_fail (description != NULL); g_return_if_fail (callback != NULL); /* add each one */ names = g_strsplit (name, ",", -1); for (guint i = 0; names[i] != NULL; i++) { FuUtilItem *item = g_new0 (FuUtilItem, 1); item->name = g_strdup (names[i]); if (i == 0) { item->description = g_strdup (description); } else { /* TRANSLATORS: this is a command alias, e.g. 'get-devices' */ item->description = g_strdup_printf (_("Alias to %s"), names[0]); } item->arguments = g_strdup (arguments); item->callback = callback; g_ptr_array_add (array, item); } } static gchar * dfu_tool_get_descriptions (GPtrArray *array) { gsize len; const gsize max_len = 31; FuUtilItem *item; GString *string; /* print each command */ string = g_string_new (""); for (guint i = 0; i < array->len; i++) { item = g_ptr_array_index (array, i); g_string_append (string, " "); g_string_append (string, item->name); len = strlen (item->name) + 2; if (item->arguments != NULL) { g_string_append (string, " "); g_string_append (string, item->arguments); len += strlen (item->arguments) + 1; } if (len < max_len) { for (guint j = len; j < max_len + 1; j++) g_string_append_c (string, ' '); g_string_append (string, item->description); g_string_append_c (string, '\n'); } else { g_string_append_c (string, '\n'); for (guint j = 0; j < max_len + 1; j++) g_string_append_c (string, ' '); g_string_append (string, item->description); g_string_append_c (string, '\n'); } } /* remove trailing newline */ if (string->len > 0) g_string_set_size (string, string->len - 1); return g_string_free (string, FALSE); } static gboolean dfu_tool_run (DfuToolPrivate *priv, const gchar *command, gchar **values, GError **error) { /* find command */ for (guint i = 0; i < priv->cmd_array->len; i++) { FuUtilItem *item = g_ptr_array_index (priv->cmd_array, i); if (g_strcmp0 (item->name, command) == 0) return item->callback (priv, values, error); } /* not found */ g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, /* TRANSLATORS: error message */ _("Command not found")); return FALSE; } static DfuDevice * dfu_tool_get_default_device (DfuToolPrivate *priv, GError **error) { g_autoptr(GUsbContext) usb_context = NULL; g_autoptr(GPtrArray) devices = NULL; /* get all the DFU devices */ usb_context = g_usb_context_new (error); if (usb_context == NULL) return NULL; g_usb_context_enumerate (usb_context); /* we specified it manually */ if (priv->device_vid_pid != NULL) { gchar *tmp; guint64 pid; guint64 vid; g_autoptr(DfuDevice) device = NULL; g_autoptr(GUsbDevice) usb_device = NULL; /* parse */ vid = g_ascii_strtoull (priv->device_vid_pid, &tmp, 16); if (vid == 0 || vid > G_MAXUINT16) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid format of VID:PID"); return NULL; } if (tmp[0] != ':') { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid format of VID:PID"); return NULL; } pid = g_ascii_strtoull (tmp + 1, NULL, 16); if (pid == 0 || pid > G_MAXUINT16) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid format of VID:PID"); return NULL; } /* find device */ usb_device = g_usb_context_find_by_vid_pid (usb_context, (guint16) vid, (guint16) pid, error); if (usb_device == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no device matches for %04x:%04x", (guint) vid, (guint) pid); return NULL; } device = dfu_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), priv->quirks); dfu_device_set_usb_context (device, usb_context); return device; } /* auto-detect first device */ devices = g_usb_context_get_devices (usb_context); for (guint i = 0; i < devices->len; i++) { GUsbDevice *usb_device = g_ptr_array_index (devices, i); g_autoptr(DfuDevice) device = dfu_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), priv->quirks); dfu_device_set_usb_context (device, usb_context); if (fu_usb_device_probe (FU_USB_DEVICE (device), NULL)) return g_steal_pointer (&device); } /* failed */ g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no DFU devices found"); return NULL; } static gboolean dfu_tool_set_vendor (DfuToolPrivate *priv, gchar **values, GError **error) { guint64 tmp; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE VID" " -- e.g. `firmware.dfu 273f"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* parse VID */ tmp = g_ascii_strtoull (values[1], NULL, 16); if (tmp == 0 || tmp > G_MAXUINT16) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse VID '%s'", values[1]); return FALSE; } dfu_firmware_set_vid (firmware, (guint16) tmp); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_product (DfuToolPrivate *priv, gchar **values, GError **error) { guint64 tmp; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE PID" " -- e.g. `firmware.dfu 1004"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* parse VID */ tmp = g_ascii_strtoull (values[1], NULL, 16); if (tmp == 0 || tmp > G_MAXUINT16) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse PID '%s'", values[1]); return FALSE; } dfu_firmware_set_pid (firmware, (guint16) tmp); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static guint16 dfu_tool_parse_release_uint16 (const gchar *version, GError **error) { gchar *endptr = NULL; guint64 tmp_lsb, tmp_msb; g_auto(GStrv) split = g_strsplit (version, ".", -1); /* check if valid */ if (g_strv_length (split) != 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid format, expected 'major.minor'"); return 0xffff; } /* parse MSB & LSB */ tmp_msb = g_ascii_strtoull (split[0], &endptr, 10); if (tmp_msb > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse version '%s'", version); return 0xffff; } tmp_lsb = g_ascii_strtoull (split[1], &endptr, 10); if (tmp_lsb > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse version '%s'", version); return 0xffff; } return (tmp_msb << 8) + tmp_lsb; } static gboolean dfu_tool_set_release (DfuToolPrivate *priv, gchar **values, GError **error) { gchar *endptr = NULL; guint64 tmp; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE RELEASE" " -- e.g. `firmware.dfu ffff"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* parse release */ tmp = g_ascii_strtoull (values[1], &endptr, 16); if (tmp > G_MAXUINT16 || endptr[0] != '\0') { tmp = dfu_tool_parse_release_uint16 (values[1], error); if (tmp == 0xffff) return FALSE; } dfu_firmware_set_release (firmware, (guint16) tmp); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static GBytes * dfu_tool_parse_hex_string (const gchar *val, GError **error) { gsize result_size; g_autofree guint8 *result = NULL; /* sanity check */ if (val == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "nothing to parse"); return NULL; } /* parse each hex byte */ result_size = strlen (val) / 2; result = g_malloc (result_size); for (guint i = 0; i < result_size; i++) { gchar buf[3] = { "xx" }; gchar *endptr = NULL; guint64 tmp; /* copy two bytes and parse as hex */ memcpy (buf, val + (i * 2), 2); tmp = g_ascii_strtoull (buf, &endptr, 16); if (tmp > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to parse '%s'", val); return NULL; } result[i] = tmp; } return g_bytes_new (result, result_size); } static guint dfu_tool_bytes_replace (GBytes *data, GBytes *search, GBytes *replace) { gsize data_sz; gsize replace_sz; gsize search_sz; guint8 *data_buf; guint8 *replace_buf; guint8 *search_buf; guint cnt = 0; data_buf = (gpointer) g_bytes_get_data (data, &data_sz); search_buf = (gpointer) g_bytes_get_data (search, &search_sz); replace_buf = (gpointer) g_bytes_get_data (replace, &replace_sz); g_return_val_if_fail (search_sz == replace_sz, FALSE); /* find and replace each one */ for (gsize i = 0; i < data_sz - search_sz; i++) { if (memcmp (data_buf + i, search_buf, search_sz) == 0) { g_print ("Replacing %" G_GSIZE_FORMAT " bytes @0x%04x\n", replace_sz, (guint) i); memcpy (data_buf + i, replace_buf, replace_sz); i += replace_sz; cnt++; } } return cnt; } static gboolean dfu_tool_patch_dump (DfuToolPrivate *priv, gchar **values, GError **error) { gsize sz = 0; g_autofree gchar *data = NULL; g_autofree gchar *str = NULL; g_autoptr(DfuPatch) patch = NULL; g_autoptr(GBytes) blob = NULL; if (g_strv_length (values) != 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE.bdiff"); return FALSE; } /* load file */ if (!g_file_get_contents (values[0], &data, &sz, error)) return FALSE; blob = g_bytes_new (data, sz); /* dump the patch to disk */ patch = dfu_patch_new (); if (!dfu_patch_import (patch, blob, error)) return FALSE; str = dfu_patch_to_string (patch); g_print ("%s\n", str); /* success */ return TRUE; } static gboolean dfu_tool_patch_apply (DfuToolPrivate *priv, gchar **values, GError **error) { DfuPatchApplyFlags flags = DFU_PATCH_APPLY_FLAG_NONE; const gchar *data_new; gsize sz_diff = 0; gsize sz_new = 0; gsize sz_old = 0; g_autofree gchar *data_diff = NULL; g_autofree gchar *data_old = NULL; g_autoptr(DfuPatch) patch = NULL; g_autoptr(GBytes) blob_diff = NULL; g_autoptr(GBytes) blob_new = NULL; g_autoptr(GBytes) blob_old = NULL; if (g_strv_length (values) != 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected OLD.bin OUT.bdiff NEW.bin"); return FALSE; } /* allow the user to shoot themselves in the foot */ if (priv->force) flags |= DFU_PATCH_APPLY_FLAG_IGNORE_CHECKSUM; if (!g_file_get_contents (values[0], &data_old, &sz_old, error)) return FALSE; blob_old = g_bytes_new (data_old, sz_old); if (!g_file_get_contents (values[1], &data_diff, &sz_diff, error)) return FALSE; blob_diff = g_bytes_new (data_diff, sz_diff); patch = dfu_patch_new (); if (!dfu_patch_import (patch, blob_diff, error)) return FALSE; blob_new = dfu_patch_apply (patch, blob_old, flags, error); if (blob_new == NULL) return FALSE; /* save to disk */ data_new = g_bytes_get_data (blob_new, &sz_new); return g_file_set_contents (values[2], data_new, sz_new, error); } static gboolean dfu_tool_patch_create (DfuToolPrivate *priv, gchar **values, GError **error) { const gchar *data_diff; gsize sz_diff = 0; gsize sz_new = 0; gsize sz_old = 0; g_autofree gchar *data_new = NULL; g_autofree gchar *data_old = NULL; g_autoptr(DfuPatch) patch = NULL; g_autoptr(GBytes) blob_diff = NULL; g_autoptr(GBytes) blob_new = NULL; g_autoptr(GBytes) blob_old = NULL; if (g_strv_length (values) != 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected OLD.bin NEW.bin OUT.bdiff"); return FALSE; } /* read files */ if (!g_file_get_contents (values[0], &data_old, &sz_old, error)) return FALSE; blob_old = g_bytes_new (data_old, sz_old); if (!g_file_get_contents (values[1], &data_new, &sz_new, error)) return FALSE; blob_new = g_bytes_new (data_new, sz_new); /* create patch */ patch = dfu_patch_new (); if (!dfu_patch_create (patch, blob_old, blob_new, error)) return FALSE; blob_diff = dfu_patch_export (patch, error); if (blob_diff == NULL) return FALSE; /* save to disk */ data_diff = g_bytes_get_data (blob_diff, &sz_diff); return g_file_set_contents (values[2], data_diff, sz_diff, error); } static gboolean dfu_tool_replace_data (DfuToolPrivate *priv, gchar **values, GError **error) { GPtrArray *images; guint cnt = 0; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GBytes) data_search = NULL; g_autoptr(GBytes) data_replace = NULL; /* check args */ if (g_strv_length (values) < 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE SEARCH REPLACE" " -- e.g. `firmware.dfu deadbeef beefdead"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* parse hex values */ data_search = dfu_tool_parse_hex_string (values[1], error); if (data_search == NULL) return FALSE; data_replace = dfu_tool_parse_hex_string (values[2], error); if (data_replace == NULL) return FALSE; if (g_bytes_get_size (data_search) != g_bytes_get_size (data_replace)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "search and replace were different sizes"); return FALSE; } /* get each data segment */ images = dfu_firmware_get_images (firmware); for (guint i = 0; i < images->len; i++) { DfuImage *image = g_ptr_array_index (images, i); GPtrArray *elements = dfu_image_get_elements (image); for (guint j = 0; j < elements->len; j++) { DfuElement *element = g_ptr_array_index (elements, j); GBytes *contents = dfu_element_get_contents (element); if (contents == NULL) continue; cnt += dfu_tool_bytes_replace (contents, data_search, data_replace); } } /* nothing done */ if (cnt == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "search string was not found"); return FALSE; } /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_target_size (DfuToolPrivate *priv, gchar **values, GError **error) { DfuElement *element; DfuImage *image; gchar *endptr; guint64 padding_char = 0x00; guint64 target_size; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE SIZE [VAL]" " -- e.g. `firmware.dfu 8000 ff"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* doesn't make sense for DfuSe */ if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_DFUSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot pad DfuSe image, try DFU"); return FALSE; } /* parse target size */ target_size = g_ascii_strtoull (values[1], &endptr, 16); if (target_size > 0xffff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse target size '%s'", values[1]); return FALSE; } /* parse padding value */ if (g_strv_length (values) > 3) { padding_char = g_ascii_strtoull (values[2], &endptr, 16); if (padding_char > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse padding value '%s'", values[2]); return FALSE; } } /* this has to exist */ if (target_size > 0) { image = dfu_firmware_get_image_default (firmware); g_assert (image != NULL); element = dfu_image_get_element (image, 0); dfu_element_set_padding_value (element, (guint8) padding_char); dfu_element_set_target_size (element, (guint32) target_size); } /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_address (DfuToolPrivate *priv, gchar **values, GError **error) { DfuElement *element; DfuFirmwareFormat firmware_format; DfuImage *image; gchar *endptr; guint64 address; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE ADDR" " -- e.g. `firmware.dfu 8000"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* only makes sense for DfuSe */ firmware_format = dfu_firmware_get_format (firmware); if (firmware_format != DFU_FIRMWARE_FORMAT_DFUSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot set address of %s image, try DfuSe", dfu_firmware_format_to_string (firmware_format)); return FALSE; } /* parse address */ address = g_ascii_strtoull (values[1], &endptr, 16); if (address > G_MAXUINT32 || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse address '%s'", values[1]); return FALSE; } /* this has to exist */ if (address > 0) { image = dfu_firmware_get_image_default (firmware); g_assert (image != NULL); element = dfu_image_get_element (image, 0); dfu_element_set_address (element, (guint32) address); } /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_metadata (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE KEY VALUE" " -- e.g. `firmware.dfu Licence GPL-2.0+"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* doesn't make sense for non-DFU */ if (dfu_firmware_get_format (firmware) == DFU_FIRMWARE_FORMAT_RAW) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Only possible on DFU/DfuSe images, try convert"); return FALSE; } /* set metadata */ dfu_firmware_set_metadata (firmware, values[1], values[2]); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_alt_setting (DfuToolPrivate *priv, gchar **values, GError **error) { DfuImage *image; guint64 tmp; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE ALT-ID" " -- e.g. `firmware.dfu 1"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* doesn't make sense for non-DfuSe */ if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Only possible on DfuSe images, try convert"); return FALSE; } /* parse VID */ tmp = g_ascii_strtoull (values[1], NULL, 10); if (tmp == 0 || tmp > G_MAXUINT8) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse alternative setting '%s'", values[1]); return FALSE; } image = dfu_firmware_get_image_default (firmware); if (image == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "found no image '%s'", values[1]); return FALSE; } dfu_image_set_alt_setting (image, (guint8) tmp); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_set_alt_setting_name (DfuToolPrivate *priv, gchar **values, GError **error) { DfuImage *image; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILE ALT-NAME" " -- e.g. `firmware.dfu ST"); return FALSE; } /* open */ file = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* doesn't make sense for non-DfuSe */ if (dfu_firmware_get_format (firmware) != DFU_FIRMWARE_FORMAT_DFUSE) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Only possible on DfuSe images, try convert"); return FALSE; } /* parse VID */ image = dfu_firmware_get_image_default (firmware); if (image == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "found no image '%s'", values[1]); return FALSE; } dfu_image_set_name (image, values[1]); /* write out new file */ return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_merge (DfuToolPrivate *priv, gchar **values, GError **error) { guint16 pid = 0xffff; guint16 rel = 0xffff; guint16 vid = 0xffff; g_autofree gchar *str_debug = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FILE-OUT FILE1 FILE2 [FILE3...]" " -- e.g. `combined.dfu lib.dfu app.dfu`"); return FALSE; } /* parse source files */ firmware = dfu_firmware_new (); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFUSE); for (guint i = 1; values[i] != NULL; i++) { GPtrArray *images; g_autoptr(GFile) file_tmp = NULL; g_autoptr(DfuFirmware) firmware_tmp = NULL; /* open up source */ file_tmp = g_file_new_for_path (values[i]); firmware_tmp = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware_tmp, file_tmp, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* check same vid:pid:rel */ if (vid != 0xffff && dfu_firmware_get_vid (firmware_tmp) != vid) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Vendor ID was already set as " "0x%04x, %s is 0x%04x", vid, values[i], dfu_firmware_get_vid (firmware_tmp)); return FALSE; } if (pid != 0xffff && dfu_firmware_get_pid (firmware_tmp) != pid) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Product ID was already set as " "0x%04x, %s is 0x%04x", pid, values[i], dfu_firmware_get_pid (firmware_tmp)); return FALSE; } if (rel != 0xffff && dfu_firmware_get_release (firmware_tmp) != rel) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Release was already set as " "0x%04x, %s is 0x%04x", rel, values[i], dfu_firmware_get_release (firmware_tmp)); return FALSE; } /* add all images to destination */ images = dfu_firmware_get_images (firmware_tmp); for (guint j = 0; j < images->len; j++) { DfuImage *image; guint8 alt_id; /* verify the alt-setting does not already exist */ image = g_ptr_array_index (images, j); alt_id = dfu_image_get_alt_setting (image); g_print ("Adding alternative setting ID of 0x%02x\n", alt_id); if (dfu_firmware_get_image (firmware, alt_id) != NULL) { if (!priv->force) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "The alternative setting ID " "of 0x%02x has already been added", alt_id); return FALSE; } g_print ("WARNING: The alternative setting " "ID of 0x%02x has already been added\n", alt_id); } /* add to destination */ dfu_firmware_add_image (firmware, image); } /* save last IDs */ vid = dfu_firmware_get_vid (firmware_tmp); pid = dfu_firmware_get_pid (firmware_tmp); rel = dfu_firmware_get_release (firmware_tmp); } /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_print ("New merged file:\n%s\n", str_debug); /* write out new file */ file = g_file_new_for_path (values[0]); return dfu_firmware_write_file (firmware, file, error); } static gboolean dfu_tool_convert (DfuToolPrivate *priv, gchar **values, GError **error) { DfuFirmwareFormat format; guint argc = g_strv_length (values); g_autofree gchar *str_debug = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file_in = NULL; g_autoptr(GFile) file_out = NULL; /* check args */ if (argc != 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FORMAT FILE-IN FILE-OUT" " -- e.g. `dfu firmware.hex firmware.dfu`"); return FALSE; } /* parse file */ file_in = g_file_new_for_path (values[1]); file_out = g_file_new_for_path (values[2]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file_in, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* set output format */ format = dfu_firmware_format_from_string (values[0]); dfu_firmware_set_format (firmware, format); if (format == DFU_FIRMWARE_FORMAT_UNKNOWN) { g_autoptr(GString) tmp = g_string_new (NULL); for (guint i = 1; i < DFU_FIRMWARE_FORMAT_LAST; i++) { if (tmp->len > 0) g_string_append (tmp, "|"); g_string_append (tmp, dfu_firmware_format_to_string (i)); } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "unknown format '%s', expected [%s]", values[0], tmp->str); return FALSE; } /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_debug ("DFU: %s", str_debug); /* write out new file */ return dfu_firmware_write_file (firmware, file_out, error); } static gboolean dfu_tool_attach (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(DfuDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; return dfu_device_attach (device, error); } static gboolean dfu_tool_reset (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(DfuDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh (device, error)) return FALSE; return dfu_device_reset (device, error); } static void fu_tool_action_changed_cb (FuDevice *device, GParamSpec *pspec, DfuToolPrivate *priv) { fu_progressbar_update (priv->progressbar, fu_device_get_status (device), fu_device_get_progress (device)); } static gboolean dfu_tool_read_alt (DfuToolPrivate *priv, gchar **values, GError **error) { DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE; g_autofree gchar *str_debug = NULL; g_autoptr(DfuDevice) device = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(DfuImage) image = NULL; g_autoptr(DfuTarget) target = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID"); return FALSE; } /* open correct device */ device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; if (priv->transfer_size > 0) dfu_device_set_transfer_size (device, priv->transfer_size); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh (device, error)) return FALSE; /* set up progress */ g_signal_connect (device, "notify::status", G_CALLBACK (fu_tool_action_changed_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_tool_action_changed_cb), priv); /* APP -> DFU */ if (dfu_device_is_runtime (device)) { g_debug ("detaching"); if (!dfu_device_detach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; } /* transfer */ target = dfu_device_get_target_by_alt_name (device, values[1], NULL); if (target == NULL) { gchar *endptr; guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10); if (tmp > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse alt-setting '%s'", values[1]); return FALSE; } target = dfu_device_get_target_by_alt_setting (device, (guint8) tmp, error); if (target == NULL) return FALSE; } /* do transfer */ image = dfu_target_upload (target, flags, error); if (image == NULL) return FALSE; /* do host reset */ if (!dfu_device_attach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* create new firmware object */ firmware = dfu_firmware_new (); dfu_firmware_set_format (firmware, DFU_FIRMWARE_FORMAT_DFU); dfu_firmware_set_vid (firmware, dfu_device_get_runtime_vid (device)); dfu_firmware_set_pid (firmware, dfu_device_get_runtime_pid (device)); dfu_firmware_add_image (firmware, image); /* save file */ file = g_file_new_for_path (values[0]); if (!dfu_firmware_write_file (firmware, file, error)) return FALSE; /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_debug ("DFU: %s", str_debug); /* success */ g_print ("%u bytes successfully uploaded from device\n", dfu_image_get_size (image)); return TRUE; } static gboolean dfu_tool_read (DfuToolPrivate *priv, gchar **values, GError **error) { DfuFirmwareFormat format; DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_NONE; g_autofree gchar *str_debug = NULL; g_autoptr(DfuDevice) device = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) == 1) { /* guess output format */ if (g_str_has_suffix (values[0], ".dfu")) { format = DFU_FIRMWARE_FORMAT_DFU; } else if (g_str_has_suffix (values[0], ".bin") || g_str_has_suffix (values[0], ".rom")) { format = DFU_FIRMWARE_FORMAT_RAW; } else if (g_str_has_suffix (values[0], ".ihex") || g_str_has_suffix (values[0], ".hex")) { format = DFU_FIRMWARE_FORMAT_INTEL_HEX; } else { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Could not guess a file format"); return FALSE; } } else if (g_strv_length (values) == 2) { format = dfu_firmware_format_from_string (values[1]); if (format == DFU_FIRMWARE_FORMAT_UNKNOWN) { g_autoptr(GString) tmp = g_string_new (NULL); for (guint i = 1; i < DFU_FIRMWARE_FORMAT_LAST; i++) { if (tmp->len > 0) g_string_append (tmp, "|"); g_string_append (tmp, dfu_firmware_format_to_string (i)); } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "unknown format '%s', expected [%s]", values[0], tmp->str); return FALSE; } } else { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILENAME [FORMAT]"); return FALSE; } /* open correct device */ device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh (device, error)) return FALSE; /* APP -> DFU */ if (dfu_device_is_runtime (device)) { if (!dfu_device_detach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) { return FALSE; } } /* transfer */ g_signal_connect (device, "notify::status", G_CALLBACK (fu_tool_action_changed_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_tool_action_changed_cb), priv); firmware = dfu_device_upload (device, flags, error); if (firmware == NULL) return FALSE; /* do host reset */ if (!dfu_device_attach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* save file */ file = g_file_new_for_path (values[0]); dfu_firmware_set_format (firmware, format); if (!dfu_firmware_write_file (firmware, file, error)) return FALSE; /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_debug ("DFU: %s", str_debug); /* success */ g_print ("%u bytes successfully uploaded from device\n", dfu_firmware_get_size (firmware)); return TRUE; } static gchar * dfu_tool_get_device_string (DfuToolPrivate *priv, DfuDevice *device) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); g_autoptr(FuDeviceLocker) locker = NULL; /* open if required, and get status */ if (usb_device == NULL) { return g_strdup_printf ("%04x:%04x [%s]", dfu_device_get_runtime_vid (device), dfu_device_get_runtime_pid (device), "removed"); } if (!fu_usb_device_is_open (FU_USB_DEVICE (device))) { g_autoptr(GError) error = NULL; locker = fu_device_locker_new (device, &error); if (locker == NULL) { return g_strdup_printf ("%04x:%04x [%s]", dfu_device_get_vid (device), dfu_device_get_pid (device), error->message); } if (!dfu_device_refresh (device, &error)) return FALSE; } return g_strdup_printf ("%04x:%04x [%s:%s]", dfu_device_get_vid (device), dfu_device_get_pid (device), dfu_state_to_string (dfu_device_get_state (device)), dfu_status_to_string (dfu_device_get_status (device))); } static void dfu_tool_device_added_cb (GUsbContext *context, DfuDevice *device, gpointer user_data) { DfuToolPrivate *priv = (DfuToolPrivate *) user_data; g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device); /* TRANSLATORS: this is when a device is hotplugged */ dfu_tool_print_indent (_("Added"), tmp, 0); } static void dfu_tool_device_removed_cb (GUsbContext *context, DfuDevice *device, gpointer user_data) { DfuToolPrivate *priv = (DfuToolPrivate *) user_data; g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device); /* TRANSLATORS: this is when a device is hotplugged */ dfu_tool_print_indent (_("Removed"), tmp, 0); } static void dfu_tool_device_changed_cb (GUsbContext *context, DfuDevice *device, gpointer user_data) { DfuToolPrivate *priv = (DfuToolPrivate *) user_data; g_autofree gchar *tmp = dfu_tool_get_device_string (priv, device); /* TRANSLATORS: this is when a device is hotplugged */ dfu_tool_print_indent (_("Changed"), tmp, 0); } static void dfu_tool_watch_cancelled_cb (GCancellable *cancellable, gpointer user_data) { GMainLoop *loop = (GMainLoop *) user_data; /* TRANSLATORS: this is when a device ctrl+c's a watch */ g_print ("%s\n", _("Cancelled")); g_main_loop_quit (loop); } static guint8 * dfu_tool_get_firmware_contents_default (DfuFirmware *firmware, gsize *length, GError **error) { DfuElement *element; DfuImage *image; GBytes *contents; image = dfu_firmware_get_image_default (firmware); if (image == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "No default image"); return NULL; } element = dfu_image_get_element (image, 0); if (element == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "No default element"); return NULL; } contents = dfu_element_get_contents (element); if (contents == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "No image contents"); return NULL; } return (guint8 *) g_bytes_get_data (contents, length); } static gboolean dfu_tool_encrypt (DfuToolPrivate *priv, gchar **values, GError **error) { gsize len; guint8 *data; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file_in = NULL; g_autoptr(GFile) file_out = NULL; /* check args */ if (g_strv_length (values) < 4) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FILENAME-IN FILENAME-OUT TYPE KEY" " -- e.g. firmware.dfu firmware.xdfu xtea deadbeef"); return FALSE; } /* check extensions */ if (!priv->force) { if (!g_str_has_suffix (values[0], ".dfu")) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid filename, expected *.dfu"); return FALSE; } if (!g_str_has_suffix (values[1], ".xdfu")) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid filename, expected *.xdfu"); return FALSE; } } /* open */ file_in = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file_in, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* get data */ data = dfu_tool_get_firmware_contents_default (firmware, &len, error); if (data == NULL) return FALSE; /* check type */ if (g_strcmp0 (values[2], "xtea") == 0) { if (!dfu_cipher_encrypt_xtea (values[3], data, (guint32) len, error)) return FALSE; dfu_firmware_set_metadata (firmware, DFU_METADATA_KEY_CIPHER_KIND, "XTEA"); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "unknown type '%s', expected [xtea]", values[2]); return FALSE; } /* write out new file */ file_out = g_file_new_for_path (values[1]); g_debug ("wrote %s", values[1]); return dfu_firmware_write_file (firmware, file_out, error); } static gboolean dfu_tool_decrypt (DfuToolPrivate *priv, gchar **values, GError **error) { gsize len; guint8 *data; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file_in = NULL; g_autoptr(GFile) file_out = NULL; /* check args */ if (g_strv_length (values) < 4) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FILENAME-IN FILENAME-OUT TYPE KEY" " -- e.g. firmware.xdfu firmware.dfu xtea deadbeef"); return FALSE; } /* check extensions */ if (!priv->force) { if (!g_str_has_suffix (values[0], ".xdfu")) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid filename, expected *.xdfu"); return FALSE; } if (!g_str_has_suffix (values[1], ".dfu")) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Invalid filename, expected *.dfu"); return FALSE; } } /* open */ file_in = g_file_new_for_path (values[0]); firmware = dfu_firmware_new (); if (!dfu_firmware_parse_file (firmware, file_in, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) { return FALSE; } /* get data */ data = dfu_tool_get_firmware_contents_default (firmware, &len, error); if (data == NULL) return FALSE; /* check type */ if (g_strcmp0 (values[2], "xtea") == 0) { if (!dfu_cipher_decrypt_xtea (values[3], data, (guint32) len, error)) return FALSE; dfu_firmware_remove_metadata (firmware, DFU_METADATA_KEY_CIPHER_KIND); } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "unknown type '%s', expected [xtea]", values[2]); return FALSE; } /* write out new file */ file_out = g_file_new_for_path (values[1]); g_debug ("wrote %s", values[1]); return dfu_firmware_write_file (firmware, file_out, error); } static gboolean dfu_tool_watch (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(GUsbContext) usb_context = NULL; g_autoptr(GMainLoop) loop = NULL; g_autoptr(GPtrArray) devices = NULL; /* get all the DFU devices */ usb_context = g_usb_context_new (error); if (usb_context == NULL) return FALSE; g_usb_context_enumerate (usb_context); /* print what's already attached */ devices = g_usb_context_get_devices (usb_context); for (guint i = 0; i < devices->len; i++) { DfuDevice *device = g_ptr_array_index (devices, i); dfu_tool_device_added_cb (usb_context, device, priv); } /* watch for any hotplugged device */ loop = g_main_loop_new (NULL, FALSE); g_signal_connect (usb_context, "device-added", G_CALLBACK (dfu_tool_device_added_cb), priv); g_signal_connect (usb_context, "device-removed", G_CALLBACK (dfu_tool_device_removed_cb), priv); g_signal_connect (usb_context, "device-changed", G_CALLBACK (dfu_tool_device_changed_cb), priv); g_signal_connect (priv->cancellable, "cancelled", G_CALLBACK (dfu_tool_watch_cancelled_cb), loop); g_main_loop_run (loop); return TRUE; } static gboolean dfu_tool_dump (DfuToolPrivate *priv, gchar **values, GError **error) { DfuFirmwareParseFlags flags = DFU_FIRMWARE_PARSE_FLAG_NONE; /* check args */ if (g_strv_length (values) < 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILENAME"); return FALSE; } /* dump corrupt files */ if (priv->force) { flags |= DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST; flags |= DFU_FIRMWARE_PARSE_FLAG_NO_VERSION_TEST; } /* open files */ for (guint i = 0; values[i] != NULL; i++) { g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GError) error_local = NULL; /* dump to screen */ g_print ("Loading %s:\n", values[i]); firmware = dfu_firmware_new (); file = g_file_new_for_path (values[i]); if (!dfu_firmware_parse_file (firmware, file, flags, &error_local)) { g_print ("Failed to load firmware: %s\n", error_local->message); continue; } g_print ("%s\n", dfu_firmware_to_string (firmware)); } return TRUE; } static gboolean dfu_tool_write_alt (DfuToolPrivate *priv, gchar **values, GError **error) { DfuImage *image; DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY; g_autofree gchar *str_debug = NULL; g_autoptr(DfuDevice) device = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(DfuTarget) target = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected " "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID " "[IMAGE-ALT-NAME|IMAGE-ALT-ID]"); return FALSE; } /* open file */ firmware = dfu_firmware_new (); file = g_file_new_for_path (values[0]); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) return FALSE; /* open correct device */ device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; if (priv->transfer_size > 0) dfu_device_set_transfer_size (device, priv->transfer_size); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh (device, error)) return FALSE; /* set up progress */ g_signal_connect (device, "notify::status", G_CALLBACK (fu_tool_action_changed_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_tool_action_changed_cb), priv); /* APP -> DFU */ if (dfu_device_is_runtime (device)) { g_debug ("detaching"); if (!dfu_device_detach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, 5000, error)) return FALSE; } /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_debug ("DFU: %s", str_debug); /* get correct target on device */ target = dfu_device_get_target_by_alt_name (device, values[1], NULL); if (target == NULL) { gchar *endptr; guint64 tmp = g_ascii_strtoull (values[1], &endptr, 10); if (tmp > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse alt-setting '%s'", values[1]); return FALSE; } target = dfu_device_get_target_by_alt_setting (device, (guint8) tmp, error); if (target == NULL) return FALSE; } /* allow overriding the firmware alt-setting */ if (g_strv_length (values) > 2) { image = dfu_firmware_get_image_by_name (firmware, values[2]); if (image == NULL) { gchar *endptr; guint64 tmp = g_ascii_strtoull (values[2], &endptr, 10); if (tmp > 0xff || endptr[0] != '\0') { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Failed to parse image alt-setting '%s'", values[2]); return FALSE; } image = dfu_firmware_get_image (firmware, (guint8) tmp); if (image == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "could not locate image in firmware for %02x", (guint) tmp); return FALSE; } } } else { g_print ("WARNING: Using default firmware image\n"); image = dfu_firmware_get_image_default (firmware); if (image == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no default image"); return FALSE; } } /* allow forcing firmware kinds */ if (priv->force) { flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER; } /* transfer */ if (!dfu_target_download (target, image, flags, error)) return FALSE; /* do host reset */ if (!dfu_device_attach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* success */ g_print ("%u bytes successfully downloaded to device\n", dfu_image_get_size (image)); return TRUE; } static gboolean dfu_tool_write (DfuToolPrivate *priv, gchar **values, GError **error) { DfuTargetTransferFlags flags = DFU_TARGET_TRANSFER_FLAG_VERIFY; g_autofree gchar *str_debug = NULL; g_autoptr(DfuDevice) device = NULL; g_autoptr(DfuFirmware) firmware = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GFile) file = NULL; /* check args */ if (g_strv_length (values) < 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments, expected FILENAME"); return FALSE; } /* open file */ firmware = dfu_firmware_new (); file = g_file_new_for_path (values[0]); if (!dfu_firmware_parse_file (firmware, file, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) return FALSE; /* open correct device */ device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh (device, error)) return FALSE; /* print the new object */ str_debug = dfu_firmware_to_string (firmware); g_debug ("DFU: %s", str_debug); /* APP -> DFU */ if (dfu_device_is_runtime (device)) { if (!dfu_device_detach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) { return FALSE; } } /* allow wildcards */ if (priv->force) { flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID; flags |= DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID; flags |= DFU_TARGET_TRANSFER_FLAG_ANY_CIPHER; } /* transfer */ g_signal_connect (device, "notify::status", G_CALLBACK (fu_tool_action_changed_cb), priv); g_signal_connect (device, "notify::progress", G_CALLBACK (fu_tool_action_changed_cb), priv); if (!dfu_device_download (device, firmware, flags, error)) return FALSE; /* do host reset */ if (!dfu_device_attach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* success */ g_print ("%u bytes successfully downloaded to device\n", dfu_firmware_get_size (firmware)); return TRUE; } static void dfu_tool_list_target (DfuTarget *target) { DfuCipherKind cipher_kind; GPtrArray *sectors; const gchar *tmp; g_autofree gchar *alt_id = NULL; g_autoptr(GError) error_local = NULL; /* TRANSLATORS: the identifier name please */ alt_id = g_strdup_printf ("%i", dfu_target_get_alt_setting (target)); dfu_tool_print_indent (_("ID"), alt_id, 1); /* this is optional */ tmp = dfu_target_get_alt_name_for_display (target, &error_local); if (tmp != NULL) { /* TRANSLATORS: interface name, e.g. "Flash" */ dfu_tool_print_indent (_("Name"), tmp, 2); } else if (!g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND)) { g_autofree gchar *str = NULL; str = g_strdup_printf ("Error: %s", error_local->message); dfu_tool_print_indent (_("Name"), str, 2); } /* this is optional */ cipher_kind = dfu_target_get_cipher_kind (target); if (cipher_kind != DFU_CIPHER_KIND_NONE) { /* TRANSLATORS: this is the encryption method used when writing */ dfu_tool_print_indent (_("Cipher"), dfu_cipher_kind_to_string (cipher_kind), 2); } /* print sector information */ sectors = dfu_target_get_sectors (target); for (guint i = 0; i < sectors->len; i++) { DfuSector *sector; g_autofree gchar *msg = NULL; g_autofree gchar *title = NULL; sector = g_ptr_array_index (sectors, i); msg = dfu_sector_to_string (sector); /* TRANSLATORS: these are areas of memory on the chip */ title = g_strdup_printf ("%s 0x%02x", _("Region"), i); dfu_tool_print_indent (title, msg, 2); } } static gchar * _bcd_version_from_uint16 (guint16 val) { #if AS_CHECK_VERSION(0,7,3) return as_utils_version_from_uint16 (val, AS_VERSION_PARSE_FLAG_USE_BCD); #else guint maj = ((val >> 12) & 0x0f) * 10 + ((val >> 8) & 0x0f); guint min = ((val >> 4) & 0x0f) * 10 + (val & 0x0f); return g_strdup_printf ("%u.%u", maj, min); #endif } static gboolean dfu_tool_list (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(GUsbContext) usb_context = NULL; g_autoptr(GPtrArray) devices = NULL; /* get all the connected USB devices */ usb_context = g_usb_context_new (error); if (usb_context == NULL) return FALSE; g_usb_context_enumerate (usb_context); devices = g_usb_context_get_devices (usb_context); for (guint i = 0; i < devices->len; i++) { DfuTarget *target; GUsbDevice *usb_device; GPtrArray *dfu_targets; const gchar *tmp; gboolean is_runtime; guint16 transfer_size; g_autofree gchar *attrs = NULL; g_autofree gchar *quirks = NULL; g_autofree gchar *version = NULL; g_autoptr(DfuDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; /* device specific */ usb_device = g_ptr_array_index (devices, i); device = dfu_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), priv->quirks); dfu_device_set_usb_context (device, usb_context); if (!fu_usb_device_probe (FU_USB_DEVICE (device), NULL)) continue; version = _bcd_version_from_uint16 (g_usb_device_get_release (usb_device)); g_print ("%s %04x:%04x [v%s]:\n", /* TRANSLATORS: detected a DFU device */ _("Found"), g_usb_device_get_vid (usb_device), g_usb_device_get_pid (usb_device), version); tmp = dfu_version_to_string (dfu_device_get_version (device)); if (tmp != NULL) { /* TRANSLATORS: DFU protocol version, e.g. 1.1 */ dfu_tool_print_indent (_("Protocol"), tmp, 1); } /* open */ locker = fu_device_locker_new (device, &error_local); if (locker == NULL) { if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_PERMISSION_DENIED)) { /* TRANSLATORS: probably not run as root... */ dfu_tool_print_indent (_("Status"), _("Permission denied"), 1); continue; } if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_debug ("ignoring warning, continuing..."); } else { /* TRANSLATORS: device has failed to report status */ dfu_tool_print_indent (_("Status"), error_local->message, 1); } continue; } if (!dfu_device_refresh_and_clear (device, &error_local)) { /* TRANSLATORS: device has failed to report status */ dfu_tool_print_indent (_("Status"), error_local->message, 1); continue; } tmp = fu_device_get_name (FU_DEVICE (device)); if (tmp != NULL) { /* TRANSLATORS: device name, e.g. 'ColorHug2' */ dfu_tool_print_indent (_("Name"), tmp, 1); } tmp = fu_device_get_serial (FU_DEVICE (device)); if (tmp != NULL) { /* TRANSLATORS: serial number, e.g. '00012345' */ dfu_tool_print_indent (_("Serial"), tmp, 1); } /* TRANSLATORS: device mode, e.g. application runtime or DFU */ is_runtime = dfu_device_is_runtime (device); dfu_tool_print_indent (_("Mode"), is_runtime ? _("Runtime") : _("DFU"), 1); tmp = dfu_status_to_string (dfu_device_get_status (device)); /* TRANSLATORS: device status, e.g. "OK" */ dfu_tool_print_indent (_("Status"), tmp, 1); tmp = dfu_state_to_string (dfu_device_get_state (device)); /* TRANSLATORS: device state, i.e. appIDLE */ dfu_tool_print_indent (_("State"), tmp, 1); transfer_size = dfu_device_get_transfer_size (device); if (transfer_size > 0) { g_autofree gchar *str = NULL; str = g_format_size_full (transfer_size, G_FORMAT_SIZE_LONG_FORMAT); /* TRANSLATORS: transfer size in bytes */ dfu_tool_print_indent (_("Transfer Size"), str, 1); } /* attributes can be an empty string */ attrs = dfu_device_get_attributes_as_string (device); if (attrs != NULL && attrs[0] != '\0') { /* TRANSLATORS: device attributes, i.e. things that * the device can do */ dfu_tool_print_indent (_("Attributes"), attrs, 1); } /* quirks are NULL if none are set */ quirks = dfu_device_get_quirks_as_string (device); if (quirks != NULL) { /* TRANSLATORS: device quirks, i.e. things that * it does that we have to work around */ dfu_tool_print_indent (_("Quirks"), quirks, 1); } /* this is optional */ tmp = dfu_device_get_chip_id (device); if (tmp != NULL) { /* TRANSLATORS: chip ID, e.g. "0x58200204" */ dfu_tool_print_indent (_("Chip ID"), tmp, 1); } /* list targets */ dfu_targets = dfu_device_get_targets (device); for (guint j = 0; j < dfu_targets->len; j++) { target = g_ptr_array_index (dfu_targets, j); dfu_tool_list_target (target); } } return TRUE; } static gboolean dfu_tool_detach (DfuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(DfuDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; /* open correct device */ device = dfu_tool_get_default_device (priv, error); if (device == NULL) return FALSE; if (priv->transfer_size > 0) dfu_device_set_transfer_size (device, priv->transfer_size); /* detatch */ locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; return dfu_device_detach (device, error); } static gboolean dfu_tool_sigint_cb (gpointer user_data) { DfuToolPrivate *priv = (DfuToolPrivate *) user_data; g_debug ("Handling SIGINT"); g_cancellable_cancel (priv->cancellable); return FALSE; } int main (int argc, char *argv[]) { gboolean ret; gboolean verbose = FALSE; gboolean version = FALSE; g_autofree gchar *cmd_descriptions = NULL; g_autoptr(DfuToolPrivate) priv = g_new0 (DfuToolPrivate, 1); g_autoptr(GError) error = NULL; g_autoptr(GOptionContext) context = NULL; const GOptionEntry options[] = { { "version", '\0', 0, G_OPTION_ARG_NONE, &version, "Print the version number", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Print verbose debug statements", NULL }, { "device", 'd', 0, G_OPTION_ARG_STRING, &priv->device_vid_pid, "Specify Vendor/Product ID(s) of DFU device", "VID:PID" }, { "transfer-size", 't', 0, G_OPTION_ARG_STRING, &priv->transfer_size, "Specify the number of bytes per USB transfer", "BYTES" }, { "force", '\0', 0, G_OPTION_ARG_NONE, &priv->force, "Force the action ignoring all warnings", NULL }, { NULL} }; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_tool_item_free); dfu_tool_add (priv->cmd_array, "convert", "FORMAT FILE-IN FILE OUT [SIZE]", /* TRANSLATORS: command description */ _("Convert firmware to DFU format"), dfu_tool_convert); dfu_tool_add (priv->cmd_array, "merge", "FILE-OUT FILE1 FILE2 [FILE3...]", /* TRANSLATORS: command description */ _("Merge multiple firmware files into one"), dfu_tool_merge); dfu_tool_add (priv->cmd_array, "set-vendor", "FILE VID", /* TRANSLATORS: command description */ _("Set vendor ID on firmware file"), dfu_tool_set_vendor); dfu_tool_add (priv->cmd_array, "set-product", "FILE PID", /* TRANSLATORS: command description */ _("Set product ID on firmware file"), dfu_tool_set_product); dfu_tool_add (priv->cmd_array, "set-address", "FILE ADDRESS", /* TRANSLATORS: command description */ _("Set element address on firmware file"), dfu_tool_set_address); dfu_tool_add (priv->cmd_array, "set-target-size", "FILE SIZE", /* TRANSLATORS: command description */ _("Set the firmware size for the target"), dfu_tool_set_target_size); dfu_tool_add (priv->cmd_array, "set-release", "FILE RELEASE", /* TRANSLATORS: command description */ _("Set release version on firmware file"), dfu_tool_set_release); dfu_tool_add (priv->cmd_array, "set-alt-setting", "FILE ALT-ID", /* TRANSLATORS: command description */ _("Set alternative number on firmware file"), dfu_tool_set_alt_setting); dfu_tool_add (priv->cmd_array, "set-alt-setting-name", "FILE VALUE", /* TRANSLATORS: command description */ _("Set alternative name on firmware file"), dfu_tool_set_alt_setting_name); dfu_tool_add (priv->cmd_array, "attach", NULL, /* TRANSLATORS: command description */ _("Attach DFU capable device back to runtime"), dfu_tool_attach); dfu_tool_add (priv->cmd_array, "reset", NULL, /* TRANSLATORS: command description */ _("Reset a DFU device"), dfu_tool_reset); dfu_tool_add (priv->cmd_array, "read", "FILENAME", /* TRANSLATORS: command description */ _("Read firmware from device into a file"), dfu_tool_read); dfu_tool_add (priv->cmd_array, "read-alt", "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID", /* TRANSLATORS: command description */ _("Read firmware from one partition into a file"), dfu_tool_read_alt); dfu_tool_add (priv->cmd_array, "write", NULL, /* TRANSLATORS: command description */ _("Write firmware from file into device"), dfu_tool_write); dfu_tool_add (priv->cmd_array, "write-alt", "FILENAME DEVICE-ALT-NAME|DEVICE-ALT-ID [IMAGE-ALT-NAME|IMAGE-ALT-ID]", /* TRANSLATORS: command description */ _("Write firmware from file into one partition"), dfu_tool_write_alt); dfu_tool_add (priv->cmd_array, "list", NULL, /* TRANSLATORS: command description */ _("List currently attached DFU capable devices"), dfu_tool_list); dfu_tool_add (priv->cmd_array, "detach", NULL, /* TRANSLATORS: command description */ _("Detach currently attached DFU capable device"), dfu_tool_detach); dfu_tool_add (priv->cmd_array, "dump", "FILENAME", /* TRANSLATORS: command description */ _("Dump details about a firmware file"), dfu_tool_dump); dfu_tool_add (priv->cmd_array, "watch", NULL, /* TRANSLATORS: command description */ _("Watch DFU devices being hotplugged"), dfu_tool_watch); dfu_tool_add (priv->cmd_array, "encrypt", "FILENAME-IN FILENAME-OUT TYPE KEY", /* TRANSLATORS: command description */ _("Encrypt firmware data"), dfu_tool_encrypt); dfu_tool_add (priv->cmd_array, "decrypt", "FILENAME-IN FILENAME-OUT TYPE KEY", /* TRANSLATORS: command description */ _("Decrypt firmware data"), dfu_tool_decrypt); dfu_tool_add (priv->cmd_array, "set-metadata", "FILE KEY VALUE", /* TRANSLATORS: command description */ _("Sets metadata on a firmware file"), dfu_tool_set_metadata); dfu_tool_add (priv->cmd_array, "replace-data", NULL, /* TRANSLATORS: command description */ _("Replace data in an existing firmware file"), dfu_tool_replace_data); dfu_tool_add (priv->cmd_array, "patch-create", NULL, /* TRANSLATORS: command description */ _("Create a binary patch using two files"), dfu_tool_patch_create); dfu_tool_add (priv->cmd_array, "patch-apply", NULL, /* TRANSLATORS: command description */ _("Apply a binary patch"), dfu_tool_patch_apply); dfu_tool_add (priv->cmd_array, "patch-dump", NULL, /* TRANSLATORS: command description */ _("Dump information about a binary patch to the screen"), dfu_tool_patch_dump); /* use animated progress bar */ priv->progressbar = fu_progressbar_new (); fu_progressbar_set_length_percentage (priv->progressbar, 50); fu_progressbar_set_length_status (priv->progressbar, 20); /* use quirks */ priv->quirks = fu_quirks_new (); if (!fu_quirks_load (priv->quirks, &error)) { /* TRANSLATORS: quirks are device-specific workarounds */ g_print ("%s: %s\n", _("Failed to load quirks"), error->message); return EXIT_FAILURE; } /* do stuff on ctrl+c */ priv->cancellable = g_cancellable_new (); g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT, dfu_tool_sigint_cb, priv, NULL); /* sort by command name */ g_ptr_array_sort (priv->cmd_array, (GCompareFunc) dfu_tool_sort_command_name_cb); /* get a list of the commands */ context = g_option_context_new (NULL); cmd_descriptions = dfu_tool_get_descriptions (priv->cmd_array); g_option_context_set_summary (context, cmd_descriptions); /* TRANSLATORS: DFU stands for device firmware update */ g_set_application_name (_("DFU Utility")); g_option_context_add_main_entries (context, options, NULL); ret = g_option_context_parse (context, &argc, &argv, &error); if (!ret) { /* TRANSLATORS: the user didn't read the man page */ g_print ("%s: %s\n", _("Failed to parse arguments"), error->message); return EXIT_FAILURE; } /* set verbose? */ if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); /* version */ if (version) { g_print ("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION); return EXIT_SUCCESS; } /* run the specified command */ ret = dfu_tool_run (priv, argv[1], (gchar**) &argv[2], &error); if (!ret) { if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL)) { g_autofree gchar *tmp = NULL; tmp = g_option_context_get_help (context, TRUE, NULL); g_print ("%s\n\n%s", error->message, tmp); } else { g_print ("%s\n", error->message); } return EXIT_FAILURE; } /* success/ */ g_object_unref (priv->progressbar); return EXIT_SUCCESS; } fwupd-1.0.6/plugins/dfu/dfu-tool.h2m000066400000000000000000000041671325145456600172660ustar00rootroot00000000000000[DESCRIPTION] .PP This manual page documents briefly the \fBdfu-tool\fR command. .PP \fBdfu-tool\fR allows a user to write various kinds of firmware onto devices supporting the USB Device Firmware Upgrade protocol. This tool can be used to switch the device from the normal runtime mode to `DFU mode' which allows the user to read and write firmware. Either the whole device can be written in one operation, or individual `targets' can be specified with the alternative name or number. .PP \fBdfu-tool\fR uses the libdfu shared library to perform actions. All synchronous actions can be safely cancelled and on failure will return errors with both a type and a full textual description. libdfu supports DFU 1.0, DFU 1.1 and the ST DfuSe vendor extension, and handles many device `quirks' necessary for the real-world implementations of DFU\&. .PP Additionally \fBdfu-tool\fR can be used to convert firmware from various different formats, or to modify details about the elements, images and metadata contained inside the firmware file. For example, you can easily convert DFU 1.1 firmware into the vendor-specific DfuSe format, convert a Intel HEX file into a raw file padded to a specific size, or add new copyright and licensing information to an existing file. Fields such as the vendor and product IDs can be changed, and the firmware elements can be encrypted and decrypted using various different methods. Merging two DfuSe files together is also possible, although specifying different alt-setting numbers before merging is a good idea to avoid confusion. .PP Although \fBdfu-tool\fR tries to provide a large number of easy-to-use commands, it may only be possible to do certain operations using the libdfu library directly. This is easier than it sounds, as the library is built with GObject Introspection support making it usable in many languages such as C, Javascript and Python. Furthermore, using the library is a good idea if you want to perform multiple operations on large firmware files, for instance, converting from an Intel HEX file, padding to a certain size, setting vendor and adding licensing information and then saving to a remote location. fwupd-1.0.6/plugins/dfu/dfu.quirk000066400000000000000000000141301325145456600167470ustar00rootroot00000000000000[fwupd-dfu] # on PC platforms the DW1820A firmware is loaded at runtime and can't # be stored on the device itself as the flash chip is unpopulated USB\VID_0A5C&PID_6412=ignore-runtime # Openmoko Freerunner / GTA02 USB\VID_1D50&PID_5119=ignore-polltimeout|no-pid-change|no-dfu-runtime|action-required|no-get-status-upload # OpenPCD Reader USB\VID_16C0&PID_076B=ignore-polltimeout # SIMtrace USB\VID_16C0&PID_0762=ignore-polltimeout # OpenPICC USB\VID_16C0&PID_076C=ignore-polltimeout # Siemens AG, PXM 40 & PXM 50 USB\VID_0908&PID_02C4&REV_0000=ignore-polltimeout USB\VID_0908&PID_02C5&REV_0000=ignore-polltimeout # Midiman M-Audio Transit USB\VID_0763&PID_2806=ignore-polltimeout # LPC DFU bootloader USB\VID_1FC9&PID_000C=force-dfu-mode # m-stack DFU USB\VID_273F&PID_1003=attach-upload-download USB\VID_273F&PID_100A=attach-upload-download # HydraBus USB\VID_1D50&PID_60A7=no-dfu-runtime|action-required # Jabra 410, 510, 710 and 810 USB\VID_0B0E&PID_0412=no-dfu-runtime USB\VID_0B0E&PID_0420=no-dfu-runtime USB\VID_0B0E&PID_2475=no-dfu-runtime USB\VID_0B0E&PID_2456=no-dfu-runtime # Jabra 410, 510, 710 and 810 (DFU mode) USB\VID_0B0E&PID_0411=no-pid-change|force-dfu-mode|ignore-upload|attach-extra-reset USB\VID_0B0E&PID_0421=no-pid-change|force-dfu-mode|ignore-upload|attach-extra-reset USB\VID_0B0E&PID_0982=no-pid-change|force-dfu-mode|ignore-upload|attach-extra-reset USB\VID_0B0E&PID_0971=no-pid-change|force-dfu-mode|ignore-upload|attach-extra-reset # Atmel AT90USB Bootloader USB\VID_03EB&PID_2FF7=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FF9=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FFA=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FFB=use-any-interface|legacy-protocol|force-dfu-mode # Atmel ATMEGA Bootloader USB\VID_03EB&PID_2FEE=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FEF=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FF0=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FF2=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FF3=use-any-interface|legacy-protocol|force-dfu-mode USB\VID_03EB&PID_2FF4=use-any-interface|legacy-protocol|force-dfu-mode # Atmel XMEGA Bootloader USB\VID_03EB&PID_2FE2=use-any-interface|force-dfu-mode [fwupd-dfu-force-version] # Leaflabs Maple3 USB\VID_1EAF&PID_0003&REV_0200=0110 # Atmel FLIP Bootloader USB\VID_03EB=ff01 [fwupd-dfu-jabra-detach] # Jabra 410 and 510 USB\VID_0B0E&PID_0412=0201 USB\VID_0B0E&PID_0420=0201 # Jabra 710 and 810 USB\VID_0B0E&PID_2475=0508 USB\VID_0B0E&PID_2456=0508 [FuUsbDevice:guid] # Jabra 410, 510, 710 and 810 USB\VID_0B0E&PID_0412=USB\VID_0B0E&PID_0411 USB\VID_0B0E&PID_0420=USB\VID_0B0E&PID_0421 USB\VID_0B0E&PID_2475=USB\VID_0B0E&PID_0982 USB\VID_0B0E&PID_2456=USB\VID_0B0E&PID_0971 [fwupd-dfu-avr-chip-id] # AT32UC3B1256 [BLDR][USER] USER@0x2000, BLDR+USER=0x40000 0x58200203=@Flash/0x2000/1*248Kg # AT32UC3A3256 [BLDR][USER] USER@0x2000, BLDR+USER=0x40000 0x58200204=@Flash/0x2000/1*248Kg # AT90USB1287 [USER][BLDR] BLDR@0x1e000, BLDR+USER=0x20000 0x581e9782=@Flash/0x0/1*120Kg # AT90USB647 [USER][BLDR] BLDR@0x0e000, BLDR+USER=0x10000 0x581e9682=@Flash/0x0/1*56Kg # AT90USB646 [USER][BLDR] BLDR@0x0e000, BLDR+USER=0x10000 0x581e9682=@Flash/0x0/1*56Kg # ATmega32U4 [USER][BLDR] BLDR@0x07000, BLDR+USER=0x08000 0x581e9587=@Flash/0x0/1*28Kg # ATmega16U4 [USER][BLDR] BLDR@0x03000, BLDR+USER=0x04000 0x581e9488=@Flash/0x0/1*12Kg # ATmega32U2 [USER][BLDR] BLDR@0x07000, BLDR+USER=0x08000 0x581e958a=@Flash/0x0/1*28Kg # ATmega16U2 [USER][BLDR] BLDR@0x03000, BLDR+USER=0x04000 0x581e9489=@Flash/0x0/1*12Kg # AT90USB162 [USER][BLDR] BLDR@0x03000, BLDR+USER=0x04000 0x581e9482=@Flash/0x0/1*12Kg # ATmega8U2 [USER][BLDR] BLDR@0x01000, BLDR+USER=0x02000 0x581e9389=@Flash/0x0/1*4Kg # AT90USB82 [USER][BLDR] BLDR@0x01000, BLDR+USER=0x02000 0x581e9382=@Flash/0x0/1*4Kg # ATxmega16A4 [USER] USER=0x4000 0x1e9441=@Flash/0x0/1*16Kg # ATxmega16C4 [USER] USER=0x4000 0x1e9544=@Flash/0x0/1*16Kg # ATxmega16D4 [USER] USER=0x4000 0x1e9442=@Flash/0x0/1*16Kg # ATxmega32A4 [USER] USER=0x8000 0x1e9541=@Flash/0x0/1*32Kg # ATxmega32C4 [USER] USER=0x8000 0x1e9443=@Flash/0x0/1*32Kg # ATxmega32D4 [USER] USER=0x8000 0x1e9542=@Flash/0x0/1*32Kg # ATxmega64A4 [USER] USER=0x10000 0x1e9646=@Flash/0x0/1*64Kg # ATxmega64C3 [USER] USER=0x10000 0x1e9649=@Flash/0x0/1*64Kg # ATxmega64D3 [USER] USER=0x10000 0x1e964a=@Flash/0x0/1*64Kg # ATxmega64D4 [USER] USER=0x10000 0x1e9647=@Flash/0x0/1*64Kg # ATxmega64A1 [USER] USER=0x10000 0x1e964e=@Flash/0x0/1*64Kg # ATxmega64A3 [USER] USER=0x10000 0x1e9642=@Flash/0x0/1*64Kg # ATxmega64B1 [USER] USER=0x10000 0x1e9652=@Flash/0x0/1*64Kg # ATxmega64B3 [USER] USER=0x10000 0x1e9651=@Flash/0x0/1*64Kg # ATxmega128C3 [USER] USER=0x20000 0x1e9752=@Flash/0x0/1*128Kg # ATxmega128D3 [USER] USER=0x20000 0x1e9748=@Flash/0x0/1*128Kg # ATxmega128D4 [USER] USER=0x20000 0x1e9747=@Flash/0x0/1*128Kg # ATxmega128A1 [USER] USER=0x20000 0x1e974c=@Flash/0x0/1*128Kg # ATxmega128A1D [USER] USER=0x20000 0x1e9741=@Flash/0x0/1*128Kg # ATxmega128A3 [USER] USER=0x20000 0x1e9742=@Flash/0x0/1*128Kg # ATxmega128A4 [USER] USER=0x20000 0x1e9746=@Flash/0x0/1*128Kg # ATxmega128B1 [USER] USER=0x20000 0x1e974d=@Flash/0x0/1*128Kg # ATxmega128B3 [USER] USER=0x20000 0x1e974b=@Flash/0x0/1*128Kg # ATxmega192C3 [USER] USER=0x30000 0x1e9751=@Flash/0x0/1*192Kg # ATxmega192D3 [USER] USER=0x30000 0x1e9749=@Flash/0x0/1*192Kg # ATxmega192A1 [USER] USER=0x30000 0x1e974e=@Flash/0x0/1*192Kg # ATxmega192A3 [USER] USER=0x30000 0x1e9744=@Flash/0x0/1*192Kg # ATxmega256 [USER] USER=0x40000 0x1e9846=@Flash/0x0/1*256Kg # ATxmega256D3 [USER] USER=0x40000 0x1e9844=@Flash/0x0/1*256Kg # ATxmega256A3 [USER] USER=0x40000 0x1e9842=@Flash/0x0/1*256Kg # ATxmega256A3B [USER] USER=0x40000 0x1e9843=@Flash/0x0/1*256Kg # ATxmega384C3 [USER] USER=0x60000 0x1e9845=@Flash/0x0/1*384Kg # ATxmega384D3 [USER] USER=0x60000 0x1e9847=@Flash/0x0/1*384Kg # ATxmega8E5 [USER] USER=0x2000 0x1e9341=@Flash/0x0/1*8Kg # ATxmega16E5 [USER] USER=0x4000 0x1e9445=@Flash/0x0/1*16Kg # ATxmega32E5 [USER] USER=0x8000 0x1e954c=@Flash/0x0/1*32Kg fwupd-1.0.6/plugins/dfu/fu-plugin-dfu.c000066400000000000000000000133351325145456600177500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "dfu-device.h" static void fu_plugin_dfu_state_changed_cb (DfuDevice *device, DfuState state, FuPlugin *plugin) { switch (state) { case DFU_STATE_DFU_UPLOAD_IDLE: fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_VERIFY); break; case DFU_STATE_DFU_DNLOAD_IDLE: fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_WRITE); break; default: break; } } gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(DfuDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; /* open the device */ device = dfu_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), fu_plugin_get_quirks (plugin)); dfu_device_set_usb_context (device, fu_plugin_get_usb_context (plugin)); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* ignore defective runtimes */ if (dfu_device_is_runtime (device) && dfu_device_has_quirk (device, DFU_DEVICE_QUIRK_IGNORE_RUNTIME)) { g_debug ("ignoring %s runtime", dfu_device_get_platform_id (device)); return TRUE; } /* watch all signals */ g_signal_connect (device, "state-changed", G_CALLBACK (fu_plugin_dfu_state_changed_cb), plugin); /* this is a guess and can be overridden in the metainfo file */ fu_device_add_icon (device, "drive-harddisk-usb"); /* insert to hash */ fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } gboolean fu_plugin_update_detach (FuPlugin *plugin, FuDevice *dev, GError **error) { DfuDevice *device = DFU_DEVICE (dev); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; /* open it */ locker = fu_device_locker_new (device, &error_local); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; /* already in DFU mode */ if (!dfu_device_is_runtime (device)) return TRUE; /* detach and USB reset */ if (!dfu_device_detach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* success */ return TRUE; } gboolean fu_plugin_update_attach (FuPlugin *plugin, FuDevice *dev, GError **error) { DfuDevice *device = DFU_DEVICE (dev); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; /* open it */ locker = fu_device_locker_new (device, &error_local); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; /* already in runtime mode */ if (dfu_device_is_runtime (device)) return TRUE; /* attach it */ if (!dfu_device_attach (device, error)) return FALSE; if (!dfu_device_wait_for_replug (device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; /* success */ return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { DfuDevice *device = DFU_DEVICE (dev); g_autoptr(DfuFirmware) dfu_firmware = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; /* open it */ locker = fu_device_locker_new (device, &error_local); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; /* hit hardware */ dfu_firmware = dfu_firmware_new (); if (!dfu_firmware_parse_data (dfu_firmware, blob_fw, DFU_FIRMWARE_PARSE_FLAG_NONE, error)) return FALSE; if (!dfu_device_download (device, dfu_firmware, DFU_TARGET_TRANSFER_FLAG_VERIFY | DFU_TARGET_TRANSFER_FLAG_WILDCARD_VID | DFU_TARGET_TRANSFER_FLAG_WILDCARD_PID, error)) return FALSE; /* success */ return TRUE; } gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *dev, FuPluginVerifyFlags flags, GError **error) { GBytes *blob_fw; DfuDevice *device = DFU_DEVICE (dev); g_autoptr(DfuFirmware) dfu_firmware = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GError) error_local = NULL; GChecksumType checksum_types[] = { G_CHECKSUM_SHA1, G_CHECKSUM_SHA256, 0 }; /* open it */ locker = fu_device_locker_new (device, &error_local); if (locker == NULL) return FALSE; if (!dfu_device_refresh_and_clear (device, error)) return FALSE; /* get data from hardware */ g_debug ("uploading from device->host"); dfu_firmware = dfu_device_upload (device, DFU_TARGET_TRANSFER_FLAG_NONE, error); if (dfu_firmware == NULL) return FALSE; /* get the checksum */ blob_fw = dfu_firmware_write_data (dfu_firmware, error); if (blob_fw == NULL) return FALSE; for (guint i = 0; checksum_types[i] != 0; i++) { g_autofree gchar *hash = NULL; hash = g_compute_checksum_for_bytes (checksum_types[i], blob_fw); fu_device_add_checksum (dev, hash); } /* success */ return TRUE; } fwupd-1.0.6/plugins/dfu/fuzzing.md000066400000000000000000000014471325145456600171410ustar00rootroot00000000000000Fuzzing ======= CC=afl-gcc meson --default-library=static ../ AFL_HARDEN=1 ninja afl-fuzz -m 300 -i fuzzing -o findings ./plugins/dfu/dfu-tool --force dump @@ afl-fuzz -m 300 -i fuzzing-patch-dump -o findings ./plugins/dfu/dfu-tool --force patch-dump @@ Generating ---------- mkdir -p fuzzing-patch-dump echo -n hello > complete-replace.old echo -n XXXXX > complete-replace.new ./plugins/dfu/dfu-tool patch-create complete-replace.old complete-replace.new fuzzing-patch-dump/complete-replace.bdiff echo -n helloworldhelloworldhelloworldhelloworld > grow-two-chunks.old echo -n XelloXorldhelloworldhelloworldhelloworlXXX > grow-two-chunks.new ./plugins/dfu/dfu-tool patch-create grow-two-chunks.old grow-two-chunks.new fuzzing-patch-dump/grow-two-chunks.bdiff fwupd-1.0.6/plugins/dfu/fuzzing/000077500000000000000000000000001325145456600166115ustar00rootroot00000000000000fwupd-1.0.6/plugins/dfu/fuzzing/example.dfu000066400000000000000000000000341325145456600207410ustar00rootroot00000000000000hello world UFDfd-fwupd-1.0.6/plugins/dfu/fuzzing/example.dfuse000066400000000000000000000005011325145456600212700ustar00rootroot00000000000000DfuSe1TargetST hello world UFDw~fwupd-1.0.6/plugins/dfu/fuzzing/firmware.hex000066400000000000000000000006001325145456600211270ustar00rootroot00000000000000:044000003DEF20F080 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A :1040780011003FEF20F0000142EF20F03DEF20F06B :00000001FF fwupd-1.0.6/plugins/dfu/fuzzing/metadata-multiple.dfu000066400000000000000000000001151325145456600227170ustar00rootroot00000000000000amaliaMDkeyvalue CopyrightRichard HughesLicenseGPL-2.0+UFDGZ+@fwupd-1.0.6/plugins/dfu/fuzzing/metadata.dfu000066400000000000000000000000431325145456600210660ustar00rootroot00000000000000amaliaMDkeyvalueUFDXfwupd-1.0.6/plugins/dfu/meson.build000066400000000000000000000052751325145456600172700ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginDfu"'] install_data(['dfu.quirk'], install_dir: join_paths(datadir, 'fwupd', 'quirks.d') ) dfu = static_library( 'dfu', sources : [ 'dfu-chunked.c', 'dfu-cipher-xtea.c', 'dfu-common.c', 'dfu-device.c', 'dfu-element.c', 'dfu-firmware.c', 'dfu-format-dfu.c', 'dfu-format-dfuse.c', 'dfu-format-ihex.c', 'dfu-format-metadata.c', 'dfu-format-raw.c', 'dfu-image.c', 'dfu-patch.c', 'dfu-sector.c', 'dfu-target.c', 'dfu-target-stm.c', 'dfu-target-avr.c', ], dependencies : [ appstream_glib, giounix, libm, gusb, ], c_args : cargs, include_directories : [ include_directories('../..'), include_directories('../../libfwupd'), include_directories('../../src'), ], ) shared_module('fu_plugin_dfu', sources : [ 'fu-plugin-dfu.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], link_with : [ dfu, ], ) dfu_tool = executable( 'dfu-tool', sources : [ 'dfu-tool.c', ], include_directories : [ include_directories('..'), include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ appstream_glib, giounix, libm, gusb, ], link_with : [ dfu, fwupd, libfwupdprivate, ], c_args : cargs, install : true, install_dir : bindir ) if get_option('man') help2man = find_program('help2man') extra = join_paths(meson.current_source_dir(), 'dfu-tool.h2m') custom_target('dfu-tool-man', input : dfu_tool, output : 'dfu-tool.1', command : [ help2man, '@INPUT@', '--no-info', '--output', '@OUTPUT@', '--name', 'dfu-tool', '--manual', 'User Commands', '--version-string', fwupd_version, '--include', extra, ], install : true, install_dir : join_paths(mandir, 'man1'), ) endif if get_option('tests') testdatadir = join_paths(meson.current_source_dir(), 'tests') cargs += '-DTESTDATADIR="' + testdatadir + '"' e = executable( 'dfu-self-test', sources : [ 'dfu-self-test.c' ], include_directories : [ include_directories('..'), include_directories('../..'), include_directories('../../libfwupd'), include_directories('../../src'), ], dependencies : [ appstream_glib, gio, gusb, libm, ], link_with : [ dfu, fwupd, libfwupdprivate, ], c_args : cargs ) test('dfu-self-test', e) endif fwupd-1.0.6/plugins/dfu/tests/000077500000000000000000000000001325145456600162575ustar00rootroot00000000000000fwupd-1.0.6/plugins/dfu/tests/dev_VRBRAIN.dfu000066400000000000000000002650221325145456600207270ustar00rootroot00000000000000DfuSejTargetST...00DD200085DD40008A9 :1067DC00E1D2000849D200080000000000000000CF :1067EC003DD20008D90300000000803F0000803F2C :1067FC000000803F4BFB00084FFB0008C5FB000866 :10680C0055FB000885FB000800C2010000000800D1 :10681C0041FC00084DFC00087DFC000859FC0008F8 :10682C00hf8?  Q=%5AM-MaY8ML+h"\+#+ K "p K"Z K"p8 *h# M\ !(`3#8  @  8BL#xB (};61@""EN@', ##p 9K`9K"Z9J#p8J`b8Kx*a5J6I` ""p"pV1K3J` p".K2J` #K,K0J` #F)K/J`#A'K-J`#<$K,J`#7"K*J` p3K)J`##pK"`*Op#Kz#Kx(#!I"ZT%Up+аR+F" Dd#Sp#p K`KJ`##pK"8  @   p/////////& '  /  -A K!L[{+#x+ F#x +2L#h&F+-M+x/FK E #+pK"h\K"A;xKh B K"p K2h\+K"Z'     @pFFF FdK];pH1x *F *-*F +*F 7zFF0IJ ,  zj&zgz.)zgjF09Ȳ ( j'jgz7zxE*4Zx-*3"+*33";!08IJ , $4 FOsFz)j9gz+jgz;"'zzg'z '  LD!Kh & Hm1H$KHX 4Rh ,1h01p )K)KOzqx'H%Kh%Kh%KS!%KF$H$"JR#I"+BH4 ILK"xHS"#x+KH}+ n!o!HK!FFOcHp@x' . 1( \ B@B1A"2 (1&2& 024D 428 hF F5!FF(h8@7 HJ! tHC q @ f2p2F($#I\ hDIx) :T3+%f]H1F(5`1FH- FH#JD! D IY\ 3+# H 0p 4M22L! 10 HH@پ22-AFFF)H)KS$A#@3B&H4$H!(F$I"FX"H#LT)H+x-+54OO&KS&p'HA(F9F"Fu @5HOH~9F HA62/"24? 3/ 3:3D31FH[J#pJ`Jp~ F@M3% X $ H@ H: h @ e3r2F F8KHZyK:S"(8FI"F`HLTH:H%KS%`&H@8F1F"F5(K H]q1F@L! 3 0?30"2433F F K H@ FS(KL FL! 36pF H0 FI$&F%Fx,,,F(FI 4 -H !p@,KH3 )Fp@𰽦zsz Hp@ H)F2FK#`p36!4^( G4_448F?hFKHD!FF 4},8(F(F !(FKDF8H!8@bH 44#+( " F-  XB#p F0-@! "F+z̿8'8g(z('iFȊ "Zpp- #-#hF 0(0# 000 (0# 00(0# 0iF8Ų*F F#cU FI F)D F0o:zD}27yF F+7 hx0h,h)h%hh"hhF rFHzhF fFH hF [FH !H%Hh"i0-2,244-C-F:ONF (+x*+LHP$1YJHu09FHHD4@3B}(F=! (_D FF F'@$|CV@FAFF(F (<1KDzz/۔zz&"y*:* hp hhhAFH F!C0H7/HCػF7Y)F8FX H9FH! DH4@3BѽB454445p-^H^L]H]HF?H:H|I hF-F6Hs1Hkh hFF/Hb -,HiZ*LFT)HP F'KS$A#@+B$HC4s1D J\,1)$H@iF.MHaY)(!GH4@3Bpm1L! 556 0e5p56-21x5/5/54M5B54𵉰FŲ-rHLTz@z,5)F{H FwH FsH wFnH nFkH -hzhKgzgj"B ZSZj2vjwz7z]Hjzzc$#DzWzWKXHzzؿF4O ,RHt FQI".8PKD0"(a{ FLI" F F !(nF0F ,FFDKS$P CHM0F)F8 F'?H)FAL4F .FH F !FPE(F|/K $F(F !FHE(Fj&K 4(F !FHE(FZK 4(F !H0HK, HH ! 5d! 551`! 5 #<5546L! 6 036"66\6-GgKxFB#eH0dHcM(h F((h`L  (F?(OO %h[OVF-[H9h*FPF>FWK 7Bα+FpB#` ZMI0-+ 'T"`TTF#h VEGH>VE V 8 ! 9H/%#hB:KY] 5#h+(64HU (4H ) )D2H-M"h*I#T.K" #F8h0h(DG&HH!0"##`0+b" ()^/+?\ Ҳ^*?V )?RZ"`J(hT ]I); J#`!TH>$ 66& X h0% (1664i66KxH*Zoy*ѓ$*O +P@JB8 pG pGpGpFDaN0FJ(ІH0Dc1p4ML!  K IFOb$*"$OrqHL! H -G.H P#9iCYC@aC'J"3+%J!0@aB"d  \B_OL d "/)F%MFED !}CeD-Ozq I5DUR2 4*xyGH 8( L! ' m@/KH"pObZ"q"$"F$FQ&IOr0pi"F\2oJ%4 X ! (L3wCr Fh 1(5 -K4B - 7 !"@1L! H 8F F (F!F8@ ŻKhB  pG\ KhC`pG\ Kh"`pG\ KhpG\ KhB  pGL! KhC`pGL! -GF,JMhQhLkFOb!(F!Or FH#+pO #kqOpO` Osb1#d1*#`1Osh1 #f1n#}1+#~1!#1##1@LC1@ls&'"O Op!@^1@~CS!T!UxdjalanaVaXaZa]a^a\qaaqaaaq@1@:sB1OzsO1D1N@~S OQF1v@S @H1@S@q`uuU O(J12#!pO - L1P1r!s`sqqaasatt&pu#qO O OP Od #0$0!0#vO OZ  u10A cKOx  %&. s&vsfv w"`f&/0ccRKcRKcRK#dRHDp#E0mOHsz0#0Oc0@30v`w`xyp|`ΐ#FOr~ Ob  6@Q. " d" Or (" O|R " @lr @R  $O~R@`!R#4#3!+a$(p IOrt"C FG,ML! H ?(|?= w?@=MKh"`pGL! K"`pGL! KhpGL! 8L% pa U%b`b8H&  z zzؿgz    K K5< *[-:Kz('( z ' H zh z z zzz:+ C3#` ,}? F E zz''zzzzzGjzjz F*  zzz 0"FI\ F.,3xD$,T\ $bC0 ,0:R+3F0 0 8 Mz Kx+ K Lh[hc` `<KKK`#+s8& ' ' ' (  ' "FHL!RHRHDR `a`` LD3 `a`` LD+ `a``  ' 0'  H :K;zXy:J{ Gzy'zjzGz3I`'zz Gz/J|`&zz Gz~'z zFj&zyjj Fj!JX|`&jj Fj~'jj FjjjJ|ڱyJ{~Fj&jj fjzz:gzzzpGH B D0 zD & & 0& F _Op[(> Mnp$`l`M1B '']K!FrhH;F K` :1+ȿA!SK IBBh ځ JhQh H& L! O@&  NN-AKx++M #kKOBZLh P &.h'h F8F n hO ( L8hOF& F@F fO0H& @ @& sLh#` hc`MhNK `hihJ3h`AI hz)hJzAgz`zz J` K Kp ' p D& &   | H  DPcBݠ @8pGKB @0pG&KhFx+F^x2nB [۲+0:D۲ *"B RҲk0>2DҲ.,L ! &qC&xx0941D8!HBCd !$H @B-OL-hӹN3x;+Kh K1+F4+Рh ($-  - -*- ,-~J#p~Jp~Jp{O:x{K`!TzJxpG)YxP)љxG)xG)yA)!pxnIR(xM( yC)!px**9N*K  (J.aH1bK`?xS+<_KhRB`7ZH#[KX`1xW+.XKZhRBZ`)xVK0*""r! PKr MKX.. HK؁  ACOzrXCAJ6#*-`;pa?J!pc=N3x+K7I x@+٣7ҲKx@+7;0;۲D,Jx۲B2,Kx- -,*K,Jډ+K$ 0 #"J'Kh`QhY`%Kz%Op S;(ј0+ K:hd#ZCK`#"2p Jx+Yp JTKx# JxM@p#~& H& L!     (  &  4' L ' ' ' ' & Kx")T %3Pitb("p-@Ex2p@"pKpK I"pK xx*DҲ pDpKp,I"p~K xx*DҲ pDp|KxI"pwK xx*DҲ pDpuK%"kKpoJ#iHjJxx)Dɲp1DpiI *hHT2 cI B@""p\KxBXJ#ppXKxB@؀VKx+J++5+U0+@ɀRKyRK*"pxNJ#mLKNJYhQ`h`iLMLNOzs+JKxrJK" p(i3|+fEK*hd#ZCCK`]:JSyyCBCA:Jp+P7JrM2KzКzJBJA2I p 0Ir/ 3Kp:(K2NZi2i1MBs+/K" p@#K|+3d+"* #'K )ݢrB !H\T H\TH\THxT3I xKx"p p#0       ' ' ' &   ' & ' 4' L  ( & ' ' '( #+?qMh`` IKx* ""pKz*?\Jx*WZx|s{ KMxO2KxK#JIXPNXPQ N@S p^ `N B|&8DC xHP( %FѬ y3+nOnMK;hlz Ezzz;z8`zXHzz_K [Id# YJ 0/F UIVK x*=z0hh'zphO*zZh''zzKJ jHJz'&z g'zz" p0hqhY``0#Ky+?pԀԐ԰ rh(K*$Jz2hzgz`z z0" *?*Ѐ:H& l & '  ( < ` '   ig  @ zD' ' ' )     t D  D& p |N%S{J z5   zg'zz oJR zzg'zDz1FJF2eIfZzS zjFjqhr`&%jQjXD%Ob6jZjSIz7gzzzzfzz 5 II12b*5 D%@2BJ( !"5V`-ql5K 7KEFBݕz0zg'zzD+KPh XF(AݐBCBB̿##""N+K ɚ ( KI @2 WHC(DBݠ @8( @00`#   H @0HH  B| 79&  D 0' 0 5`3hN S(3:z%gh h w Jв^ *ESjIzzOzrzz % % K z z1Fg'zFz5 XZzjshzr`Fj&%j:jDzK{I@2Z6jjz7gzzzzfzz `DRXSkK "35V+`-[Ft 2dJhd"cJ0 B`Kh`KhBs(@BB#0YKUKWKqF/ ЈrxSKhYh |hP (x3xLM+;+D+pGkjc+Fii++ AMihYh sxhh iwb3aN@ (И1+i[hO0K"a 6jx+KYh  ++i+ +%;*j%K/aS2ia[haiiB ji\ Yi3a*jI2*bQ2 #a#+a |#s`SH D  & @0' H & ( p |  L! OH& HM H & rhK2r`J!JZx2Ҳ!RZpJ`#pJ3ar h@B  % H& L! ' & 8)M-h F ;@h @I -@I zjg @z` ( fjz) 1zzK '  z0 z 8Ds8 DI@ 8(L(zE0'M: ' +:z' -zKZz'zK zzzzz0:zK'zzgzzzzKg'zz'zzQ8@8H 5<@ A$ & @FaD& L=DI@&  zz 8 F F 7@ zzzzzzz  88- H F F F@H @H 8@H ʰ@L *@L kZ+zeZHZz )jk+z*z( Fjjzzk'zkhzjjjz+jzhj(z jzz8ssB(@pGDpG pG -VKVzVzVMfhzgzzzPK0gzz:MKz gzFz* 0zz*ziFz:zzBD0z+9KZx9Krh@!Qz7'zzzh@#:z-K:zwz*Jzz(K)L 'hxzzwz 0d 8D `gh 0YH 8D``h {/NKhD`Kh8D2`` 755Д z  aD B  75|&  & &  $tI$    &   #Khz"I"N #Or3h(` }IJ00`z0`J8zz+hgzzgzBzD o".`0(`#+`   ;-A b(ЧKLN" `$r , 10`3*э0#01 ' [ ' 1O \KOBZ'MkiCka ?GOCk4   >#J@QR3$+~KJ` pu1+ vH tHrHpHJO`nHOp)O ReK "Z_JOA'F0[M 0 kiCka ?VK "OCk|OpX# R(h3# 0G C   : O 4 / cy]kBkA# 0cyYJBJACBCA0N10P10O@Ozs 0 KJ100#O00O010K00 #K`cy+KOrKOzrK"K"Zs( L! & @' P MH@@H 4  p | & K "ZOB$OB$@-OK 0*RB+[B$BF%FF'FF&F00+?.=|K{Ih!{KH_[_QB@wK 5 *0  d#oQCjKiIFX`DBrP0XC0#aKy .<_K`;p]I 0YK^T DOzRbH^+[B . ѻ0+[Bd+#H0X }# 0O@Ky. r {C 3Oq x .BF;FSF1I԰hZ0I5 q\%  T T DDT D  D  O RoOD6D.%  K ZJ҈ڀd' L!   L & H  $( D' t F d @ ( |' -O$%F'F/FN@і$0 3SC[#AK8h!@QB>K^s* D;Jxk#08y3KC:|PC #3zCC2J5࠻/I>D zT 0 0 D OOO#KD XD0Or YCKT TD  `K>N#hD=J#`x3۲p"7G0O 8FXD10c̐0  PDK"h`KPCOzr AqJ# K'``J3B6 9' H L! ( d' ' & ( I@' 4C  D x' m ' ( @~' ' 8( $( '  8 *JB ?'K&K+  (#KZi Za xK "ZkxK "]KIh h*h{JXpJPi# sPa `#pqKx[O`0O5z'  p @,  & $ KDL! -A #O(7"LFF0貘G"@SBKI hK@+;c3 K# cDDD 5-S2 `$0G'4,ѽ'  L! < P (03J(_(1K2K[2K2zYxz1L2HgzZz]}.Ifjz,zjjZfjxjjZfj{jjZfj}jjZfjxjjZfjzz\{}JGz'zz:Gz K'zz K`0( m=?H B( X' l' zDEMA-O- M1+   '20 IJ hh,F(nC 3`O@z Kx >OppO(;ЍNL0B, !:z DB#0}K20 B xN#3#"AF^BĿc۲2BC@*iLȁ"xBј *2" O@#p [NXL!0B DB O@( 1BO RJ#`S``PJ`S`F0#EKx+@O F0s@Kx[DK[xC1ј0+@;JSxFñF0##x_+1+𰀶F0+@#x}+@r"xW*/KOzrOpY v)K " o&K JxZ*!Jxp"K KxpK ""p#x]+[+^+F0k"xo**};L! , @ ' ' H p  & 8 t L p | ( n \ ]   !#x~+#x+щKOr+#0#x+ѳ3+ѳ; +s3+ s;s Fp#0 HuJuKxquIIxYBxpHp2$[|SnKx*nJxjJ2!"jKx2eJRxpgK"pgH#"0T$$@ "C@TB̿$$>"C@dBԿ!!\@3 C +#CLIFB  XT3+FKxFLKKK KK0B  o@xCEJ`S` O #HZ  KThG KShGK Kȱ!d"*j zzzzgzz"` L! ( ( ( ( H  < j z z Kfj}1j:zfzz pG33S@EL! @CXCK@rz!OzrPCx!pGL! 8 %$ D =O I~A#"FB3+"DJpJXC!SCJ8L! . z' ' 0 J Hh1KB#H`hH@!@IP# h,D$ `0t H    pKMh*h*!N+`3hL{ciGhG+h"hHID+`iG#3` phG#iG+hbh D0`+`p p, l x (   K-O[hHIG(gKԒF*L&5FF Oz !#Q a9Y DQ#i3+z#a#zz`j:wjzz6z7jzzzzzz#*)0*09#i+ ;:z  Kf1:z Ozs0#0$080`{`;` YOzr3 !"*0q5-|0;0#9: ) 3+lOjL8dM(@#FiN5!PXaDP! R3+]Nj( 0Osj! 2l! 2QJn1PKYF;;; (iJO:2*IKjlYnBIDKHY*2#F@H52*&FPFXfDFP& R3+0Hja*5Kp5Kp5K!p/KjYl,In1'KIX::,Jx&I#hp2"jHhhIl Rn! JFS*j1+jl1kn1( t& & p  L!   @ H :  n  \  8JLKUhOE%GKe"p8L! @( p:K:Lh"h*j33#`6K7H[hG6K7I{F"h `#4ND"p!F.J2NZS1NS3+хs/Kx(K*Jp(]rt!(X h+1"h!H"I#JB"KZi Za#J^ZBĿMZS^BLS3+J#`^^J,D%D+D+pA FM p p, ( & &  L! @B@BKO 0O0C#@H 8M+hF!Fhn+hyT@q8D F @ @޿F @ӿKhZyQYqDypGD F F@8F$ FM , L > ! #h"(Fq#hF8@D F ܿF ؿKhyD pFF F$㲝B0]w4pDm-C'$%KxBKJ\ !#@F F &FDNEJ65$$ dWGNGM3hGL+`O`##` hd#h3#`AM!"(F # +p$#lpp$ h#OPf+U 3K"4U4F H*#+U!Qp"T4 ~( #+U4Op(c "*U "T4O{y*+ #+U4 # f+UyK"U0O tUi K"U{y+*#+U!Qp"T4Kp& L! -O%KhBpKNL"33`Kx OھO;x 3hLh(R#hh#hI $bBbAI *ѭK[x+#(K4B *M(""&*<(""* @(OG ZqHq"*yFP@q"*ѓHG ByA@qQGDqB@F0u+i+@E+ȆB+ @+A+@φ j$C+RD+@Æ ^pJ#pf+bd+9e+@ LjK=FD D [F WF S@D MDD DDRJyxDCSxCyDSyDCSzDLKyDzD$YzDA$yD$zzD$D4Z{DB4{D4|DDyDZ|DBD|DD|DD}DTZ}DBT}}DTDT3K xFg+h+@1/Ho+$l+ƃj+k+@! &Km%Kh#KxѼm+n+r+Kp+q+@L@$s+|t+@ D $ & L! D ' F( ' ' l +݄>+w'x+ԁ v+Vw+@L xSOF++@x0@$+J+X+@𓅿L r++++F++zw++@qKJ+ń +ˀ+@bL`8+v+@T $$<$KS4, @KLrKp ```KKKxBp z4`pvrsDE`u|KxB҅KpzKH4F]vLwY U#Q$M%I!E"JoaCoLeO+?@;B7D3%!|@8 }~x$MKS4,oBK[x+kEK(O"F$Y  ;KXy 9HhB 4J"@C3-K -K-Lo&O4#%L L}vrnHs G ( H ' & ' ' ' 4' l L! ^( @ &  & 0 ' 8 LO~62.K[y+++Q+!+2L_+3+F0_+AѴ0_++6Ѵ0H@*_+Ѵ0+"Ѵ0@_++Ѵ0++ Ѵ0@@ t O~ 0sKFt!عhй@'_;FPF!FJFX;FPF'!F"PPF!FJF;FI|mй|_O SFHF!F"5'SFHF!F",SFHF!F"%SFHFO !F"HF!F"SFHF!F"SF HF!F"SFHF!F"SF6#_!F"KF.'_;FHF!F";FHF!F"'HF!F"#HF!F"#'_;FPF!F"#PF!F";F 9!N :$K_4,ѕ .KLzKx h`h K K KH L! ' & ' ' ' 4' L L K$ KhK K!"hoKOrh!^KK|!K2h +[BXCh(@B!OrAL B >#:$6%2!." L 4`x!z`}DE/ H0B݁K\KB4F$KJ#DzB 40E$xL P@BD| ( #}~3 $4 ,hF RKPK\h$FHF@F FIKh m,*k 4UKhTKhSKh0BPK]OK]NK]MK]4 IL`q=OVXZxzP8L `yyqVXZxz, $$K#D4Q,zK#D4, $K]4; , F C 3h"I 5D' H & ' ' '( L! VBېBFpGFpG Դ ȿA pG` pGAKV!-X)t*;z;zX!Z19I*hȊ p( :'ꪰh *z'@h @H @H  @j @j  zizGZZK* jijZFZZzHj*(( ih ZjzL! I@4CH 80"L-:0 z :ɚ芰0) : FȊz U z() z F zh) z 78 :*0"& CC [BK[B CC[B [B C C  CC[B [BK[BKxF|pGH K!!#K`]L! & pGpG*K+Jhh`)JhY`Qhh`'J`haQhha%JYahaQhhZb"JbQY҈څJQYJنQZJx"BLB4@2Jd JlQp JnhfJR^ \ , ' ' L' d'  &  F( 2 &  0 I8+ F,d ಽ@CppNLMG 0x#h(hchhh K K K3x#t+h`kh`p' ' ' 4' L 8FF#F IX8+ FI׹+  S+I)]pGe-O F BM kh3FF+hBv=H+hFT#<9Hkh3k`7K"Dp$5KxBT  !\@0KhB kh3k` &OE5'Kx!, @4!p+h #XDCDx ( '00&Jh4x#0004 :h2:`O2z`(hHE,  XY I -OM+x;+-Pg{ON9shd3B@$KJxB 3h}O\0;h34;`1hwKR\*@z`O2Z`#r##sK rH !3"F(@aOpfK0O2`Z`#S`#O#dJ#cH!(@AXKO2`Z`#8[J\H#$!(@*MK,p`%JL#hc`##`HKxchD@+@#+c`@BKh + ^^  $)2:BKVDHch;OBHBICJch);GAKAH$ch;<=K>H9K=H@7K;HBch;*8K9Hhch;"6K7Hych ;*K4H}pch;&K0H~!ech;,K-H]ch ;c`#h3#`2FE F"J#`"J`"J`!K`# I h\\X^(\8\^XXVXL! XH YY Y( 2Y@ EYRYbY }Y h Kh)@MI ,hKh h`hhh i`ii &O";h@BS z6.Ѵ(Nr*n,j@1.S;hզKd0 G;hZ;hՠnN lInEpA0<2844608,:(@1<&KxB F6<<0;h+h^P+h{J|Ik``KC3!A[t!"*`oH4$9DB#eNZP whh3hhhDshhC$ ;Ph[h4 ,#  iiQ3 +"FX ?( (1)+##2 *++CCO @@pB ?@b^Z %cS)(O @?J 4J J Bj?8% +`] ++,`Y &`Y !`Y@ `Y `Y@`Y5 -O Ѭh \ L!  5rOK!h@B Ы ;DR S<5-# (( D 3+ORO_i-H1)HHB@F%FF)))6ѻbY_F-`Y@ O # `Y@ `Y `]0@ {`YvbY_5-OѻPFguKhUйdd0%P# llA3+5 nh A<5%-J$k R@ @;#O T+2  E2h2rh2h20" D4,$2h[D4rhDhD"0 D,$6KxB2h[D4rhDhD"0 D'I hչ^^0sh2h`"K"Ir`JC2!ARt!33`Op(NKIhBFLM`"h+hB bhkhBJh+&Kh["H h`h#h+`chk`#  5rO ?B' h JKx*|BJhhBRhhBs Kh2` Kh2 *"` Kh2`#+p ' ' h `N3x+@^M  B#4 FF24F"F4OHOIAiBĿ@BKJ̿۲#p"1 0$ ,hFDIc,hFCI zhFAIBsB?I?IhF"F[>HiF"6P;HiF "08 86K4B0pN!"3H3O3K3J`t2`Y`1K1K$<`;+&!*)KxB  hyCXBXA$K#Dz0   m ;h"@C;`4,L##`#``3p L! ( YI YYYYY+  \ 2  H Kx* $Hpp"F I@o + YO /K"pp  pG pG FFF pG+ FFF pGFF pGHpGBFH<@K`F (#h+ѰXBXA K" @ K" ZOpF$ F@8F F7 !(6 ,D@(@ d,  (  , $ <88J#pF F`F z(2h*( )F"H i f p p <@FOrH T Q NCXBXA<@ F##0#0#0H#iF0']@YBK" % =(F)FL(F$\9NOzs Oq3`>(3 xU5-ѝ0+ѝ0+3h3h+ OA!(: !(F 8U4,ѝ0@ $ $)F ($%%F3h[3h+ Oq($(F!( Kp Kx"pxpx@ l J KxpxpGJ 8KxFF,KxXI,  ع(FOq8$ h(FOq<u !v  8 8J l p,KFxFFLxYK(KxXv, 1Ft$5Op;( 0(F8$$З !FY 1FUOpP (F<uOp(   p p pJ l rKx F܀(Ԁ@ !F$hF!R(Н0 + 0? 1"] "C2;!MN3x뱍 !( hF!(0$ <ѝ 0"  F(hF!(1x 0a ? B 39@+`J[ 33+`F=#KxF?p iFT(i0 ѝ 0Z`3xXIO Xdh(Q!F! aF(I& Z(CG0P!8$$- F pJ l Op!LH#Op#pK"`.   #$    #  #   # Op(Op##pL:0! xm t KhK@3KHI"`pGd@ p d@! #B\T3DBpGhFFF (:( F B08²*3 `O0hsxbوBXxF   ~~(C#H} }B"CCFpGj0F9F@x*F#2#j qiB x.٣i`xD9F*F#> y ٿFpGFF-R#x+Gfy.D08F)FOrzU#A".2#/23 R#""i0010a#202#"2 "h2#"2 "i2r!2b`x9F3Feq!`x F0 jBpF FFx*Fpx0#(O5$b$ Fp#qO3bF.2/"C"KB(єh i0Bbf0Cg0B"K"BBД @` C @ @   UFAT-A#`FFF_KS'@,[4`#xk`x3-R R##p`pEBC F!($s"xIyy AayCXyA!M2*&]P- F)Fh  6.%( < ;0C#єGF0S єVW0@`T0CU0@ @`as+pؔ=p)K BєA0B C""єDpC0S# єR0SpCcPp;CQpC#?>pW(gDB+@qBOvB&&&3/D.caa!bb*є^ _Bb\ C]B"bb*?t.OCaDab FRS/`O3#a`.OcqXєa `0C#+P Fi(Jє.2/"`qC".KB?є2 30Bb00C10B"&KB.є"2Bb2C2B"KBє2"Cc"C"C##a2"Cc"C"C#`J&p3  (F   | URRaArrAax Ci9;B=xj0 pG)F F^CiB[x+)+:+TQjV!O0w!j&D FW!0`(F&5Fci5B. % F)F0A(!еB F)FopBOW#i`Z;#acyCcq F9F*F=((F( -Cƈ6FF i+Yh3ahBPx:Kn(F B hCiB4/hzF(=(C hF( h9F00Or)FHF5,#hxB "q h(#hj2b7jb` h)F a#hOH0CDca  -A x/+FF\+6%`3x+I F)Fhea\+@Чi !8F "%:(F!*F0< +6 +##-t8x( 8p)Ҳ) C*Cr F!2`iz(JRoaizL#hx;`3x/+F/+\+.+RЍB;Հ;+N\BoB, h!i(bixzYi\3 B + F! ($   A.Ba. ;B۲{U5h)ђ FҲ !a^^!Fp h!iUHcix+; F!( 8FF h!i<F``i)F "i "`ii[#h"q(F8)pF F$CiB!ciB F)F F p(A F)F"h#iZ3#acyCcq5F p p@F1 HP#F p!pB#P,iF"@ | -CFF(#`'(@ , BH(gG 0ozjsd>8g#&ssr #t&wfwww`t!F#vv&ufu0F@F1F,O(?>`IFrH7(5z/Ա-;O,0aHG ,bqq!F(aCc"Cb`C#`0a0F    -OF#0FFF(@y(@𫀣y@񦀣hB(%h*w h : S* !iYaiF(hhB}`{)JU#iaa!ay[ !FiQ$;Xx#(Dѣy#@qaiXF 8_U( "Л0 B9F2FCFiAE $A!Ory#@qOH&&iBТhhB қ$2F#T qahvB8.F D$09F2FyC@qh3D`03D7D0dyC q  Ch+7F]D<-s *Fh 0]ohe`3`0pF(Mѣy *F[ !FiQ$;Xx#(8ѣy#@q hi9F%jzC rh+w kw㉫w{w#iv" +u vku#uu +vhvtty# q#h"q hp@ ppF FV `F#Fy*O0 kF(B]KxF ( Kh KOzq9Y` I #!`!`KK`##p \ j8- F F!( F! ( F!(ѠFFF$B1](F4-AFFFF$CE(F9F0U4p%#!F& 0 P P`OSA=*H(H !"`&H !"["#H !VO@!OsPP PP0@,ѭP@ ,ѭ@P,#`0Os! H0aHH/H!Vp@<@ Kh2`pG  J IhhhBJhhOzrPC  KhpG 8FF@B8F,Ozp< N@ #xCssiL sa8F%% e@@KJ`KJ`pG ᆳ  JKh ))JJPhQhPhJJ? IIhA1BCI`JIh\h@`pG8@\ $zK OKOp MKhB`"`h!q!1`HIY`h!!``hB2`@Kh22oh3#+ 4Kh"`4J hBb`0.KlBRd.JhAA`h`hBB`hBR`(JZ`hBr`h J$K@a`h#`hC`Kh +hLOc`GJJ`KhOzsK:Z`"# "`"`O`|8@0$0Pp@T@<@@B \ 5FiG#1 #15hG 5iG 5jG 5[jG ! FF@")!@" F###15x[hG iFF'+ + FiF FiFK FiFp Fb pF)<ѐ1+A4! 1Bx)4!$ D$1 F$)8QV^B <1B2FH .؆h&@`h L`Fh&E`yFh@5CE`h,@`yh"C`3+ѽOs`#qCqqqpGpGApGj!@$bj@CbKBO!_OKBO!TO KB O!IO!@BT@X@\@𵅰F2OhF F*h0K&?66 L!!  B! S  +# "KsBB#SCCC  COrWCOzr7CC'#iC###c# C C#*C#@BA3`#KrCOC€pGC# pGCs#s pGCs#s pGApGCc#c pG C#pGK"pppG8@Kh **KKYhZhYhKK?JRhB2KCR I`h J\h@C`h$]#`hB1R\@`8@$z Kk C"cpG8@KZk C"XcpG8@Kl C"dpG8@KZl C"XdpG8@Kj C"bpG8@KZj C"XbpG8@C +Jh+ oSo#pG8@#1 3o(1 0 ]KZoBrZgpG8@Kk C"cpG,@K[kB  pG,@KcpG,@KB OP!OP!@KBO@!O@ KB O@!uO@!@n0@8@<@ L#C#C̈#C #CL#C#C̉AR#CC#c #CÀCÁ#pGC@#@ pGpGpGCS#S pGB  pG0$$$ %*C$ BD!C00$$$ %@u-- $DE"B3D0JBbBаO Т2BbBbBJ#pCJBbB#@s CKhb KBcBыz#pG@@O3C`#CrpGC# pG# p N"s *C#5C +CMBeB͉N#+C#+C 5C$@t,ChBcp@# 0 $D$$ # D$ CMCMBeB͉#COu@E "@bBMBhc0@#s 0 $s$$ #s,C C#MC#MBeB͉#cC#O5@E# "@RBMBhc0@#S 0 "B #SB" C3MC3 MBeB $DDhd0@#C`ÁCpG# CpG#c C!pG# CpG#c C!pG#"CÀpG@kpGkpGkpGlpG#  CpG#@c C!pG#  CpG#@c C!pG FI+F> F鈽@. F鈽@.'w?? &% eFE!CAq@aF'W?? &@v%U6mm 6 F&E1F3AQ@aFD0)oCCoSCD0pG C#pGB  pGCpGʈ0#@S FC Ci C"R" C#@sCFhFKBcB**hORYCd# (21 21C"0@CS#S pGpGB$B 0+ 00h C#`B  pG #@CpG7#LF +h<i*BaJi:  0A 0xl3P"FBQ"(`2 02@#BO hA#3D"#p)O@p #p#CpOsÀ#rrOC A #p#CpOcÀ#KrbExa`FF$B g0aeWa41FxbBaDb ebFB 24RTFB R`c 1 @8z+FOP /$ѓkazeC Cch##PCoooQCoC`+x+>#cDhE `6hC@`#zbz+O4O< Ch ch!zh)C3`#z+k#ceoU-#EUcEc hEc x+hh"bDE ` 8hhB` pGhh"` pG#C ahaKi; U ]A #ChaKi; 9 ]A hh)o]sosCS CC`2 ) hXipGhZii@pGiha`pGhO1#aQahQ`QaIaxB#CpiC`SC Ca pG8 1"`iFhe"`z+F!h!OaYbb"baEOrQboEQ Q! FQ Fn"i#O1aSaa!iabxB3ih( O@` a `#bxB3Rmh( O@` a ` iCs ax+K@"bYC c Fs 8ihA+++ pG pG pGiih hA( ` o  `ZhBrZ` 0Mx x-Oic%dmcB#h ԍhe xɈeCaSCSCC#`ii Ca 00Mx x$-"Fic%ImcBio4 `i!a 0Nx F xSi.Eэi)h,icfD h?fDx.f^t,axx,iila x,3i'fk5Cecx,ihTAQAQxAAi!`x)6hx@0Nmh1h4i+e#cD +D;cD ]Ce4ax+x\micax+SyAQAQxAACm` Ji=фi#h&iGBblPphBfbNa">FbP`"ax* xi ijaCC#`x+?Ki+<i xXk!CZc3 x\m#h%iFhJ"ebp` :FeMa 5F"bP"ax* xTm iba xCCBm` Kx+ x тih+CCC`CmhB` pGKx+ xx iBmh)oUSCS` pGiii@ pGiKmhPi@pGiii@pG##0"Ob0#0Cmax*`XahO"`pGzcih 1 !oAo`pGFA#"1!#FaxB(!@ ! 2#F"axB(!@ H#N#IKPT\2 F Fk F!# Fd F@ѼpͲO(q\q pMp`p̀+# q p˲O(q\q pKp 8(%eC\uAKa#`aKpDUx+ ay 8(&fCv'OpU` a"aKaa ˲O(q\q $p pKp ˲O(q\q$ p pKp Fi#a h C`pG-OF  FF(@(T F&FFFO H=_ FYFF sm%`xBix33Kh FhYFGx+ Ѻє1+ Fsm%`jsm%`+՘Kh FhGsm%`  OX6 (  }@ FiFF&FO #i_i]k% ih C@Zk% "Zc0`yKh F[hYFGxB ѹє1+ F4i0%`*0%`0%`0 %`i0@%`0%`+A01,! 1B8F 0iO cE)0Q,1B# !$]B(F O FZF0$1+D$101D0Q0i0%`  OZ (6Y h"Za/ڣzC 1 !oAo`#iZh"Z`+Kh FiGhOBZa 9%Kh F[iG#ihhOaYaz 1hB`hB`KiBa ;Kh FhGh"Za 7hi"aj(%ECC+\u+ Fa"i 3Da` V2F Fhh3D`iDahiBa 6#iZh%"Z` F)F#F*FaxBXi!`m2`#i&O2fafE"aZa/"aho ` F hORZa Kh FiG0F F`h FhK(#pOs ##p@##c%hOR` Za Kh FiGhOZa  Kh FjGhOZa ` L h(KJhIhG##`  $ - C# HpG Kh*`4N"`3x+.L#hoK"`!hhB#3p KOb`h590BD!`=`)D!`!9` L!1p"D!: - 8(# M KiF(FG5 F!*F@0 8- $ p x`F F' -!͈Jx K!IhF*FG0FIeKI`K*F`v%(KFh)F*FG!%Kx + ++K !+ʈ:*(:"0F I I"9xK`(Fp$ - !F} F!y! FuK[hG $ 85F9 !#C5 F@ !#:! F"#4 K"%q]qKhG5J@0 F!\(F8` $ - pKx*M)h p5 L90&hBD&`1D!`!L)`"D!M p - # J IB IYXP3 H IOB@+@  f 87 pGKpG -A 9L:NFQ! F F F!"" F!%#' F$OXp p P P0F@ p P @0FAF0F!F0F`F0F@F!F/Os0Os0(#00F#0 PPp@P0F)F0F!F F@@8'MF!(F+,, ,,!,6#82@,% ,-#8C ', д"#8C8#8C#8C#8C #8C(#8C0H!8@0@K2O0pG 8F@4H! <, H)Ft@4H!|0<,H`80@KpG K"pG -C FG !C !?UO !: !6"8F !$%&Oh8F@ P ` @CH@ P ` @u@F@g(F!F8F !"8F!""8F!OS8FOIPP`@H8FPP@`:OC8F P!P"`#@+@FXHF!FOs&0Os.0(#00@F# 40$`(`*P,@2`j@F1F@F!F@ @8@8'MF!(F|+,, ,,!,6#82@,% ,-#8C ', д"#8C8#8C#8C#8C #8C(#8C0H!8@38@K2O0pG 8F@H!< <, H)F$@H!,0<,H88@-AF FF~5O@H! ?/HAF@ H!@?/H p4> 8@KpG K"pG KS 0hzqKCOzp`pG KS 0h`pG KS Bh# h$h`C (K JB"xCpx+ K"pK(9pGpG  p JH@#B L#"@SB x(K##x3#p  d -OO\TO[ @& FFC! FBF F\0"# O 0 z0Os$08Kx p!+ O O +*********" F FIF| F FIF{ F FIF| F' FIF{ { F! F!L$l``   48<@Q`(F+  _KxBKhG  KxBKS 0h`pG h K3pG F FF'#0 F#P` 0 0WpFHM"F4"p+(Y{"ـ  @RBؘx K# v+6"(Y{p@ _ -OlKO &6h#FFt`h0O #'iF0pZY!{RF F:FOqJ F)FZF0F _tK|-ApsK|pF!  !O0!kH !"riH !"mfH !"hdH!"caH!"^_H!"Y]H!"T[H !"O! FXHJWH!"ETH!"@SH!";PH!"6"MH!1cy"+KKybxOO+##3DJR#p%z]y*Ix?K?J`"`=Jaby (#"y#"6I/6K"pE3N3I2x$3x33p:Z&#|* !!!|*A&J|JCOzc#KxKKxrpcJ!㉒KC&5-ї| J`  @@@@ `_ eE %@B   h uhhG8F F(F8h[hGhhGhhGhiG"Բ KS$0B"ӲH0B``pF&4K] F!([ F!)F F,K%5 F5F- F)F(C F)F)F F K%5 F.- F)F(+ F)F)F FK%5 F  - F!( F!)F FK%5 Fh ({G6.p` p FFFn(K"0`qsp )   !!!!"[pG8F FF!{h*F h!{8@ۿ#000J]FFFSJKUCh>OIBR:# 0: # F 00p@B\ @Fh h!(`{@H@O@H@H@H@@FkF!" : 0C#:Kzzgzzz*  B"*zgzzz*  B"*z!Fgzz: 0Kx  -A^KpOS$0[H@#0o2 !F" !`" d  %'F&F!" 2 x  0DB FDBF_D >KZi=BZaOO !" %!" 2 I  0B FBF_&KZi=BZaOJ!z!Mzzz!p" zzzzjzzzz'zzz<! " 7 !"2d FO~S+`k`` @ @@oF ^F7$FM !"P0H+K+`Kk` F0KppG KORKppG@  pF>H FOa  Oa 5H 0 [Oa.H !"OaF'H,ѝ0 C"#  B"  B"0KhFx1Fn 0C#0 0C#0 0C#0KhF)FxP Fp@  pFF F,, ,\,дb,$ $$$$$$Oa\H'k ? -W@9*>h!3?h!I@*"AO8@zJ$@Oܲ~_FЕEuh-;П? -g 8*7' 8O2аOA<)!*I* ;-8---@П-z-z0 0g 8*z* ,g 8& # 88@O"--+z -g 8zz0 7 8:C:8<1ڟ 8-- z -g 8 8 8 8I.3I@?ɿI?I@-GZ5G-Jj&HOݽPHGOݸ~_ѷ .QO OCз~_\дOhд|_jc )@C~_Os;ZfзOs6JÉ,ρ4 ۽G˻,z ڨ~XZ;0@ ~_,ZOڷ~_ GBO ,jO ,ZB j& j % yv@ rj2B ka?KV_z`'zoJOV>EDH~Q@?JE@ 6Fj::JZJO *Dzwj*&*IAQ!DwZej1z 7 &z `:   ::DgjJ!ZZZJe:vZ'zeZZ$ZEzzJ:7%zj ` *7EZJ'ZuZejjf** ` ***vjfjjvjfzz7$z7z*"b"*5z7dzzvz$d$ZJ*vGjf'z"zz :Z wjj:F+#B@󪀲O{oв|_~"F#c#:}j}*}:}*}J}J}Z}Z6z&jwz:j Fzz'zg*"J*JvBjZgjZjjFz7Cz'jzwfjvz0g :D:(   F!XJET,1V Ujvj7jjNz(' ' O~:ADQHME"*7ez@A+7j@B:^U2l>>>m>?aO8v?Ý68v?5r1?r1?L13ݵU8a 6*>?Iq<83C`B ;?p6?aap:J#DBjFfݏJB+zJ$@ۀBpgzfПzwj wzj7zzpJBfݴOI:TJz~jz7gzz'&zzz7gzz'&z@zz@@z ##nI )F.ڕzzGzgz@Bzz" B` pp@z zz[j[zwz wjwzj7zz$SjJZKzz&zzj fj(% fzHKA$S!0B0gzz0G .pgzzڱGzgzzz@B0gz*S+ݟ1z1Z@ZZpezzz5z*S,,܅ze Bp'zПzwjO0wzj7zzr#SjzwzO0wjwzj7zz]zZe  uzzzI?@??CD57ICCPbD57."?a.21$:#BOp0j+=۲OQ,ӡCH[%V[,F!OrBD9OCORDm|UUZppG ppG [D0@ "D:#CH_,z:+``z1J1Z1Z1j1j1zZ'Zj'jz''z j z 7@ pG`zJZZjjzJZB'Zj'jz''zJBC:ZuZ` j jv 5 pGZj pGNGt1| 7a *=>H?-O-װLd9T%FH#sCFeD0"+XzjzBzѸO C^DBzQF"F#j2z3BzzB  DFzxDV3D, ݬB2D1D`(z@zzrjzz7 z CB@F@ ) zgɚz9g@a\!0CL!0DC +-*, *@@cF !S+pC !BѸ ݸb\"0?L"0+iе@xgB fD#V-^EC+@S\# *@ OS-*ЦDfvE. De ewDBPzzz QF"F#j2z3BzѸBztF@c\#0lheC; 0I)@F9@@I XB_z Tz zgz2zg z :L$0JL'@ /6}B*z 2DszzcEgz  bzB 逐Iz"F#Bjz3EzV0BC(zd,𳇇*b\"0L"0z "wzzBE[*!2, *?!/@󹀹Vz. DS(z/FSj6zvjvjGzcjBz/@VDQ(zF0Sj6zvjvjGzcjBzPzF3zBwz,}.j/zgzfjGzzjzW/t.{;z3zBwzgz.j/zvz/zBwz gzz/E{.%z3zBwzgzzz$gzO_\'0:+ݮ S?:) z,./z*`k` 'FZL$Pzzte:#CH_z:#`zZjjzZj'Z'jz'ZpeZzZ z  0` pG zz pG./4/ײ86 P<*>* pG pGS+ P1)FzOv1)O=HAC'@C O,)#L@ 'OG2KI?JD6zZ'ZD- ugz0g $80 85jp&jzj8c/KBܣB*zz'z#p'z'z@ 86zg g 8!KB zz'z#pgzz|zz#vzpGz0z#zl?ɿ>i8㽫>LeeIq?@*"C:pG:#@O  pG:#@ 9))F"HABzp'zz +!$ ]KpGO:]KpG0 ]KpGzp'zz+۟ OC D( :Iq:3@ pGO pGKBB pGCXBXApG pG:3A-*бOұ D)0)"BBR*0 zJ 'zB:"Q*9LP2B ܟ:H *  :H   ' 1"BBRz*'' L<`B Iq3!BCC:pG! "-NFFFF +&BҥmPFIFG(n%F,FHFKhpG #B\T3DFBpGF"F4x+\T3,ɲF;BFpG)FpGF+*8pGKh#B\tdx,\ 5x/ 4-3,%(F F2KK:,DB!0x F x+ 0"F4x8#\(\B30F0K-AhmFFP e`m`D`a`ma\ambbm\ccmccm\ddmddmwm\b0F9Fm#A h(FF[k>B F`pM`(FkB.F#FF[!!p+F`F?H-OF4F[@x&F--Ѵux'+-ux3 0- xX(Qex#4+ #/ oJOJ&0F 0=  лOW O7 Bڶ? HEUEP&O6[s /O" o@O@0*@BBa`+# 0FJF Fh)F"F0@r KFh p%5 -8 %-F?ۍB=!KhF!F h[ + `PBbh`Khc` F FIhL#h0F' `)F0F"CF$B %` #  ZBPp0Fa 0 #3` pL H 8L#FF#`C#h+`847 JhcDiFB`FpGK "`O0pGK`P 47 87 AC0OAOCT U d\e\OTTUUmB ,D6-0OO1OL1@BaAOO3L3RBcC𧀤  "ACYA  *(L CQqEO ~nӱ I_0O< ODR𚀼O_P PAQA0_L @AAёF  3   2  ! ؿ  ܿA @Q)C0o< 4  @!E0   @)F0!)F04=Nd\e\)ДT FF0! 0_T\@IA(AA0<0EEAApO0d\FFe\ FFP4R5A!0!pG0Od2OOP!pG0Od2EH@BO>BOO1OpCO`QpGOpG0O`tE!A PpG0O PpG0E@BaAOd2_\?ܮO_ 2_ 2  @!DpO LlTU  ,D!LQ#LSP5R5AC8РOBOVNd@t_NmAFB!AUQO @^PO. oؾO_PPAQpFF@\¿ AQpAO<6޿ Ap <5 4  @B!Ap!B^C pp   @ApA^C pp N C!A! p^C ppF@AъBWٲK  @C) 3 |C GB <B@:/DqFABI7퀈B@;CB#B #FFF@BaApG@BӂBހ#"#*9( #2 wBG B8ҺBAFpF@ E@7҄E:FBBCRBcCd@BaAO4[@ '( &@C; CA BI2yҋBw٨)DGG B1`ҺB^;/DCC %C OI! C 3: BC E 25ҚE39cD 3GG E 3ҹE:gDBEBO *F bF;FBj#F FFFCFBF :S9/D<-FFF+CъBSٲW  C! + gCFB 67B@:&DaEAB 6 B@߀;CB#FFpGBJس.MыBӂBր#"FFpG$*| & #* BAB <ҊBÀ`FEEB,1𖀧B@:BBFFpG#FFFpG "@COH! /C3= EC E 2mӔF3GG E?3aFE L #BOIEbF+Fc@ !& C ̧C LcE  2:cE8٨D A AB 0"ҊB ;!DCCI:F 3F Fk@B 2#3F2FE٬ #DE='DFF8!D:# (( ( (( F #F@@@@@@@@@@@@@@AAAA&A*A3A7A=ACAFAMAPAUAaAdAjAqA{AAAAAAAAAA}>>Y >>>>>> ?6a ?(?y??? ??e ??6?] @ @u@6=6F@N@V@^@e@m@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZVRBrain CLI version 2.31 Jul 20 2015 / 13:01:43Available commands: %s %s System Uptime: %d seconds, Voltage: %d * 0.1V (%dS battery) Hardware: %s @ %dMHz, detected sensors: %s ACCHW: %s.%cCycle Time: %d, I2C Errors: %d, config size: %d Saving... Rebooting...Must be any order of AETR1234 Current assignment: Error: Enable and plug in GPS first Enabling GPS passthrough... Enabled features: Available features: Invalid feature name... Disabled Enabled Leaving CLI mode... Resetting to defaults... Current mixer: %s Available mixers: Invalid mixer type... Mixer set to %s Current profile: %d Usage: motor index [value] - show [or set] motor value No such motor, use a number [0, %d] Motor %d is set at %d Invalid motor value, 1000..2000 Setting motor %d to %d aux %u %u Invalid Feature index: must be < %u %d %dCurrent settings: %s set to ERR: Value assignment out of range ERR: Unknown variable name Current Config: Copy everything below here... mixer %s cmix %dcmix %d 0 0 0 0 feature -%s feature %s map %s set %s = NG OK Custom mixer: Motor Thr Roll Pitch Yaw #%d: %s Sanity check: resetloadLoaded %s mix... Wrong number of arguments, needs idx thr roll pitch yaw Motor number must be between 1 and %d Entering CLI Mode, type 'exit' to return, or 'help' # ERR: Unknown command, try 'help' looptimeemf_avoidancemidrcminthrottlemaxthrottlemincommandmincheckmaxcheckdeadband3d_lowdeadband3d_highneutral3ddeadband3d_throttlemotor_pwm_rateservo_pwm_ratepwm_filterretarded_armdisarm_kill_switchfw_althold_dirreboot_charactersoftserial_baudratesoftserial_1_invertedsoftserial_2_invertedgps_typegps_baudrategps_ubx_sbasgps_autobaudserialrx_typespektrum_sat_bindspektrum_sat_on_flexporttelemetry_providertelemetry_porttelemetry_switchvbatscalecurrentscalecurrentoffsetmultiwiicurrentoutputvbatmaxcellvoltagevbatmincellvoltagevbatwarningcellvoltagepower_adc_channelalign_gyroalign_accalign_magalign_board_rollalign_board_pitchalign_board_yawyaw_control_directionacc_hardwaremag_hardwaremax_angle_inclinationmoron_thresholdgyro_lpfgyro_cmpf_factorgyro_cmpfm_factorpid_controlleryawdeadbandalt_hold_throttle_neutralalt_hold_fast_changethrottle_correction_valuethrottle_correction_anglerc_raterc_expothr_midthr_exporoll_pitch_rateyaw_ratetpa_ratetpa_breakpointfailsafe_delayfailsafe_off_delayfailsafe_throttlefailsafe_detect_thresholdauto_disarm_boardrssi_aux_channelrssi_adc_channelrssi_adc_maxrssi_adc_offsetyaw_directiontri_unarmed_servofw_roll_throwfw_pitch_throwfw_vector_trustgimbal_flagsacc_lpf_factoraccxy_deadbandaccz_deadbandacc_unarmedcalsmall_angleacc_trim_pitchacc_trim_rollbaro_tab_sizebaro_noise_lpfbaro_cf_velbaro_cf_altaccz_lpf_cutoffmag_declinationgps_pos_pgps_pos_igps_pos_dgps_posr_pgps_posr_igps_posr_dgps_nav_pgps_nav_igps_nav_dgps_wp_radiusnav_controls_headingnav_speed_minnav_speed_maxnav_slew_ratep_pitchi_pitchp_rolli_rollp_yawi_yawp_alti_altd_altp_leveli_leveld_levelp_veli_veld_velfw_gps_maxcorrfw_gps_rudderfw_gps_maxclimbfw_gps_maxdivefw_climb_throttlefw_cruise_throttlefw_idle_throttlefw_scaler_throttlefw_roll_compfw_rth_altblackbox_rate_numblackbox_rate_denomauxfeature_name auxflag or blank for listcmixdesign custom mixerdefaultsreset to defaults and rebootdumpprint configurable settings in a pastable formexitfeaturelist or -val or valgpspassthroughpassthrough gps to serialhelpmapmapping of rc channel ordermixer name or listmotorget/set motor output valueprofileindex (0 to 2)savesave and rebootname=value or blank or * for listshow system statusversionNaze 32Naze32 rev.5Naze32 SPADXL345MPU6050MMA845xBMA280MPU6500NoneGYROACCBAROSONARGPSGPS+MAGPPMVBATINFLIGHT_ACC_CALSERIALRXMOTOR_STOPSERVO_TILTSOFTSERIALLED_RINGFAILSAFETELEMETRYPOWERMETERVARIO3DFW_FAILSAFE_RTHSYNCPWMFASTPWMI2CBLACKBOXTRIQUADPQUADXBIGIMBALY6HEX6FLYING_WINGY4HEX6XOCTOX8OCTOFLATPOCTOFLATXAIRPLANEHELI_120_CCPMHELI_90_DEGVTAIL4HEX6HPPM_TO_SERVODUALCOPTERSINGLECOPTERCUSTOMr@w@{@@@@@6'@/@<@6X! (#6Z!  7" 7" 7" +7" 67" ?7" H7" W7" g7" q7" 7" 2}7" 27" 7" 7" 7" 7 & 0~7" 7" K8" 8" .8" 78" D8" Q8" ^8" l8" ~8" 8" 8" 8" 8" 8" '8" r8" 9" 29" 2+9" 2B9" T9" _9" i9" s9" Lh9" Lh9" Lh9" 9" 9" 9" d9" 9" :" d:" d(:H < 7: dC: ]: r: : :g :h d:i d:j d:k d:l d:m d:n :! ;! ;! ,;! dF;" <X;" i;" z;" ;" ;! ;! ;,! ;0! ;4! ;! ;v <x d<w d< ,< 8<t ,G<r ,U<y 0c<| r< ~< < <p PF<M <W <a <N <X <b <O <Y <c = ! =$! *=&! 8=(! F=#! dT=J \=T 9^ d=I k=S }9] r=K x=U 9_ ~=L =V =` =P =Z =d =R =\ =f =6! -=8! -=:! -=! >@! >B! ,>D! ?>H! L>b W>&  i>&  ddddddAERT1234AETR1234`M bbbbbbbGbIbObgb0?[]|"*+,.:;<=>?[]|!ޟHI@@@@__p_?_ !"#$%&'@M !"#$%&'HIJKLMHIJKLMDEFGABC@@@@@@ @@@ @@@@@@@ @@.@@ .@@@@@@ @@ @@@@ @@@@@@ @  @@ @um{eigSTM32 Virtual ComPort in HS modeSTM32 Virtual ComPort in FS ModeSTMicroelectronics00000000050B00000000050CVCP ConfigVCP InterfaceKacosfpowfsqrtf?5???I@˖@@S@A/AIA1bAS{A:A˖A\AA~AAA1AASAB: BBBB\#B)B/B66B~5.Dp&_~A99S9_(;/Z mm6~' OF?f_-u'{=9Rk_]V0F{k 6a^e_h@Ms'1Vs`{k ?973.P+'"D0C0i71h!"33h!38c>I?^{?? ((((( AAAAAABBBBBB f b1??m=  z d Ca3ݯ% C2 $$$$  @@ ]I=???KOUAM}Y @@We}a UFD"Ofwupd-1.0.6/plugins/dfu/tests/example.bin000066400000000000000000000000141325145456600203770ustar00rootroot00000000000000hello world fwupd-1.0.6/plugins/dfu/tests/example.dfu000066400000000000000000000000341325145456600204070ustar00rootroot00000000000000hello world UFDfd-fwupd-1.0.6/plugins/dfu/tests/example.xdfu000066400000000000000000000000341325145456600205770ustar00rootroot00000000000000iy_fs5UFDM3fwupd-1.0.6/plugins/dfu/tests/firmware.bin000066400000000000000000000002101325145456600205560ustar00rootroot00000000000000=   ? B = fwupd-1.0.6/plugins/dfu/tests/firmware.hex000066400000000000000000000006001325145456600205750ustar00rootroot00000000000000:044000003DEF20F080 :10400800FACF01F0FBCF02F0E9CF03F0EACF04F0DA :10401800E1CF05F0E2CF06F0D9CF07F0DACF08F00C :10402800F3CF09F0F4CF0AF0F6CF0BF0F7CF0CF08E :10403800F8CF0DF0F5CF0EF00EC0F5FF0DC0F8FF6C :104048000CC0F7FF0BC0F6FF0AC0F4FF09C0F3FF6E :1040580008C0DAFF07C0D9FF06C0E2FF05C0E1FFCC :1040680004C0EAFF03C0E9FF02C0FBFF01C0FAFF7A :1040780011003FEF20F0000142EF20F03DEF20F06B :00000001FF fwupd-1.0.6/plugins/dfu/tests/firmware.shex000066400000000000000000000013371325145456600207700ustar00rootroot00000000000000DfuSeTargetihex@=   ? B = TargetsignaturedeadbeefUFD'fwupd-1.0.6/plugins/dfu/tests/firmware.sig000066400000000000000000000000101325145456600205660ustar00rootroot00000000000000deadbeeffwupd-1.0.6/plugins/dfu/tests/kiibohd.dfu.bin000066400000000000000000001073041325145456600211440ustar00rootroot00000000000000 AM9999999999999999999999999999999999999-L9999999999!KL RM("#,KJ`JZ`KxxBp#JIBIYXP3KJB"C+K"+JBK"pKO"`KK2`"C,b @8@? @ .@@@Cirv(bUKh2`pG H L#hX#hY#h KhPl4@HnbHK!hHJK`ub,u  H K!hHK!hH@𾾌b(b4u H K!hiHK!haH@𞾹b(b8uHK!hIH@b(uDFBpG#B\T3pGr K Ih Kh hbIKN1B3;B0!2Ozp pG8FF@z<zu8CB$pG8 FFH,!(Fa"KBЊBXB H(F!H8@B#cchT8d/du8#M(F눛B,FH(!yHh!qH(y!jH 8+yC#+qKq(qh#\#3#"㈒BK"#y;۲#q8idziu-Ar9M`+x8L#yO[G4H#+p##c#qT0O;y /H#+p#0+H;*H~8y!'Hw:y*""Kp/#;K"pp#;H(㈛BK"pxK"pRKp+K ذ"*px I#;р"xI K"pb`@ddd0eu`@`@-C3L㈛BF FFX FkBR"cB""#FB)I)ah;ET!ah;!`ph7TgN7B pw*J#pKx Fд"px԰# p K"pKp  `@`@`@-AFKFFF!"0"#0 `,FBڍ@!"n @ɲ"a 340 cHt !$"#@u7#0#F F0 !"6 (F!F", 0HDH!"@ӿu7f#$0@ 0hF!" !" #H#I#KhB@`!JOs`S` K"p"Zq"Zp "qKOb` !" #>KhB2`KOr`Kh B2`!#F*H!"mH!"h ! "@pcg4@@`@T@@@D@g7f H # !" ! "mH!"@4ug0 " FF! Y# 0# 0@!"` 2#$0 @BЍ @!"L #0! F? H4Z ! "0^eiFx"IJH@ !Fu0$H1H.iFmx|+ H!!F"%,FeD  H -%FH)F"0uxeezi0$HHiF)x|+ H!F"%,FeD  H-%FH)F"0uxeezix+@#$0@|xs@n#0hF!"b@ 4030xsP!"G(  pGx+6 "-JCDBxxJCDBxx Dp"CIBx DKxAx3aBpKxAx3!DBp#JAxD3+pH#p$#Cp!"@UTTx  Hx <xF])s FFF(Hp@ڹ (-JhJxɲ(#pJx"x* b*ِ:b&& Jy0!*Fd. Fp@IpesLiF##xm iFxT+ t+л Kx2" Kx*""HpmHjKx]ujh7² "B(L")I"-$J$JR#$CB#8T#%CD#Os`Kx+)hC $JR#0"B  T#%!D#Os` Kx(B hChC`` 0@@@@p-I-H-H !q$*K D!Xx4B  ,$H#H !X$ K D!Xx4B f,HH!H ?H! FM&HVC#2qCqH*UO5cpppq J Jpjjhuhh( HHHHHqhhh iiK-OB8FK J2Kh%_4OE 0Px!C O"KzCay!q!aq|IHIx@ !!O~HqE1O\ R E  OQRcy+EѢy#y Ҳ+  aB# *# aB*cq(#cq#VH8FayzRKxay"yB+)8FY+ 8F!R`yDGH 7}CJ0RD!Px5C T -^=K*^:;H:H-K!%5H6H)K!0H1H!0F+H-H$&H{*Hx!'Hq'HnI%4(yhy!H`!(HYh!HRH,HOJ%iziuYi|iiijvjjH kHHKx8"puk pFOrBF F1K x+;/H(F!t-H !m*H);( 'H>&K'Hh2`&Kp%K&Hh2`%K"p(F!KH pKKh2`#+#JJp KxH!(F- H !&H 8 plziu5lYlaljl0M͋+hH#`k Hh$ HcH]U$4j , 0kulp89H9M:LF9HC9H@8K9Jx9K( FF66H36K!x4H+4K!x2H#2K!x0H0K!h.H.K!h,H (y!*Hx!'H'K!xH$K!hH!K!hH(x!jH x!8@au6llllmmm4m@mBmJmRm7iFHMLJ#pxS+ D+ d+s+#p H#+p# H#+p##p0uhmm-AFFF(M#Sx;D+ %H` F#HZ &B5Kxk!HG FvHA"SYxHXpD6px1p)!Yp\RxB2T#cCV*"T mmnu* FJHJKx#Oq*IZB" 1BCK#ZCBK""pr?K@MxAɲ)pBUi:N"p3xS:H0x!`8HY7Kx6H!(xR4H!hxK0Hx!D*H&H:XB OrB&Kp$Kxx")pp# 0  ! =KC#K!p F ! F "K!pp 8 pn5EB9nunzi)H*HQnn FYC;F98M+ hp`p^p\(qZhq8WkyY/KDHp;+O+K[x++JxBѪx)KxS20)y(JGkx+#JxB86O&+p!LNxxp*p cx"bp"x*#pK!2F0 H!2F2F Hiy"#pp"pcp88 s(k!LxcxF*+#pcp&xx+.%#"1F0 p%pPp/1F*F*#0B! F 5 !""#pp"pcps Lxx".p Kpx!0ppp*ksLex&x#.cp" 0#1F*F%p0&pepp HF5,H0Kx   o+osLxx".p#0#1Fp 0ppp8FF H HK FpKx` 8aoo8FFH-HKx{ H F!R H KxBp F 8o+oou-CLxFFx%/p# hF*F!0pPp#HFɲ*F+ppiFHxS(    B Kh " 0]u-k-G0,K x(p,F $ B@`pF;Lex`phF!*F%p@F9F*Fep0BLx%.&phF!2Fp@F9F2FpsLbxxF*+#cpp"xx*+%#%pp0B! F Z5 !"S"#pp"pcppiF HH( ]uo! L H"!Or H !" FK!" !pp!6 >HrHoK"pu$pNNNIF$NH4pMKp LKpLKMLhMMMOBb`hBb`@"/Or/FK2`OQrZ`DKEJ pxQpCJCIxpBI pxAKBHpxZrAJ#pR!p>KpSp=KhB`ZhBZ`9J##pp7J`7Jp"*pE<5M/`W/b넪`b`b0K+a3+c/KYYYY,Io ` b+KhA`##p(I#p # pQ p%I,# pQ p#KO1`O!`2p@*q4k4@@@@@@ @@@@@@<@@@@@>@@ @ @@-CF(WKWKOTHr#$0RK"2FE𒀲ɱ"bCDJNM DP\3xs8F!AHG!Eѽ=M$0F+ I3x8H0_B_A3x4H&/ ''$pD3x/H/#$09/O "$ OqWpQ"$ kx+ѩ"F 3x۱Hhx!x3xH KJx8FS"01"FG K"$ 3x+?gHb6@@tp>zi6Up\pbphpnpupcKxFBbKx*aJxxD_K`JhhB @qB `#xCXKx+WKx VKx+TLx#0+ACQN3x+PKxPKpx%MHm!(FKHf!0xGH_x!EHX>Kx-Тx:K*xHDpx=I:pp *"p=8N3x;  p@3Kx,Kpx%ñ/H%!(F'H!0x#H! H!Kx-ДK)ГBD `H1H"p5H pD @@p@mu@@@p@Kx]K"DKBED pGK"pGHH !$ H! H K S40F"4G ,uRtwtpsiFDK( ]|-C%FFF'iFx+YuK+ 0!+K_FFyDCB:"H-"H*HFY H$! xH!`xHx!H#JHXB HHH3h+R90 xaxG7F5BҰFsu{tpt=Gtt L H#x8##pH x@<u%us$%FiFx ,L+0ŲƲ H H(F H0F!F#K^U4,puJuluO  L H#x8##pH| x@.usu L H#x8##peHb x@0uu-C+HАЀ*O*N+M+LI+HFHFC! @F<%HK%H68F30x!(F,!  F%!V HF F@FH&8Fpx!(F !  F !CuvO v0luuu4vwtp8DHDMDH(x-BH$+xB ?K"3!xU4EњBZ.PoKOE#kp2Ҳ1ɲ34$'FcKB@ЀbM=(Y((M]H5xy#Bh<E:3۲K, P>0x!;O1ɲC\DFAE HE BHO 1ɲ3#ZC9K!T5 {% ߲I3H5Py#B>E63۲K. P50x!3%1ɲC\DFaEM@E H]]O p1ɲ3#ZCK!T4L/HB10 |y: J~%/F0KBB/K/J0̀O  @R#0] 4O E!K ]S1PxxG ]  y3D_ @ ] 050xpJx#3pb J Ip pK3z#ײ~}s.>BJHIJ#pJpJJpJI"XZT! D+ApF H"TJpp3@B{.0|/F JV(-OFg5L @ 2H2H(F.HT50x$f4#FBp !$H8]! 4 H|䲛!BHq>]HkHgH`HY0++нHHHOGuyzn z zz/zzzGz V(-OFLMMKO KDJHIH FcEHU$0x&չCH>I S@H!Xx=Hx!Ow4F&!l3H !;2b.H0 [30F"G)H #:x yB!PxC:x 3yBH۲H;x 6y3DBHB0]f-H}JuOz zzz@mzvzxzn zsiFxR+T+0;04)]KxKpKxKppGCBE>H8H5Kx@auLMH$H!Kx@Mur=7 K"pF+xL+ iFIx#x3#p0CLiF8##px pAiF'Kp]E)0(HKx# H0@ɼ+ K L%xE@%p(00M ?)(HpG)0(HKx# H0@+ K L%xE %p(p0xp0 M%X ?)(HoYl"I#ST2*JJpJppGY  >X )(H@JL#x+)##pM)8 F(H8@1M+x+,,p8M)p(dHdL#x%F. +^K$pQ(p1(CXBXA +xx-!p+ QK"xCppMJx+LHth,YpJJTpJH F!d+ф@KC䲥@xC"p9KxBpp#۲-+<.,8K9J]]"F/I xD 3Ҳh* 2I2K\\(I xD p1c۲+,J\!KxAp##PҲ-*&I'K\\I xDDKxp@Bp Hr F)FHp@i% IL(\CT x+D\ T x3 ppM?>B͌Y cr3/6uHI@`KxFJKx+J!T3۲Kx Jp"x(KpF@\MBY ?>h!C\ 1JK`pG K LxBp` Hpx. ''GApD5lC+r JR#AhB#J2@a"b  8( rKS 0 0[hbpG pGr#JD,ՙJR1@,C0X`K AR1@d0X` KB10 Kx:pb3 +bK"p@z@@bC+02J@@DrL\* 0"0"HJP#@@#R#A`B#""T C` ##CC`b0l8KJ\+JBJK`pG@@ -GKx`խKxJx);۲p Jx);۲p K"p+KLxҲ O@ZZhT70; +LJJJJJJ(JJJ hMRh+`j`JD7 OJ!&o9`!aap+س:؂+)؀+@𑁂L!papHh@2B س@/rB@zxKa@2B$p@!BCسoأc+ajkK"o@Y]Kx`NpxfKҲpxB!Bv آRB:rB@>x\K8BB:2B@2xWK,3jpj8~6FE&FdV (pPFIJKLPV (aPFEKIPDK#CK :*"" 9K"p&F8J8K2D3D,pO%8F0X`0KD800D830H80P`JD3 D3030H6H! .D3D8ѭK Lx1F#p @kn @X@HlcDM|L8 lbz0@+h؝LK!pap\i&pgૈ*Yi)VњKDx"MH/ૈ*Hi)EњKDxB<3 lB 3SL ,23 lB * !x2+y+R~H!1F|H3 _ 3SL,3 B3jqK pqKppiK"p(!mL F!B8F@.45F@% F)F v,D@-5F@.45F@% F)Fv,D@-[K<`"ZKXZM+B!B#\SIXT3+ x+SK"p @!Bk(y ( RxLKxJKpF >H!&F( x2"HpAM+xՅKNxKH0x!nH2x##r#br !F+x# [wKzNxKzH0!QtH2#br #r#r !Ff+x#@3x.EнdKjOxciH!8x,gH0F!eN$cH0x!px!x!x!0y! py! WH};xTI#r&"fr ## !F.pBKxFKHc+x+l3xCO+68x!AHU&!6.:HG&!y6.4H:3K!}0H2&!X}6.+H%;x(Icr FO&" k"$I F2 +""!I F2 +BF"I FBD +"#3#0F!F#+pkTMm?AX  >ȑziY u_ m n r Jh+b pGO@@!`bIH"SC"PB`pG  KH"+ Jx" Jx rJOA!hC`bpG bkL#hk hBSDzB K"` KxO0 `(C FxkK؈Kh[DpG x-C-N#F F3p,O+M+hF+G X)Kx 2p (#3pmKpKx*"pO0)hJH#p@B8"F DDHB\ 3DK?+@#  #+`K"p4p Fopktn8Kx L!h1K %`8F  8@}K"p8opnHû͒HHH@uttH֒-A$!KxB< HKS$H';NV$0YY!HJKmV$0XY _H8v_V$0D7hhl Hi4䲾ْvziuKxp\!H> H; H8H5H2H/H,H)H&H#H HHHHK!hK!hK!hK!h@u4Ux.bޔ%yT@X@\@`@ L H#x3H#H##pu0F0#x +F0x[ ``0-A"Kx+=!M$(FTFKxB&3MU$0YqR0U$0DhG64L FvK K K H KIJKK(lunv Jx +H@>LD#YpJB#/KH$pKpKpKp H K H Ip Kp Kp(tzXZ-O(M+x+I'O$8FiFT.F&F#KxB#O O [$0S 8[$0S `_  _4#H+p H0F;3+xZ*p,T(ltzRB 3@DpG J K8x Id"2 x#xd!JCTpGBH\T3pG(l Kpd$ M4& H.p[ HX Fg3FڲY\HT F*pp(tzltM,xIH+xpNc+oH0nH-#3p>Z2pkJTkKx +xBiHhH#F*xB bJ^\!bH 3FaH&0*&+#+p+xTOB@UI ] *FD "+,!#MH+pSHRH@;PH+p *z;x;;p*)* *n"=HCEKEJxxB4 @p1ɲ )p!p!px;Jpd"SC:J!TBM [x[+IK]A+"2O/K xB#F U ! "8'KFx!8 "B#Kps]B+ M! "0KFx!0 "B,p@"04TkW(ulߖzitzKhB"`KOr`pG@L@KKhB"`pG@@S x3"hCx+уx+]pGFF3x)pGF"CBڡ\\TT2;0F" %303TT"F UF0@ٿ]0F" %303PT F T0@FiFhF]p$ -7&0&c5D UF* * *x"T40" UBX0$T"TFp@ FiFhF]p$ -7&0&5D  UF* ** x"T D0"pB0 T3"TFp@M FiFhFL]F+"KBF ,BxOppF %& F;++ F  + -+x+FO6%F --"F!!BFL0<3 $:aC-9*0:3 BF*7:f*W:pNMI! Hard Fault! SCB_HFSR: Memory Manager Fault! SCB_CFSR: SCB_MMAR: Bus Fault! SCB_CFSR: SCB_BFAR: Usage Fault! SCB_CFSR: RESET TO LOADERWrite to given register page starting at address. i.e. 0x2 0x24 0xF0 0x12Test out the led pages.efAesgefececeVce cef9Read the given register page.Disable software shutdown.DEBUG - DATA: WARNING - I2C_BufferPush failed, buffer full: ERROR - No buffer to pop an entry from... ERROR - I2C NAK detected... ERROR - Arbitration lost... ERROR - Slave Address I2C NAK detected... DEBUG - Attempting to read byte - DEBUG - NEXT INFO - Sending: | LED_control_capability(mode,amount,index)i2cRecvi2cSendledCtrlledRPageledStartledTestledWPageledZeroBasic LED control. Args: []$Zero out LED register pages (non-configuration).Send I2C sequence of bytes and expect a reply of 1 byte on the last sequence. Use |'s to split sequences with a stop.Send I2C sequence of bytes. Use |'s to split sequences with a stop.ISSI LED Module CommandsEnables matrix debug mode, prints out each scan code. If argument T is given, prints out each scan code state transition.INFO - Matrix Debug Mode: INFO - Columns: INFO - Rows: INFO - Max Keys: OPHRIERROR - Matrix scan bug!! Report me! INFO - Max scans: INFO - Previous scans: INFO - Scan Number: : 0x: 0xmatrixDebugmatrixStatePrints out the current scan table N times. O - Off, P - Press, H - Hold, R - Release, I - InvalidMatrix Module Commandsjg!j-jpppppppqq q4r)++qk!6qr,Aqmq9#Lqq$Wqq=-bqk#Toggle UARTConnect debug mode.UARTConnect status.DEBUG - Animation INFO - Connect Debug Mode ToggleDEBUG - PENDING SET -> WARNING - Cable Fault! Slave Master DEBUG - CABLECHECK RECEIVE - INFO - List of UARTConnect commandsMasterSlaveINFO - UARTConnect Status Device Type: Device Id: Max Id: Master <= Status: Faults: / Rx: Tx: Slave <= Status: INFO - Setting device as slave.INFO - Setting device as master.WARNING - Too much data to send on UART, waiting... +ERROR - Invalid ScanCode direction... WARNING - Not enough interconnect layout nodes configured: DEBUG - ERROR - Too big of a command to fit into the buffer...ERROR - Invalid UART to send from... DEBUG - IdRequest ERROR - Invalid IdRequest direction... DEBUG - IdEnumeration ERROR - Invalid IdEnumeration direction... DEBUG - IdReport INFO - Id Reported: INFO - Sending Sync Idles...INFO - Resetting UARTConnect state... Wait SYN SOH ### CMD ERROR - Invalid UARTStatus...TxFIFO 0 - TxFIFO 1 - CableCheckIdRequestIdEnumerationIdReportScanCodeAnimationRemoteCapabilityRemoteOutputRemoteInputconnectCmdconnectDbgconnectIdlconnectLstconnectMstconnectRstconnectStsLists available UARTConnect commands and index idUARTConnect Module CommandsSets the device as master. Use argument of s to set as slave.Resets both Rx and Tx connect buffers and state variables.Sends a command via UART Connect, first arg is which uart, next arg is the command, rest are the arguments.Sends N number of Idle commands, 2 is the default value, and should be sufficient in most cases. +/  ,Y88%988yF=GGGFFG  N  N?   # @ 1 vR "Send key-release event to macro module. Duplicates have undefined behaviour. S10 Scancode 0x0AEG K8 INFO - Capabilities List INFO - KWARNING - flashModeEnabled not set, cancelling firmware reload... INFO - Set flashModeEnabled to 1 in your kll configuration.INFO - Layer Debug Mode: INFO - Setting Layer L to - INFO - Macro Debug Mode: INFO - Macro Processing Mode: INFO - Layer ListD: KType + stdFuncMap (default) Layer State: First -> Last Indices: 1: INFO - Pending Key Events: : INFO - Pending Trigger Macros: INFO - Pending Result Macros: INFO - Trigger Macros Range: T0 -> TINFO - Result Macros Range: R0 -> RINFO - Trigger : Result Macro Pairs T : RDEBUG - Layer 0Macro_layerState(layerIndex,layerState)Macro_layerShift(layerIndex)Macro_layerLatch(layerIndex)Macro_layerLock(layerIndex)Macro_layerRotate(previous)ERROR - Scan Code has no defined Trigger Macro: ERROR - Invalid key state - ERROR - Invalid type - WARNING - ScanCode is out of range/not defined - WARNING - ScanCode is out of range/not defined: ERROR - LED State Type - Not implemented... ERROR - Analog State Type - Not implemented... ERROR - Invalid State Type. This is a bug. DEBUG - Macro Step INFO - Trigger Macro Index: |; Position: Result Macro Index: Trigger Macro State: WaitingINFO - Result Macro Index: (, Final Trigger State (State/Type): capListcapSelectkeyHoldkeyPresskeyReleaselayerDebuglayerListlayerStatemacroDebugmacroListmacroProcmacroShowmacroStep DPause/Resume macro processing.   ! Send key-press events to the macro module. Duplicates have undefined behaviour. S10 Scancode 0x0AMacro Module Commands RCK Layer debug mode. Shows layer stack and any changes. /  : %L O ! Show the macro corresponding to the given index. T16 Indexed Trigger Macro 0x10, R12 Indexed Result Macro 0x0C QSHL>$& (F>  ǀss؂7|{<a|`h@tsNt {_4ՀsƂT|}y|/|ssssL{D{|;|̓]|\!LEu3|s8sɃscssL܂у{dN}W~8H{@XÀ s P U9 % 7H 0 Q  8:I "36*,/#&MP BD:=1 & JUuVH4v * =D;Modify specified indexed layer state . L2 Indexed Layer 0x02 0 Off, 1 Shift, 2 Latch, 4 Lock States ) 6  3 HM< EGJ')List available layers. 7  B C? E(0z|2z‡u3zP;z_{;zs<z{q4z-}5z04z 5z]6{${I5 {e|ME{߃M3 'Send key-hold events to the macro module. Duplicates have undefined behaviour. S10 Scancode 0x0A G  $1I  P  BS*A579.0%   T+ ORTFPrints an indexed list of all non USB keycode capabilities.<  I  45=Do N macro processing steps. Defaults to 1.Disables/Enables sending USB keycodes to the Output Module and prints U/K codes.  F > L6  .I}DDt<@p D} q W} s ~C{P{H{&)X|%PI}Z{R ˀ!s"#s$\%s&'$()(*{+ă,D|-Ճ.|/l0R}1/2Z3S456Ԉ789!:;s<l=s>?s@ʂAItBCU{DMEڃF|GvH\}IxJ~KL*MUNNOP Q+R.SЀT?|UV  V2' AV(+-!$.Triggers the specified capabilities. First two args are state and stateType. K11 Keyboard Capability 0x0B ?" 5@Q  M4# 9 A2List the defined trigger and result macros.KN@C38; , -   ;4 ) O  < J-Keyboard Protocol Mode: 0 - Boot, 1 - OS/NKRO ModePrepare a space separated list of USB codes (decimal). Waits until sendKeys.USB Module CommandsЍcE܍ 5F#EEFYFSend the prepared list of USB codes and modifier byte.Set the modfier byte: 1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUIINFO - Keyboard Protocol: INFO - LED State: Output_consCtrlSend(consCode)WARNING - Consumer Control is not implemented for Boot Mode Output_noneSend()Output_sysCtrlSend(sysCode)WARNING - System Control is not implemented for Boot Mode Output_flashMode()Output_kbdProtocolBoot()Output_kbdProtocolNKRO()Output_usbCodeSend(usbCode)WARNING - USB Key limit reached WARNING - USB Code above 104/0x68 in Boot Mode: WARNING - USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: kbdProtocoloutputDebugreadLEDssendKeyssetKeyssetModToggle Output Debug mode.Read LED byte: 1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc. BG F"?! "N}! "xv!6 "U!O "5!h 6   : $  T   l  X  zWARNING - CLEAR_FEATURE - Device/Interface WARNING - SET_FEATURE - Device/Interface WARNING - Unknown interface - ERROR - USB not configured... WARNING - USB Transmit Timeout... SysCtrl[] ConsCtrl[DEBUG - Boot USB: DEBUG - NKRO USB: You're looking at it :PSends a software restart, should be similar to powering on the device.Clear the screen.Signals microcontroller to reflash/reload.Version information about this firmware. c   Revision: 7b7a55899f392ebb7f615fd1801aaaa3dcc3f738 Branch: master Tree Status: Clean Repo Origin: https://github.com/kiibohd/controller.git Commit Date: 2015-10-18 17:54:41 -0700 Commit Author: Jacob Alexander Build Date: 2015-11-12 14:20:55 +0000 Build OS: Linux-4.1.5-x86_64-linode61 Architecture: arm Chip: mk20dx128vlf5 CPU: cortex-m4 Device: Keyboard Modules: Scan(KType) Macro(PartialMap) Output(pjrcUSB) Debug(full) Unique Id: INFO - Hex debug mode disabled... INFO - Hex debug mode enabled... RROR"" is not a valid command...type helpERROR - Max number of dictionaries defined already...  : ERROR - Serial line buffer is full, dropping character and resetting...   clearcliDebughelpledreloadresetrestartversionResets the terminal back to initial settings.gXkyZXėY yX'X YYEnables/Disables indicator LED. Try a couple times just in case the LED is in an odd state. Warning: May adversely affect some modules...General CommandsEnables/Disables hex output of the most recent cli input.),   )")-*m* &!'|} }}}$},}4}<}d}l}t}|}}}dlt|8t܀ LT\dL|t (08\dltЂDPX`hphĈ̈0t܈{} u)uu%)u.%)1uui%3)uu%)u.%)݁u %u  ) %5F;ue 9B &u  0 1 2 5&u  6 66Virtual Serial Port - DataJoystick MouseMedia KeysNKRO Keyboard   !"?  !"}@  $$$$@  @@  !"v  !"U  !"5    )%uu 0 1%u H%5Eu 8%5Eu H5Eu 8%u u&) u& *Boot Keyboard@M:Virtual Serial Port - StatusKiibohdRKeyboard - KType PartialMap pjrcUSB full u)%uu)uu%) RClean master - 2015-10-18 17:54:41 -0700UFD0U5fwupd-1.0.6/plugins/dfu/tests/metadata.dfu000066400000000000000000000000431325145456600205340ustar00rootroot00000000000000amaliaMDkeyvalueUFDXfwupd-1.0.6/plugins/ebitdo/000077500000000000000000000000001325145456600156055ustar00rootroot00000000000000fwupd-1.0.6/plugins/ebitdo/README.md000066400000000000000000000006421325145456600170660ustar00rootroot000000000000008Bitdo Support ============== Introduction ------------ This plugin can flash the firmware on the 8Bitdo game pads. Ebitdo support is supported directly by this project with the embedded libebitdo library and is possible thanks to the vendor open sourcing the flashing tool. The 8Bitdo devices share legacy USB VID/PIDs with other projects and so we have to be a bit careful to not claim other devices as our own. fwupd-1.0.6/plugins/ebitdo/data/000077500000000000000000000000001325145456600165165ustar00rootroot00000000000000fwupd-1.0.6/plugins/ebitdo/data/nes30pro.txt000066400000000000000000000107671325145456600207430ustar00rootroot00000000000000Bus 003 Device 017: ID 2002:9000 DAP Technologies Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x2002 DAP Technologies idProduct 0x9000 bcdDevice 0.01 iManufacturer 1 8Bitdo NES30 Pro iProduct 2 8Bitdo NES30 Pro iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 480mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 123 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 16 Device Status: 0x0000 (Bus Powered) Bus 003 Device 019: ID 0483:5750 STMicroelectronics Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0483 STMicroelectronics idProduct 0x5750 bcdDevice 2.00 iManufacturer 1 8BitdoJoy iProduct 2 8Bitdo iSerial 3 BootMod bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 480mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 33 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 16 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/ebitdo/data/scf30.txt000066400000000000000000000106001325145456600201720ustar00rootroot00000000000000 Bus 002 Device 053: ID 1235:ab21 Focusrite-Novation Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1235 Focusrite-Novation idProduct 0xab21 bcdDevice 0.01 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 480mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 99 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 16 Bus 002 Device 055: ID 0483:5750 STMicroelectronics Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0483 STMicroelectronics idProduct 0x5750 bcdDevice 2.00 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 480mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 33 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 16 fwupd-1.0.6/plugins/ebitdo/data/sf30pro.txt000066400000000000000000000303401325145456600205530ustar00rootroot00000000000000Start + Y --------- Bus 001 Device 008: ID 057e:2009 Nintendo Co., Ltd Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x057e Nintendo Co., Ltd idProduct 0x2009 bcdDevice 2.00 iManufacturer 1 Nintendo Co., Ltd. iProduct 2 Pro Controller iSerial 3 000000000001 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 203 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 8 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 8 Device Status: 0x0000 (Bus Powered) Start + B ------------ Bus 001 Device 009: ID 2dc8:6000 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x2dc8 idProduct 0x6000 bcdDevice 0.01 iManufacturer 1 8Bitdo SF30 Pro iProduct 2 8Bitdo SF30 Pro iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 480mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 123 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 16 Device Status: 0x0000 (Bus Powered) Start + A --------- Bus 001 Device 012: ID 054c:05c4 Sony Corp. DualShock 4 Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x054c Sony Corp. idProduct 0x05c4 DualShock 4 bcdDevice 1.00 iManufacturer 1 Sony Computer Entertainment iProduct 2 Wireless Controller iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 41 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 499 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Device Status: 0x0000 (Bus Powered) Start + X --------- Bus 001 Device 013: ID 045e:028e Microsoft Corp. Xbox360 Controller Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 255 Vendor Specific Class bDeviceSubClass 255 Vendor Specific Subclass bDeviceProtocol 255 Vendor Specific Protocol bMaxPacketSize0 8 idVendor 0x045e Microsoft Corp. idProduct 0x028e Xbox360 Controller bcdDevice 1.14 iManufacturer 1 8Bitdo SF30 Pro iProduct 2 Controller iSerial 3 (error) bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 153 bNumInterfaces 4 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 93 bInterfaceProtocol 1 iInterface 0 ** UNRECOGNIZED: 11 21 00 01 01 25 81 14 00 00 00 00 13 01 08 00 00 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 4 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 4 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 93 bInterfaceProtocol 3 iInterface 0 ** UNRECOGNIZED: 1b 21 00 01 01 01 82 40 01 02 20 16 83 00 00 00 00 00 00 16 03 00 00 00 00 00 00 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 2 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 4 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 64 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 16 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 93 bInterfaceProtocol 2 iInterface 0 ** UNRECOGNIZED: 09 21 00 01 01 22 84 07 00 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 16 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 253 bInterfaceProtocol 19 iInterface 4 µ∡H釰俸샴`翰⣸贠øĀ贤Ǹɀ败˸赐ϸ桀F㏰៸贠ø贀Ǹ赀˸赐ϸ桀F⟰ ** UNRECOGNIZED: 06 41 00 01 01 03 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/ebitdo/data/update.csv000066400000000000000000032101711325145456600205220ustar00rootroot00000000000000# Total Phase Data Center(tm) v6.63 # (c) 2005-2015 Total Phase, Inc. # www.totalphase.com # # Fri Jun 03 12:02:30 2016 # # Level,Sp,Index,m:s.ms.us,Dur,Len,Err,Dev,Ep,Record,Summary 0,,0,0:00.000.000,,,,,,Capture started (Aggregate),[Fri 03 Jun 2016 12:00:01 BST] 0,,1,0:00.000.024,,,,,, / , 0,,2,0:09.124.398,,,,,, / , 0,,3,0:09.565.223,,,,,, / , 0,,4,0:09.643.335,,,,,, / , 0,,5,0:10.095.673,,,,,, / , 0,,6,0:10.126.773,,,,,, / , 0,,7,0:10.127.444,31.007.125 ms,,,,,[32 SOF],[Frames: 1881 - 1912] 0,,8,0:10.158.452,13.000 us,8 B,,00,00,SETUP txn,80 06 00 01 00 00 40 00 0,,12,0:10.159.448,2.812 us,,,,,[1 SOF],[Frame: 1913] 0,,13,0:10.159.451,20.229 us,18 B,,00,00,IN txn,12 01 00 02 00 00 00 40 83 04 50 57 00 02 01 02 03 01 0,,17,0:10.160.448,1.002.958 ms,,,,,[2 SOF],[Frames: 1914 - 1915] 0,,18,0:10.161.452,7.666 us,0 B,,00,00,OUT txn, 0,,22,0:10.162.449,2.833 us,,,,,[1 SOF],[Frame: 1916] 0,,23,0:10.162.542,,,,,, / , 0,,24,0:10.189.147,,,,,, / , 0,,25,0:10.189.452,31.007.125 ms,,,,,[32 SOF],[Frames: 1943 - 1974] 0,,26,0:10.220.460,13.000 us,8 B,,00,00,SETUP txn,00 05 01 00 00 00 00 00 0,,30,0:10.221.457,2.812 us,,,,,[1 SOF],[Frame: 1975] 0,,31,0:10.221.460,8.229 us,0 B,,00,00,IN txn, 0,,35,0:10.222.457,30.007.000 ms,,,,,[31 SOF],[Frames: 1976 - 2006] 0,,36,0:10.252.465,13.000 us,8 B,,01,00,SETUP txn,80 06 00 01 00 00 12 00 0,,40,0:10.253.461,2.895 us,,,,,[1 SOF],[Frame: 2007] 0,,41,0:10.253.465,20.229 us,18 B,,01,00,IN txn,12 01 00 02 00 00 00 40 83 04 50 57 00 02 01 02 03 01 0,,45,0:10.254.461,2.812 us,,,,,[1 SOF],[Frame: 2008] 0,,46,0:10.254.465,7.645 us,0 B,,01,00,OUT txn, 0,,50,0:10.255.462,1.003.041 ms,,,,,[2 SOF],[Frames: 2009 - 2010] 0,,51,0:10.256.465,13.083 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 FF 00 0,,55,0:10.257.462,2.812 us,,,,,[1 SOF],[Frame: 2011] 0,,56,0:10.257.465,35.729 us,41 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01… 0,,60,0:10.258.462,1.002.958 ms,,,,,[2 SOF],[Frames: 2012 - 2013] 0,,61,0:10.259.465,7.666 us,0 B,,01,00,OUT txn, 0,,65,0:10.260.462,1.003.125 ms,,,,,[2 SOF],[Frames: 2014 - 2015] 0,,66,0:10.261.466,13.083 us,8 B,,01,00,SETUP txn,80 06 03 03 09 04 FF 00 0,,70,0:10.262.463,2.895 us,,,,,[1 SOF],[Frame: 2016] 0,,71,0:10.262.466,25.562 us,26 B,,01,00,IN txn,1A 03 38 00 42 00 69 00 74 00 64 00 6F 00 20 00 00 00 00 00 00 00 00 00… 0,,75,0:10.263.463,1.003.041 ms,,,,,[2 SOF],[Frames: 2017 - 2018] 0,,76,0:10.264.466,7.666 us,0 B,,01,00,OUT txn, 0,,80,0:10.265.463,1.003.041 ms,,,,,[2 SOF],[Frames: 2019 - 2020] 0,,81,0:10.266.466,13.062 us,8 B,,01,00,SETUP txn,80 06 00 03 00 00 FF 00 0,,85,0:10.267.463,2.916 us,,,,,[1 SOF],[Frame: 2021] 0,,86,0:10.267.467,10.916 us,4 B,,01,00,IN txn,04 03 09 04 0,,90,0:10.268.463,1.003.041 ms,,,,,[2 SOF],[Frames: 2022 - 2023] 0,,91,0:10.269.467,7.645 us,0 B,,01,00,OUT txn, 0,,95,0:10.270.464,1.003.041 ms,,,,,[2 SOF],[Frames: 2024 - 2025] 0,,96,0:10.271.467,13.062 us,8 B,,01,00,SETUP txn,80 06 02 03 09 04 FF 00 0,,100,0:10.272.464,2.895 us,,,,,[1 SOF],[Frame: 2026] 0,,101,0:10.272.467,20.229 us,18 B,,01,00,IN txn,12 03 38 00 42 00 69 00 74 00 64 00 6F 00 20 00 20 00 0,,105,0:10.273.464,1.003.041 ms,,,,,[2 SOF],[Frames: 2027 - 2028] 0,,106,0:10.274.468,7.645 us,0 B,,01,00,OUT txn, 0,,110,0:10.275.464,1.003.041 ms,,,,,[2 SOF],[Frames: 2029 - 2030] 0,,111,0:10.276.468,13.000 us,8 B,,01,00,SETUP txn,80 06 00 06 00 00 0A 00 0,,115,0:10.277.465,2.895 us,,,,,[1 SOF],[Frame: 2031] 0,,116,0:10.277.468,4.583 us,,,01,00,IN txn (STALL), 0,,119,0:10.278.465,4.003.458 ms,,,,,[5 SOF],[Frames: 2032 - 2036] 0,,120,0:10.282.469,13.020 us,8 B,,01,00,SETUP txn,80 06 00 01 00 00 12 00 0,,124,0:10.283.465,2.895 us,,,,,[1 SOF],[Frame: 2037] 0,,125,0:10.283.469,20.229 us,18 B,,01,00,IN txn,12 01 00 02 00 00 00 40 83 04 50 57 00 02 01 02 03 01 0,,129,0:10.284.466,2.895 us,,,,,[1 SOF],[Frame: 2038] 0,,130,0:10.284.469,7.666 us,0 B,,01,00,OUT txn, 0,,134,0:10.285.466,1.003.041 ms,,,,,[2 SOF],[Frames: 2039 - 2040] 0,,135,0:10.286.470,13.000 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 09 00 0,,139,0:10.287.466,2.895 us,,,,,[1 SOF],[Frame: 2041] 0,,140,0:10.287.469,14.229 us,9 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 0,,144,0:10.288.466,2.916 us,,,,,[1 SOF],[Frame: 2042] 0,,145,0:10.288.469,7.666 us,0 B,,01,00,OUT txn, 0,,149,0:10.289.466,1.003.041 ms,,,,,[2 SOF],[Frames: 2043 - 2044] 0,,150,0:10.290.470,13.000 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 29 00 0,,154,0:10.291.467,3.000 us,,,,,[1 SOF],[Frame: 2045] 0,,155,0:10.291.470,35.750 us,41 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01… 0,,159,0:10.292.467,2.979 us,,,,,[1 SOF],[Frame: 2046] 0,,160,0:10.292.470,7.666 us,0 B,,01,00,OUT txn, 0,,164,0:10.293.467,1.002.958 ms,,,,,[2 SOF],[Frames: 2047 - 0] 0,,165,0:10.294.472,13.000 us,8 B,,01,00,SETUP txn,00 09 01 00 00 00 00 00 0,,169,0:10.295.467,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,170,0:10.295.470,8.229 us,0 B,,01,00,IN txn, 0,,174,0:10.296.467,2.812 us,,,,,[1 SOF],[Frame: 2] 0,,175,0:10.296.471,13.000 us,8 B,,01,00,SETUP txn,21 0A 00 00 00 00 00 00 0,,179,0:10.297.467,2.833 us,,,,,[1 SOF],[Frame: 3] 0,,180,0:10.297.471,4.604 us,,,01,00,IN txn (STALL), 0,,183,0:10.298.468,1.002.958 ms,,,,,[2 SOF],[Frames: 4 - 5] 0,,184,0:10.299.473,13.083 us,8 B,,01,00,SETUP txn,81 06 00 22 00 00 61 00 0,,188,0:10.300.468,2.833 us,,,,,[1 SOF],[Frame: 6] 0,,189,0:10.300.471,30.416 us,33 B,,01,00,IN txn,05 8C 09 01 A1 01 09 03 15 00 26 00 FF 75 08 95 40 81 02 09 04 15 00 26… 0,,193,0:10.301.468,1.002.958 ms,,,,,[2 SOF],[Frames: 7 - 8] 0,,194,0:10.302.471,7.666 us,0 B,,01,00,OUT txn, 0,,198,0:10.303.468,88.015.041 ms,,,,,[89 SOF],[Frames: 9 - 97] 0,,199,0:10.391.484,50.312 us,64 B,,01,01,OUT txn,05 00 16 01 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,203,0:10.392.481,207.031.562 ms,,,,,[208 SOF],[Frames: 98 - 305] 0,,204,0:10.599.513,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,208,0:10.600.509,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,209,0:10.326.475,288.090.895 ms,64 B,,01,02,IN txn [9 POLL],0C 00 16 07 00 04 04 00 0B 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,214,0:10.615.512,192.029.479 ms,,,,,[193 SOF],[Frames: 321 - 513] 0,,215,0:10.807.541,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,219,0:10.808.538,30.006.979 ms,,,,,[31 SOF],[Frames: 514 - 544] 0,,220,0:10.646.519,192.077.562 ms,64 B,,01,02,IN txn [6 POLL],0C 00 16 07 00 04 04 00 0B 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,225,0:10.839.543,1.999.280.375 s,,,,,[2000 SOF],[Frames: 545 - 496] [Periodic Timeout] 0,,226,0:10.870.550,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,227,0:12.839.820,1.999.280.375 s,,,,,[2000 SOF],[Frames: 497 - 448] [Periodic Timeout] 0,,228,0:12.886.830,1.984.280.062 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,229,0:14.840.098,1.999.280.375 s,,,,,[2000 SOF],[Frames: 449 - 400] [Periodic Timeout] 0,,230,0:14.903.110,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,231,0:16.840.376,1.999.280.375 s,,,,,[2000 SOF],[Frames: 401 - 352] [Periodic Timeout] 0,,232,0:16.919.390,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,233,0:18.840.653,288.042.812 ms,,,,,[289 SOF],[Frames: 353 - 641] 0,,234,0:19.128.697,50.333 us,64 B,,01,01,OUT txn,05 00 1A 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,238,0:19.129.694,30.006.979 ms,,,,,[31 SOF],[Frames: 642 - 672] 0,,239,0:18.935.670,224.082.354 ms,64 B,,01,02,IN txn [7 POLL],2D 00 19 24 00 7F 1E 50 33 39 31 32 02 4E 39 31 38 2C BD CB 0F 9A 89 12… 0,,244,0:19.160.698,1.999.280.354 s,,,,,[2000 SOF],[Frames: 673 - 624] [Periodic Timeout] 0,,245,0:19.191.705,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,246,0:21.160.975,1.999.280.375 s,,,,,[2000 SOF],[Frames: 625 - 576] [Periodic Timeout] 0,,247,0:21.207.985,1.984.280.020 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,248,0:23.161.253,1.999.280.354 s,,,,,[2000 SOF],[Frames: 577 - 528] [Periodic Timeout] 0,,249,0:23.224.265,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,250,0:25.161.531,1.999.280.375 s,,,,,[2000 SOF],[Frames: 529 - 480] [Periodic Timeout] 0,,251,0:25.240.545,1.984.280.041 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,252,0:27.161.809,1.552.218.375 s,,,,,[1553 SOF],[Frames: 481 - 2033] 0,,253,0:28.714.027,50.333 us,64 B,,01,01,OUT txn,23 00 16 1F 00 01 1C 00 0B 01 00 00 00 A0 00 08 00 B8 00 00 80 68 CF 01… 0,,257,0:28.715.024,15.004.916 ms,,,,,[16 SOF],[Frames: 2034 - 1] 0,,258,0:28.730.029,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 1C 00 0B 01 00 00 00 A0 00 08 00 B8 00 00 80 68 CF 01… 0,,262,0:27.256.825,1.984.280.020 s,,,01,02,[63 IN-NAK],[Periodic Timeout] 0,,263,0:28.731.026,1.839.258.145 s,,,,,[1840 SOF],[Frames: 2 - 1841] 0,,264,0:28.746.032,1.824.303.562 s,64 B,,01,01,OUT txn [114 POLL],05 00 1D 01 00 00 1C 00 0B 01 00 00 00 A0 00 08 00 B8 00 00 80 68 CF 01… 0,,725,0:30.571.282,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,726,0:29.273.105,1.312.233.062 s,64 B,,01,02,IN txn [41 POLL],06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,731,0:30.586.284,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,732,0:30.586.287,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 1C 00 0B 01 00 00 00 A0 00 08 00 B8 00 00 80 68 CF 01… 0,,736,0:30.587.284,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,737,0:30.602.289,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB 7D 28 D4 3A 00 4A F1 30 AC 25 4C FD 08 67 17… 0,,741,0:30.603.286,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,742,0:30.617.291,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,746,0:30.618.288,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,747,0:30.618.292,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB 7D 28 D4 3A 00 4A F1 30 AC 25 4C FD 08 67 17… 0,,751,0:30.619.288,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,752,0:30.634.294,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D0 E3 13 0F 27 61 F6 24 5D 4B B2 25 D4 AF 56 6E… 0,,756,0:30.635.291,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,757,0:30.649.296,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,761,0:30.650.293,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,762,0:30.650.296,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D0 E3 13 0F 27 61 F6 24 5D 4B B2 25 D4 AF 56 6E… 0,,766,0:30.651.293,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,767,0:30.666.298,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C DD 4E 02 98 67 3D 24 80 29 06 7C CB A8 FD 44… 0,,771,0:30.667.295,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,772,0:30.681.300,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,776,0:30.682.297,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,777,0:30.682.300,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C DD 4E 02 98 67 3D 24 80 29 06 7C CB A8 FD 44… 0,,781,0:30.683.297,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,782,0:30.698.303,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 6A 81 1E F9 A0 8D 24 E8 A3 35 4C E8 67 F3 F9… 0,,786,0:30.699.300,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,787,0:30.713.305,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,791,0:30.714.302,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,792,0:30.714.305,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 6A 81 1E F9 A0 8D 24 E8 A3 35 4C E8 67 F3 F9… 0,,796,0:30.715.302,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,797,0:30.730.307,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 32 52 7B 9D C1 93 B1 88 79 49 FB 02 32 9F BA… 0,,801,0:30.731.304,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,802,0:30.745.309,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,806,0:30.746.306,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,807,0:30.746.309,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 32 52 7B 9D C1 93 B1 88 79 49 FB 02 32 9F BA… 0,,811,0:30.747.306,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,812,0:30.762.312,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 08 B8 FC B9 85 51 F6 32 2E E3 BD EF 38 77 72… 0,,816,0:30.763.308,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,817,0:30.777.314,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,821,0:30.778.311,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,822,0:30.778.314,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 08 B8 FC B9 85 51 F6 32 2E E3 BD EF 38 77 72… 0,,826,0:30.779.311,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,827,0:30.794.316,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D1 EC AF 7B 87 DB 1A 24 35 70 6F 77 0B 07 AE 30… 0,,831,0:30.795.313,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,832,0:30.809.318,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,836,0:30.810.315,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,837,0:30.810.318,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D1 EC AF 7B 87 DB 1A 24 35 70 6F 77 0B 07 AE 30… 0,,841,0:30.811.315,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,842,0:30.826.320,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 91 59 84 CB 48 C0 82 4C D9 EB C5 7E 78 F1 0B… 0,,846,0:30.827.317,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,847,0:30.841.323,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,851,0:30.842.319,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,852,0:30.842.323,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 91 59 84 CB 48 C0 82 4C D9 EB C5 7E 78 F1 0B… 0,,856,0:30.843.320,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,857,0:30.858.325,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE BA 5B 62 0B 67 2F A6 8F 71 D4 C3 30 08 C9 B7… 0,,861,0:30.859.322,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,862,0:30.873.327,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,866,0:30.874.324,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,867,0:30.874.327,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE BA 5B 62 0B 67 2F A6 8F 71 D4 C3 30 08 C9 B7… 0,,871,0:30.875.324,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,872,0:30.890.329,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 BF D6 CF DE B4 36 32 1D 5C 56 AE 14 03 70 42… 0,,876,0:30.891.326,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,877,0:30.905.331,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,881,0:30.906.328,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,882,0:30.906.332,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 BF D6 CF DE B4 36 32 1D 5C 56 AE 14 03 70 42… 0,,886,0:30.907.328,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,887,0:30.922.334,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF 24 EF 66 05 78 4C 13 3E AA C1 D2 E9 C7 6C 41… 0,,891,0:30.923.331,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,892,0:30.937.336,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,896,0:30.938.333,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,897,0:30.938.336,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF 24 EF 66 05 78 4C 13 3E AA C1 D2 E9 C7 6C 41… 0,,901,0:30.939.333,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,902,0:30.954.338,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8B B7 26 DC 03 B1 E2 C0 F6 AB 95 C8 C6 8A B8 77… 0,,906,0:30.955.335,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,907,0:30.969.340,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,911,0:30.970.337,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,912,0:30.970.340,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8B B7 26 DC 03 B1 E2 C0 F6 AB 95 C8 C6 8A B8 77… 0,,916,0:30.971.337,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,917,0:30.986.343,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D 68 58 E9 BE C1 35 C5 D8 04 E9 3B E4 CB 8C 0E… 0,,921,0:30.987.340,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,922,0:31.001.345,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,926,0:31.002.342,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,927,0:31.002.345,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D 68 58 E9 BE C1 35 C5 D8 04 E9 3B E4 CB 8C 0E… 0,,931,0:31.003.342,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,932,0:31.018.347,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 21 BB 73 CE 2E 26 27 1C DF E7 01 8A 78 1C BC… 0,,936,0:31.019.344,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,937,0:31.033.349,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,941,0:31.034.346,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,942,0:31.034.349,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 21 BB 73 CE 2E 26 27 1C DF E7 01 8A 78 1C BC… 0,,946,0:31.035.346,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,947,0:31.050.352,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF 98 9B 98 3F D8 A7 7B FF FD A5 2B 32 CF 42 E3… 0,,951,0:31.051.348,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,952,0:31.065.354,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,956,0:31.066.351,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,957,0:31.066.354,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF 98 9B 98 3F D8 A7 7B FF FD A5 2B 32 CF 42 E3… 0,,961,0:31.067.351,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,962,0:31.082.356,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AC C5 DE 5D 0C A9 27 3D 37 88 70 55 0A AF 1B 33… 0,,966,0:31.083.353,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,967,0:31.097.358,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,971,0:31.098.355,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,972,0:31.098.358,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AC C5 DE 5D 0C A9 27 3D 37 88 70 55 0A AF 1B 33… 0,,976,0:31.099.355,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,977,0:31.114.360,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 77 F3 6D 38 6A 16 2E F4 76 80 DD 73 3A D4 88… 0,,981,0:31.115.357,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,982,0:31.129.363,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,986,0:31.130.359,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,987,0:31.130.363,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 77 F3 6D 38 6A 16 2E F4 76 80 DD 73 3A D4 88… 0,,991,0:31.131.360,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,992,0:31.146.365,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 B9 74 C4 E1 68 3B 17 91 E7 22 F0 F4 91 77 E2… 0,,996,0:31.147.362,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,997,0:31.161.367,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1001,0:31.162.364,16.005.041 ms,,,,,[17 SOF],[Frames: 385 - 401] 0,,1002,0:31.178.369,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 A6 A0 56 CA 7E 26 FF AB EE 6A 14 00 AB 77 D6… 0,,1006,0:31.179.366,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,1007,0:31.193.371,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1011,0:31.194.368,16.005.041 ms,,,,,[17 SOF],[Frames: 417 - 433] 0,,1012,0:31.210.374,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 A6 A0 56 CA 7E 26 FF AB EE 6A 14 00 AB 77 D6… 0,,1016,0:31.211.371,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,1017,0:31.225.376,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1021,0:31.226.373,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,1022,0:31.226.376,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 A6 A0 56 CA 7E 26 FF AB EE 6A 14 00 AB 77 D6… 0,,1026,0:31.227.373,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,1027,0:31.242.378,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 90 84 4C FF 0A E7 3B 9A AC 33 6A A2 52 E2 A4… 0,,1031,0:31.243.375,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,1032,0:31.257.380,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1036,0:31.258.377,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,1037,0:31.258.380,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 90 84 4C FF 0A E7 3B 9A AC 33 6A A2 52 E2 A4… 0,,1041,0:31.259.377,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,1042,0:31.274.383,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 07 97 FC 22 EC 53 D1 BB 1F C2 4E D3 05 56 1E A9… 0,,1046,0:31.275.380,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,1047,0:31.289.385,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1051,0:31.290.382,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,1052,0:31.290.385,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 07 97 FC 22 EC 53 D1 BB 1F C2 4E D3 05 56 1E A9… 0,,1056,0:31.291.382,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,1057,0:31.306.387,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF 19 3C 8C 2F C8 7B 3A 5E 28 74 86 64 6E 97 28… 0,,1061,0:31.307.384,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,1062,0:31.321.389,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1066,0:31.322.386,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,1067,0:31.322.389,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF 19 3C 8C 2F C8 7B 3A 5E 28 74 86 64 6E 97 28… 0,,1071,0:31.323.386,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,1072,0:31.338.392,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 68 E4 2B F6 74 64 05 5E C3 F7 B4 46 E6 8C BC… 0,,1076,0:31.339.388,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,1077,0:31.353.394,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1081,0:31.354.391,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,1082,0:31.354.394,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 68 E4 2B F6 74 64 05 5E C3 F7 B4 46 E6 8C BC… 0,,1086,0:31.355.391,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,1087,0:31.370.396,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 97 F8 20 A8 A5 6A 61 16 FD 82 60 00 4B 05 DB 2D… 0,,1091,0:31.371.393,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,1092,0:31.385.398,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1096,0:31.386.395,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,1097,0:31.386.398,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 97 F8 20 A8 A5 6A 61 16 FD 82 60 00 4B 05 DB 2D… 0,,1101,0:31.387.395,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,1102,0:31.402.400,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A2 7E 0A FF 96 2C E8 4C A1 D0 BE E3 3A 36 18 28… 0,,1106,0:31.403.397,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,1107,0:31.417.403,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1111,0:31.418.399,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,1112,0:31.418.403,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A2 7E 0A FF 96 2C E8 4C A1 D0 BE E3 3A 36 18 28… 0,,1116,0:31.419.400,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,1117,0:31.434.405,50.854 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF D8 5F 12 48 C6 CD 87 70 93 E0 CE C2 C8 92 FF… 0,,1121,0:31.435.402,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,1122,0:31.449.407,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1126,0:31.450.404,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,1127,0:31.450.407,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF D8 5F 12 48 C6 CD 87 70 93 E0 CE C2 C8 92 FF… 0,,1131,0:31.451.404,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,1132,0:31.466.409,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 27 3E 1F C9 6F 01 DD A9 D7 33 14 B9 DE 56 08… 0,,1136,0:31.467.406,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,1137,0:31.481.411,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1141,0:31.482.408,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,1142,0:31.482.412,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 27 3E 1F C9 6F 01 DD A9 D7 33 14 B9 DE 56 08… 0,,1146,0:31.483.408,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,1147,0:31.498.414,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C3 26 6B 5E 85 30 FB 6A 78 D9 C4 D1 71 0D 01 AA… 0,,1151,0:31.499.411,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,1152,0:31.513.416,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1156,0:31.514.413,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,1157,0:31.514.416,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C3 26 6B 5E 85 30 FB 6A 78 D9 C4 D1 71 0D 01 AA… 0,,1161,0:31.515.413,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,1162,0:31.530.418,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 49 B1 42 9A AD 07 51 4A 3B 9F 83 F5 3A 52 98… 0,,1166,0:31.531.415,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,1167,0:31.545.420,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1171,0:31.546.417,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,1172,0:31.546.420,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 49 B1 42 9A AD 07 51 4A 3B 9F 83 F5 3A 52 98… 0,,1176,0:31.547.417,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,1177,0:31.562.423,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 91 B9 91 C2 AD A6 00 99 92 1B 63 B8 60 D0 26… 0,,1181,0:31.563.420,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,1182,0:31.577.425,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1186,0:31.578.422,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,1187,0:31.578.425,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC 91 B9 91 C2 AD A6 00 99 92 1B 63 B8 60 D0 26… 0,,1191,0:31.579.422,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,1192,0:31.594.427,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 3A 70 87 32 41 29 84 34 5E 03 54 85 C0 C4 9D… 0,,1196,0:31.595.424,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,1197,0:31.609.429,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1201,0:31.610.426,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,1202,0:31.610.429,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 3A 70 87 32 41 29 84 34 5E 03 54 85 C0 C4 9D… 0,,1206,0:31.611.426,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,1207,0:31.626.432,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 9F 96 DB 76 CC A0 2D 87 D2 F0 74 2E C9 B8 F9… 0,,1211,0:31.627.428,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,1212,0:31.641.434,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1216,0:31.642.431,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,1217,0:31.642.434,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 9F 96 DB 76 CC A0 2D 87 D2 F0 74 2E C9 B8 F9… 0,,1221,0:31.643.431,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,1222,0:31.658.436,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 D2 EA CB FE 7B 7B E3 FE 98 D9 6D F3 D4 9F 4C… 0,,1226,0:31.659.433,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,1227,0:31.673.438,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1231,0:31.674.435,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,1232,0:31.674.438,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 D2 EA CB FE 7B 7B E3 FE 98 D9 6D F3 D4 9F 4C… 0,,1236,0:31.675.435,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,1237,0:31.690.440,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 2C B9 B8 67 65 0E 62 6A 12 00 B9 51 93 AB 76… 0,,1241,0:31.691.437,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,1242,0:31.705.443,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1246,0:31.706.439,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,1247,0:31.706.443,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 2C B9 B8 67 65 0E 62 6A 12 00 B9 51 93 AB 76… 0,,1251,0:31.707.440,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,1252,0:31.722.445,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 54 91 CD 15 CF 37 70 1E 40 83 70 52 33 C6 A1… 0,,1256,0:31.723.442,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,1257,0:31.737.447,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1261,0:31.738.444,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,1262,0:31.738.447,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 54 91 CD 15 CF 37 70 1E 40 83 70 52 33 C6 A1… 0,,1266,0:31.739.444,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,1267,0:31.754.449,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 0A F6 77 15 90 B5 B0 6A AC EC B9 56 F8 51 C8… 0,,1271,0:31.755.446,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,1272,0:31.769.451,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1276,0:31.770.448,16.005.125 ms,,,,,[17 SOF],[Frames: 993 - 1009] 0,,1277,0:31.786.454,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 20 64 E9 0E 99 B4 72 5F DC 48 F6 3A F2 B3 C6… 0,,1281,0:31.787.451,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,1282,0:31.801.456,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1286,0:31.802.453,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,1287,0:31.802.456,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 20 64 E9 0E 99 B4 72 5F DC 48 F6 3A F2 B3 C6… 0,,1291,0:31.803.453,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,1292,0:31.818.458,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B B1 5A 26 3A B6 1A BC CC 28 BA 62 86 70 89 1E… 0,,1296,0:31.819.455,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,1297,0:31.833.460,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1301,0:31.834.457,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,1302,0:31.834.460,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B B1 5A 26 3A B6 1A BC CC 28 BA 62 86 70 89 1E… 0,,1306,0:31.835.457,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,1307,0:31.850.463,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C B0 C5 8E D3 6B F4 2A E7 D1 E0 EB 2B 22 B9 2C… 0,,1311,0:31.851.460,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,1312,0:31.865.465,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1316,0:31.866.462,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,1317,0:31.866.465,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C B0 C5 8E D3 6B F4 2A E7 D1 E0 EB 2B 22 B9 2C… 0,,1321,0:31.867.462,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,1322,0:31.882.467,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 F1 7E 3F BA 67 BA 7C DE DD 8B 8C 98 9F C6 F5… 0,,1326,0:31.883.464,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,1327,0:31.897.469,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1331,0:31.898.466,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,1332,0:31.898.469,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 F1 7E 3F BA 67 BA 7C DE DD 8B 8C 98 9F C6 F5… 0,,1336,0:31.899.466,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,1337,0:31.914.472,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 35 C8 8B 4D CE A3 EC FC EE 20 B9 53 00 2E 2F 67… 0,,1341,0:31.915.468,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,1342,0:31.929.474,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1346,0:31.930.471,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,1347,0:31.930.474,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 35 C8 8B 4D CE A3 EC FC EE 20 B9 53 00 2E 2F 67… 0,,1351,0:31.931.471,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,1352,0:31.946.476,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 0C 95 20 4C 59 B9 B1 E0 43 20 E8 00 29 C1 FA… 0,,1356,0:31.947.473,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,1357,0:31.961.478,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1361,0:31.962.475,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,1362,0:31.962.478,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 0C 95 20 4C 59 B9 B1 E0 43 20 E8 00 29 C1 FA… 0,,1366,0:31.963.475,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,1367,0:31.978.480,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A B6 DC FD A0 C5 1B 37 C6 6F 8C C3 63 23 2C E8… 0,,1371,0:31.979.477,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,1372,0:31.993.483,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1376,0:31.994.479,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,1377,0:31.994.483,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A B6 DC FD A0 C5 1B 37 C6 6F 8C C3 63 23 2C E8… 0,,1381,0:31.995.480,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,1382,0:32.010.485,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 EB 47 C8 52 F3 28 09 82 7E F6 91 B3 24 8A 6B… 0,,1386,0:32.011.482,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,1387,0:32.025.487,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1391,0:32.026.484,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,1392,0:32.026.487,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 EB 47 C8 52 F3 28 09 82 7E F6 91 B3 24 8A 6B… 0,,1396,0:32.027.484,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,1397,0:32.042.489,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB B1 35 6D B3 AD E0 D5 08 64 94 45 F1 00 14 7A… 0,,1401,0:32.043.486,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,1402,0:32.057.491,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1406,0:32.058.488,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,1407,0:32.058.492,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB B1 35 6D B3 AD E0 D5 08 64 94 45 F1 00 14 7A… 0,,1411,0:32.059.488,15.004.916 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,1412,0:32.074.494,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 F7 F9 DC 55 01 23 D1 90 80 05 69 01 80 90 5E… 0,,1416,0:32.075.491,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,1417,0:32.089.496,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1421,0:32.090.493,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,1422,0:32.090.496,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 F7 F9 DC 55 01 23 D1 90 80 05 69 01 80 90 5E… 0,,1426,0:32.091.493,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,1427,0:32.106.498,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C 0B 1E 13 8D B2 6E EF 95 57 69 90 3E CB 86 D9… 0,,1431,0:32.107.495,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,1432,0:32.121.500,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1436,0:32.122.497,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,1437,0:32.122.500,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C 0B 1E 13 8D B2 6E EF 95 57 69 90 3E CB 86 D9… 0,,1441,0:32.123.497,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,1442,0:32.138.503,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 45 AD E8 A2 46 6F E0 2F 78 FB AD B6 1E 13 9B… 0,,1446,0:32.139.500,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,1447,0:32.153.505,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1451,0:32.154.502,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,1452,0:32.154.505,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 45 AD E8 A2 46 6F E0 2F 78 FB AD B6 1E 13 9B… 0,,1456,0:32.155.502,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,1457,0:32.170.507,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 F7 0A F2 B5 7E 4D 07 06 B9 A5 AA 13 56 98 A0… 0,,1461,0:32.171.504,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,1462,0:32.185.509,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1466,0:32.186.506,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,1467,0:32.186.509,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 F7 0A F2 B5 7E 4D 07 06 B9 A5 AA 13 56 98 A0… 0,,1471,0:32.187.506,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,1472,0:32.202.512,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C4 07 28 27 AD 79 8B EA FF 90 30 CD ED 1E 7E 65… 0,,1476,0:32.203.508,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,1477,0:32.217.514,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1481,0:32.218.510,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,1482,0:32.218.514,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C4 07 28 27 AD 79 8B EA FF 90 30 CD ED 1E 7E 65… 0,,1486,0:32.219.511,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,1487,0:32.234.516,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D EF A8 CB C9 99 CE D2 69 EB 90 72 17 08 01 14… 0,,1491,0:32.235.513,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,1492,0:32.249.518,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1496,0:32.250.515,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,1497,0:32.250.518,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D EF A8 CB C9 99 CE D2 69 EB 90 72 17 08 01 14… 0,,1501,0:32.251.515,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,1502,0:32.266.520,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A D5 7B F6 67 10 92 64 46 45 A4 48 D0 AC 08 87… 0,,1506,0:32.267.517,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,1507,0:32.281.523,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1511,0:32.282.519,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,1512,0:32.282.523,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A D5 7B F6 67 10 92 64 46 45 A4 48 D0 AC 08 87… 0,,1516,0:32.283.520,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,1517,0:32.298.525,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D1 D8 84 39 8E 3B 94 24 A1 4B 89 B9 3A 9D EB 33… 0,,1521,0:32.299.522,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,1522,0:32.313.527,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1526,0:32.314.524,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,1527,0:32.314.527,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D1 D8 84 39 8E 3B 94 24 A1 4B 89 B9 3A 9D EB 33… 0,,1531,0:32.315.524,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,1532,0:32.330.529,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE 1A FF 43 FA 58 94 D0 35 DC 9D 55 BB 7A ED 41… 0,,1536,0:32.331.526,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,1537,0:32.345.531,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1541,0:32.346.528,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,1542,0:32.346.532,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE 1A FF 43 FA 58 94 D0 35 DC 9D 55 BB 7A ED 41… 0,,1546,0:32.347.528,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,1547,0:32.362.534,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A1 7A 47 E5 00 E0 0D 6D 1D 9A DC A1 0B 2F 24 D1… 0,,1551,0:32.363.531,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,1552,0:32.377.536,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1556,0:32.378.533,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,1557,0:32.378.536,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A1 7A 47 E5 00 E0 0D 6D 1D 9A DC A1 0B 2F 24 D1… 0,,1561,0:32.379.533,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,1562,0:32.394.538,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C0 F9 EC 91 41 76 FC 09 42 B6 ED C2 71 3B AE 63… 0,,1566,0:32.395.535,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,1567,0:32.409.540,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1571,0:32.410.537,16.005.041 ms,,,,,[17 SOF],[Frames: 1633 - 1649] 0,,1572,0:32.426.543,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A0 3A 51 81 A7 26 D5 0E 6C ED DB 99 02 B0 6A 9C… 0,,1576,0:32.427.540,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,1577,0:32.441.545,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1581,0:32.442.542,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,1582,0:32.442.545,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A0 3A 51 81 A7 26 D5 0E 6C ED DB 99 02 B0 6A 9C… 0,,1586,0:32.443.542,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,1587,0:32.458.547,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 6A 03 2E BD 3D FD B8 DA 07 A2 22 86 BB 9D FC… 0,,1591,0:32.459.544,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,1592,0:32.473.549,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1596,0:32.474.546,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,1597,0:32.474.549,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 6A 03 2E BD 3D FD B8 DA 07 A2 22 86 BB 9D FC… 0,,1601,0:32.475.546,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,1602,0:32.490.552,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 A3 FA 54 E3 F3 CD 3F 20 0B 43 41 FE 0D 52 3C… 0,,1606,0:32.491.548,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,1607,0:32.505.554,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1611,0:32.506.550,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,1612,0:32.506.554,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 A3 FA 54 E3 F3 CD 3F 20 0B 43 41 FE 0D 52 3C… 0,,1616,0:32.507.551,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,1617,0:32.522.556,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD BE 6D 16 2E BF 61 E2 2F 8E E4 88 5C 9D 8E 27… 0,,1621,0:32.523.553,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,1622,0:32.537.558,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1626,0:32.538.555,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,1627,0:32.538.558,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD BE 6D 16 2E BF 61 E2 2F 8E E4 88 5C 9D 8E 27… 0,,1631,0:32.539.555,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,1632,0:32.554.560,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 54 5D F2 53 23 65 43 57 D4 C2 C7 F9 A1 F0 B6 20… 0,,1636,0:32.555.557,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,1637,0:32.569.562,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1641,0:32.570.559,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,1642,0:32.570.563,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 54 5D F2 53 23 65 43 57 D4 C2 C7 F9 A1 F0 B6 20… 0,,1646,0:32.571.559,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,1647,0:32.586.565,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1F 92 B1 0A 6D 3B DF A0 C7 CE B8 DD DD 6B 8E 20… 0,,1651,0:32.587.562,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,1652,0:32.601.567,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1656,0:32.602.564,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,1657,0:32.602.567,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1F 92 B1 0A 6D 3B DF A0 C7 CE B8 DD DD 6B 8E 20… 0,,1661,0:32.603.564,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,1662,0:32.618.569,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC EE A7 CC 67 01 8F 3D 78 9C 22 C2 ED 73 54 31… 0,,1666,0:32.619.566,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,1667,0:32.633.571,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1671,0:32.634.568,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,1672,0:32.634.571,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EC EE A7 CC 67 01 8F 3D 78 9C 22 C2 ED 73 54 31… 0,,1676,0:32.635.568,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,1677,0:32.650.574,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 2A 96 8B 8B 07 9E E6 FE F9 3B 43 22 45 06 F4… 0,,1681,0:32.651.571,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,1682,0:32.665.576,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1686,0:32.666.573,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,1687,0:32.666.576,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9A 2A 96 8B 8B 07 9E E6 FE F9 3B 43 22 45 06 F4… 0,,1691,0:32.667.573,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,1692,0:32.682.578,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EE 69 75 CB 1F 8C 63 DF 7F A7 EB A7 EA C2 3F 54… 0,,1696,0:32.683.575,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,1697,0:32.697.580,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1701,0:32.698.577,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,1702,0:32.698.580,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EE 69 75 CB 1F 8C 63 DF 7F A7 EB A7 EA C2 3F 54… 0,,1706,0:32.699.577,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,1707,0:32.714.583,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 20 BA 64 DD 01 08 6E 7D 57 CB F1 6D A7 ED 9D FE… 0,,1711,0:32.715.579,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,1712,0:32.729.585,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1716,0:32.730.582,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,1717,0:32.730.585,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 20 BA 64 DD 01 08 6E 7D 57 CB F1 6D A7 ED 9D FE… 0,,1721,0:32.731.582,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,1722,0:32.746.587,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CB 5A 01 0F 9C 98 A8 9E 74 7E 5E 74 26 20 D5 72… 0,,1726,0:32.747.584,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,1727,0:32.761.589,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1731,0:32.762.586,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,1732,0:32.762.589,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CB 5A 01 0F 9C 98 A8 9E 74 7E 5E 74 26 20 D5 72… 0,,1736,0:32.763.586,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,1737,0:32.778.592,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D4 E6 7A 96 C0 4E BA 80 CA C4 3C DC AD B7 B0 3C… 0,,1741,0:32.779.588,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,1742,0:32.793.594,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1746,0:32.794.590,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,1747,0:32.794.594,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D4 E6 7A 96 C0 4E BA 80 CA C4 3C DC AD B7 B0 3C… 0,,1751,0:32.795.591,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,1752,0:32.810.596,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D3 A0 BC CF 14 D7 7A BB 25 F7 1E 45 8C F1 76 BA… 0,,1756,0:32.811.593,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,1757,0:32.825.598,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1761,0:32.826.595,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,1762,0:32.826.598,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D3 A0 BC CF 14 D7 7A BB 25 F7 1E 45 8C F1 76 BA… 0,,1766,0:32.827.595,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,1767,0:32.842.600,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 A2 66 12 39 B0 83 CE E5 84 74 C6 AC 50 C3 BC… 0,,1771,0:32.843.597,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,1772,0:32.857.602,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1776,0:32.858.599,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,1777,0:32.858.603,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 A2 66 12 39 B0 83 CE E5 84 74 C6 AC 50 C3 BC… 0,,1781,0:32.859.599,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,1782,0:32.874.605,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 FD 25 FF 65 86 B5 1E 20 E0 31 7E E2 8C A5 FE… 0,,1786,0:32.875.602,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,1787,0:32.889.607,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1791,0:32.890.604,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,1792,0:32.890.607,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 FD 25 FF 65 86 B5 1E 20 E0 31 7E E2 8C A5 FE… 0,,1796,0:32.891.604,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,1797,0:32.906.609,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C5 DA B6 D7 2D B7 2C 8D 07 D3 92 80 F1 2B 91 4A… 0,,1801,0:32.907.606,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,1802,0:32.921.611,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1806,0:32.922.608,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,1807,0:32.922.611,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C5 DA B6 D7 2D B7 2C 8D 07 D3 92 80 F1 2B 91 4A… 0,,1811,0:32.923.608,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,1812,0:32.938.614,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 1F A4 8C 58 9D 4F E9 05 B8 B7 6D 62 3F 48 D2… 0,,1816,0:32.939.611,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,1817,0:32.953.616,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1821,0:32.954.613,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,1822,0:32.954.616,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 1F A4 8C 58 9D 4F E9 05 B8 B7 6D 62 3F 48 D2… 0,,1826,0:32.955.613,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,1827,0:32.970.618,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 ED 54 23 7D 48 1E 3C 0D 0B E2 2C 2C FD E5 93 E4… 0,,1831,0:32.971.615,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,1832,0:32.985.620,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1836,0:32.986.617,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,1837,0:32.986.620,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 ED 54 23 7D 48 1E 3C 0D 0B E2 2C 2C FD E5 93 E4… 0,,1841,0:32.987.617,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,1842,0:33.002.623,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 3D 45 74 34 A6 63 3F 89 6E 3F D6 8A 04 FD 74… 0,,1846,0:33.003.619,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,1847,0:33.017.625,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1851,0:33.018.622,16.005.041 ms,,,,,[17 SOF],[Frames: 193 - 209] 0,,1852,0:33.034.627,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 FC 9B 03 2D 29 7D FD 47 6F A9 C9 6D C9 5C 86… 0,,1856,0:33.035.624,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,1857,0:33.049.629,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1861,0:33.050.626,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,1862,0:33.050.629,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 FC 9B 03 2D 29 7D FD 47 6F A9 C9 6D C9 5C 86… 0,,1866,0:33.051.626,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,1867,0:33.066.631,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 99 0E 95 5F BF 6F D0 99 D9 10 FC CE BC 31 2F FE… 0,,1871,0:33.067.628,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,1872,0:33.081.634,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1876,0:33.082.630,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,1877,0:33.082.634,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 99 0E 95 5F BF 6F D0 99 D9 10 FC CE BC 31 2F FE… 0,,1881,0:33.083.631,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,1882,0:33.098.636,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 50 A2 7D 4F 26 27 68 4A 9D D9 8D 19 40 29 0B… 0,,1886,0:33.099.633,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,1887,0:33.113.638,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1891,0:33.114.635,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,1892,0:33.114.638,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 50 A2 7D 4F 26 27 68 4A 9D D9 8D 19 40 29 0B… 0,,1896,0:33.115.635,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,1897,0:33.130.640,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA FF 5B 7A B8 4A C3 7C 58 C0 52 71 05 3D BA BB… 0,,1901,0:33.131.637,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,1902,0:33.145.642,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1906,0:33.146.639,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,1907,0:33.146.643,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA FF 5B 7A B8 4A C3 7C 58 C0 52 71 05 3D BA BB… 0,,1911,0:33.147.639,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,1912,0:33.162.645,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 1A 17 C8 5C 7A 47 6E 59 E1 A3 B6 17 C6 53 51… 0,,1916,0:33.163.642,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,1917,0:33.177.647,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1921,0:33.178.644,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,1922,0:33.178.647,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 1A 17 C8 5C 7A 47 6E 59 E1 A3 B6 17 C6 53 51… 0,,1926,0:33.179.644,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,1927,0:33.194.649,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9D 97 DF 34 83 7B 9C 9C 0E CF A0 A4 26 87 EC 9A… 0,,1931,0:33.195.646,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,1932,0:33.209.651,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1936,0:33.210.648,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,1937,0:33.210.651,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9D 97 DF 34 83 7B 9C 9C 0E CF A0 A4 26 87 EC 9A… 0,,1941,0:33.211.648,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,1942,0:33.226.654,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 81 94 4A 76 2C 4D AA 19 85 E9 B1 EC 35 94 4A… 0,,1946,0:33.227.651,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,1947,0:33.241.656,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1951,0:33.242.653,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,1952,0:33.242.656,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 81 94 4A 76 2C 4D AA 19 85 E9 B1 EC 35 94 4A… 0,,1956,0:33.243.653,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,1957,0:33.258.658,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 C5 74 96 6B B0 76 AC 97 DE F8 02 50 59 D6 5D… 0,,1961,0:33.259.655,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,1962,0:33.273.660,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1966,0:33.274.657,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,1967,0:33.274.660,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 C5 74 96 6B B0 76 AC 97 DE F8 02 50 59 D6 5D… 0,,1971,0:33.275.657,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,1972,0:33.290.663,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 21 8B 60 AF B1 AB C8 56 7D 5B FE B7 38 7F 6D 2D… 0,,1976,0:33.291.659,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,1977,0:33.305.665,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1981,0:33.306.662,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,1982,0:33.306.665,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 21 8B 60 AF B1 AB C8 56 7D 5B FE B7 38 7F 6D 2D… 0,,1986,0:33.307.662,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,1987,0:33.322.667,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9F D2 4D 4D EB 1B AC 51 5B A3 E5 58 79 7D D7 D0… 0,,1991,0:33.323.664,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,1992,0:33.337.669,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,1996,0:33.338.666,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,1997,0:33.338.669,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9F D2 4D 4D EB 1B AC 51 5B A3 E5 58 79 7D D7 D0… 0,,2001,0:33.339.666,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,2002,0:33.354.671,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 59 BE 1B C4 AA EE 1C EE BB EF 36 92 02 F1 88… 0,,2006,0:33.355.668,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,2007,0:33.369.674,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2011,0:33.370.670,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,2012,0:33.370.674,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 59 BE 1B C4 AA EE 1C EE BB EF 36 92 02 F1 88… 0,,2016,0:33.371.671,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,2017,0:33.386.676,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EE 8B C5 D3 A6 A7 9B E0 0E FF 60 E9 0B DC F0 C5… 0,,2021,0:33.387.673,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,2022,0:33.401.678,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2026,0:33.402.675,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,2027,0:33.402.678,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EE 8B C5 D3 A6 A7 9B E0 0E FF 60 E9 0B DC F0 C5… 0,,2031,0:33.403.675,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,2032,0:33.418.680,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F B6 0A BF D1 4F E4 7B 84 DE 01 00 0F 8A 96 E8… 0,,2036,0:33.419.677,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,2037,0:33.433.682,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2041,0:33.434.679,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,2042,0:33.434.683,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F B6 0A BF D1 4F E4 7B 84 DE 01 00 0F 8A 96 E8… 0,,2046,0:33.435.679,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,2047,0:33.450.685,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 BB 6B D9 28 2D F5 CF 18 89 00 66 D9 55 81 92… 0,,2051,0:33.451.682,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,2052,0:33.465.687,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2056,0:33.466.684,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,2057,0:33.466.687,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 BB 6B D9 28 2D F5 CF 18 89 00 66 D9 55 81 92… 0,,2061,0:33.467.684,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,2062,0:33.482.689,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 07 AC 24 58 34 5E D0 3D CB 55 E8 EA 37 3E AC… 0,,2066,0:33.483.686,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,2067,0:33.497.691,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2071,0:33.498.688,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,2072,0:33.498.691,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 07 AC 24 58 34 5E D0 3D CB 55 E8 EA 37 3E AC… 0,,2076,0:33.499.688,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,2077,0:33.514.694,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D CA 5F 42 85 E3 1F 9E 46 A7 84 D2 CE 41 99 A1… 0,,2081,0:33.515.691,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,2082,0:33.529.696,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2086,0:33.530.693,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,2087,0:33.530.696,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D CA 5F 42 85 E3 1F 9E 46 A7 84 D2 CE 41 99 A1… 0,,2091,0:33.531.693,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,2092,0:33.546.698,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C1 FC 6B 5C 0F 4F D6 BE 83 BC 22 FE 85 5B 8B EA… 0,,2096,0:33.547.695,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,2097,0:33.561.700,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2101,0:33.562.697,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,2102,0:33.562.700,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C1 FC 6B 5C 0F 4F D6 BE 83 BC 22 FE 85 5B 8B EA… 0,,2106,0:33.563.697,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,2107,0:33.578.703,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 E1 C6 AD C7 1F 46 95 51 69 F1 0F E8 90 C1 69… 0,,2111,0:33.579.699,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,2112,0:33.593.705,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2116,0:33.594.702,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,2117,0:33.594.705,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 E1 C6 AD C7 1F 46 95 51 69 F1 0F E8 90 C1 69… 0,,2121,0:33.595.702,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,2122,0:33.610.707,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 AC F1 35 B2 BD 1A 21 EB B5 76 4A E3 59 A9 FE… 0,,2126,0:33.611.704,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,2127,0:33.625.709,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2131,0:33.626.706,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,2132,0:33.626.709,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 AC F1 35 B2 BD 1A 21 EB B5 76 4A E3 59 A9 FE… 0,,2136,0:33.627.706,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,2137,0:33.642.711,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 21 4E FD AB 65 F4 65 CD 3F E0 BB 40 52 FD 69… 0,,2141,0:33.643.708,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,2142,0:33.657.714,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2146,0:33.658.710,16.005.041 ms,,,,,[17 SOF],[Frames: 833 - 849] 0,,2147,0:33.674.716,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 E3 1D 93 7E FE AA B1 7B F3 38 72 C2 50 9F 6D… 0,,2151,0:33.675.713,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,2152,0:33.689.718,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2156,0:33.690.715,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,2157,0:33.690.718,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 E3 1D 93 7E FE AA B1 7B F3 38 72 C2 50 9F 6D… 0,,2161,0:33.691.715,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,2162,0:33.706.720,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 7A 07 EA AC B7 AD 05 58 6F C9 51 60 C3 C3 02… 0,,2166,0:33.707.717,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,2167,0:33.721.722,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2171,0:33.722.719,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,2172,0:33.722.723,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 7A 07 EA AC B7 AD 05 58 6F C9 51 60 C3 C3 02… 0,,2176,0:33.723.719,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,2177,0:33.738.725,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 81 1E 1D A4 D7 2C A7 F5 15 81 F7 F9 A6 A2 24… 0,,2181,0:33.739.722,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,2182,0:33.753.727,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2186,0:33.754.724,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,2187,0:33.754.727,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 81 1E 1D A4 D7 2C A7 F5 15 81 F7 F9 A6 A2 24… 0,,2191,0:33.755.724,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,2192,0:33.770.729,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 24 2A 89 38 3F F1 66 68 E5 A6 54 7E 5C EB E8… 0,,2196,0:33.771.726,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,2197,0:33.785.731,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2201,0:33.786.728,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,2202,0:33.786.731,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 24 2A 89 38 3F F1 66 68 E5 A6 54 7E 5C EB E8… 0,,2206,0:33.787.728,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,2207,0:33.802.734,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F FD 56 69 9A 60 BB A0 CD 63 F3 D2 EA C4 97 68… 0,,2211,0:33.803.731,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,2212,0:33.817.736,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2216,0:33.818.733,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,2217,0:33.818.736,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F FD 56 69 9A 60 BB A0 CD 63 F3 D2 EA C4 97 68… 0,,2221,0:33.819.733,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,2222,0:33.834.738,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 53 57 1F 5D BB 31 C4 B1 0E 0C 5F 4B A8 85 FF… 0,,2226,0:33.835.735,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,2227,0:33.849.740,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2231,0:33.850.737,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,2232,0:33.850.740,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 53 57 1F 5D BB 31 C4 B1 0E 0C 5F 4B A8 85 FF… 0,,2236,0:33.851.737,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,2237,0:33.866.743,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 04 53 56 D8 2B C9 B0 8E 94 7C BF 12 B7 D0 2D… 0,,2241,0:33.867.739,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,2242,0:33.881.745,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2246,0:33.882.742,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,2247,0:33.882.745,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 04 53 56 D8 2B C9 B0 8E 94 7C BF 12 B7 D0 2D… 0,,2251,0:33.883.742,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,2252,0:33.898.747,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D4 F7 67 CC D4 AD E1 45 75 5F 8E 45 15 1B 2F 93… 0,,2256,0:33.899.744,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,2257,0:33.913.749,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2261,0:33.914.746,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,2262,0:33.914.749,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D4 F7 67 CC D4 AD E1 45 75 5F 8E 45 15 1B 2F 93… 0,,2266,0:33.915.746,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,2267,0:33.930.751,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5C 5B E7 63 93 87 E2 C0 EC D5 E6 E3 9E 6F CF 01… 0,,2271,0:33.931.748,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,2272,0:33.945.754,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2276,0:33.946.750,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,2277,0:33.946.754,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5C 5B E7 63 93 87 E2 C0 EC D5 E6 E3 9E 6F CF 01… 0,,2281,0:33.947.751,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,2282,0:33.962.756,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 B3 5E B8 2B 1C 2E C2 EF 69 11 DC 69 70 4D 32… 0,,2286,0:33.963.753,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,2287,0:33.977.758,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2291,0:33.978.755,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,2292,0:33.978.758,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 B3 5E B8 2B 1C 2E C2 EF 69 11 DC 69 70 4D 32… 0,,2296,0:33.979.755,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,2297,0:33.994.760,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B 50 F6 5B 45 B2 86 CC B4 EB B2 80 A5 B4 7F C2… 0,,2301,0:33.995.757,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,2302,0:34.009.762,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2306,0:34.010.759,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,2307,0:34.010.763,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B 50 F6 5B 45 B2 86 CC B4 EB B2 80 A5 B4 7F C2… 0,,2311,0:34.011.759,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,2312,0:34.026.765,50.916 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D 54 0B BF 20 6C 1A 08 89 77 2A 9D 69 58 FC BF… 0,,2316,0:34.027.762,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,2317,0:34.041.767,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2321,0:34.042.764,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,2322,0:34.042.767,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D 54 0B BF 20 6C 1A 08 89 77 2A 9D 69 58 FC BF… 0,,2326,0:34.043.764,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,2327,0:34.058.769,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 69 DC 56 86 00 38 21 4F 22 E6 58 6B 2C 0A 4F… 0,,2331,0:34.059.766,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,2332,0:34.073.771,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2336,0:34.074.768,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,2337,0:34.074.771,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 69 DC 56 86 00 38 21 4F 22 E6 58 6B 2C 0A 4F… 0,,2341,0:34.075.768,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,2342,0:34.090.774,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 4B 7D A1 64 EC 87 D4 22 09 2D 0B FF 7F 64 F4… 0,,2346,0:34.091.771,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,2347,0:34.105.776,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2351,0:34.106.773,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,2352,0:34.106.776,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 4B 7D A1 64 EC 87 D4 22 09 2D 0B FF 7F 64 F4… 0,,2356,0:34.107.773,15.004.916 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,2357,0:34.122.778,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 60 8F D0 CB 17 5B F1 C3 06 71 B3 56 0B F7 C8… 0,,2361,0:34.123.775,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,2362,0:34.137.780,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2366,0:34.138.777,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,2367,0:34.138.780,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 60 8F D0 CB 17 5B F1 C3 06 71 B3 56 0B F7 C8… 0,,2371,0:34.139.777,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,2372,0:34.154.783,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FB DB A2 1B D6 7E 8A 16 95 2A 83 E0 6C 2A BF 85… 0,,2376,0:34.155.779,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,2377,0:34.169.785,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2381,0:34.170.781,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,2382,0:34.170.785,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FB DB A2 1B D6 7E 8A 16 95 2A 83 E0 6C 2A BF 85… 0,,2386,0:34.171.782,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,2387,0:34.186.787,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D1 FF F7 9E 82 94 07 C4 0D 8B 6C 79 C2 92 A9 84… 0,,2391,0:34.187.784,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,2392,0:34.201.789,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2396,0:34.202.786,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,2397,0:34.202.789,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D1 FF F7 9E 82 94 07 C4 0D 8B 6C 79 C2 92 A9 84… 0,,2401,0:34.203.786,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,2402,0:34.218.791,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 1C EF 46 A1 E7 3B 90 F3 74 27 42 7C 4E 1E C2… 0,,2406,0:34.219.788,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,2407,0:34.233.793,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2411,0:34.234.790,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,2412,0:34.234.794,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 1C EF 46 A1 E7 3B 90 F3 74 27 42 7C 4E 1E C2… 0,,2416,0:34.235.791,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,2417,0:34.250.796,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 ED 2A C7 6F C4 06 A0 BF 78 89 0E A5 2B DC CA 00… 0,,2421,0:34.251.793,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,2422,0:34.265.798,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2426,0:34.266.795,16.005.041 ms,,,,,[17 SOF],[Frames: 1441 - 1457] 0,,2427,0:34.282.800,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 70 03 63 0D C3 B5 A3 6B F6 B3 18 0E 97 F9 44… 0,,2431,0:34.283.797,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,2432,0:34.297.802,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2436,0:34.298.799,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,2437,0:34.298.803,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 70 03 63 0D C3 B5 A3 6B F6 B3 18 0E 97 F9 44… 0,,2441,0:34.299.799,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,2442,0:34.314.805,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 69 95 89 1B D6 D0 B7 C2 83 95 10 75 06 44 FE… 0,,2446,0:34.315.802,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,2447,0:34.329.807,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2451,0:34.330.804,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,2452,0:34.330.807,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 69 95 89 1B D6 D0 B7 C2 83 95 10 75 06 44 FE… 0,,2456,0:34.331.804,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,2457,0:34.346.809,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 82 BE 6A 45 AF 82 B0 CA 63 42 29 72 D3 6C 85… 0,,2461,0:34.347.806,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,2462,0:34.361.811,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2466,0:34.362.808,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,2467,0:34.362.811,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 82 BE 6A 45 AF 82 B0 CA 63 42 29 72 D3 6C 85… 0,,2471,0:34.363.808,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,2472,0:34.378.814,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 6C F1 3D 3B 97 CB 0F 86 AB 1B EC 7D 03 4E 4E… 0,,2476,0:34.379.811,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,2477,0:34.393.816,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2481,0:34.394.813,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,2482,0:34.394.816,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 6C F1 3D 3B 97 CB 0F 86 AB 1B EC 7D 03 4E 4E… 0,,2486,0:34.395.813,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,2487,0:34.410.818,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 2D ED CF 5B E8 BF 21 44 84 25 9D 0B 1E 51 48… 0,,2491,0:34.411.815,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,2492,0:34.425.820,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2496,0:34.426.817,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,2497,0:34.426.820,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9A 2D ED CF 5B E8 BF 21 44 84 25 9D 0B 1E 51 48… 0,,2501,0:34.427.817,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,2502,0:34.442.823,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 24 59 DF 7D D9 D5 51 C7 34 62 A7 94 65 9D 09… 0,,2506,0:34.443.819,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,2507,0:34.457.825,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2511,0:34.458.821,2.833 us,,,,,[1 SOF],[Frame: 1633] 0,,2512,0:34.458.825,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 24 59 DF 7D D9 D5 51 C7 34 62 A7 94 65 9D 09… 0,,2516,0:34.459.822,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,2517,0:34.474.827,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 CB 54 3E 5D 9B 5C 29 A4 9C 64 3F 24 2A CC 2E… 0,,2521,0:34.475.824,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,2522,0:34.489.829,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2526,0:34.490.826,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,2527,0:34.490.829,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 CB 54 3E 5D 9B 5C 29 A4 9C 64 3F 24 2A CC 2E… 0,,2531,0:34.491.826,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,2532,0:34.506.831,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 13 92 83 E9 70 31 E0 3D 04 E9 6C 6B C3 63 6B… 0,,2536,0:34.507.828,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,2537,0:34.521.833,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2541,0:34.522.830,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,2542,0:34.522.834,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 13 92 83 E9 70 31 E0 3D 04 E9 6C 6B C3 63 6B… 0,,2546,0:34.523.831,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,2547,0:34.538.836,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 35 6F 7D 86 79 6F EE 64 48 75 4B 36 EA 98 A7 4E… 0,,2551,0:34.539.833,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,2552,0:34.553.838,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2556,0:34.554.835,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,2557,0:34.554.838,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 35 6F 7D 86 79 6F EE 64 48 75 4B 36 EA 98 A7 4E… 0,,2561,0:34.555.835,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,2562,0:34.570.840,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 2B 3C 15 F4 4F 30 5B 03 4E 04 31 31 33 11 CE… 0,,2566,0:34.571.837,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,2567,0:34.585.842,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2571,0:34.586.839,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,2572,0:34.586.843,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 2B 3C 15 F4 4F 30 5B 03 4E 04 31 31 33 11 CE… 0,,2576,0:34.587.839,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,2577,0:34.602.845,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 21 45 2C 94 DB D3 A3 39 E9 5A 44 A6 BC 6C D9 4E… 0,,2581,0:34.603.842,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,2582,0:34.617.847,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2586,0:34.618.844,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,2587,0:34.618.847,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 21 45 2C 94 DB D3 A3 39 E9 5A 44 A6 BC 6C D9 4E… 0,,2591,0:34.619.844,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,2592,0:34.634.849,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 64 46 0B FF 18 F4 46 44 73 61 55 E3 02 CE 9B 46… 0,,2596,0:34.635.846,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,2597,0:34.649.851,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2601,0:34.650.848,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,2602,0:34.650.851,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 64 46 0B FF 18 F4 46 44 73 61 55 E3 02 CE 9B 46… 0,,2606,0:34.651.848,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,2607,0:34.666.854,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 2B DE 82 16 9E D3 C1 05 DB D7 C3 28 C4 E4 D8… 0,,2611,0:34.667.850,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,2612,0:34.681.856,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2616,0:34.682.853,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,2617,0:34.682.856,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 2B DE 82 16 9E D3 C1 05 DB D7 C3 28 C4 E4 D8… 0,,2621,0:34.683.853,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,2622,0:34.698.858,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 8C 22 16 FC 1D 79 E6 FF EC DC B5 03 F2 95 FC… 0,,2626,0:34.699.855,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,2627,0:34.713.860,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2631,0:34.714.857,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,2632,0:34.714.860,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 8C 22 16 FC 1D 79 E6 FF EC DC B5 03 F2 95 FC… 0,,2636,0:34.715.857,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,2637,0:34.730.862,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 BE CB C5 2A 35 AC 6F FA 8B 3E 5A 2E C2 EA 41… 0,,2641,0:34.731.859,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,2642,0:34.745.865,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2646,0:34.746.861,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,2647,0:34.746.865,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C6 BE CB C5 2A 35 AC 6F FA 8B 3E 5A 2E C2 EA 41… 0,,2651,0:34.747.862,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,2652,0:34.762.867,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 29 8C 92 43 A3 87 DB 17 D8 91 0B DC 31 29 F8… 0,,2656,0:34.763.864,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,2657,0:34.777.869,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2661,0:34.778.866,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,2662,0:34.778.869,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C6 29 8C 92 43 A3 87 DB 17 D8 91 0B DC 31 29 F8… 0,,2666,0:34.779.866,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,2667,0:34.794.871,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E E9 09 57 76 6C 4F D6 62 61 A7 E6 4C 67 E4 DB… 0,,2671,0:34.795.868,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,2672,0:34.809.873,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2676,0:34.810.870,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,2677,0:34.810.874,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E E9 09 57 76 6C 4F D6 62 61 A7 E6 4C 67 E4 DB… 0,,2681,0:34.811.870,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,2682,0:34.826.876,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC 48 25 24 DE 7E 6F B8 76 B4 9F 06 AB 4C 9C D7… 0,,2686,0:34.827.873,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,2687,0:34.841.878,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2691,0:34.842.875,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,2692,0:34.842.878,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC 48 25 24 DE 7E 6F B8 76 B4 9F 06 AB 4C 9C D7… 0,,2696,0:34.843.875,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,2697,0:34.858.880,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E 29 63 B6 D9 AA EF 34 76 DF 79 98 3F 8C B5 D2… 0,,2701,0:34.859.877,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,2702,0:34.873.882,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2706,0:34.874.879,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,2707,0:34.874.882,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E 29 63 B6 D9 AA EF 34 76 DF 79 98 3F 8C B5 D2… 0,,2711,0:34.875.879,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,2712,0:34.890.885,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3A 08 E5 D1 BA 9F 4C 1A 5B A7 55 11 23 89 CB 80… 0,,2716,0:34.891.882,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,2717,0:34.905.887,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2721,0:34.906.884,16.005.041 ms,,,,,[17 SOF],[Frames: 33 - 49] 0,,2722,0:34.922.889,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D8 66 C2 6C 83 00 2F 89 96 CB 16 EB 52 43 68 CF… 0,,2726,0:34.923.886,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,2727,0:34.937.891,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2731,0:34.938.888,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,2732,0:34.938.891,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D8 66 C2 6C 83 00 2F 89 96 CB 16 EB 52 43 68 CF… 0,,2736,0:34.939.888,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,2737,0:34.954.894,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 AC AB 74 98 6E 61 27 BE F7 69 08 76 B4 73 6B… 0,,2741,0:34.955.890,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,2742,0:34.969.896,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2746,0:34.970.893,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,2747,0:34.970.896,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 AC AB 74 98 6E 61 27 BE F7 69 08 76 B4 73 6B… 0,,2751,0:34.971.893,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,2752,0:34.986.898,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B 92 6F 5B 63 96 83 E3 45 98 DE 59 D9 11 EB 87… 0,,2756,0:34.987.895,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,2757,0:35.001.900,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2761,0:35.002.897,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,2762,0:35.002.900,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B 92 6F 5B 63 96 83 E3 45 98 DE 59 D9 11 EB 87… 0,,2766,0:35.003.897,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,2767,0:35.018.902,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 1E 9E 7E 0B 7D A0 ED 5C F2 84 6C 52 28 7A 7A… 0,,2771,0:35.019.899,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,2772,0:35.033.905,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2776,0:35.034.901,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,2777,0:35.034.905,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 1E 9E 7E 0B 7D A0 ED 5C F2 84 6C 52 28 7A 7A… 0,,2781,0:35.035.902,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,2782,0:35.050.907,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C5 64 13 73 C3 A0 E8 1B AF 0A 4B 39 D4 54 32 26… 0,,2786,0:35.051.904,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,2787,0:35.065.909,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2791,0:35.066.906,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,2792,0:35.066.909,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C5 64 13 73 C3 A0 E8 1B AF 0A 4B 39 D4 54 32 26… 0,,2796,0:35.067.906,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,2797,0:35.082.911,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 F1 3B A7 73 C2 7D A6 12 13 70 57 52 BB 7C 9B… 0,,2801,0:35.083.908,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,2802,0:35.097.913,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2806,0:35.098.910,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,2807,0:35.098.914,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 F1 3B A7 73 C2 7D A6 12 13 70 57 52 BB 7C 9B… 0,,2811,0:35.099.910,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,2812,0:35.114.916,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 4F 46 B4 93 4E 56 DA 7C 82 E3 BC 6E 86 72 6C… 0,,2816,0:35.115.913,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,2817,0:35.129.918,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2821,0:35.130.915,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,2822,0:35.130.918,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 4F 46 B4 93 4E 56 DA 7C 82 E3 BC 6E 86 72 6C… 0,,2826,0:35.131.915,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,2827,0:35.146.920,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 D7 0D 2B F8 1E 70 05 F4 8C 86 C0 6F C4 4B 03… 0,,2831,0:35.147.917,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,2832,0:35.161.922,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2836,0:35.162.919,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,2837,0:35.162.922,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 D7 0D 2B F8 1E 70 05 F4 8C 86 C0 6F C4 4B 03… 0,,2841,0:35.163.919,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,2842,0:35.178.925,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 B9 90 89 DB 3C 2C FF D7 89 CB 42 AA 78 29 6C… 0,,2846,0:35.179.922,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,2847,0:35.193.927,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2851,0:35.194.924,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,2852,0:35.194.927,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 B9 90 89 DB 3C 2C FF D7 89 CB 42 AA 78 29 6C… 0,,2856,0:35.195.924,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,2857,0:35.210.929,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 91 DC FC B6 7E 01 62 41 D1 98 72 5B 65 D7 18… 0,,2861,0:35.211.926,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,2862,0:35.225.931,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2866,0:35.226.928,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,2867,0:35.226.931,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 91 DC FC B6 7E 01 62 41 D1 98 72 5B 65 D7 18… 0,,2871,0:35.227.928,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,2872,0:35.242.934,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E9 B2 7A 96 3B 6C 66 D7 1C 82 B0 CA 57 1A 69 48… 0,,2876,0:35.243.930,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,2877,0:35.257.936,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2881,0:35.258.933,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,2882,0:35.258.936,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E9 B2 7A 96 3B 6C 66 D7 1C 82 B0 CA 57 1A 69 48… 0,,2886,0:35.259.933,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,2887,0:35.274.938,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B 26 D9 C6 7C B0 78 5B CE 0D 7C CC 51 3C EB 3C… 0,,2891,0:35.275.935,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,2892,0:35.289.940,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2896,0:35.290.937,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,2897,0:35.290.940,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B 26 D9 C6 7C B0 78 5B CE 0D 7C CC 51 3C EB 3C… 0,,2901,0:35.291.937,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,2902,0:35.306.942,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0C 7F 8A 6C 7C AA 59 EA 84 1A 60 F0 5A 3F 61 91… 0,,2906,0:35.307.939,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,2907,0:35.321.945,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2911,0:35.322.941,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,2912,0:35.322.945,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0C 7F 8A 6C 7C AA 59 EA 84 1A 60 F0 5A 3F 61 91… 0,,2916,0:35.323.942,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,2917,0:35.338.947,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 17 51 85 99 58 4A 89 37 2B 0C 91 E1 3D 2C 2C E9… 0,,2921,0:35.339.944,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,2922,0:35.353.949,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2926,0:35.354.946,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,2927,0:35.354.949,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 17 51 85 99 58 4A 89 37 2B 0C 91 E1 3D 2C 2C E9… 0,,2931,0:35.355.946,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,2932,0:35.370.951,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AB B0 BD 54 D0 BE 6F 9B C4 02 42 5C 17 5A 74 6A… 0,,2936,0:35.371.948,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,2937,0:35.385.953,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2941,0:35.386.950,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,2942,0:35.386.954,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AB B0 BD 54 D0 BE 6F 9B C4 02 42 5C 17 5A 74 6A… 0,,2946,0:35.387.950,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,2947,0:35.402.956,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF 06 30 30 A2 1C 73 A9 B8 3D 37 37 8D BC B5 F7… 0,,2951,0:35.403.953,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,2952,0:35.417.958,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2956,0:35.418.955,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,2957,0:35.418.958,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF 06 30 30 A2 1C 73 A9 B8 3D 37 37 8D BC B5 F7… 0,,2961,0:35.419.955,15.004.916 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,2962,0:35.434.960,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AD 61 D7 99 B1 FD DC D1 C8 62 7A BC 83 F3 B3 7B… 0,,2966,0:35.435.957,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,2967,0:35.449.962,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2971,0:35.450.959,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,2972,0:35.450.962,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AD 61 D7 99 B1 FD DC D1 C8 62 7A BC 83 F3 B3 7B… 0,,2976,0:35.451.959,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,2977,0:35.466.965,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 BE 91 BB 19 68 85 83 8F 30 FB 66 9D 19 4F C7… 0,,2981,0:35.467.962,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,2982,0:35.481.967,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,2986,0:35.482.964,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,2987,0:35.482.967,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 BE 91 BB 19 68 85 83 8F 30 FB 66 9D 19 4F C7… 0,,2991,0:35.483.964,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,2992,0:35.498.969,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 0E EF FA 4C 20 07 83 F3 B9 FE 72 01 57 6D 5C… 0,,2996,0:35.499.966,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,2997,0:35.513.971,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3001,0:35.514.968,16.005.041 ms,,,,,[17 SOF],[Frames: 641 - 657] 0,,3002,0:35.530.974,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 55 BA 2E 4E 75 8F 38 E8 DA BC C9 70 43 76 0B… 0,,3006,0:35.531.970,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,3007,0:35.545.976,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3011,0:35.546.973,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,3012,0:35.546.976,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 55 BA 2E 4E 75 8F 38 E8 DA BC C9 70 43 76 0B… 0,,3016,0:35.547.973,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,3017,0:35.562.978,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 CD 5B FF DA 80 1A 2D E0 BB 2A 99 46 6F E3 36… 0,,3021,0:35.563.975,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,3022,0:35.577.980,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3026,0:35.578.977,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,3027,0:35.578.980,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 CD 5B FF DA 80 1A 2D E0 BB 2A 99 46 6F E3 36… 0,,3031,0:35.579.977,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,3032,0:35.594.982,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA E1 AF FE FE FA FB 85 8F 9A 5B 8A 9C AC F8 3D… 0,,3036,0:35.595.979,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,3037,0:35.609.985,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3041,0:35.610.981,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,3042,0:35.610.985,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA E1 AF FE FE FA FB 85 8F 9A 5B 8A 9C AC F8 3D… 0,,3046,0:35.611.982,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,3047,0:35.626.987,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 34 58 B7 16 BE 8D 33 D1 1D 6F C7 00 1A 1E 26… 0,,3051,0:35.627.984,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,3052,0:35.641.989,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3056,0:35.642.986,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,3057,0:35.642.989,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 34 58 B7 16 BE 8D 33 D1 1D 6F C7 00 1A 1E 26… 0,,3061,0:35.643.986,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,3062,0:35.658.991,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 89 D4 B6 A8 6F 14 CD 3F 43 E3 6B 12 68 9B F9 3C… 0,,3066,0:35.659.988,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,3067,0:35.673.993,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3071,0:35.674.990,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,3072,0:35.674.994,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 89 D4 B6 A8 6F 14 CD 3F 43 E3 6B 12 68 9B F9 3C… 0,,3076,0:35.675.990,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,3077,0:35.690.996,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E8 11 24 19 1A BA 1C 72 BB CB B9 93 20 3E 7B C8… 0,,3081,0:35.691.993,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,3082,0:35.705.998,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3086,0:35.706.995,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,3087,0:35.706.998,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E8 11 24 19 1A BA 1C 72 BB CB B9 93 20 3E 7B C8… 0,,3091,0:35.707.995,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,3092,0:35.723.000,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 F8 34 A3 4E E9 33 11 08 18 03 4D 0C 38 B1 6A… 0,,3096,0:35.723.997,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,3097,0:35.738.002,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3101,0:35.738.999,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,3102,0:35.739.002,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 F8 34 A3 4E E9 33 11 08 18 03 4D 0C 38 B1 6A… 0,,3106,0:35.739.999,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,3107,0:35.755.005,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A 8E D4 41 0D E0 23 44 05 AD 4E 5D 5B AB 37 63… 0,,3111,0:35.756.002,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,3112,0:35.770.007,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3116,0:35.771.004,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,3117,0:35.771.007,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A 8E D4 41 0D E0 23 44 05 AD 4E 5D 5B AB 37 63… 0,,3121,0:35.772.004,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,3122,0:35.787.009,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 CA 20 38 AA 23 3B 38 91 D2 0E FA 33 8C 7B 5A… 0,,3126,0:35.788.006,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,3127,0:35.802.011,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3131,0:35.803.008,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,3132,0:35.803.011,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 CA 20 38 AA 23 3B 38 91 D2 0E FA 33 8C 7B 5A… 0,,3136,0:35.804.008,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,3137,0:35.819.014,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 ED 62 CE D8 AC EE 00 B2 58 E8 35 89 71 36 41… 0,,3141,0:35.820.010,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,3142,0:35.834.016,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3146,0:35.835.013,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,3147,0:35.835.016,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 ED 62 CE D8 AC EE 00 B2 58 E8 35 89 71 36 41… 0,,3151,0:35.836.013,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,3152,0:35.851.018,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B3 E4 C5 74 8F 0F 96 56 70 27 A5 11 6A CA 6B 7B… 0,,3156,0:35.852.015,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,3157,0:35.866.020,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3161,0:35.867.017,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,3162,0:35.867.020,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B3 E4 C5 74 8F 0F 96 56 70 27 A5 11 6A CA 6B 7B… 0,,3166,0:35.868.017,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,3167,0:35.883.023,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 C9 F0 81 2C 79 0B A9 E6 AF 0A 88 78 AB 01 38… 0,,3171,0:35.884.019,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,3172,0:35.898.025,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3176,0:35.899.021,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,3177,0:35.899.025,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 C9 F0 81 2C 79 0B A9 E6 AF 0A 88 78 AB 01 38… 0,,3181,0:35.900.022,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,3182,0:35.915.027,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E C6 0C 60 B2 EB 94 DA 94 3B E9 4B 6C BC 63 0F… 0,,3186,0:35.916.024,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,3187,0:35.930.029,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3191,0:35.931.026,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,3192,0:35.931.029,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E C6 0C 60 B2 EB 94 DA 94 3B E9 4B 6C BC 63 0F… 0,,3196,0:35.932.026,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,3197,0:35.947.031,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 84 F8 D7 DF B8 C9 30 80 FF 1D B4 99 66 5F 0D 23… 0,,3201,0:35.948.028,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,3202,0:35.962.033,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3206,0:35.963.030,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,3207,0:35.963.034,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 84 F8 D7 DF B8 C9 30 80 FF 1D B4 99 66 5F 0D 23… 0,,3211,0:35.964.030,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,3212,0:35.979.036,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C B4 58 4B 1B 7D F8 DC 80 B9 F8 E8 5C 80 6A 97… 0,,3216,0:35.980.033,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,3217,0:35.994.038,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3221,0:35.995.035,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,3222,0:35.995.038,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C B4 58 4B 1B 7D F8 DC 80 B9 F8 E8 5C 80 6A 97… 0,,3226,0:35.996.035,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,3227,0:36.011.040,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 28 26 F2 51 9D 76 72 1D 9E 1F 9A BE 8B 9F E1 EA… 0,,3231,0:36.012.037,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,3232,0:36.026.042,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3236,0:36.027.039,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,3237,0:36.027.043,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 28 26 F2 51 9D 76 72 1D 9E 1F 9A BE 8B 9F E1 EA… 0,,3241,0:36.028.039,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,3242,0:36.043.045,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 19 98 6A D7 85 35 EE 8D 03 16 A0 DF 47 90 0F… 0,,3246,0:36.044.042,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,3247,0:36.058.047,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3251,0:36.059.044,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,3252,0:36.059.047,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 19 98 6A D7 85 35 EE 8D 03 16 A0 DF 47 90 0F… 0,,3256,0:36.060.044,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,3257,0:36.075.049,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D3 81 3C 6B 32 27 E5 94 39 98 10 5A 6F 28 EB 09… 0,,3261,0:36.076.046,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,3262,0:36.090.051,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3266,0:36.091.048,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,3267,0:36.091.051,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D3 81 3C 6B 32 27 E5 94 39 98 10 5A 6F 28 EB 09… 0,,3271,0:36.092.048,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,3272,0:36.107.054,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF 6A 22 A7 6F 0B 68 F7 8A 3E B3 4F DA C6 80 24… 0,,3276,0:36.108.050,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,3277,0:36.122.056,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3281,0:36.123.052,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,3282,0:36.123.056,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF 6A 22 A7 6F 0B 68 F7 8A 3E B3 4F DA C6 80 24… 0,,3286,0:36.124.053,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,3287,0:36.139.058,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B 81 A1 77 E9 C3 A0 41 32 44 2E DC 3A 32 DA 9A… 0,,3291,0:36.140.055,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,3292,0:36.154.060,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3296,0:36.155.057,16.005.041 ms,,,,,[17 SOF],[Frames: 1281 - 1297] 0,,3297,0:36.171.062,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 81 2D 84 83 A1 75 B6 B6 8F 0A D8 E8 3E F4 B4… 0,,3301,0:36.172.059,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,3302,0:36.186.064,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3306,0:36.187.061,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,3307,0:36.187.065,50.895 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 81 2D 84 83 A1 75 B6 B6 8F 0A D8 E8 3E F4 B4… 0,,3311,0:36.188.062,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,3312,0:36.203.067,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 C4 34 6F DB 27 0B C0 61 48 90 8E 27 2A 1A E7… 0,,3316,0:36.204.064,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,3317,0:36.218.069,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3321,0:36.219.066,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,3322,0:36.219.069,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 C4 34 6F DB 27 0B C0 61 48 90 8E 27 2A 1A E7… 0,,3326,0:36.220.066,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,3327,0:36.235.071,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3D 5E 13 85 CD 7A E7 51 2D A0 0E 17 EB 9C 83 00… 0,,3331,0:36.236.068,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,3332,0:36.250.073,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3336,0:36.251.070,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,3337,0:36.251.074,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3D 5E 13 85 CD 7A E7 51 2D A0 0E 17 EB 9C 83 00… 0,,3341,0:36.252.070,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,3342,0:36.267.076,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 79 4B E2 7F 7B F6 64 4F D4 8C 78 33 1B 63 E5… 0,,3346,0:36.268.073,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,3347,0:36.282.078,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3351,0:36.283.075,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,3352,0:36.283.078,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 79 4B E2 7F 7B F6 64 4F D4 8C 78 33 1B 63 E5… 0,,3356,0:36.284.075,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,3357,0:36.299.080,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE FB AB 46 B9 12 68 FD B6 7E 69 F2 58 7F 7D 5F… 0,,3361,0:36.300.077,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,3362,0:36.314.082,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3366,0:36.315.079,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,3367,0:36.315.082,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE FB AB 46 B9 12 68 FD B6 7E 69 F2 58 7F 7D 5F… 0,,3371,0:36.316.079,15.004.916 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,3372,0:36.331.085,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 63 8B 7A 94 B9 55 B8 B2 6D 92 69 2C 8E DD 12… 0,,3376,0:36.332.082,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,3377,0:36.346.087,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3381,0:36.347.084,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,3382,0:36.347.087,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 63 8B 7A 94 B9 55 B8 B2 6D 92 69 2C 8E DD 12… 0,,3386,0:36.348.084,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,3387,0:36.363.089,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 1E 56 F6 A7 EE C2 1E 95 E1 6B 70 9C 6E A8 15… 0,,3391,0:36.364.086,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,3392,0:36.378.091,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3396,0:36.379.088,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,3397,0:36.379.091,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A 1E 56 F6 A7 EE C2 1E 95 E1 6B 70 9C 6E A8 15… 0,,3401,0:36.380.088,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,3402,0:36.395.094,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 77 F1 F7 FD BB 77 D3 1F 6D 0B 71 99 6F 44 5F… 0,,3406,0:36.396.090,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,3407,0:36.410.096,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3411,0:36.411.092,2.833 us,,,,,[1 SOF],[Frame: 1537] 0,,3412,0:36.411.096,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 77 F1 F7 FD BB 77 D3 1F 6D 0B 71 99 6F 44 5F… 0,,3416,0:36.412.093,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,3417,0:36.427.098,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E 0A 27 0F 6A 8D 3D F8 6E 3A 44 A2 C2 73 2E 0D… 0,,3421,0:36.428.095,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,3422,0:36.442.100,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3426,0:36.443.097,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,3427,0:36.443.100,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E 0A 27 0F 6A 8D 3D F8 6E 3A 44 A2 C2 73 2E 0D… 0,,3431,0:36.444.097,15.004.916 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,3432,0:36.459.102,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB 08 57 77 E9 17 D4 0C 5E BB 02 11 F6 40 D4 E5… 0,,3436,0:36.460.099,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,3437,0:36.474.104,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3441,0:36.475.101,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,3442,0:36.475.105,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB 08 57 77 E9 17 D4 0C 5E BB 02 11 F6 40 D4 E5… 0,,3446,0:36.476.102,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,3447,0:36.491.107,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 40 E5 53 C2 00 5E 17 B3 41 D8 CE 58 07 30 47 86… 0,,3451,0:36.492.104,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,3452,0:36.506.109,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3456,0:36.507.106,2.833 us,,,,,[1 SOF],[Frame: 1633] 0,,3457,0:36.507.109,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 40 E5 53 C2 00 5E 17 B3 41 D8 CE 58 07 30 47 86… 0,,3461,0:36.508.106,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,3462,0:36.523.111,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 40 9D 5A 99 57 14 6F 32 BA F6 7E 37 2D D5 5A… 0,,3466,0:36.524.108,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,3467,0:36.538.113,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3471,0:36.539.110,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,3472,0:36.539.113,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 40 9D 5A 99 57 14 6F 32 BA F6 7E 37 2D D5 5A… 0,,3476,0:36.540.110,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,3477,0:36.555.116,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 A4 3D 01 D2 DF 2C 78 F8 84 A6 D9 90 C0 34 F1… 0,,3481,0:36.556.113,14.004.750 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,3482,0:36.570.118,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3486,0:36.571.115,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,3487,0:36.571.118,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 A4 3D 01 D2 DF 2C 78 F8 84 A6 D9 90 C0 34 F1… 0,,3491,0:36.572.115,15.004.916 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,3492,0:36.587.120,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 49 D2 9A 26 2D B2 FD 86 E0 38 E2 44 2E 06 78… 0,,3496,0:36.588.117,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,3497,0:36.602.122,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3501,0:36.603.119,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,3502,0:36.603.122,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 49 D2 9A 26 2D B2 FD 86 E0 38 E2 44 2E 06 78… 0,,3506,0:36.604.119,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,3507,0:36.619.125,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 35 DB 35 DA 85 44 34 2F 71 62 3C D9 01 E4 5C 2B… 0,,3511,0:36.620.121,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,3512,0:36.634.127,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3516,0:36.635.124,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,3517,0:36.635.127,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 35 DB 35 DA 85 44 34 2F 71 62 3C D9 01 E4 5C 2B… 0,,3521,0:36.636.124,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,3522,0:36.651.129,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 46 CE 1D 4D 73 C4 AA D8 95 44 95 E0 18 28 E4… 0,,3526,0:36.652.126,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,3527,0:36.666.131,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3531,0:36.667.128,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,3532,0:36.667.131,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 46 CE 1D 4D 73 C4 AA D8 95 44 95 E0 18 28 E4… 0,,3536,0:36.668.128,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,3537,0:36.683.133,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 88 32 FC 0F D6 6C 46 CE 19 6F 78 B5 ED 21 A9 83… 0,,3541,0:36.684.130,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,3542,0:36.698.136,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3546,0:36.699.132,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,3547,0:36.699.136,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 88 32 FC 0F D6 6C 46 CE 19 6F 78 B5 ED 21 A9 83… 0,,3551,0:36.700.133,15.004.916 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,3552,0:36.715.138,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A 5F DF F8 FD 99 DC C4 78 66 0F 33 89 4F AA F6… 0,,3556,0:36.716.135,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,3557,0:36.730.140,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3561,0:36.731.137,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,3562,0:36.731.140,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A 5F DF F8 FD 99 DC C4 78 66 0F 33 89 4F AA F6… 0,,3566,0:36.732.137,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,3567,0:36.747.142,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 CB 14 EF 50 12 A8 0C 6A BB 2F 30 8B 9C ED 90… 0,,3571,0:36.748.139,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,3572,0:36.762.144,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3576,0:36.763.141,16.005.041 ms,,,,,[17 SOF],[Frames: 1889 - 1905] 0,,3577,0:36.779.147,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 E6 F6 76 CF 6E D3 80 8C 43 6F 85 20 26 AF B7… 0,,3581,0:36.780.144,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,3582,0:36.794.149,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3586,0:36.795.146,2.833 us,,,,,[1 SOF],[Frame: 1921] 0,,3587,0:36.795.149,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C6 E6 F6 76 CF 6E D3 80 8C 43 6F 85 20 26 AF B7… 0,,3591,0:36.796.146,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,3592,0:36.811.151,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D 91 58 F8 5A F2 F0 8A 30 34 85 00 CD 59 01 E2… 0,,3596,0:36.812.148,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,3597,0:36.826.153,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3601,0:36.827.150,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,3602,0:36.827.153,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 91 58 F8 5A F2 F0 8A 30 34 85 00 CD 59 01 E2… 0,,3606,0:36.828.150,15.004.916 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,3607,0:36.843.156,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 8E D6 A5 95 63 EC 64 86 44 DF 7B 11 11 C5 DD… 0,,3611,0:36.844.153,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,3612,0:36.858.158,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3616,0:36.859.155,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,3617,0:36.859.158,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 26 8E D6 A5 95 63 EC 64 86 44 DF 7B 11 11 C5 DD… 0,,3621,0:36.860.155,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,3622,0:36.875.160,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 2A 3B 2F 93 C8 04 09 58 C2 C3 B2 EF 7E 93 3B… 0,,3626,0:36.876.157,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,3627,0:36.890.162,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3631,0:36.891.159,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,3632,0:36.891.162,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 2A 3B 2F 93 C8 04 09 58 C2 C3 B2 EF 7E 93 3B… 0,,3636,0:36.892.159,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,3637,0:36.907.165,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 E7 61 D7 09 D8 11 93 E3 53 FC F4 52 4B AB C0… 0,,3641,0:36.908.161,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,3642,0:36.922.167,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3646,0:36.923.164,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,3647,0:36.923.167,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 E7 61 D7 09 D8 11 93 E3 53 FC F4 52 4B AB C0… 0,,3651,0:36.924.164,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,3652,0:36.939.169,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D 59 45 3A 78 41 FE 3D F0 6B 61 C8 B3 77 1D 64… 0,,3656,0:36.940.166,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,3657,0:36.954.171,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3661,0:36.955.168,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,3662,0:36.955.171,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D 59 45 3A 78 41 FE 3D F0 6B 61 C8 B3 77 1D 64… 0,,3666,0:36.956.168,15.004.916 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,3667,0:36.971.173,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8B 62 B4 06 AF 8D 71 0F 03 00 C6 16 83 B2 FB 1D… 0,,3671,0:36.972.170,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,3672,0:36.986.176,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3676,0:36.987.172,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,3677,0:36.987.176,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8B 62 B4 06 AF 8D 71 0F 03 00 C6 16 83 B2 FB 1D… 0,,3681,0:36.988.173,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,3682,0:37.003.178,50.916 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 50 6E 9D FF 30 A3 C0 20 17 76 AB FF CF D2 46 E5… 0,,3686,0:37.004.175,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,3687,0:37.018.180,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3691,0:37.019.177,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,3692,0:37.019.180,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 50 6E 9D FF 30 A3 C0 20 17 76 AB FF CF D2 46 E5… 0,,3696,0:37.020.177,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,3697,0:37.035.182,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A2 A1 57 8C 42 65 B1 B5 15 5F 52 D1 41 FA 5C 19… 0,,3701,0:37.036.179,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,3702,0:37.050.184,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3706,0:37.051.181,2.833 us,,,,,[1 SOF],[Frame: 129] 0,,3707,0:37.051.185,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A2 A1 57 8C 42 65 B1 B5 15 5F 52 D1 41 FA 5C 19… 0,,3711,0:37.052.181,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,3712,0:37.067.187,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD D2 F9 31 20 27 F8 41 D5 D0 3F 7A F7 8E 22 06… 0,,3716,0:37.068.184,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,3717,0:37.082.189,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3721,0:37.083.186,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,3722,0:37.083.189,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD D2 F9 31 20 27 F8 41 D5 D0 3F 7A F7 8E 22 06… 0,,3726,0:37.084.186,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,3727,0:37.099.191,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 7B 53 48 41 4B 90 45 62 14 0C 6C 81 A7 BC 0B… 0,,3731,0:37.100.188,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,3732,0:37.114.193,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3736,0:37.115.190,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,3737,0:37.115.193,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 7B 53 48 41 4B 90 45 62 14 0C 6C 81 A7 BC 0B… 0,,3741,0:37.116.190,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,3742,0:37.131.196,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D D1 9C 75 D0 DE 85 C0 4B AD 9A 85 24 62 A9 0F… 0,,3746,0:37.132.193,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,3747,0:37.146.198,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3751,0:37.147.195,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,3752,0:37.147.198,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D D1 9C 75 D0 DE 85 C0 4B AD 9A 85 24 62 A9 0F… 0,,3756,0:37.148.195,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,3757,0:37.163.200,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 91 C7 A0 56 0D C4 D7 4F 42 7E 64 A9 0A E0 EA… 0,,3761,0:37.164.197,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,3762,0:37.178.202,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3766,0:37.179.199,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,3767,0:37.179.202,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 91 C7 A0 56 0D C4 D7 4F 42 7E 64 A9 0A E0 EA… 0,,3771,0:37.180.199,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,3772,0:37.195.205,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 43 08 37 D6 B8 AC EF 46 86 24 C0 8A D2 09 19 CC… 0,,3776,0:37.196.201,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,3777,0:37.210.207,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3781,0:37.211.204,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,3782,0:37.211.207,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 43 08 37 D6 B8 AC EF 46 86 24 C0 8A D2 09 19 CC… 0,,3786,0:37.212.204,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,3787,0:37.227.209,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF FB CA B4 0C CC 03 B1 B4 3F A5 98 B7 14 58 3A… 0,,3791,0:37.228.206,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,3792,0:37.242.211,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3796,0:37.243.208,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,3797,0:37.243.211,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF FB CA B4 0C CC 03 B1 B4 3F A5 98 B7 14 58 3A… 0,,3801,0:37.244.208,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,3802,0:37.259.213,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA C4 32 36 7F 78 CB 75 C9 E2 55 25 F5 79 18 4E… 0,,3806,0:37.260.210,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,3807,0:37.274.216,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3811,0:37.275.212,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,3812,0:37.275.216,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA C4 32 36 7F 78 CB 75 C9 E2 55 25 F5 79 18 4E… 0,,3816,0:37.276.213,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,3817,0:37.291.218,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EA DF 2E 6A 5B E4 DA 2D 8B 36 6D 19 98 CD 62 A9… 0,,3821,0:37.292.215,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,3822,0:37.306.220,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3826,0:37.307.217,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,3827,0:37.307.220,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EA DF 2E 6A 5B E4 DA 2D 8B 36 6D 19 98 CD 62 A9… 0,,3831,0:37.308.217,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,3832,0:37.323.222,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 22 1B 4D E7 E4 EA E1 29 1B C5 95 7D 21 C0 87… 0,,3836,0:37.324.219,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,3837,0:37.338.224,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3841,0:37.339.221,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,3842,0:37.339.225,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 22 1B 4D E7 E4 EA E1 29 1B C5 95 7D 21 C0 87… 0,,3846,0:37.340.221,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,3847,0:37.355.227,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 52 27 23 31 18 1F 24 1D B7 8C 59 3C 22 71 45 71… 0,,3851,0:37.356.224,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,3852,0:37.370.229,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3856,0:37.371.226,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,3857,0:37.371.229,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 52 27 23 31 18 1F 24 1D B7 8C 59 3C 22 71 45 71… 0,,3861,0:37.372.226,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,3862,0:37.387.231,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C9 79 F8 84 AE 61 CF 9E 6A 83 A2 2E 59 1E B8 2E… 0,,3866,0:37.388.228,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,3867,0:37.402.233,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3871,0:37.403.230,16.005.041 ms,,,,,[17 SOF],[Frames: 481 - 497] 0,,3872,0:37.419.236,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 13 31 27 BB 58 66 50 8E 1C A6 E4 98 D1 13 19… 0,,3876,0:37.420.233,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,3877,0:37.434.238,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3881,0:37.435.235,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,3882,0:37.435.238,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E3 13 31 27 BB 58 66 50 8E 1C A6 E4 98 D1 13 19… 0,,3886,0:37.436.235,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,3887,0:37.451.240,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 19 E9 4C 86 43 85 A3 9D 0C C7 F9 48 93 BA 48 92… 0,,3891,0:37.452.237,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,3892,0:37.466.242,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3896,0:37.467.239,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,3897,0:37.467.242,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 19 E9 4C 86 43 85 A3 9D 0C C7 F9 48 93 BA 48 92… 0,,3901,0:37.468.239,15.004.916 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,3902,0:37.483.245,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7F B5 61 C7 48 8F FA 39 50 45 02 57 03 19 D2 F4… 0,,3906,0:37.484.241,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,3907,0:37.498.247,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3911,0:37.499.244,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,3912,0:37.499.247,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7F B5 61 C7 48 8F FA 39 50 45 02 57 03 19 D2 F4… 0,,3916,0:37.500.244,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,3917,0:37.515.249,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 7E 09 BD 88 74 34 C1 F0 2C 51 39 F7 49 F2 FB… 0,,3921,0:37.516.246,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,3922,0:37.530.251,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3926,0:37.531.248,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,3927,0:37.531.251,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 7E 09 BD 88 74 34 C1 F0 2C 51 39 F7 49 F2 FB… 0,,3931,0:37.532.248,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,3932,0:37.547.253,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6B 2D 4E 2D 8A 39 A0 2D 33 53 3D 0A AD A8 AF 3A… 0,,3936,0:37.548.250,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,3937,0:37.562.256,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3941,0:37.563.252,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,3942,0:37.563.256,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6B 2D 4E 2D 8A 39 A0 2D 33 53 3D 0A AD A8 AF 3A… 0,,3946,0:37.564.253,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,3947,0:37.579.258,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D3 42 06 04 5B 76 9C 5E F4 C0 5B EE 2F 79 CD 3E… 0,,3951,0:37.580.255,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,3952,0:37.594.260,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3956,0:37.595.257,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,3957,0:37.595.260,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D3 42 06 04 5B 76 9C 5E F4 C0 5B EE 2F 79 CD 3E… 0,,3961,0:37.596.257,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,3962,0:37.611.262,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 1F B1 9F 3C 9E 1A 0B 2E A3 D1 A9 F3 7B 1B 61… 0,,3966,0:37.612.259,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,3967,0:37.626.264,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3971,0:37.627.261,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,3972,0:37.627.265,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 1F B1 9F 3C 9E 1A 0B 2E A3 D1 A9 F3 7B 1B 61… 0,,3976,0:37.628.261,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,3977,0:37.643.267,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 D6 D9 9C CA AC E2 5C 6A 23 3F EC 08 15 81 30… 0,,3981,0:37.644.264,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,3982,0:37.658.269,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,3986,0:37.659.266,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,3987,0:37.659.269,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 D6 D9 9C CA AC E2 5C 6A 23 3F EC 08 15 81 30… 0,,3991,0:37.660.266,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,3992,0:37.675.271,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 23 15 A3 1A 9A 5A 42 08 86 27 3F 50 9A 31 62… 0,,3996,0:37.676.268,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,3997,0:37.690.273,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4001,0:37.691.270,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,4002,0:37.691.273,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 23 15 A3 1A 9A 5A 42 08 86 27 3F 50 9A 31 62… 0,,4006,0:37.692.270,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,4007,0:37.707.276,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 7C FD 72 2A C1 77 78 98 77 83 16 09 EE 6B EA… 0,,4011,0:37.708.273,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,4012,0:37.722.278,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4016,0:37.723.275,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,4017,0:37.723.278,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 7C FD 72 2A C1 77 78 98 77 83 16 09 EE 6B EA… 0,,4021,0:37.724.275,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,4022,0:37.739.280,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC FB 15 7D FB 41 70 E8 DF 4F 87 49 CB E3 51 40… 0,,4026,0:37.740.277,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,4027,0:37.754.282,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4031,0:37.755.279,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,4032,0:37.755.282,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC FB 15 7D FB 41 70 E8 DF 4F 87 49 CB E3 51 40… 0,,4036,0:37.756.279,15.004.916 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,4037,0:37.771.285,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E 1F EF AD DA C5 52 9C AC 25 B1 F5 EA FC 99 8A… 0,,4041,0:37.772.281,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,4042,0:37.786.287,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4046,0:37.787.284,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,4047,0:37.787.287,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E 1F EF AD DA C5 52 9C AC 25 B1 F5 EA FC 99 8A… 0,,4051,0:37.788.284,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,4052,0:37.803.289,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A 58 DF 3F 73 9A 11 8B 84 34 EF C7 60 9C DD 59… 0,,4056,0:37.804.286,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,4057,0:37.818.291,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4061,0:37.819.288,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,4062,0:37.819.291,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A 58 DF 3F 73 9A 11 8B 84 34 EF C7 60 9C DD 59… 0,,4066,0:37.820.288,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,4067,0:37.835.293,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 29 3B 81 F5 AA E2 AA 0C 46 4F BE 3E AD 0F A0… 0,,4071,0:37.836.290,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,4072,0:37.850.296,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4076,0:37.851.292,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,4077,0:37.851.296,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A 29 3B 81 F5 AA E2 AA 0C 46 4F BE 3E AD 0F A0… 0,,4081,0:37.852.293,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,4082,0:37.867.298,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B7 CA BF A4 CA E9 E6 1F 42 8C D2 1B D9 1F 36 52… 0,,4086,0:37.868.295,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,4087,0:37.882.300,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4091,0:37.883.297,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,4092,0:37.883.300,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B7 CA BF A4 CA E9 E6 1F 42 8C D2 1B D9 1F 36 52… 0,,4096,0:37.884.297,15.004.916 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,4097,0:37.899.302,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 28 C3 04 39 5F 69 1F 30 59 FD 7E 11 BC 82 5B F6… 0,,4101,0:37.900.299,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,4102,0:37.914.304,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4106,0:37.915.301,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,4107,0:37.915.305,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 28 C3 04 39 5F 69 1F 30 59 FD 7E 11 BC 82 5B F6… 0,,4111,0:37.916.301,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,4112,0:37.931.307,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 70 09 E5 11 05 D0 B0 43 D2 FA D4 2D E1 32 3C 1F… 0,,4116,0:37.932.304,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,4117,0:37.946.309,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4121,0:37.947.306,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,4122,0:37.947.309,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 70 09 E5 11 05 D0 B0 43 D2 FA D4 2D E1 32 3C 1F… 0,,4126,0:37.948.306,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,4127,0:37.963.311,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1F C2 73 3B 1A 28 C6 17 89 57 10 FC D4 21 61 95… 0,,4131,0:37.964.308,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,4132,0:37.978.313,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4136,0:37.979.310,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,4137,0:37.979.313,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1F C2 73 3B 1A 28 C6 17 89 57 10 FC D4 21 61 95… 0,,4141,0:37.980.310,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,4142,0:37.995.316,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 63 0E C2 91 0F 43 E5 C8 C8 EF 79 4A E4 07 32… 0,,4146,0:37.996.313,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,4147,0:38.010.318,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4151,0:38.011.315,16.005.041 ms,,,,,[17 SOF],[Frames: 1089 - 1105] 0,,4152,0:38.027.320,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 2B 05 C1 9F 75 4B EA D2 9F 1B 7D 6E 0C E2 0B… 0,,4156,0:38.028.317,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,4157,0:38.042.322,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4161,0:38.043.319,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,4162,0:38.043.322,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 2B 05 C1 9F 75 4B EA D2 9F 1B 7D 6E 0C E2 0B… 0,,4166,0:38.044.319,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,4167,0:38.059.325,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 EF 7A 5D 6C A8 94 BB 17 F0 D7 51 71 C0 87 23… 0,,4171,0:38.060.321,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,4172,0:38.074.327,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4176,0:38.075.323,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,4177,0:38.075.327,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 EF 7A 5D 6C A8 94 BB 17 F0 D7 51 71 C0 87 23… 0,,4181,0:38.076.324,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,4182,0:38.091.329,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 54 9A 58 82 72 82 3E 83 DE 45 6A ED 75 ED FE… 0,,4186,0:38.092.326,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,4187,0:38.106.331,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4191,0:38.107.328,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,4192,0:38.107.331,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 54 9A 58 82 72 82 3E 83 DE 45 6A ED 75 ED FE… 0,,4196,0:38.108.328,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,4197,0:38.123.333,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 FE 81 18 9B 8D AD 7B 0A 83 66 76 EA 4C E2 C8… 0,,4201,0:38.124.330,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,4202,0:38.138.335,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4206,0:38.139.332,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,4207,0:38.139.336,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 FE 81 18 9B 8D AD 7B 0A 83 66 76 EA 4C E2 C8… 0,,4211,0:38.140.333,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,4212,0:38.155.338,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 26 52 ED 4C E2 AA 2C 53 60 95 4B DF 29 7B 42… 0,,4216,0:38.156.335,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,4217,0:38.170.340,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4221,0:38.171.337,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,4222,0:38.171.340,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 26 52 ED 4C E2 AA 2C 53 60 95 4B DF 29 7B 42… 0,,4226,0:38.172.337,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,4227,0:38.187.342,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 A5 61 4E 54 64 E2 9E D2 E0 16 8E 3E 25 39 E5… 0,,4231,0:38.188.339,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,4232,0:38.202.344,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4236,0:38.203.341,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,4237,0:38.203.345,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 A5 61 4E 54 64 E2 9E D2 E0 16 8E 3E 25 39 E5… 0,,4241,0:38.204.341,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,4242,0:38.219.347,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB BB B2 64 AF 9A 11 E1 77 39 FB A6 DB 2A 92 2D… 0,,4246,0:38.220.344,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,4247,0:38.234.349,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4251,0:38.235.346,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,4252,0:38.235.349,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB BB B2 64 AF 9A 11 E1 77 39 FB A6 DB 2A 92 2D… 0,,4256,0:38.236.346,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,4257,0:38.251.351,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A 85 2D B4 E2 7C 56 39 78 8B 61 01 BD A9 38 13… 0,,4261,0:38.252.348,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,4262,0:38.266.353,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4266,0:38.267.350,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,4267,0:38.267.353,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A 85 2D B4 E2 7C 56 39 78 8B 61 01 BD A9 38 13… 0,,4271,0:38.268.350,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,4272,0:38.283.356,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC E6 53 2B 86 71 1B 58 83 23 27 99 26 FE F0 7E… 0,,4276,0:38.284.353,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,4277,0:38.298.358,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4281,0:38.299.355,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,4282,0:38.299.358,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EC E6 53 2B 86 71 1B 58 83 23 27 99 26 FE F0 7E… 0,,4286,0:38.300.355,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,4287,0:38.315.360,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 DE 11 BF BC 77 07 C9 4D D1 BD 9B 70 C2 A7 41… 0,,4291,0:38.316.357,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,4292,0:38.330.362,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4296,0:38.331.359,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,4297,0:38.331.362,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 DE 11 BF BC 77 07 C9 4D D1 BD 9B 70 C2 A7 41… 0,,4301,0:38.332.359,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,4302,0:38.347.365,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B 59 0A 6F DF B1 7D AD 3E 63 B9 1E D7 82 9D F5… 0,,4306,0:38.348.361,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,4307,0:38.362.367,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4311,0:38.363.363,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,4312,0:38.363.367,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B 59 0A 6F DF B1 7D AD 3E 63 B9 1E D7 82 9D F5… 0,,4316,0:38.364.364,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,4317,0:38.379.369,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 11 E5 84 90 6C 33 1C D5 5D D3 BB F4 8A 34 98 BA… 0,,4321,0:38.380.366,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,4322,0:38.394.371,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4326,0:38.395.368,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,4327,0:38.395.371,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 11 E5 84 90 6C 33 1C D5 5D D3 BB F4 8A 34 98 BA… 0,,4331,0:38.396.368,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,4332,0:38.411.373,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AC A7 20 79 3F B0 45 CB AB FF 4E 5E E9 99 19 56… 0,,4336,0:38.412.370,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,4337,0:38.426.376,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4341,0:38.427.372,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,4342,0:38.427.376,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AC A7 20 79 3F B0 45 CB AB FF 4E 5E E9 99 19 56… 0,,4346,0:38.428.373,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,4347,0:38.443.378,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B ED 01 E9 AB 5A B3 55 AC FE 5A 16 A5 57 44 3A… 0,,4351,0:38.444.375,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,4352,0:38.458.380,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4356,0:38.459.377,2.833 us,,,,,[1 SOF],[Frame: 1537] 0,,4357,0:38.459.380,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B ED 01 E9 AB 5A B3 55 AC FE 5A 16 A5 57 44 3A… 0,,4361,0:38.460.377,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,4362,0:38.475.382,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 65 FA FC 9A C0 A5 26 C6 13 37 D0 28 3D 65 FB… 0,,4366,0:38.476.379,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,4367,0:38.490.384,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4371,0:38.491.381,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,4372,0:38.491.384,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 65 FA FC 9A C0 A5 26 C6 13 37 D0 28 3D 65 FB… 0,,4376,0:38.492.381,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,4377,0:38.507.387,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B D6 95 CE 0D 12 9D 55 69 1C CA 7B 1C A1 47 34… 0,,4381,0:38.508.384,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,4382,0:38.522.389,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4386,0:38.523.386,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,4387,0:38.523.389,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B D6 95 CE 0D 12 9D 55 69 1C CA 7B 1C A1 47 34… 0,,4391,0:38.524.386,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,4392,0:38.539.391,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F9 6A 6E DD 9E D7 C2 8B 9E 94 53 45 49 C9 4C 81… 0,,4396,0:38.540.388,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,4397,0:38.554.393,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4401,0:38.555.390,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,4402,0:38.555.393,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F9 6A 6E DD 9E D7 C2 8B 9E 94 53 45 49 C9 4C 81… 0,,4406,0:38.556.390,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,4407,0:38.571.396,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 84 D9 8F 4D C6 90 CD 03 03 52 C5 8B B9 D4 D6 37… 0,,4411,0:38.572.392,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,4412,0:38.586.398,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4416,0:38.587.395,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,4417,0:38.587.398,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 84 D9 8F 4D C6 90 CD 03 03 52 C5 8B B9 D4 D6 37… 0,,4421,0:38.588.395,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,4422,0:38.603.400,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 1E 4B 36 AF 33 29 D0 F3 D3 88 AE 45 E9 A2 C8… 0,,4426,0:38.604.397,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,4427,0:38.618.402,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4431,0:38.619.399,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,4432,0:38.619.402,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 1E 4B 36 AF 33 29 D0 F3 D3 88 AE 45 E9 A2 C8… 0,,4436,0:38.620.399,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,4437,0:38.635.404,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 DD AD 76 8C 17 66 EE 4B E0 88 41 4A EF 17 2C… 0,,4441,0:38.636.401,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,4442,0:38.650.407,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4446,0:38.651.403,16.005.041 ms,,,,,[17 SOF],[Frames: 1729 - 1745] 0,,4447,0:38.667.409,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 6C 8F 69 D2 A1 62 D6 DE 67 8F B0 61 D6 9F 50… 0,,4451,0:38.668.406,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,4452,0:38.682.411,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4456,0:38.683.408,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,4457,0:38.683.411,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 6C 8F 69 D2 A1 62 D6 DE 67 8F B0 61 D6 9F 50… 0,,4461,0:38.684.408,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,4462,0:38.699.413,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 5B DB 08 D8 F3 FD F3 22 08 A6 46 F5 B6 25 30… 0,,4466,0:38.700.410,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,4467,0:38.714.415,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4471,0:38.715.412,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,4472,0:38.715.416,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 5B DB 08 D8 F3 FD F3 22 08 A6 46 F5 B6 25 30… 0,,4476,0:38.716.412,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,4477,0:38.731.418,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 30 4D B9 A4 0E F8 C4 D9 07 45 97 08 7F 25 A1… 0,,4481,0:38.732.415,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,4482,0:38.746.420,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4486,0:38.747.417,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,4487,0:38.747.420,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 30 4D B9 A4 0E F8 C4 D9 07 45 97 08 7F 25 A1… 0,,4491,0:38.748.417,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,4492,0:38.763.422,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF 9B F6 F8 7C 2A C8 7B F5 56 A7 C4 85 5C CA 28… 0,,4496,0:38.764.419,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,4497,0:38.778.424,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4501,0:38.779.421,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,4502,0:38.779.424,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF 9B F6 F8 7C 2A C8 7B F5 56 A7 C4 85 5C CA 28… 0,,4506,0:38.780.421,15.004.916 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,4507,0:38.795.427,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 8B 2D 1A 6D 8A 68 11 AA EF 4C 04 25 1D D4 63… 0,,4511,0:38.796.424,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,4512,0:38.810.429,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4516,0:38.811.426,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,4517,0:38.811.429,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 8B 2D 1A 6D 8A 68 11 AA EF 4C 04 25 1D D4 63… 0,,4521,0:38.812.426,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,4522,0:38.827.431,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4F F8 DE D5 42 90 D5 9F 93 57 3D DE 44 9A 6C A2… 0,,4526,0:38.828.428,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,4527,0:38.842.433,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4531,0:38.843.430,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,4532,0:38.843.433,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4F F8 DE D5 42 90 D5 9F 93 57 3D DE 44 9A 6C A2… 0,,4536,0:38.844.430,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,4537,0:38.859.436,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 A8 76 AA 52 BC F5 A9 11 7A 36 C3 91 4B E3 60… 0,,4541,0:38.860.432,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,4542,0:38.874.438,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4546,0:38.875.435,2.833 us,,,,,[1 SOF],[Frame: 1953] 0,,4547,0:38.875.438,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 A8 76 AA 52 BC F5 A9 11 7A 36 C3 91 4B E3 60… 0,,4551,0:38.876.435,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,4552,0:38.891.440,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C0 D8 22 FB 12 46 EF E8 ED D3 09 A8 6A C1 DB 14… 0,,4556,0:38.892.437,14.004.750 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,4557,0:38.906.442,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4561,0:38.907.439,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,4562,0:38.907.442,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C0 D8 22 FB 12 46 EF E8 ED D3 09 A8 6A C1 DB 14… 0,,4566,0:38.908.439,15.005.000 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,4567,0:38.923.445,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB 47 70 20 FA 9C 0E CC 34 2A 7F A9 10 95 8C 4A… 0,,4571,0:38.924.441,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,4572,0:38.938.447,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4576,0:38.939.443,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,4577,0:38.939.447,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB 47 70 20 FA 9C 0E CC 34 2A 7F A9 10 95 8C 4A… 0,,4581,0:38.940.444,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,4582,0:38.955.449,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 33 2E 9B A9 5E 95 A4 E0 02 35 FA 0F 1F B1 DB 44… 0,,4586,0:38.956.446,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,4587,0:38.970.451,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4591,0:38.971.448,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,4592,0:38.971.451,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 33 2E 9B A9 5E 95 A4 E0 02 35 FA 0F 1F B1 DB 44… 0,,4596,0:38.972.448,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,4597,0:38.987.453,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 78 D0 82 EB 98 B3 E5 AA 4D 46 B8 27 A0 12 9C 1A… 0,,4601,0:38.988.450,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,4602,0:39.002.455,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4606,0:39.003.452,2.833 us,,,,,[1 SOF],[Frame: 33] 0,,4607,0:39.003.456,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 78 D0 82 EB 98 B3 E5 AA 4D 46 B8 27 A0 12 9C 1A… 0,,4611,0:39.004.452,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,4612,0:39.019.458,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 CE EA 7F 9F A2 53 F7 3C EE 03 E0 94 07 50 E4… 0,,4616,0:39.020.455,14.004.750 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,4617,0:39.034.460,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4621,0:39.035.457,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,4622,0:39.035.460,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 CE EA 7F 9F A2 53 F7 3C EE 03 E0 94 07 50 E4… 0,,4626,0:39.036.457,15.004.916 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,4627,0:39.051.462,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 1E A4 CA 4F 39 CB D9 53 C6 C3 D6 5A 89 FB 1E… 0,,4631,0:39.052.459,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,4632,0:39.066.464,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4636,0:39.067.461,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,4637,0:39.067.464,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 1E A4 CA 4F 39 CB D9 53 C6 C3 D6 5A 89 FB 1E… 0,,4641,0:39.068.461,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,4642,0:39.083.467,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 78 15 CC 2D 94 6A CF 88 A8 18 D4 A9 8F 64 31… 0,,4646,0:39.084.464,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,4647,0:39.098.469,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4651,0:39.099.466,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,4652,0:39.099.469,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 78 15 CC 2D 94 6A CF 88 A8 18 D4 A9 8F 64 31… 0,,4656,0:39.100.466,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,4657,0:39.115.471,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 78 DB 39 3E 15 D2 31 50 A3 77 B6 19 45 78 49… 0,,4661,0:39.116.468,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,4662,0:39.130.473,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4666,0:39.131.470,2.833 us,,,,,[1 SOF],[Frame: 161] 0,,4667,0:39.131.473,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 78 DB 39 3E 15 D2 31 50 A3 77 B6 19 45 78 49… 0,,4671,0:39.132.470,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,4672,0:39.147.476,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BB 16 0F 5D 2F D3 55 7F 2C F2 A9 A5 D7 08 54 5B… 0,,4676,0:39.148.472,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,4677,0:39.162.478,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4681,0:39.163.475,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,4682,0:39.163.478,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BB 16 0F 5D 2F D3 55 7F 2C F2 A9 A5 D7 08 54 5B… 0,,4686,0:39.164.475,15.004.916 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,4687,0:39.179.480,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 1D 76 30 65 4F 27 24 54 E6 DE 06 1A 96 11 31… 0,,4691,0:39.180.477,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,4692,0:39.194.482,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4696,0:39.195.479,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,4697,0:39.195.482,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 1D 76 30 65 4F 27 24 54 E6 DE 06 1A 96 11 31… 0,,4701,0:39.196.479,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,4702,0:39.211.484,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 94 0C A6 3E 6C 23 C2 C6 25 9D B2 4A A5 C6 1B… 0,,4706,0:39.212.481,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,4707,0:39.226.487,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4711,0:39.227.483,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,4712,0:39.227.487,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 94 0C A6 3E 6C 23 C2 C6 25 9D B2 4A A5 C6 1B… 0,,4716,0:39.228.484,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,4717,0:39.243.489,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 83 AF 13 B8 51 9E FC 9A 11 DC 96 A6 50 35 96 C4… 0,,4721,0:39.244.486,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,4722,0:39.258.491,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4726,0:39.259.488,16.005.041 ms,,,,,[17 SOF],[Frames: 289 - 305] 0,,4727,0:39.275.493,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 30 FE CF 3D 6E 4D 60 CE F0 88 9B 15 71 39 A9 57… 0,,4731,0:39.276.490,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,4732,0:39.290.495,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4736,0:39.291.492,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,4737,0:39.291.496,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 30 FE CF 3D 6E 4D 60 CE F0 88 9B 15 71 39 A9 57… 0,,4741,0:39.292.492,15.004.916 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,4742,0:39.307.498,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 28 7A 45 1B E6 F2 9E 28 C0 A9 74 77 16 ED D0… 0,,4746,0:39.308.495,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,4747,0:39.322.500,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4751,0:39.323.497,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,4752,0:39.323.500,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 28 7A 45 1B E6 F2 9E 28 C0 A9 74 77 16 ED D0… 0,,4756,0:39.324.497,15.004.916 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,4757,0:39.339.502,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 C8 4B E4 EB 5E DF 2C D0 71 C8 19 A2 C5 BF B2… 0,,4761,0:39.340.499,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,4762,0:39.354.504,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4766,0:39.355.501,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,4767,0:39.355.504,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 C8 4B E4 EB 5E DF 2C D0 71 C8 19 A2 C5 BF B2… 0,,4771,0:39.356.501,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,4772,0:39.371.507,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 59 4D 99 33 AF A2 8C BF 01 A1 7B EA 72 C9 12… 0,,4776,0:39.372.504,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,4777,0:39.386.509,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4781,0:39.387.506,2.833 us,,,,,[1 SOF],[Frame: 417] 0,,4782,0:39.387.509,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 59 4D 99 33 AF A2 8C BF 01 A1 7B EA 72 C9 12… 0,,4786,0:39.388.506,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,4787,0:39.403.511,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A E8 D7 1A 5E 9B B7 7C 35 AD 47 AE 40 EB 9A 6A… 0,,4791,0:39.404.508,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,4792,0:39.418.513,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4796,0:39.419.510,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,4797,0:39.419.513,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A E8 D7 1A 5E 9B B7 7C 35 AD 47 AE 40 EB 9A 6A… 0,,4801,0:39.420.510,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,4802,0:39.435.516,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 53 B0 3F D7 7B B9 AA FC A3 89 7B 53 6E 93 DD 50… 0,,4806,0:39.436.512,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,4807,0:39.450.518,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4811,0:39.451.515,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,4812,0:39.451.518,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 53 B0 3F D7 7B B9 AA FC A3 89 7B 53 6E 93 DD 50… 0,,4816,0:39.452.515,15.004.916 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,4817,0:39.467.520,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE 43 5D D2 96 F1 25 AF D3 2F F8 AC A9 66 50 55… 0,,4821,0:39.468.517,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,4822,0:39.482.522,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4826,0:39.483.519,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,4827,0:39.483.522,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE 43 5D D2 96 F1 25 AF D3 2F F8 AC A9 66 50 55… 0,,4831,0:39.484.519,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,4832,0:39.499.524,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF E3 03 24 8A E8 1B 45 42 4D B7 C5 DA 83 26 7F… 0,,4836,0:39.500.521,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,4837,0:39.514.527,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4841,0:39.515.523,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,4842,0:39.515.527,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF E3 03 24 8A E8 1B 45 42 4D B7 C5 DA 83 26 7F… 0,,4846,0:39.516.524,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,4847,0:39.531.529,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 70 36 4D 35 6F 4A 5C 52 1D 4B B3 1B E5 03 AF 80… 0,,4851,0:39.532.526,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,4852,0:39.546.531,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4856,0:39.547.528,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,4857,0:39.547.531,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 70 36 4D 35 6F 4A 5C 52 1D 4B B3 1B E5 03 AF 80… 0,,4861,0:39.548.528,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,4862,0:39.563.533,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B0 70 03 C7 22 B8 F6 63 AD D3 68 46 09 49 7B 29… 0,,4866,0:39.564.530,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,4867,0:39.578.535,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4871,0:39.579.532,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,4872,0:39.579.536,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B0 70 03 C7 22 B8 F6 63 AD D3 68 46 09 49 7B 29… 0,,4876,0:39.580.532,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,4877,0:39.595.538,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 39 D5 36 6F 66 F6 68 57 FC 9C 98 50 79 B9 54 FF… 0,,4881,0:39.596.535,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,4882,0:39.610.540,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4886,0:39.611.537,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,4887,0:39.611.540,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 39 D5 36 6F 66 F6 68 57 FC 9C 98 50 79 B9 54 FF… 0,,4891,0:39.612.537,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,4892,0:39.627.542,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF 8A 9B 49 C1 67 D3 E4 B1 28 3B 6B 8A 76 44 97… 0,,4896,0:39.628.539,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,4897,0:39.642.544,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4901,0:39.643.541,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,4902,0:39.643.544,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF 8A 9B 49 C1 67 D3 E4 B1 28 3B 6B 8A 76 44 97… 0,,4906,0:39.644.541,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,4907,0:39.659.547,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F8 68 8D F9 35 C0 13 3B 96 3A AD 0B F4 0E 1B A5… 0,,4911,0:39.660.544,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,4912,0:39.674.549,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4916,0:39.675.546,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,4917,0:39.675.549,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F8 68 8D F9 35 C0 13 3B 96 3A AD 0B F4 0E 1B A5… 0,,4921,0:39.676.546,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,4922,0:39.691.551,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F 8E 8C 8E 3A 4E E4 25 AF E7 D2 11 6E 3F C0 87… 0,,4926,0:39.692.548,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,4927,0:39.706.553,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4931,0:39.707.550,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,4932,0:39.707.553,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F 8E 8C 8E 3A 4E E4 25 AF E7 D2 11 6E 3F C0 87… 0,,4936,0:39.708.550,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,4937,0:39.723.556,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6E 98 1F 27 B8 FA 7C 6F 69 83 74 0F 2E E2 37 78… 0,,4941,0:39.724.552,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,4942,0:39.738.558,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4946,0:39.739.555,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,4947,0:39.739.558,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6E 98 1F 27 B8 FA 7C 6F 69 83 74 0F 2E E2 37 78… 0,,4951,0:39.740.555,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,4952,0:39.755.560,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 70 8D 35 90 2E AE C1 B9 45 63 C8 AF D1 28 8D A0… 0,,4956,0:39.756.557,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,4957,0:39.770.562,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4961,0:39.771.559,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,4962,0:39.771.562,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 70 8D 35 90 2E AE C1 B9 45 63 C8 AF D1 28 8D A0… 0,,4966,0:39.772.559,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,4967,0:39.787.564,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E 7E 19 16 D6 66 E7 43 0F 35 EB D4 A7 0D D7 07… 0,,4971,0:39.788.561,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,4972,0:39.802.567,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4976,0:39.803.563,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,4977,0:39.803.567,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E 7E 19 16 D6 66 E7 43 0F 35 EB D4 A7 0D D7 07… 0,,4981,0:39.804.564,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,4982,0:39.819.569,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 40 9A 7D BD 1E DB 21 F1 58 A9 0D 36 9E 5E 9A… 0,,4986,0:39.820.566,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,4987,0:39.834.571,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,4991,0:39.835.568,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,4992,0:39.835.571,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 40 9A 7D BD 1E DB 21 F1 58 A9 0D 36 9E 5E 9A… 0,,4996,0:39.836.568,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,4997,0:39.851.573,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 E4 8B 27 38 43 7C 9E C8 E5 E5 4E 3A DF 98 C6… 0,,5001,0:39.852.570,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,5002,0:39.866.575,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5006,0:39.867.572,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,5007,0:39.867.576,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 E4 8B 27 38 43 7C 9E C8 E5 E5 4E 3A DF 98 C6… 0,,5011,0:39.868.572,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,5012,0:39.883.578,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 77 B6 E8 24 4F BE 68 58 C9 86 FA 40 70 30 01… 0,,5016,0:39.884.575,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,5017,0:39.898.580,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5021,0:39.899.577,16.005.041 ms,,,,,[17 SOF],[Frames: 929 - 945] 0,,5022,0:39.915.582,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 13 F5 E7 6A FC C1 88 24 94 49 44 E2 96 40 01… 0,,5026,0:39.916.579,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,5027,0:39.930.584,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5031,0:39.931.581,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,5032,0:39.931.584,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 13 F5 E7 6A FC C1 88 24 94 49 44 E2 96 40 01… 0,,5036,0:39.932.581,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,5037,0:39.947.587,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC BD 70 AB 5F 56 8B 70 DC AF AD CC 43 8D 6A 10… 0,,5041,0:39.948.584,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,5042,0:39.962.589,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5046,0:39.963.586,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,5047,0:39.963.589,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC BD 70 AB 5F 56 8B 70 DC AF AD CC 43 8D 6A 10… 0,,5051,0:39.964.586,15.005.000 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,5052,0:39.979.591,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 29 E1 3C 14 9D 2F 6D AE 60 B7 AA 26 75 7F 84… 0,,5056,0:39.980.588,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,5057,0:39.994.593,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5061,0:39.995.590,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,5062,0:39.995.593,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 29 E1 3C 14 9D 2F 6D AE 60 B7 AA 26 75 7F 84… 0,,5066,0:39.996.590,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,5067,0:40.011.596,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 7F E7 E6 E8 9D F9 05 09 66 C7 6C 11 E8 9A 54… 0,,5071,0:40.012.592,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,5072,0:40.026.598,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5076,0:40.027.594,2.833 us,,,,,[1 SOF],[Frame: 1057] 0,,5077,0:40.027.598,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 7F E7 E6 E8 9D F9 05 09 66 C7 6C 11 E8 9A 54… 0,,5081,0:40.028.595,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,5082,0:40.043.600,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 09 26 42 2F 9C C9 0F E8 D7 03 CD EC 8B 8B 6E E5… 0,,5086,0:40.044.597,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,5087,0:40.058.602,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5091,0:40.059.599,2.833 us,,,,,[1 SOF],[Frame: 1089] 0,,5092,0:40.059.602,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 09 26 42 2F 9C C9 0F E8 D7 03 CD EC 8B 8B 6E E5… 0,,5096,0:40.060.599,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,5097,0:40.075.604,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 0B 6E C2 D2 01 EE 88 E7 21 B3 2A CB AB 1E 41… 0,,5101,0:40.076.601,14.004.750 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,5102,0:40.090.606,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5106,0:40.091.603,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,5107,0:40.091.607,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 0B 6E C2 D2 01 EE 88 E7 21 B3 2A CB AB 1E 41… 0,,5111,0:40.092.604,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,5112,0:40.107.609,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A 2D 5A 07 96 00 75 EA DA 3A 7A 8E 88 74 FB CD… 0,,5116,0:40.108.606,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,5117,0:40.122.611,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5121,0:40.123.608,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,5122,0:40.123.611,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A 2D 5A 07 96 00 75 EA DA 3A 7A 8E 88 74 FB CD… 0,,5126,0:40.124.608,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,5127,0:40.139.613,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 EC 1C 1E CA 9C D9 E7 AC 82 AA FF 44 1F ED 32… 0,,5131,0:40.140.610,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,5132,0:40.154.615,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5136,0:40.155.612,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,5137,0:40.155.616,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 EC 1C 1E CA 9C D9 E7 AC 82 AA FF 44 1F ED 32… 0,,5141,0:40.156.612,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,5142,0:40.171.618,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD 61 08 79 AB 53 20 52 90 53 30 3B 64 A2 AB 87… 0,,5146,0:40.172.615,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,5147,0:40.186.620,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5151,0:40.187.617,2.833 us,,,,,[1 SOF],[Frame: 1217] 0,,5152,0:40.187.620,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD 61 08 79 AB 53 20 52 90 53 30 3B 64 A2 AB 87… 0,,5156,0:40.188.617,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,5157,0:40.203.622,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF FF 04 2C 9E C5 09 A0 A4 D6 DA 2C E8 00 B8 7F… 0,,5161,0:40.204.619,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,5162,0:40.218.624,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5166,0:40.219.621,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,5167,0:40.219.624,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF FF 04 2C 9E C5 09 A0 A4 D6 DA 2C E8 00 B8 7F… 0,,5171,0:40.220.621,15.004.916 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,5172,0:40.235.627,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 76 1E 23 A0 8C 27 6F 92 EF 46 85 24 B3 5D D9… 0,,5176,0:40.236.624,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,5177,0:40.250.629,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5181,0:40.251.626,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,5182,0:40.251.629,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 76 1E 23 A0 8C 27 6F 92 EF 46 85 24 B3 5D D9… 0,,5186,0:40.252.626,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,5187,0:40.267.631,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 46 B2 22 0E 4E 74 E7 34 DE EF A2 3C 9D F4 21… 0,,5191,0:40.268.628,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,5192,0:40.282.633,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5196,0:40.283.630,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,5197,0:40.283.633,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 46 B2 22 0E 4E 74 E7 34 DE EF A2 3C 9D F4 21… 0,,5201,0:40.284.630,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,5202,0:40.299.636,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D4 73 34 48 8C 7A FB 3F 77 3B 35 94 4D 62 6F 4F… 0,,5206,0:40.300.632,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,5207,0:40.314.638,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5211,0:40.315.634,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,5212,0:40.315.638,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D4 73 34 48 8C 7A FB 3F 77 3B 35 94 4D 62 6F 4F… 0,,5216,0:40.316.635,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,5217,0:40.331.640,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C C7 C9 93 A2 06 8C 07 22 13 44 C0 DE 59 16 F5… 0,,5221,0:40.332.637,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,5222,0:40.346.642,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5226,0:40.347.639,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,5227,0:40.347.642,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C C7 C9 93 A2 06 8C 07 22 13 44 C0 DE 59 16 F5… 0,,5231,0:40.348.639,15.004.916 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,5232,0:40.363.644,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 5B BC 0E 87 29 19 7A 52 03 B3 BF 85 30 91 B1… 0,,5236,0:40.364.641,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,5237,0:40.378.646,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5241,0:40.379.643,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,5242,0:40.379.647,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 5B BC 0E 87 29 19 7A 52 03 B3 BF 85 30 91 B1… 0,,5246,0:40.380.644,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,5247,0:40.395.649,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E9 FD 3A 89 B6 92 25 E0 FC 06 F6 50 DE D5 46 CE… 0,,5251,0:40.396.646,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,5252,0:40.410.651,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5256,0:40.411.648,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,5257,0:40.411.651,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E9 FD 3A 89 B6 92 25 E0 FC 06 F6 50 DE D5 46 CE… 0,,5261,0:40.412.648,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,5262,0:40.427.653,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E F9 0E 83 46 03 1A 86 E5 D4 74 2B D8 19 B0 F2… 0,,5266,0:40.428.650,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,5267,0:40.442.655,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5271,0:40.443.652,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,5272,0:40.443.655,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E F9 0E 83 46 03 1A 86 E5 D4 74 2B D8 19 B0 F2… 0,,5276,0:40.444.652,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,5277,0:40.459.658,50.916 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F A1 D4 D6 A4 93 9F 7A 4B F2 FE 57 86 0B B6 19… 0,,5281,0:40.460.655,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,5282,0:40.474.660,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5286,0:40.475.657,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,5287,0:40.475.660,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F A1 D4 D6 A4 93 9F 7A 4B F2 FE 57 86 0B B6 19… 0,,5291,0:40.476.657,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,5292,0:40.491.662,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 E7 CD 40 70 16 D3 97 8D B6 9E F8 F7 32 26 78… 0,,5296,0:40.492.659,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,5297,0:40.506.664,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5301,0:40.507.661,16.005.125 ms,,,,,[17 SOF],[Frames: 1537 - 1553] 0,,5302,0:40.523.667,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 D4 31 1A E6 5A 78 D3 E1 EE 69 92 53 2A 58 93… 0,,5306,0:40.524.663,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,5307,0:40.538.669,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5311,0:40.539.666,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,5312,0:40.539.669,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 D4 31 1A E6 5A 78 D3 E1 EE 69 92 53 2A 58 93… 0,,5316,0:40.540.666,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,5317,0:40.555.671,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D1 3F 29 CF FE 48 4B B5 BE E0 BA 9D B3 DA 72 54… 0,,5321,0:40.556.668,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,5322,0:40.570.673,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5326,0:40.571.670,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,5327,0:40.571.673,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D1 3F 29 CF FE 48 4B B5 BE E0 BA 9D B3 DA 72 54… 0,,5331,0:40.572.670,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,5332,0:40.587.675,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1A F1 7F 68 52 EB 7C 44 57 47 36 36 05 1A D8 29… 0,,5336,0:40.588.672,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,5337,0:40.602.678,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5341,0:40.603.674,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,5342,0:40.603.678,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1A F1 7F 68 52 EB 7C 44 57 47 36 36 05 1A D8 29… 0,,5346,0:40.604.675,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,5347,0:40.619.680,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 49 98 44 70 0C 4F BD FB 20 50 29 BD A0 6C BA C6… 0,,5351,0:40.620.677,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,5352,0:40.634.682,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5356,0:40.635.679,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,5357,0:40.635.682,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 49 98 44 70 0C 4F BD FB 20 50 29 BD A0 6C BA C6… 0,,5361,0:40.636.679,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,5362,0:40.651.684,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 DC BF E8 8A B9 39 AA 6D 7F 48 56 8B F1 5E AF… 0,,5366,0:40.652.681,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,5367,0:40.666.686,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5371,0:40.667.683,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,5372,0:40.667.687,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 DC BF E8 8A B9 39 AA 6D 7F 48 56 8B F1 5E AF… 0,,5376,0:40.668.683,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,5377,0:40.683.689,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3D A8 43 96 82 18 70 4D 5A AA 2B 21 0D 56 D9 01… 0,,5381,0:40.684.686,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,5382,0:40.698.691,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5386,0:40.699.688,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,5387,0:40.699.691,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3D A8 43 96 82 18 70 4D 5A AA 2B 21 0D 56 D9 01… 0,,5391,0:40.700.688,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,5392,0:40.715.693,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 C7 E3 B6 B1 DF 6B E4 0A 21 08 F4 27 57 B5 7C… 0,,5396,0:40.716.690,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,5397,0:40.730.695,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5401,0:40.731.692,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,5402,0:40.731.696,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 C7 E3 B6 B1 DF 6B E4 0A 21 08 F4 27 57 B5 7C… 0,,5406,0:40.732.692,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,5407,0:40.747.698,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A 74 AC 2D C6 A2 FA 4B D9 19 A5 00 DE 64 37 27… 0,,5411,0:40.748.695,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,5412,0:40.762.700,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5416,0:40.763.697,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,5417,0:40.763.700,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A 74 AC 2D C6 A2 FA 4B D9 19 A5 00 DE 64 37 27… 0,,5421,0:40.764.697,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,5422,0:40.779.702,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 16 7D 4A 28 61 09 8C 39 EF 94 34 E8 0E A7 94… 0,,5426,0:40.780.699,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,5427,0:40.794.704,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5431,0:40.795.701,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,5432,0:40.795.704,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 16 7D 4A 28 61 09 8C 39 EF 94 34 E8 0E A7 94… 0,,5436,0:40.796.701,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,5437,0:40.811.707,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3C 03 3E CD E3 2C AD 47 B0 1D D3 53 B2 E4 16 A1… 0,,5441,0:40.812.703,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,5442,0:40.826.709,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5446,0:40.827.706,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,5447,0:40.827.709,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3C 03 3E CD E3 2C AD 47 B0 1D D3 53 B2 E4 16 A1… 0,,5451,0:40.828.706,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,5452,0:40.843.711,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 17 38 82 03 0D 8C 06 FC AF 3E 10 39 0E 4D 01… 0,,5456,0:40.844.708,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,5457,0:40.858.713,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5461,0:40.859.710,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,5462,0:40.859.713,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 17 38 82 03 0D 8C 06 FC AF 3E 10 39 0E 4D 01… 0,,5466,0:40.860.710,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,5467,0:40.875.715,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 69 0F 13 54 CC 46 D7 6E C9 32 AA 25 A5 56 2C 3C… 0,,5471,0:40.876.712,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,5472,0:40.890.718,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5476,0:40.891.714,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,5477,0:40.891.718,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 69 0F 13 54 CC 46 D7 6E C9 32 AA 25 A5 56 2C 3C… 0,,5481,0:40.892.715,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,5482,0:40.907.720,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 9B 99 FF E5 FA E8 FC E1 CA C8 42 EA 69 2E 9E… 0,,5486,0:40.908.717,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,5487,0:40.922.722,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5491,0:40.923.719,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,5492,0:40.923.722,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC 9B 99 FF E5 FA E8 FC E1 CA C8 42 EA 69 2E 9E… 0,,5496,0:40.924.719,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,5497,0:40.939.724,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A 12 C7 B7 09 B9 1E 6D 37 E8 5F 87 18 56 54 61… 0,,5501,0:40.940.721,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,5502,0:40.954.726,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5506,0:40.955.723,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,5507,0:40.955.727,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A 12 C7 B7 09 B9 1E 6D 37 E8 5F 87 18 56 54 61… 0,,5511,0:40.956.723,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,5512,0:40.971.729,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 12 2E 5A 0F 5F EA 8D 2D 90 EC 65 12 2B 7C B6… 0,,5516,0:40.972.726,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,5517,0:40.986.731,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5521,0:40.987.728,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,5522,0:40.987.731,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 12 2E 5A 0F 5F EA 8D 2D 90 EC 65 12 2B 7C B6… 0,,5526,0:40.988.728,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,5527,0:41.003.733,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F4 4E 98 A2 2C 4C 43 34 0B 4E EF E8 C2 85 8A 06… 0,,5531,0:41.004.730,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,5532,0:41.018.735,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5536,0:41.019.732,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,5537,0:41.019.735,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F4 4E 98 A2 2C 4C 43 34 0B 4E EF E8 C2 85 8A 06… 0,,5541,0:41.020.732,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,5542,0:41.035.738,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D8 9F 33 EE 23 FA BD 25 A7 21 0F EB 47 CC 29 8C… 0,,5546,0:41.036.735,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,5547,0:41.050.740,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5551,0:41.051.737,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,5552,0:41.051.740,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D8 9F 33 EE 23 FA BD 25 A7 21 0F EB 47 CC 29 8C… 0,,5556,0:41.052.737,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,5557,0:41.067.742,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 F8 A8 C7 98 F5 01 4C EC 5A 11 F0 FB 0D 3D 6A… 0,,5561,0:41.068.739,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,5562,0:41.082.744,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5566,0:41.083.741,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,5567,0:41.083.744,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 F8 A8 C7 98 F5 01 4C EC 5A 11 F0 FB 0D 3D 6A… 0,,5571,0:41.084.741,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,5572,0:41.099.747,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D 7F B2 25 D3 57 0F 97 76 B0 B4 86 CC 73 04 7F… 0,,5576,0:41.100.743,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,5577,0:41.114.749,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5581,0:41.115.746,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,5582,0:41.115.749,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 7F B2 25 D3 57 0F 97 76 B0 B4 86 CC 73 04 7F… 0,,5586,0:41.116.746,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,5587,0:41.131.751,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4B 2B FE 5F C7 06 79 EC F6 DB DD 6B 3D 86 B3 52… 0,,5591,0:41.132.748,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,5592,0:41.146.753,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5596,0:41.147.750,16.005.041 ms,,,,,[17 SOF],[Frames: 129 - 145] 0,,5597,0:41.163.755,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4B 2B FE 5F C7 06 79 EC F6 DB DD 6B 3D 86 B3 52… 0,,5601,0:41.164.752,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,5602,0:41.178.758,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5606,0:41.179.754,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,5607,0:41.179.758,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4B 2B FE 5F C7 06 79 EC F6 DB DD 6B 3D 86 B3 52… 0,,5611,0:41.180.755,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,5612,0:41.195.760,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 5A 18 7B 79 D3 2C CA 33 B5 A7 40 85 1A A0 43… 0,,5616,0:41.196.757,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,5617,0:41.210.762,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5621,0:41.211.759,2.833 us,,,,,[1 SOF],[Frame: 193] 0,,5622,0:41.211.762,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 5A 18 7B 79 D3 2C CA 33 B5 A7 40 85 1A A0 43… 0,,5626,0:41.212.759,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,5627,0:41.227.764,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 03 F9 9D 33 1E 22 70 D6 CD FB 29 92 92 20 96 6A… 0,,5631,0:41.228.761,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,5632,0:41.242.766,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5636,0:41.243.763,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,5637,0:41.243.767,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 03 F9 9D 33 1E 22 70 D6 CD FB 29 92 92 20 96 6A… 0,,5641,0:41.244.763,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,5642,0:41.259.769,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 53 EA 8F AE B0 1D 88 C5 8A 6C 7E 8B 02 A7 4B A3… 0,,5646,0:41.260.766,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,5647,0:41.274.771,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5651,0:41.275.768,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,5652,0:41.275.771,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 53 EA 8F AE B0 1D 88 C5 8A 6C 7E 8B 02 A7 4B A3… 0,,5656,0:41.276.768,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,5657,0:41.291.773,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 07 EC 7B C5 C9 EC 70 56 E7 3C 61 C6 F1 FD 75… 0,,5661,0:41.292.770,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,5662,0:41.306.775,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5666,0:41.307.772,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,5667,0:41.307.775,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 07 EC 7B C5 C9 EC 70 56 E7 3C 61 C6 F1 FD 75… 0,,5671,0:41.308.772,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,5672,0:41.323.778,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 4F E9 7D BA 92 E7 7D C8 AE F9 32 2E A9 E1 44… 0,,5676,0:41.324.775,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,5677,0:41.338.780,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5681,0:41.339.777,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,5682,0:41.339.780,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 4F E9 7D BA 92 E7 7D C8 AE F9 32 2E A9 E1 44… 0,,5686,0:41.340.777,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,5687,0:41.355.782,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA DB 79 79 07 7F 71 45 5E F4 63 4C D8 E7 C9 A7… 0,,5691,0:41.356.779,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,5692,0:41.370.784,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5696,0:41.371.781,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,5697,0:41.371.784,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA DB 79 79 07 7F 71 45 5E F4 63 4C D8 E7 C9 A7… 0,,5701,0:41.372.781,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,5702,0:41.387.787,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 E3 B9 C7 DB 0F 59 AE A3 87 86 5F 27 BC EE 04… 0,,5706,0:41.388.783,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,5707,0:41.402.789,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5711,0:41.403.786,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,5712,0:41.403.789,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 E3 B9 C7 DB 0F 59 AE A3 87 86 5F 27 BC EE 04… 0,,5716,0:41.404.786,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,5717,0:41.419.791,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7E C6 C5 55 80 30 5F C0 5E 76 93 BF 7B 00 C3 31… 0,,5721,0:41.420.788,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,5722,0:41.434.793,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5726,0:41.435.790,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,5727,0:41.435.793,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7E C6 C5 55 80 30 5F C0 5E 76 93 BF 7B 00 C3 31… 0,,5731,0:41.436.790,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,5732,0:41.451.795,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 2A 38 E2 E0 09 9E 16 0F B5 B8 44 88 AB EC 52… 0,,5736,0:41.452.792,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,5737,0:41.466.798,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5741,0:41.467.794,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,5742,0:41.467.798,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 2A 38 E2 E0 09 9E 16 0F B5 B8 44 88 AB EC 52… 0,,5746,0:41.468.795,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,5747,0:41.483.800,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE 37 1B 35 3A 46 7A 1F 62 B9 FD AE 37 BD 2E EF… 0,,5751,0:41.484.797,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,5752,0:41.498.802,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5756,0:41.499.799,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,5757,0:41.499.802,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE 37 1B 35 3A 46 7A 1F 62 B9 FD AE 37 BD 2E EF… 0,,5761,0:41.500.799,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,5762,0:41.515.804,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 E6 6D 0D 3A AA 20 7A 11 03 A8 8C 25 86 A3 36… 0,,5766,0:41.516.801,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,5767,0:41.530.806,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5771,0:41.531.803,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,5772,0:41.531.807,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 E6 6D 0D 3A AA 20 7A 11 03 A8 8C 25 86 A3 36… 0,,5776,0:41.532.803,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,5777,0:41.547.809,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C4 A5 42 56 93 25 13 8B F1 AC 8B 59 62 66 17 56… 0,,5781,0:41.548.806,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,5782,0:41.562.811,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5786,0:41.563.808,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,5787,0:41.563.811,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C4 A5 42 56 93 25 13 8B F1 AC 8B 59 62 66 17 56… 0,,5791,0:41.564.808,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,5792,0:41.579.813,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 89 BE F3 C6 B9 08 41 B7 A9 23 88 EF 6C 07 5E 6F… 0,,5796,0:41.580.810,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,5797,0:41.594.815,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5801,0:41.595.812,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,5802,0:41.595.815,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 89 BE F3 C6 B9 08 41 B7 A9 23 88 EF 6C 07 5E 6F… 0,,5806,0:41.596.812,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,5807,0:41.611.818,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 A4 83 2A 0E 46 17 B9 9D 22 48 B1 0B 8D F8 9C… 0,,5811,0:41.612.815,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,5812,0:41.626.820,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5816,0:41.627.817,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,5817,0:41.627.820,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 A4 83 2A 0E 46 17 B9 9D 22 48 B1 0B 8D F8 9C… 0,,5821,0:41.628.817,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,5822,0:41.643.822,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 08 F8 B0 FD AB 0C 7A 68 D2 BA B1 44 57 12 2A… 0,,5826,0:41.644.819,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,5827,0:41.658.824,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5831,0:41.659.821,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,5832,0:41.659.824,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 08 F8 B0 FD AB 0C 7A 68 D2 BA B1 44 57 12 2A… 0,,5836,0:41.660.821,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,5837,0:41.675.827,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA BF 26 7E F4 B5 F0 1F EE 8B A8 A7 CD EA FB C4… 0,,5841,0:41.676.823,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,5842,0:41.690.829,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5846,0:41.691.826,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,5847,0:41.691.829,50.729 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA BF 26 7E F4 B5 F0 1F EE 8B A8 A7 CD EA FB C4… 0,,5851,0:41.692.826,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,5852,0:41.707.831,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC 96 8C 90 E9 C7 F5 38 35 3E 51 95 5E F6 1B 94… 0,,5856,0:41.708.828,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,5857,0:41.722.833,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5861,0:41.723.830,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,5862,0:41.723.833,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC 96 8C 90 E9 C7 F5 38 35 3E 51 95 5E F6 1B 94… 0,,5866,0:41.724.830,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,5867,0:41.739.835,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 AF 88 95 89 2F 03 63 D2 E7 24 1E 7A 15 44 8E… 0,,5871,0:41.740.832,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,5872,0:41.754.838,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5876,0:41.755.834,16.005.041 ms,,,,,[17 SOF],[Frames: 737 - 753] 0,,5877,0:41.771.840,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 DA 25 45 05 F6 CA A2 15 B9 88 80 A3 2F DF B1… 0,,5881,0:41.772.837,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,5882,0:41.786.842,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5886,0:41.787.839,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,5887,0:41.787.842,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 DA 25 45 05 F6 CA A2 15 B9 88 80 A3 2F DF B1… 0,,5891,0:41.788.839,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,5892,0:41.803.844,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3D 1A 95 52 65 03 7D A7 31 43 35 32 6E 25 24 7D… 0,,5896,0:41.804.841,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,5897,0:41.818.846,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5901,0:41.819.843,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,5902,0:41.819.847,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3D 1A 95 52 65 03 7D A7 31 43 35 32 6E 25 24 7D… 0,,5906,0:41.820.843,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,5907,0:41.835.849,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 17 5E AE 13 27 28 F8 96 20 4E 60 6B FB B2 70… 0,,5911,0:41.836.846,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,5912,0:41.850.851,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5916,0:41.851.848,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,5917,0:41.851.851,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 17 5E AE 13 27 28 F8 96 20 4E 60 6B FB B2 70… 0,,5921,0:41.852.848,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,5922,0:41.867.853,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A1 C7 ED 1F EF 52 61 4D 34 30 D3 63 63 F6 E4 8C… 0,,5926,0:41.868.850,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,5927,0:41.882.855,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5931,0:41.883.852,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,5932,0:41.883.855,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A1 C7 ED 1F EF 52 61 4D 34 30 D3 63 63 F6 E4 8C… 0,,5936,0:41.884.852,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,5937,0:41.899.858,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 72 3C 08 53 62 43 5B 51 2A C4 AF E0 7A 6B 43… 0,,5941,0:41.900.855,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,5942,0:41.914.860,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5946,0:41.915.857,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,5947,0:41.915.860,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 72 3C 08 53 62 43 5B 51 2A C4 AF E0 7A 6B 43… 0,,5951,0:41.916.857,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,5952,0:41.931.862,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E 09 5F 89 1E C0 05 F4 B4 CD D2 EF B4 3A E4 65… 0,,5956,0:41.932.859,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,5957,0:41.946.864,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5961,0:41.947.861,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,5962,0:41.947.864,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E 09 5F 89 1E C0 05 F4 B4 CD D2 EF B4 3A E4 65… 0,,5966,0:41.948.861,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,5967,0:41.963.867,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 BD CA E2 7C 9C ED 2B 52 AF A7 C1 D8 01 18 82… 0,,5971,0:41.964.863,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,5972,0:41.978.869,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5976,0:41.979.865,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,5977,0:41.979.869,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 BD CA E2 7C 9C ED 2B 52 AF A7 C1 D8 01 18 82… 0,,5981,0:41.980.866,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,5982,0:41.995.871,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 18 2A 32 F7 28 94 19 29 C3 E7 F2 DB FB E7 F5… 0,,5986,0:41.996.868,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,5987,0:42.010.873,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,5991,0:42.011.870,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,5992,0:42.011.873,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A 18 2A 32 F7 28 94 19 29 C3 E7 F2 DB FB E7 F5… 0,,5996,0:42.012.870,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,5997,0:42.027.875,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E 39 8F 44 27 97 B0 DB 78 EF 6B 90 78 E4 6A BB… 0,,6001,0:42.028.872,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,6002,0:42.042.877,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6006,0:42.043.874,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,6007,0:42.043.878,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E 39 8F 44 27 97 B0 DB 78 EF 6B 90 78 E4 6A BB… 0,,6011,0:42.044.875,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,6012,0:42.059.880,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 DA CF 22 79 58 FB D5 09 FC 92 CC EE 86 9C B1… 0,,6016,0:42.060.877,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,6017,0:42.074.882,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6021,0:42.075.879,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,6022,0:42.075.882,50.729 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 DA CF 22 79 58 FB D5 09 FC 92 CC EE 86 9C B1… 0,,6026,0:42.076.879,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,6027,0:42.091.884,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 8A A0 FB E8 5A EE F3 3E F8 E9 AE BE 48 90 A8… 0,,6031,0:42.092.881,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,6032,0:42.106.886,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6036,0:42.107.883,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,6037,0:42.107.887,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 8A A0 FB E8 5A EE F3 3E F8 E9 AE BE 48 90 A8… 0,,6041,0:42.108.883,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,6042,0:42.123.889,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 8B 55 1C B2 14 21 46 C1 E4 74 B8 73 6F B1 4F… 0,,6046,0:42.124.886,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,6047,0:42.138.891,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6051,0:42.139.888,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,6052,0:42.139.891,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 8B 55 1C B2 14 21 46 C1 E4 74 B8 73 6F B1 4F… 0,,6056,0:42.140.888,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,6057,0:42.155.893,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 52 1A FF 71 8D 9B E9 6B A9 41 37 DB DD E4 BC DC… 0,,6061,0:42.156.890,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,6062,0:42.170.895,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6066,0:42.171.892,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,6067,0:42.171.895,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 52 1A FF 71 8D 9B E9 6B A9 41 37 DB DD E4 BC DC… 0,,6071,0:42.172.892,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,6072,0:42.187.898,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C7 A6 C6 E6 15 40 FF C1 A4 9E 09 2B 5F 20 66 73… 0,,6076,0:42.188.895,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,6077,0:42.202.900,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6081,0:42.203.897,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,6082,0:42.203.900,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C7 A6 C6 E6 15 40 FF C1 A4 9E 09 2B 5F 20 66 73… 0,,6086,0:42.204.897,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,6087,0:42.219.902,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A 2C 73 C1 6C 5F C5 81 D2 AB 05 2F EC 40 E1 4D… 0,,6091,0:42.220.899,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,6092,0:42.234.904,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6096,0:42.235.901,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,6097,0:42.235.904,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A 2C 73 C1 6C 5F C5 81 D2 AB 05 2F EC 40 E1 4D… 0,,6101,0:42.236.901,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,6102,0:42.251.907,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3A E8 BB 93 4A 78 0A EA 9E 28 E9 20 18 C0 B7 07… 0,,6106,0:42.252.903,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,6107,0:42.266.909,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6111,0:42.267.905,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,6112,0:42.267.909,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3A E8 BB 93 4A 78 0A EA 9E 28 E9 20 18 C0 B7 07… 0,,6116,0:42.268.906,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,6117,0:42.283.911,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 C2 EE 6E 63 AD 46 81 BE 41 58 B1 F3 83 E8 C0… 0,,6121,0:42.284.908,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,6122,0:42.298.913,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6126,0:42.299.910,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,6127,0:42.299.913,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 C2 EE 6E 63 AD 46 81 BE 41 58 B1 F3 83 E8 C0… 0,,6131,0:42.300.910,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,6132,0:42.315.915,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 56 06 50 AF CE 53 D0 53 0F C2 AC 7B 8D EC 95 CE… 0,,6136,0:42.316.912,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,6137,0:42.330.917,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6141,0:42.331.914,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,6142,0:42.331.918,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 56 06 50 AF CE 53 D0 53 0F C2 AC 7B 8D EC 95 CE… 0,,6146,0:42.332.914,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,6147,0:42.347.920,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 DD C8 EB 92 7F 8F BB 43 BD 96 80 D9 4A 18 13… 0,,6151,0:42.348.917,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,6152,0:42.362.922,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6156,0:42.363.919,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,6157,0:42.363.922,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 DD C8 EB 92 7F 8F BB 43 BD 96 80 D9 4A 18 13… 0,,6161,0:42.364.919,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,6162,0:42.379.924,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 60 02 1E 0C 61 93 28 BB B0 BA 83 B8 02 1A DB E1… 0,,6166,0:42.380.921,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,6167,0:42.394.926,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6171,0:42.395.923,16.005.041 ms,,,,,[17 SOF],[Frames: 1377 - 1393] 0,,6172,0:42.411.929,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 02 1E 0C 61 93 28 BB B0 BA 83 B8 02 1A DB E1… 0,,6176,0:42.412.926,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,6177,0:42.426.931,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6181,0:42.427.928,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,6182,0:42.427.931,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 02 1E 0C 61 93 28 BB B0 BA 83 B8 02 1A DB E1… 0,,6186,0:42.428.928,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,6187,0:42.443.933,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F 42 29 42 9F F5 3C 02 31 14 5C 96 11 A6 AE B1… 0,,6191,0:42.444.930,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,6192,0:42.458.935,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6196,0:42.459.932,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,6197,0:42.459.935,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F 42 29 42 9F F5 3C 02 31 14 5C 96 11 A6 AE B1… 0,,6201,0:42.460.932,15.004.916 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,6202,0:42.475.938,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 B3 4B 3E 4D 30 3E 79 30 26 5F F0 24 18 BC 00… 0,,6206,0:42.476.934,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,6207,0:42.490.940,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6211,0:42.491.937,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,6212,0:42.491.940,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 B3 4B 3E 4D 30 3E 79 30 26 5F F0 24 18 BC 00… 0,,6216,0:42.492.937,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,6217,0:42.507.942,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D 03 40 E6 3C 7D F6 3F 11 83 F6 78 AD 3B 70 58… 0,,6221,0:42.508.939,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,6222,0:42.522.944,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6226,0:42.523.941,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,6227,0:42.523.944,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 03 40 E6 3C 7D F6 3F 11 83 F6 78 AD 3B 70 58… 0,,6231,0:42.524.941,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,6232,0:42.539.946,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB E8 59 D2 89 3A E5 0E 6A 2F 91 1C F4 F7 B2 DE… 0,,6236,0:42.540.943,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,6237,0:42.554.949,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6241,0:42.555.945,2.833 us,,,,,[1 SOF],[Frame: 1537] 0,,6242,0:42.555.949,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB E8 59 D2 89 3A E5 0E 6A 2F 91 1C F4 F7 B2 DE… 0,,6246,0:42.556.946,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,6247,0:42.571.951,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C5 CB BA FA 44 65 02 BC A7 72 77 DE 3F 44 EF AE… 0,,6251,0:42.572.948,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,6252,0:42.586.953,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6256,0:42.587.950,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,6257,0:42.587.953,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C5 CB BA FA 44 65 02 BC A7 72 77 DE 3F 44 EF AE… 0,,6261,0:42.588.950,15.004.916 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,6262,0:42.603.955,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 54 AC C6 1E E1 19 FC 70 45 32 52 21 9E E6 E8 65… 0,,6266,0:42.604.952,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,6267,0:42.618.957,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6271,0:42.619.954,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,6272,0:42.619.958,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 54 AC C6 1E E1 19 FC 70 45 32 52 21 9E E6 E8 65… 0,,6276,0:42.620.954,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,6277,0:42.635.960,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 5E DB C5 5C B7 58 3B DE EB 7D D1 10 B6 59 DB… 0,,6281,0:42.636.957,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,6282,0:42.650.962,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6286,0:42.651.959,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,6287,0:42.651.962,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 5E DB C5 5C B7 58 3B DE EB 7D D1 10 B6 59 DB… 0,,6291,0:42.652.959,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,6292,0:42.667.964,50.812 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C7 8A 79 B7 74 4E 5C F0 8D 0E 91 90 F8 AB 0D 06… 0,,6296,0:42.668.961,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,6297,0:42.682.966,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6301,0:42.683.963,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,6302,0:42.683.966,50.854 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C7 8A 79 B7 74 4E 5C F0 8D 0E 91 90 F8 AB 0D 06… 0,,6306,0:42.684.963,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,6307,0:42.699.969,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 EA 5D C7 54 B9 7A D7 60 17 2B 2E 1F F6 D8 2B… 0,,6311,0:42.700.966,14.004.750 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,6312,0:42.714.971,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6316,0:42.715.968,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,6317,0:42.715.971,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 EA 5D C7 54 B9 7A D7 60 17 2B 2E 1F F6 D8 2B… 0,,6321,0:42.716.968,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,6322,0:42.731.973,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 2B 22 5E 38 AA 43 97 B4 C7 78 25 EA 95 05 91… 0,,6326,0:42.732.970,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,6327,0:42.746.975,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6331,0:42.747.972,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,6332,0:42.747.975,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 2B 22 5E 38 AA 43 97 B4 C7 78 25 EA 95 05 91… 0,,6336,0:42.748.972,15.004.916 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,6337,0:42.763.978,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF E2 31 C6 B0 D7 B9 CE 64 C2 EC A2 6C AC D1 80… 0,,6341,0:42.764.974,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,6342,0:42.778.980,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6346,0:42.779.977,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,6347,0:42.779.980,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF E2 31 C6 B0 D7 B9 CE 64 C2 EC A2 6C AC D1 80… 0,,6351,0:42.780.977,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,6352,0:42.795.982,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 B2 A2 AB 90 51 01 AF A9 56 4D 4E 87 47 CD 67… 0,,6356,0:42.796.979,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,6357,0:42.810.984,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6361,0:42.811.981,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,6362,0:42.811.984,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 B2 A2 AB 90 51 01 AF A9 56 4D 4E 87 47 CD 67… 0,,6366,0:42.812.981,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,6367,0:42.827.986,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8F 9F CF 3A 43 79 A1 93 12 9E 02 A9 89 17 D6 96… 0,,6371,0:42.828.983,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,6372,0:42.842.989,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6376,0:42.843.985,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,6377,0:42.843.989,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8F 9F CF 3A 43 79 A1 93 12 9E 02 A9 89 17 D6 96… 0,,6381,0:42.844.986,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,6382,0:42.859.991,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F8 04 1E 26 45 C6 11 A9 33 73 19 5B B3 D3 9D 76… 0,,6386,0:42.860.988,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,6387,0:42.874.993,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6391,0:42.875.990,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,6392,0:42.875.993,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F8 04 1E 26 45 C6 11 A9 33 73 19 5B B3 D3 9D 76… 0,,6396,0:42.876.990,15.004.916 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,6397,0:42.891.995,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 05 12 92 01 BA 7C A8 12 F7 6B D1 AC D3 78 F3… 0,,6401,0:42.892.992,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,6402,0:42.906.997,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6406,0:42.907.994,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,6407,0:42.907.998,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 05 12 92 01 BA 7C A8 12 F7 6B D1 AC D3 78 F3… 0,,6411,0:42.908.994,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,6412,0:42.924.000,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 58 40 81 D2 33 40 4F 78 79 48 AD 5F 4B C8 7F… 0,,6416,0:42.924.997,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,6417,0:42.939.002,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6421,0:42.939.999,2.833 us,,,,,[1 SOF],[Frame: 1921] 0,,6422,0:42.940.002,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 58 40 81 D2 33 40 4F 78 79 48 AD 5F 4B C8 7F… 0,,6426,0:42.940.999,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,6427,0:42.956.004,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC 43 D5 36 0C 12 1E 2F BE 7A 73 8B 34 BC 86 95… 0,,6431,0:42.957.001,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,6432,0:42.971.006,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6436,0:42.972.003,2.833 us,,,,,[1 SOF],[Frame: 1953] 0,,6437,0:42.972.006,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC 43 D5 36 0C 12 1E 2F BE 7A 73 8B 34 BC 86 95… 0,,6441,0:42.973.003,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,6442,0:42.988.009,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B A8 54 AE B1 26 F4 EE 27 C6 75 6D 22 19 C3 58… 0,,6446,0:42.989.006,14.004.750 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,6447,0:43.003.011,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6451,0:43.004.008,16.005.125 ms,,,,,[17 SOF],[Frames: 1985 - 2001] 0,,6452,0:43.020.013,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D 65 45 6C 53 46 FC 1D AF 34 52 63 C9 0F 06 9C… 0,,6456,0:43.021.010,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,6457,0:43.035.015,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6461,0:43.036.012,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,6462,0:43.036.015,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D 65 45 6C 53 46 FC 1D AF 34 52 63 C9 0F 06 9C… 0,,6466,0:43.037.012,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,6467,0:43.052.018,50.729 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 3A 07 9C 6B 1B 17 FF A5 A6 4E BD 1F 4A D6 FF… 0,,6471,0:43.053.014,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,6472,0:43.067.020,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6476,0:43.068.017,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,6477,0:43.068.020,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 3A 07 9C 6B 1B 17 FF A5 A6 4E BD 1F 4A D6 FF… 0,,6481,0:43.069.017,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,6482,0:43.084.022,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 AB 21 A1 70 27 6B E9 81 BE 3A 4B C8 66 D0 05… 0,,6486,0:43.085.019,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,6487,0:43.099.024,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6491,0:43.100.021,2.833 us,,,,,[1 SOF],[Frame: 33] 0,,6492,0:43.100.024,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 AB 21 A1 70 27 6B E9 81 BE 3A 4B C8 66 D0 05… 0,,6496,0:43.101.021,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,6497,0:43.116.026,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D9 81 62 76 F1 BA 80 10 82 15 F6 9E 83 56 B5 65… 0,,6501,0:43.117.023,14.004.750 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,6502,0:43.131.029,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6506,0:43.132.025,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,6507,0:43.132.029,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D9 81 62 76 F1 BA 80 10 82 15 F6 9E 83 56 B5 65… 0,,6511,0:43.133.026,15.004.916 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,6512,0:43.148.031,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E D6 B2 14 EB 88 ED 29 FA 88 3E 21 2E E7 64 0B… 0,,6516,0:43.149.028,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,6517,0:43.163.033,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6521,0:43.164.030,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,6522,0:43.164.033,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E D6 B2 14 EB 88 ED 29 FA 88 3E 21 2E E7 64 0B… 0,,6526,0:43.165.030,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,6527,0:43.180.035,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA 49 85 96 48 67 6A 09 75 D0 66 20 9A C4 4D 81… 0,,6531,0:43.181.032,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,6532,0:43.195.037,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6536,0:43.196.034,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,6537,0:43.196.038,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA 49 85 96 48 67 6A 09 75 D0 66 20 9A C4 4D 81… 0,,6541,0:43.197.034,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,6542,0:43.212.040,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 B8 52 2D 42 6F FE 35 05 0E B2 54 6B 0C 7F 7B… 0,,6546,0:43.213.037,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,6547,0:43.227.042,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6551,0:43.228.039,2.833 us,,,,,[1 SOF],[Frame: 161] 0,,6552,0:43.228.042,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 B8 52 2D 42 6F FE 35 05 0E B2 54 6B 0C 7F 7B… 0,,6556,0:43.229.039,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,6557,0:43.244.044,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 E6 35 AF D5 F1 F1 A5 CA 77 78 EE EF A6 BE D6… 0,,6561,0:43.245.041,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,6562,0:43.259.046,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6566,0:43.260.043,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,6567,0:43.260.046,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 E6 35 AF D5 F1 F1 A5 CA 77 78 EE EF A6 BE D6… 0,,6571,0:43.261.043,15.004.916 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,6572,0:43.276.049,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 DE 2E C1 38 25 07 DE 1A AA EB 7E 47 E0 BA CD… 0,,6576,0:43.277.046,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,6577,0:43.291.051,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6581,0:43.292.048,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,6582,0:43.292.051,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 DE 2E C1 38 25 07 DE 1A AA EB 7E 47 E0 BA CD… 0,,6586,0:43.293.048,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,6587,0:43.308.053,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 C1 6D 87 81 F6 9C 7E 8F D8 AD 49 CA 36 2C C4… 0,,6591,0:43.309.050,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,6592,0:43.323.055,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6596,0:43.324.052,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,6597,0:43.324.055,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 C1 6D 87 81 F6 9C 7E 8F D8 AD 49 CA 36 2C C4… 0,,6601,0:43.325.052,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,6602,0:43.340.058,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 3F D3 97 FB 77 41 39 10 FD 95 E0 3B AF 20 9D… 0,,6606,0:43.341.054,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,6607,0:43.355.060,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6611,0:43.356.057,2.833 us,,,,,[1 SOF],[Frame: 289] 0,,6612,0:43.356.060,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 3F D3 97 FB 77 41 39 10 FD 95 E0 3B AF 20 9D… 0,,6616,0:43.357.057,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,6617,0:43.372.062,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 B4 C9 0C A4 F8 6E 31 83 28 C4 FF 95 89 EC 7B… 0,,6621,0:43.373.059,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,6622,0:43.387.064,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6626,0:43.388.061,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,6627,0:43.388.064,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 B4 C9 0C A4 F8 6E 31 83 28 C4 FF 95 89 EC 7B… 0,,6631,0:43.389.061,15.004.916 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,6632,0:43.404.066,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C CC 8E F8 B3 B0 0E 8E 93 D6 93 AA D8 91 53 5B… 0,,6636,0:43.405.063,14.004.750 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,6637,0:43.419.069,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6641,0:43.420.065,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,6642,0:43.420.069,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C CC 8E F8 B3 B0 0E 8E 93 D6 93 AA D8 91 53 5B… 0,,6646,0:43.421.066,15.004.916 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,6647,0:43.436.071,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 17 09 E3 98 81 95 D1 67 B7 00 9D E7 14 45 56 AF… 0,,6651,0:43.437.068,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,6652,0:43.451.073,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6656,0:43.452.070,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,6657,0:43.452.073,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 17 09 E3 98 81 95 D1 67 B7 00 9D E7 14 45 56 AF… 0,,6661,0:43.453.070,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,6662,0:43.468.075,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E 0E E8 C6 19 00 5F AE E5 21 18 7C E6 DB 9D 14… 0,,6666,0:43.469.072,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,6667,0:43.483.077,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6671,0:43.484.074,2.833 us,,,,,[1 SOF],[Frame: 417] 0,,6672,0:43.484.078,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E 0E E8 C6 19 00 5F AE E5 21 18 7C E6 DB 9D 14… 0,,6676,0:43.485.074,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,6677,0:43.500.080,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA 71 9E 84 62 C4 D0 08 67 8A 05 D7 6A 03 3A 5F… 0,,6681,0:43.501.077,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,6682,0:43.515.082,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6686,0:43.516.079,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,6687,0:43.516.082,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA 71 9E 84 62 C4 D0 08 67 8A 05 D7 6A 03 3A 5F… 0,,6691,0:43.517.079,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,6692,0:43.532.084,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 6D F8 0C 22 A3 1A 3E 16 B0 A0 15 C9 F8 82 F3… 0,,6696,0:43.533.081,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,6697,0:43.547.086,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6701,0:43.548.083,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,6702,0:43.548.086,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 6D F8 0C 22 A3 1A 3E 16 B0 A0 15 C9 F8 82 F3… 0,,6706,0:43.549.083,15.004.916 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,6707,0:43.564.089,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 7A 6F 26 8A 82 3C FB 9B AB 7A C4 E6 BB C7 14… 0,,6711,0:43.565.086,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,6712,0:43.579.091,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6716,0:43.580.088,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,6717,0:43.580.091,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 7A 6F 26 8A 82 3C FB 9B AB 7A C4 E6 BB C7 14… 0,,6721,0:43.581.088,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,6722,0:43.596.093,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C3 42 61 37 31 88 FF 0F 56 2D BE AD 01 E9 27 97… 0,,6726,0:43.597.090,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,6727,0:43.611.095,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6731,0:43.612.092,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,6732,0:43.612.095,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C3 42 61 37 31 88 FF 0F 56 2D BE AD 01 E9 27 97… 0,,6736,0:43.613.092,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,6737,0:43.628.098,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7E E7 5B 3F 6C B0 94 A2 53 ED B2 3A C9 0D CA B5… 0,,6741,0:43.629.094,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,6742,0:43.643.100,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6746,0:43.644.097,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,6747,0:43.644.100,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7E E7 5B 3F 6C B0 94 A2 53 ED B2 3A C9 0D CA B5… 0,,6751,0:43.645.097,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,6752,0:43.660.102,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF 29 6A 50 89 9E A5 C5 21 B5 7B FF B9 E7 8D 34… 0,,6756,0:43.661.099,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,6757,0:43.675.104,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6761,0:43.676.101,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,6762,0:43.676.104,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF 29 6A 50 89 9E A5 C5 21 B5 7B FF B9 E7 8D 34… 0,,6766,0:43.677.101,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,6767,0:43.692.106,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5C A0 90 A6 2D 72 28 64 FA 40 3E 42 CA AD 3F BD… 0,,6771,0:43.693.103,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,6772,0:43.707.108,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6776,0:43.708.105,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,6777,0:43.708.109,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5C A0 90 A6 2D 72 28 64 FA 40 3E 42 CA AD 3F BD… 0,,6781,0:43.709.106,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,6782,0:43.724.111,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D BF 16 19 DB 60 05 87 4B 79 B0 C1 C5 08 B0 19… 0,,6786,0:43.725.108,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,6787,0:43.739.113,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6791,0:43.740.110,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,6792,0:43.740.113,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D BF 16 19 DB 60 05 87 4B 79 B0 C1 C5 08 B0 19… 0,,6796,0:43.741.110,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,6797,0:43.756.115,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5C AF 93 EC EC CC FF BD AF ED 45 4C 18 6E 77 22… 0,,6801,0:43.757.112,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,6802,0:43.771.117,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6806,0:43.772.114,2.833 us,,,,,[1 SOF],[Frame: 705] 0,,6807,0:43.772.118,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5C AF 93 EC EC CC FF BD AF ED 45 4C 18 6E 77 22… 0,,6811,0:43.773.114,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,6812,0:43.788.120,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 59 15 EB 46 28 AD F2 5D F8 0E A7 10 7B F8 27 A8… 0,,6816,0:43.789.117,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,6817,0:43.803.122,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6821,0:43.804.119,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,6822,0:43.804.122,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 59 15 EB 46 28 AD F2 5D F8 0E A7 10 7B F8 27 A8… 0,,6826,0:43.805.119,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,6827,0:43.820.124,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B 0D CA 40 F5 6F 75 EB 7C E4 2E F0 FA C3 6B D0… 0,,6831,0:43.821.121,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,6832,0:43.835.126,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6836,0:43.836.123,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,6837,0:43.836.126,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B 0D CA 40 F5 6F 75 EB 7C E4 2E F0 FA C3 6B D0… 0,,6841,0:43.837.123,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,6842,0:43.852.129,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 0E 63 B4 26 16 C6 49 1D 4F 59 1F C8 AE A1 96… 0,,6846,0:43.853.126,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,6847,0:43.867.131,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6851,0:43.868.128,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,6852,0:43.868.131,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 0E 63 B4 26 16 C6 49 1D 4F 59 1F C8 AE A1 96… 0,,6856,0:43.869.128,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,6857,0:43.884.133,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C 68 1B 79 0A A2 A9 9C 9B 4D 42 A3 90 51 F3 20… 0,,6861,0:43.885.130,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,6862,0:43.899.135,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6866,0:43.900.132,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,6867,0:43.900.135,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C 68 1B 79 0A A2 A9 9C 9B 4D 42 A3 90 51 F3 20… 0,,6871,0:43.901.132,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,6872,0:43.916.138,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 8B DF 36 2B 4F 0E 8E 95 A1 32 00 BC 38 91 DE… 0,,6876,0:43.917.134,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,6877,0:43.931.140,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6881,0:43.932.136,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,6882,0:43.932.140,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 8B DF 36 2B 4F 0E 8E 95 A1 32 00 BC 38 91 DE… 0,,6886,0:43.933.137,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,6887,0:43.948.142,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 65 37 9B A3 26 80 43 7D C7 8B F2 95 BC CB 6A B0… 0,,6891,0:43.949.139,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,6892,0:43.963.144,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6896,0:43.964.141,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,6897,0:43.964.144,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 65 37 9B A3 26 80 43 7D C7 8B F2 95 BC CB 6A B0… 0,,6901,0:43.965.141,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,6902,0:43.980.146,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6E 97 08 BE CE 8F 22 B4 19 32 81 BD 2E D0 E1 5C… 0,,6906,0:43.981.143,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,6907,0:43.995.148,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6911,0:43.996.145,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,6912,0:43.996.149,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6E 97 08 BE CE 8F 22 B4 19 32 81 BD 2E D0 E1 5C… 0,,6916,0:43.997.146,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,6917,0:44.012.151,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EA B5 72 5F 51 1D B8 9D CF 94 03 A7 2A 46 1B E1… 0,,6921,0:44.013.148,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,6922,0:44.027.153,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6926,0:44.028.150,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,6927,0:44.028.153,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EA B5 72 5F 51 1D B8 9D CF 94 03 A7 2A 46 1B E1… 0,,6931,0:44.029.150,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,6932,0:44.044.155,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C3 17 00 B2 04 65 2C DA 39 83 80 6F CD 2B 7E 1E… 0,,6936,0:44.045.152,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,6937,0:44.059.157,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6941,0:44.060.154,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,6942,0:44.060.158,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C3 17 00 B2 04 65 2C DA 39 83 80 6F CD 2B 7E 1E… 0,,6946,0:44.061.154,15.005.000 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,6947,0:44.076.160,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 38 67 41 12 3D C7 B8 24 0B 27 CB 6C 86 43 D9… 0,,6951,0:44.077.157,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,6952,0:44.091.162,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6956,0:44.092.159,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,6957,0:44.092.162,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 38 67 41 12 3D C7 B8 24 0B 27 CB 6C 86 43 D9… 0,,6961,0:44.093.159,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,6962,0:44.108.164,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 7E E1 5B AF 5A B4 9A B6 A7 95 CB 29 14 68 70… 0,,6966,0:44.109.161,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,6967,0:44.123.166,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6971,0:44.124.163,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,6972,0:44.124.166,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A 7E E1 5B AF 5A B4 9A B6 A7 95 CB 29 14 68 70… 0,,6976,0:44.125.163,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,6977,0:44.140.169,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 7F AA 49 AF C5 15 AA 86 AC 8F 50 7C E8 AA 20… 0,,6981,0:44.141.165,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,6982,0:44.155.171,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,6986,0:44.156.168,2.833 us,,,,,[1 SOF],[Frame: 1089] 0,,6987,0:44.156.171,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 7F AA 49 AF C5 15 AA 86 AC 8F 50 7C E8 AA 20… 0,,6991,0:44.157.168,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,6992,0:44.172.173,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 6F 0A 18 7E C0 02 17 D4 5D 3A F6 D6 AB 7B 1D… 0,,6996,0:44.173.170,14.004.750 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,6997,0:44.187.175,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7001,0:44.188.172,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,7002,0:44.188.175,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 6F 0A 18 7E C0 02 17 D4 5D 3A F6 D6 AB 7B 1D… 0,,7006,0:44.189.172,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,7007,0:44.204.177,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 69 57 98 ED 6E C3 05 36 95 E4 F6 EC E2 C5 0B… 0,,7011,0:44.205.174,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,7012,0:44.219.180,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7016,0:44.220.176,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,7017,0:44.220.180,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 69 57 98 ED 6E C3 05 36 95 E4 F6 EC E2 C5 0B… 0,,7021,0:44.221.177,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,7022,0:44.236.182,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3D 2A D0 CB F6 61 FF B7 06 92 2B C6 BA 5F F8 42… 0,,7026,0:44.237.179,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,7027,0:44.251.184,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7031,0:44.252.181,16.005.041 ms,,,,,[17 SOF],[Frames: 1185 - 1201] 0,,7032,0:44.268.186,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 54 BC 18 C2 97 1B CC 80 D5 6E CB 85 F0 51 6C 7B… 0,,7036,0:44.269.183,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,7037,0:44.283.188,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7041,0:44.284.185,2.833 us,,,,,[1 SOF],[Frame: 1217] 0,,7042,0:44.284.189,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 54 BC 18 C2 97 1B CC 80 D5 6E CB 85 F0 51 6C 7B… 0,,7046,0:44.285.185,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,7047,0:44.300.191,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A 1F ED 17 49 33 06 4A FB C8 28 2C 17 C7 BC 8E… 0,,7051,0:44.301.188,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,7052,0:44.315.193,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7056,0:44.316.190,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,7057,0:44.316.193,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A 1F ED 17 49 33 06 4A FB C8 28 2C 17 C7 BC 8E… 0,,7061,0:44.317.190,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,7062,0:44.332.195,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C 80 D5 FD 88 DB C8 9A 7E 4E 73 E4 C6 EF 78 75… 0,,7066,0:44.333.192,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,7067,0:44.347.197,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7071,0:44.348.194,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,7072,0:44.348.197,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C 80 D5 FD 88 DB C8 9A 7E 4E 73 E4 C6 EF 78 75… 0,,7076,0:44.349.194,15.004.916 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,7077,0:44.364.200,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 47 60 BD 72 54 03 D4 F6 71 47 9B 8B F3 77 33… 0,,7081,0:44.365.197,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,7082,0:44.379.202,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7086,0:44.380.199,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,7087,0:44.380.202,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 47 60 BD 72 54 03 D4 F6 71 47 9B 8B F3 77 33… 0,,7091,0:44.381.199,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,7092,0:44.396.204,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C 8B D9 B6 FD 2D 3F 63 59 BE 92 34 A2 5E E8 EE… 0,,7096,0:44.397.201,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,7097,0:44.411.206,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7101,0:44.412.203,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,7102,0:44.412.206,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C 8B D9 B6 FD 2D 3F 63 59 BE 92 34 A2 5E E8 EE… 0,,7106,0:44.413.203,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,7107,0:44.428.209,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E E7 D3 76 A7 17 8D FB E3 BF 84 2F 16 C2 90 E8… 0,,7111,0:44.429.205,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,7112,0:44.443.211,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7116,0:44.444.208,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,7117,0:44.444.211,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E E7 D3 76 A7 17 8D FB E3 BF 84 2F 16 C2 90 E8… 0,,7121,0:44.445.208,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,7122,0:44.460.213,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 3D 06 12 DE 8B 56 7D C3 9C 5A 84 51 42 15 83… 0,,7126,0:44.461.210,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,7127,0:44.475.215,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7131,0:44.476.212,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,7132,0:44.476.215,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 3D 06 12 DE 8B 56 7D C3 9C 5A 84 51 42 15 83… 0,,7136,0:44.477.212,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,7137,0:44.492.217,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 47 9E 1E 7B DE FD 39 7A 05 47 C0 6D 57 85 11 A5… 0,,7141,0:44.493.214,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,7142,0:44.507.220,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7146,0:44.508.216,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,7147,0:44.508.220,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 47 9E 1E 7B DE FD 39 7A 05 47 C0 6D 57 85 11 A5… 0,,7151,0:44.509.217,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,7152,0:44.524.222,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 C2 77 FA F9 10 49 83 A9 D2 D1 3A 8B F2 A6 A1… 0,,7156,0:44.525.219,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,7157,0:44.539.224,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7161,0:44.540.221,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,7162,0:44.540.224,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 C2 77 FA F9 10 49 83 A9 D2 D1 3A 8B F2 A6 A1… 0,,7166,0:44.541.221,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,7167,0:44.556.226,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB 93 78 D7 69 B2 50 C3 56 29 3A 06 26 69 1C 3C… 0,,7171,0:44.557.223,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,7172,0:44.571.229,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7176,0:44.572.225,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,7177,0:44.572.229,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB 93 78 D7 69 B2 50 C3 56 29 3A 06 26 69 1C 3C… 0,,7181,0:44.573.225,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,7182,0:44.588.231,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AD D1 CD 02 16 52 F2 D0 0F 51 0D 95 7E 47 22 00… 0,,7186,0:44.589.228,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,7187,0:44.603.233,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7191,0:44.604.230,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,7192,0:44.604.233,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AD D1 CD 02 16 52 F2 D0 0F 51 0D 95 7E 47 22 00… 0,,7196,0:44.605.230,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,7197,0:44.620.235,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 41 1B 9A 14 AB 81 3F 39 6D A7 A0 13 11 19 F0… 0,,7201,0:44.621.232,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,7202,0:44.635.237,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7206,0:44.636.234,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,7207,0:44.636.237,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 41 1B 9A 14 AB 81 3F 39 6D A7 A0 13 11 19 F0… 0,,7211,0:44.637.234,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,7212,0:44.652.240,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 4F C1 84 6E 73 8D A1 88 2C CF 81 D1 70 C0 9D… 0,,7216,0:44.653.237,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,7217,0:44.667.242,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7221,0:44.668.239,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,7222,0:44.668.242,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 4F C1 84 6E 73 8D A1 88 2C CF 81 D1 70 C0 9D… 0,,7226,0:44.669.239,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,7227,0:44.684.244,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D6 6B CF 0B 9F 92 3B 6B DC C5 BA 3C 72 8C 65 C9… 0,,7231,0:44.685.241,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,7232,0:44.699.246,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7236,0:44.700.243,2.833 us,,,,,[1 SOF],[Frame: 1633] 0,,7237,0:44.700.246,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D6 6B CF 0B 9F 92 3B 6B DC C5 BA 3C 72 8C 65 C9… 0,,7241,0:44.701.243,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,7242,0:44.716.249,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 69 20 57 E7 9F D7 44 E8 5A 99 57 E3 38 C1 F7 35… 0,,7246,0:44.717.245,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,7247,0:44.731.251,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7251,0:44.732.248,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,7252,0:44.732.251,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 69 20 57 E7 9F D7 44 E8 5A 99 57 E3 38 C1 F7 35… 0,,7256,0:44.733.248,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,7257,0:44.748.253,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EE FF 7D CA 09 C4 51 96 57 40 FA 88 0C 12 67 3C… 0,,7261,0:44.749.250,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,7262,0:44.763.255,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7266,0:44.764.252,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,7267,0:44.764.255,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EE FF 7D CA 09 C4 51 96 57 40 FA 88 0C 12 67 3C… 0,,7271,0:44.765.252,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,7272,0:44.780.257,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B7 94 A3 61 B9 7A EF 7E 62 AB 57 5E 5C 3B 6B 5E… 0,,7276,0:44.781.254,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,7277,0:44.795.260,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7281,0:44.796.256,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,7282,0:44.796.260,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B7 94 A3 61 B9 7A EF 7E 62 AB 57 5E 5C 3B 6B 5E… 0,,7286,0:44.797.257,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,7287,0:44.812.262,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 1B E5 1A A2 1E 16 35 1B 63 85 18 EF 67 B8 9C… 0,,7291,0:44.813.259,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,7292,0:44.827.264,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7296,0:44.828.261,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,7297,0:44.828.264,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 1B E5 1A A2 1E 16 35 1B 63 85 18 EF 67 B8 9C… 0,,7301,0:44.829.261,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,7302,0:44.844.266,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6F 73 23 65 C2 26 F8 49 4D 54 04 1C D2 71 A3 63… 0,,7306,0:44.845.263,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,7307,0:44.859.268,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7311,0:44.860.265,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,7312,0:44.860.269,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6F 73 23 65 C2 26 F8 49 4D 54 04 1C D2 71 A3 63… 0,,7316,0:44.861.265,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,7317,0:44.876.271,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 2F 45 F9 44 08 D9 61 2B 73 BD 18 F9 E8 85 B3… 0,,7321,0:44.877.268,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,7322,0:44.891.273,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7326,0:44.892.270,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,7327,0:44.892.273,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 2F 45 F9 44 08 D9 61 2B 73 BD 18 F9 E8 85 B3… 0,,7331,0:44.893.270,15.004.916 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,7332,0:44.908.275,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 20 B1 B2 F5 CE 94 1A 01 CD 21 8B 83 FB 28 BE A8… 0,,7336,0:44.909.272,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,7337,0:44.923.277,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7341,0:44.924.274,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,7342,0:44.924.277,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 20 B1 B2 F5 CE 94 1A 01 CD 21 8B 83 FB 28 BE A8… 0,,7346,0:44.925.274,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,7347,0:44.940.280,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 96 2F 77 B2 16 25 2F DD 57 2D 79 B7 30 C1 E2… 0,,7351,0:44.941.277,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,7352,0:44.955.282,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7356,0:44.956.279,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,7357,0:44.956.282,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 96 2F 77 B2 16 25 2F DD 57 2D 79 B7 30 C1 E2… 0,,7361,0:44.957.279,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,7362,0:44.972.284,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 93 6A E4 32 32 A6 01 6F EA 74 55 36 54 71 77… 0,,7366,0:44.973.281,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,7367,0:44.987.286,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7371,0:44.988.283,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,7372,0:44.988.286,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 93 6A E4 32 32 A6 01 6F EA 74 55 36 54 71 77… 0,,7376,0:44.989.283,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,7377,0:45.004.289,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 D8 B3 3B F8 57 01 DF A3 45 F6 1B 58 AE DA CC… 0,,7381,0:45.005.285,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,7382,0:45.019.291,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7386,0:45.020.288,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,7387,0:45.020.291,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 D8 B3 3B F8 57 01 DF A3 45 F6 1B 58 AE DA CC… 0,,7391,0:45.021.288,15.004.916 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,7392,0:45.036.293,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 70 80 2D AE 7E 15 1F 43 F0 0B D1 A3 E0 34 4D… 0,,7396,0:45.037.290,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,7397,0:45.051.295,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7401,0:45.052.292,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,7402,0:45.052.295,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 70 80 2D AE 7E 15 1F 43 F0 0B D1 A3 E0 34 4D… 0,,7406,0:45.053.292,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,7407,0:45.068.298,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 38 53 88 2D F7 F2 0A 21 B0 10 6C 8E 3C 8D 16… 0,,7411,0:45.069.294,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,7412,0:45.083.300,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7416,0:45.084.296,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,7417,0:45.084.300,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 38 53 88 2D F7 F2 0A 21 B0 10 6C 8E 3C 8D 16… 0,,7421,0:45.085.297,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,7422,0:45.100.302,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF 37 C9 86 52 E0 1B B4 0F 3A 3C 9F EF 18 93 46… 0,,7426,0:45.101.299,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,7427,0:45.115.304,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7431,0:45.116.301,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,7432,0:45.116.304,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF 37 C9 86 52 E0 1B B4 0F 3A 3C 9F EF 18 93 46… 0,,7436,0:45.117.301,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,7437,0:45.132.306,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 91 95 04 EC 45 07 95 46 C0 62 85 89 33 03 7D A1… 0,,7441,0:45.133.303,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,7442,0:45.147.308,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7446,0:45.148.305,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,7447,0:45.148.309,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 91 95 04 EC 45 07 95 46 C0 62 85 89 33 03 7D A1… 0,,7451,0:45.149.305,15.004.916 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,7452,0:45.164.311,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 72 AF 78 A2 E0 54 F8 FB 37 E2 35 E3 08 63 99 A7… 0,,7456,0:45.165.308,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,7457,0:45.179.313,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7461,0:45.180.310,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,7462,0:45.180.313,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 72 AF 78 A2 E0 54 F8 FB 37 E2 35 E3 08 63 99 A7… 0,,7466,0:45.181.310,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,7467,0:45.196.315,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C A9 12 30 3F 62 A5 DB 73 6B F8 5F 58 1B D4 03… 0,,7471,0:45.197.312,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,7472,0:45.211.317,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7476,0:45.212.314,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,7477,0:45.212.317,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C A9 12 30 3F 62 A5 DB 73 6B F8 5F 58 1B D4 03… 0,,7481,0:45.213.314,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,7482,0:45.228.320,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 83 C1 63 3B 10 5D 90 8C 6C B9 E8 7E 33 E3 16… 0,,7486,0:45.229.317,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,7487,0:45.243.322,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7491,0:45.244.319,2.833 us,,,,,[1 SOF],[Frame: 129] 0,,7492,0:45.244.322,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 83 C1 63 3B 10 5D 90 8C 6C B9 E8 7E 33 E3 16… 0,,7496,0:45.245.319,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,7497,0:45.260.324,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 1A C1 27 D7 03 2C 3B D7 5C 04 7D 4D 72 C6 EE… 0,,7501,0:45.261.321,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,7502,0:45.275.326,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7506,0:45.276.323,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,7507,0:45.276.326,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 1A C1 27 D7 03 2C 3B D7 5C 04 7D 4D 72 C6 EE… 0,,7511,0:45.277.323,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,7512,0:45.292.329,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 81 5A B3 B4 DE C8 1D F8 24 3D 7B 14 24 4A 88… 0,,7516,0:45.293.325,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,7517,0:45.307.331,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7521,0:45.308.328,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,7522,0:45.308.331,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 81 5A B3 B4 DE C8 1D F8 24 3D 7B 14 24 4A 88… 0,,7526,0:45.309.328,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,7527,0:45.324.333,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF 17 78 49 58 CB F2 39 5D 45 EA C1 20 4E D3 88… 0,,7531,0:45.325.330,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,7532,0:45.339.335,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7536,0:45.340.332,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,7537,0:45.340.335,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF 17 78 49 58 CB F2 39 5D 45 EA C1 20 4E D3 88… 0,,7541,0:45.341.332,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,7542,0:45.356.337,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F B0 3A A2 60 45 95 AC E7 E6 DD D7 F3 22 A6 21… 0,,7546,0:45.357.334,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,7547,0:45.371.340,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7551,0:45.372.336,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,7552,0:45.372.340,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F B0 3A A2 60 45 95 AC E7 E6 DD D7 F3 22 A6 21… 0,,7556,0:45.373.337,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,7557,0:45.388.342,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F9 A4 91 D1 15 54 64 87 D6 60 A9 05 E0 1F D8 D1… 0,,7561,0:45.389.339,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,7562,0:45.403.344,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7566,0:45.404.341,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,7567,0:45.404.344,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F9 A4 91 D1 15 54 64 87 D6 60 A9 05 E0 1F D8 D1… 0,,7571,0:45.405.341,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,7572,0:45.420.346,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 60 3E 87 84 A8 A3 5F 47 AE A5 25 14 57 F1 7A… 0,,7576,0:45.421.343,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,7577,0:45.435.348,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7581,0:45.436.345,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,7582,0:45.436.349,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 60 3E 87 84 A8 A3 5F 47 AE A5 25 14 57 F1 7A… 0,,7586,0:45.437.345,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,7587,0:45.452.351,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB 21 73 CC DA E8 45 5E ED 2C 08 F9 5E CE 3B 11… 0,,7591,0:45.453.348,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,7592,0:45.467.353,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7596,0:45.468.350,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,7597,0:45.468.353,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB 21 73 CC DA E8 45 5E ED 2C 08 F9 5E CE 3B 11… 0,,7601,0:45.469.350,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,7602,0:45.484.355,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C 97 5A B5 C5 37 5D 3E 58 64 26 29 E5 D2 EC 66… 0,,7606,0:45.485.352,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,7607,0:45.499.357,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7611,0:45.500.354,16.005.041 ms,,,,,[17 SOF],[Frames: 385 - 401] 0,,7612,0:45.516.360,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F C0 8D 89 92 E0 4D A9 76 90 15 7B A4 9B 5F 7F… 0,,7616,0:45.517.357,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,7617,0:45.531.362,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7621,0:45.532.359,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,7622,0:45.532.362,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F C0 8D 89 92 E0 4D A9 76 90 15 7B A4 9B 5F 7F… 0,,7626,0:45.533.359,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,7627,0:45.548.364,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC AD A7 26 19 A9 87 48 39 F8 42 60 02 5D F0 1B… 0,,7631,0:45.549.361,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,7632,0:45.563.366,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7636,0:45.564.363,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,7637,0:45.564.366,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC AD A7 26 19 A9 87 48 39 F8 42 60 02 5D F0 1B… 0,,7641,0:45.565.363,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,7642,0:45.580.369,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 51 35 55 24 D0 F6 8B 4B 6D D2 59 97 4A 62 56… 0,,7646,0:45.581.365,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,7647,0:45.595.371,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7651,0:45.596.367,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,7652,0:45.596.371,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 51 35 55 24 D0 F6 8B 4B 6D D2 59 97 4A 62 56… 0,,7656,0:45.597.368,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,7657,0:45.612.373,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 C5 B5 9B B1 7D EA CC A4 E2 B8 E1 91 33 F1 2A… 0,,7661,0:45.613.370,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,7662,0:45.627.375,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7666,0:45.628.372,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,7667,0:45.628.375,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 C5 B5 9B B1 7D EA CC A4 E2 B8 E1 91 33 F1 2A… 0,,7671,0:45.629.372,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,7672,0:45.644.377,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D 11 CA 4B 1C BF A5 8D 88 14 E7 B5 8A 02 63 8C… 0,,7676,0:45.645.374,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,7677,0:45.659.379,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7681,0:45.660.376,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,7682,0:45.660.380,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D 11 CA 4B 1C BF A5 8D 88 14 E7 B5 8A 02 63 8C… 0,,7686,0:45.661.377,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,7687,0:45.676.382,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 0D 4C 97 53 5D EF B1 A5 D2 AB 44 3D 5C 11 FC… 0,,7691,0:45.677.379,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,7692,0:45.691.384,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7696,0:45.692.381,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,7697,0:45.692.384,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 0D 4C 97 53 5D EF B1 A5 D2 AB 44 3D 5C 11 FC… 0,,7701,0:45.693.381,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,7702,0:45.708.386,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 67 25 14 73 19 CA E9 E1 64 E1 02 8E C7 37 07… 0,,7706,0:45.709.383,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,7707,0:45.723.388,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7711,0:45.724.385,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,7712,0:45.724.389,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 67 25 14 73 19 CA E9 E1 64 E1 02 8E C7 37 07… 0,,7716,0:45.725.385,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,7717,0:45.740.391,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC C0 5F 3E D8 B3 66 96 21 98 22 40 95 B2 79 B3… 0,,7721,0:45.741.388,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,7722,0:45.755.393,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7726,0:45.756.390,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,7727,0:45.756.393,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC C0 5F 3E D8 B3 66 96 21 98 22 40 95 B2 79 B3… 0,,7731,0:45.757.390,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,7732,0:45.772.395,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 19 4D 6A F5 0F 6B 6C 8C 57 5C 44 00 6C 16 6D 19… 0,,7736,0:45.773.392,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,7737,0:45.787.397,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7741,0:45.788.394,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,7742,0:45.788.397,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 19 4D 6A F5 0F 6B 6C 8C 57 5C 44 00 6C 16 6D 19… 0,,7746,0:45.789.394,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,7747,0:45.804.400,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5C 69 EE 6A DC 5A 83 E1 69 48 F3 77 21 9C 1F C3… 0,,7751,0:45.805.397,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,7752,0:45.819.402,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7756,0:45.820.399,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,7757,0:45.820.402,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5C 69 EE 6A DC 5A 83 E1 69 48 F3 77 21 9C 1F C3… 0,,7761,0:45.821.399,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,7762,0:45.836.404,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 66 8F 96 7E 04 EB 7A B1 EB E5 9D 32 F7 60 A3 A4… 0,,7766,0:45.837.401,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,7767,0:45.851.406,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7771,0:45.852.403,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,7772,0:45.852.406,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 66 8F 96 7E 04 EB 7A B1 EB E5 9D 32 F7 60 A3 A4… 0,,7776,0:45.853.403,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,7777,0:45.868.409,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 31 78 71 F6 28 AA 72 8D 8B A1 7A 34 FD 37 AE… 0,,7781,0:45.869.405,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,7782,0:45.883.411,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7786,0:45.884.407,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,7787,0:45.884.411,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 31 78 71 F6 28 AA 72 8D 8B A1 7A 34 FD 37 AE… 0,,7791,0:45.885.408,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,7792,0:45.900.413,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 B5 F9 C0 5B 1F C1 F4 04 CB E6 E0 32 71 03 3C… 0,,7796,0:45.901.410,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,7797,0:45.915.415,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7801,0:45.916.412,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,7802,0:45.916.415,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 B5 F9 C0 5B 1F C1 F4 04 CB E6 E0 32 71 03 3C… 0,,7806,0:45.917.412,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,7807,0:45.932.417,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 F9 BD 4F 43 B0 27 3C 73 34 7C D6 2F EB 7D 98… 0,,7811,0:45.933.414,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,7812,0:45.947.419,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7816,0:45.948.416,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,7817,0:45.948.420,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 F9 BD 4F 43 B0 27 3C 73 34 7C D6 2F EB 7D 98… 0,,7821,0:45.949.416,15.004.916 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,7822,0:45.964.422,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D 7C B3 74 CA 7B D5 AF 56 FE 1E F4 B0 52 2E 28… 0,,7826,0:45.965.419,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,7827,0:45.979.424,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7831,0:45.980.421,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,7832,0:45.980.424,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D 7C B3 74 CA 7B D5 AF 56 FE 1E F4 B0 52 2E 28… 0,,7836,0:45.981.421,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,7837,0:45.996.426,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 0B 86 24 1D C3 98 A5 F1 0A B0 3F 3F 24 F6 42… 0,,7841,0:45.997.423,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,7842,0:46.011.428,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7846,0:46.012.425,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,7847,0:46.012.428,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 0B 86 24 1D C3 98 A5 F1 0A B0 3F 3F 24 F6 42… 0,,7851,0:46.013.425,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,7852,0:46.028.431,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 70 5F 2E FB 4F 5D F0 59 16 D7 2B 74 A0 8E 18 C7… 0,,7856,0:46.029.428,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,7857,0:46.043.433,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7861,0:46.044.430,2.833 us,,,,,[1 SOF],[Frame: 929] 0,,7862,0:46.044.433,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 70 5F 2E FB 4F 5D F0 59 16 D7 2B 74 A0 8E 18 C7… 0,,7866,0:46.045.430,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,7867,0:46.060.435,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 55 65 B4 53 20 6A 4B 58 43 C7 3D B5 BD 67 A4 C2… 0,,7871,0:46.061.432,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,7872,0:46.075.437,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7876,0:46.076.434,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,7877,0:46.076.437,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 55 65 B4 53 20 6A 4B 58 43 C7 3D B5 BD 67 A4 C2… 0,,7881,0:46.077.434,15.004.916 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,7882,0:46.092.440,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF 5B 3F 84 E5 71 F4 3F 09 5D 73 A8 4D 05 B8 A9… 0,,7886,0:46.093.436,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,7887,0:46.107.442,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7891,0:46.108.439,16.005.125 ms,,,,,[17 SOF],[Frames: 993 - 1009] 0,,7892,0:46.124.444,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 B3 72 1E BB 53 71 7E 6F D4 71 59 78 26 B6 0B… 0,,7896,0:46.125.441,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,7897,0:46.139.446,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7901,0:46.140.443,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,7902,0:46.140.446,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 26 B3 72 1E BB 53 71 7E 6F D4 71 59 78 26 B6 0B… 0,,7906,0:46.141.443,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,7907,0:46.156.448,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA 72 B8 05 01 19 0D 06 8A C7 19 AC 71 96 4B 73… 0,,7911,0:46.157.445,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,7912,0:46.171.451,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7916,0:46.172.447,2.833 us,,,,,[1 SOF],[Frame: 1057] 0,,7917,0:46.172.451,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA 72 B8 05 01 19 0D 06 8A C7 19 AC 71 96 4B 73… 0,,7921,0:46.173.448,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,7922,0:46.188.453,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 11 64 D6 22 CC C9 A5 C3 D1 BC 4B E6 5C 98 5C… 0,,7926,0:46.189.450,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,7927,0:46.203.455,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7931,0:46.204.452,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,7932,0:46.204.455,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 11 64 D6 22 CC C9 A5 C3 D1 BC 4B E6 5C 98 5C… 0,,7936,0:46.205.452,15.004.916 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,7937,0:46.220.457,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 68 F5 49 23 40 53 70 06 AC A8 94 D6 B2 C0 F1… 0,,7941,0:46.221.454,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,7942,0:46.235.459,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7946,0:46.236.456,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,7947,0:46.236.460,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 68 F5 49 23 40 53 70 06 AC A8 94 D6 B2 C0 F1… 0,,7951,0:46.237.456,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,7952,0:46.252.462,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 99 A6 DC D8 41 49 E9 9D C1 CC 7B D6 71 26 0A… 0,,7956,0:46.253.459,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,7957,0:46.267.464,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7961,0:46.268.461,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,7962,0:46.268.464,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 99 A6 DC D8 41 49 E9 9D C1 CC 7B D6 71 26 0A… 0,,7966,0:46.269.461,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,7967,0:46.284.466,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 38 5F 46 0B C9 6D 42 83 55 4B 1F 73 DD 77 10… 0,,7971,0:46.285.463,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,7972,0:46.299.468,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7976,0:46.300.465,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,7977,0:46.300.468,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 38 5F 46 0B C9 6D 42 83 55 4B 1F 73 DD 77 10… 0,,7981,0:46.301.465,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,7982,0:46.316.471,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 F2 31 E0 98 84 F0 60 64 1F 01 46 69 8A 02 7B… 0,,7986,0:46.317.468,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,7987,0:46.331.473,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,7991,0:46.332.470,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,7992,0:46.332.473,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 F2 31 E0 98 84 F0 60 64 1F 01 46 69 8A 02 7B… 0,,7996,0:46.333.470,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,7997,0:46.348.475,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 12 B0 16 76 6A 8D B2 84 7C A9 AA 7B 0D 1F 16… 0,,8001,0:46.349.472,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,8002,0:46.363.477,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8006,0:46.364.474,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,8007,0:46.364.477,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 12 B0 16 76 6A 8D B2 84 7C A9 AA 7B 0D 1F 16… 0,,8011,0:46.365.474,15.004.916 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,8012,0:46.380.480,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 35 DA B9 EE A7 35 33 89 C2 2E 05 79 ED C1 68 71… 0,,8016,0:46.381.476,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,8017,0:46.395.482,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8021,0:46.396.479,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,8022,0:46.396.482,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 35 DA B9 EE A7 35 33 89 C2 2E 05 79 ED C1 68 71… 0,,8026,0:46.397.479,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,8027,0:46.412.484,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 43 F1 85 CE 65 12 12 DB 24 DF 87 6D 96 5A 85 0D… 0,,8031,0:46.413.481,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,8032,0:46.427.486,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8036,0:46.428.483,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,8037,0:46.428.486,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 43 F1 85 CE 65 12 12 DB 24 DF 87 6D 96 5A 85 0D… 0,,8041,0:46.429.483,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,8042,0:46.444.488,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 E8 71 6E 0A E9 73 3C A7 2A CB A1 91 4B 85 D0… 0,,8046,0:46.445.485,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,8047,0:46.459.491,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8051,0:46.460.487,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,8052,0:46.460.491,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 E8 71 6E 0A E9 73 3C A7 2A CB A1 91 4B 85 D0… 0,,8056,0:46.461.488,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,8057,0:46.476.493,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 4C 2E 19 7A 24 68 64 85 6E F2 BD FB EA 01 88… 0,,8061,0:46.477.490,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,8062,0:46.491.495,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8066,0:46.492.492,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,8067,0:46.492.495,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 4C 2E 19 7A 24 68 64 85 6E F2 BD FB EA 01 88… 0,,8071,0:46.493.492,15.004.916 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,8072,0:46.508.497,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 24 0B A0 98 46 88 ED 7A BE 06 64 F4 D2 33 AF 8D… 0,,8076,0:46.509.494,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,8077,0:46.523.499,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8081,0:46.524.496,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,8082,0:46.524.500,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 24 0B A0 98 46 88 ED 7A BE 06 64 F4 D2 33 AF 8D… 0,,8086,0:46.525.496,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,8087,0:46.540.502,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E8 89 78 69 EA 7A DF 0B 35 55 93 AD E4 57 99 22… 0,,8091,0:46.541.499,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,8092,0:46.555.504,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8096,0:46.556.501,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,8097,0:46.556.504,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E8 89 78 69 EA 7A DF 0B 35 55 93 AD E4 57 99 22… 0,,8101,0:46.557.501,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,8102,0:46.572.506,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 E1 E7 BD 55 7C 91 9A 6B A3 4F 3A E9 26 CD DA… 0,,8106,0:46.573.503,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,8107,0:46.587.508,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8111,0:46.588.505,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,8112,0:46.588.508,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 26 E1 E7 BD 55 7C 91 9A 6B A3 4F 3A E9 26 CD DA… 0,,8116,0:46.589.505,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,8117,0:46.604.511,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C 93 CE 2E 1E DE 6B 33 9B E4 1E AA 37 33 66 CB… 0,,8121,0:46.605.508,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,8122,0:46.619.513,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8126,0:46.620.510,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,8127,0:46.620.513,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C 93 CE 2E 1E DE 6B 33 9B E4 1E AA 37 33 66 CB… 0,,8131,0:46.621.510,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,8132,0:46.636.515,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF D6 B0 97 45 2B EC 68 97 9F FF 14 5A 30 8E FA… 0,,8136,0:46.637.512,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,8137,0:46.651.517,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8141,0:46.652.514,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,8142,0:46.652.517,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BF D6 B0 97 45 2B EC 68 97 9F FF 14 5A 30 8E FA… 0,,8146,0:46.653.514,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,8147,0:46.668.520,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 FC E1 28 8A B1 14 0F F8 9C D0 B5 9B 66 0A DB… 0,,8151,0:46.669.516,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,8152,0:46.683.522,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8156,0:46.684.519,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,8157,0:46.684.522,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 FC E1 28 8A B1 14 0F F8 9C D0 B5 9B 66 0A DB… 0,,8161,0:46.685.519,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,8162,0:46.700.524,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 AA CE 3A 61 9D C4 77 7F F9 97 18 66 54 82 E5… 0,,8166,0:46.701.521,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,8167,0:46.715.526,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8171,0:46.716.523,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,8172,0:46.716.526,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 AA CE 3A 61 9D C4 77 7F F9 97 18 66 54 82 E5… 0,,8176,0:46.717.523,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,8177,0:46.732.528,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 63 0F 3D 61 9A 3F DA 21 FB F3 34 3D 7D 91 56… 0,,8181,0:46.733.525,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,8182,0:46.747.531,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8186,0:46.748.527,16.005.041 ms,,,,,[17 SOF],[Frames: 1633 - 1649] 0,,8187,0:46.764.533,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0E 9F C4 ED B3 DA B9 A8 69 A1 D7 27 C5 D9 94 5B… 0,,8191,0:46.765.530,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,8192,0:46.779.535,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8196,0:46.780.532,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,8197,0:46.780.535,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0E 9F C4 ED B3 DA B9 A8 69 A1 D7 27 C5 D9 94 5B… 0,,8201,0:46.781.532,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,8202,0:46.796.537,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 C1 0E 01 EE 30 F1 13 66 7E 3C 68 60 27 86 B4… 0,,8206,0:46.797.534,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,8207,0:46.811.539,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8211,0:46.812.536,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,8212,0:46.812.540,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 C1 0E 01 EE 30 F1 13 66 7E 3C 68 60 27 86 B4… 0,,8216,0:46.813.536,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,8217,0:46.828.542,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A E7 BB E2 0B A2 D3 B0 23 67 68 F5 1D 9D 00 7D… 0,,8221,0:46.829.539,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,8222,0:46.843.544,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8226,0:46.844.541,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,8227,0:46.844.544,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A E7 BB E2 0B A2 D3 B0 23 67 68 F5 1D 9D 00 7D… 0,,8231,0:46.845.541,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,8232,0:46.860.546,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD F8 CC C1 4C 1F D5 A2 C4 E5 CA 09 85 79 28 F5… 0,,8236,0:46.861.543,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,8237,0:46.875.548,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8241,0:46.876.545,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,8242,0:46.876.549,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD F8 CC C1 4C 1F D5 A2 C4 E5 CA 09 85 79 28 F5… 0,,8246,0:46.877.545,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,8247,0:46.892.551,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 94 18 48 BE A4 7D 88 B4 D7 08 E4 F7 96 B0 1B… 0,,8251,0:46.893.548,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,8252,0:46.907.553,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8256,0:46.908.550,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,8257,0:46.908.553,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A 94 18 48 BE A4 7D 88 B4 D7 08 E4 F7 96 B0 1B… 0,,8261,0:46.909.550,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,8262,0:46.924.555,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C B2 D2 74 49 87 14 24 FD E3 90 C3 03 E1 1C 2A… 0,,8266,0:46.925.552,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,8267,0:46.939.557,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8271,0:46.940.554,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,8272,0:46.940.557,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C B2 D2 74 49 87 14 24 FD E3 90 C3 03 E1 1C 2A… 0,,8276,0:46.941.554,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,8277,0:46.956.560,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 47 97 9D 5C F6 3D 52 7C 15 94 D2 B7 D2 0F 3F 3A… 0,,8281,0:46.957.556,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,8282,0:46.971.562,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8286,0:46.972.559,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,8287,0:46.972.562,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 47 97 9D 5C F6 3D 52 7C 15 94 D2 B7 D2 0F 3F 3A… 0,,8291,0:46.973.559,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,8292,0:46.988.564,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 2A 2A FC 14 DB A2 71 C6 94 EC 58 B9 B9 45 89… 0,,8296,0:46.989.561,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,8297,0:47.003.566,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8301,0:47.004.563,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,8302,0:47.004.566,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 2A 2A FC 14 DB A2 71 C6 94 EC 58 B9 B9 45 89… 0,,8306,0:47.005.563,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,8307,0:47.020.568,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E9 DD E0 93 40 94 A5 5E 7C 20 03 21 4F D8 E2 B7… 0,,8311,0:47.021.565,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,8312,0:47.035.571,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8316,0:47.036.567,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,8317,0:47.036.571,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E9 DD E0 93 40 94 A5 5E 7C 20 03 21 4F D8 E2 B7… 0,,8321,0:47.037.568,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,8322,0:47.052.573,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 49 9A CC 62 68 79 81 19 93 D0 E2 A7 7A 24 59… 0,,8326,0:47.053.570,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,8327,0:47.067.575,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8331,0:47.068.572,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,8332,0:47.068.575,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 49 9A CC 62 68 79 81 19 93 D0 E2 A7 7A 24 59… 0,,8336,0:47.069.572,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,8337,0:47.084.577,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 8D 5A FA 40 A2 B7 6B 07 62 5A FD 20 F9 3F 5B… 0,,8341,0:47.085.574,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,8342,0:47.099.579,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8346,0:47.100.576,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,8347,0:47.100.580,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 8D 5A FA 40 A2 B7 6B 07 62 5A FD 20 F9 3F 5B… 0,,8351,0:47.101.576,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,8352,0:47.116.582,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F7 51 8E 04 26 EC 1B 99 35 68 3D 00 A0 08 5A 06… 0,,8356,0:47.117.579,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,8357,0:47.131.584,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8361,0:47.132.581,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,8362,0:47.132.584,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F7 51 8E 04 26 EC 1B 99 35 68 3D 00 A0 08 5A 06… 0,,8366,0:47.133.581,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,8367,0:47.148.586,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF 5A D0 95 29 B0 25 11 FA 18 8A B8 60 83 BE CE… 0,,8371,0:47.149.583,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,8372,0:47.163.588,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8376,0:47.164.585,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,8377,0:47.164.588,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF 5A D0 95 29 B0 25 11 FA 18 8A B8 60 83 BE CE… 0,,8381,0:47.165.585,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,8382,0:47.180.591,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 7F 12 E3 AC DA C6 B6 DC E0 BC 1C 0C 0A 24 C6… 0,,8386,0:47.181.588,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,8387,0:47.195.593,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8391,0:47.196.590,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,8392,0:47.196.593,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 7F 12 E3 AC DA C6 B6 DC E0 BC 1C 0C 0A 24 C6… 0,,8396,0:47.197.590,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,8397,0:47.212.595,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 88 3D 74 FD 72 B4 18 FC 9A 9A DC 43 93 14 3D… 0,,8401,0:47.213.592,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,8402,0:47.227.597,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8406,0:47.228.594,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,8407,0:47.228.597,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 88 3D 74 FD 72 B4 18 FC 9A 9A DC 43 93 14 3D… 0,,8411,0:47.229.594,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,8412,0:47.244.600,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 77 09 C3 AD 4C FF E5 3F 58 F1 18 C3 61 B7 B2 89… 0,,8416,0:47.245.596,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,8417,0:47.259.602,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8421,0:47.260.598,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,8422,0:47.260.602,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 77 09 C3 AD 4C FF E5 3F 58 F1 18 C3 61 B7 B2 89… 0,,8426,0:47.261.599,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,8427,0:47.276.604,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 35 83 90 7D B3 CB 1E 04 AC CE 0B 1B F5 4D EC… 0,,8431,0:47.277.601,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,8432,0:47.291.606,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8436,0:47.292.603,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,8437,0:47.292.606,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 35 83 90 7D B3 CB 1E 04 AC CE 0B 1B F5 4D EC… 0,,8441,0:47.293.603,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,8442,0:47.308.608,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 8F 29 77 FC 78 16 E3 DA 36 B0 8E CE 35 96 BE… 0,,8446,0:47.309.605,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,8447,0:47.323.610,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8451,0:47.324.607,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,8452,0:47.324.611,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 8F 29 77 FC 78 16 E3 DA 36 B0 8E CE 35 96 BE… 0,,8456,0:47.325.608,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,8457,0:47.340.613,50.729 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 9D F2 B1 F2 BE EE 6F 6A 08 6E 8F FF A0 BD 97… 0,,8461,0:47.341.610,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,8462,0:47.355.615,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8466,0:47.356.612,16.005.041 ms,,,,,[17 SOF],[Frames: 193 - 209] 0,,8467,0:47.372.617,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE 31 B4 72 9C 8A 35 A9 B1 75 CB D6 41 39 A9 FF… 0,,8471,0:47.373.614,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,8472,0:47.387.619,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8476,0:47.388.616,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,8477,0:47.388.620,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE 31 B4 72 9C 8A 35 A9 B1 75 CB D6 41 39 A9 FF… 0,,8481,0:47.389.616,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,8482,0:47.404.622,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 52 33 9F F5 CE 4F 38 49 D6 1D 37 9D C9 C7 78… 0,,8486,0:47.405.619,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,8487,0:47.419.624,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8491,0:47.420.621,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,8492,0:47.420.624,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 52 33 9F F5 CE 4F 38 49 D6 1D 37 9D C9 C7 78… 0,,8496,0:47.421.621,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,8497,0:47.436.626,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF FF 17 80 BE CB EE 5A D2 F9 5D 2C 69 9B 62 8D… 0,,8501,0:47.437.623,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,8502,0:47.451.628,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8506,0:47.452.625,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,8507,0:47.452.628,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF FF 17 80 BE CB EE 5A D2 F9 5D 2C 69 9B 62 8D… 0,,8511,0:47.453.625,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,8512,0:47.468.631,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 69 21 7D 17 0B DB 64 6D 9F 8F 15 64 B0 DB DF F8… 0,,8516,0:47.469.628,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,8517,0:47.483.633,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8521,0:47.484.630,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,8522,0:47.484.633,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 69 21 7D 17 0B DB 64 6D 9F 8F 15 64 B0 DB DF F8… 0,,8526,0:47.485.630,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,8527,0:47.500.635,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 01 CA AD B2 2B 69 F7 DB 6F 8C 5D 37 1E 91 03… 0,,8531,0:47.501.632,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,8532,0:47.515.637,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8536,0:47.516.634,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,8537,0:47.516.637,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 01 CA AD B2 2B 69 F7 DB 6F 8C 5D 37 1E 91 03… 0,,8541,0:47.517.634,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,8542,0:47.532.640,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 61 EE 17 92 3B 75 3F A9 2B 24 D3 57 EC 2A 81… 0,,8546,0:47.533.636,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,8547,0:47.547.642,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8551,0:47.548.638,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,8552,0:47.548.642,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 61 EE 17 92 3B 75 3F A9 2B 24 D3 57 EC 2A 81… 0,,8556,0:47.549.639,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,8557,0:47.564.644,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 3F 23 A5 E4 F9 63 23 8B D7 04 74 DB 89 57 D2… 0,,8561,0:47.565.641,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,8562,0:47.579.646,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8566,0:47.580.643,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,8567,0:47.580.646,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 3F 23 A5 E4 F9 63 23 8B D7 04 74 DB 89 57 D2… 0,,8571,0:47.581.643,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,8572,0:47.596.648,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A2 AA 08 EB 97 3F 8C 0A 19 F7 C2 42 41 1D 8A CC… 0,,8576,0:47.597.645,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,8577,0:47.611.650,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8581,0:47.612.647,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,8582,0:47.612.651,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A2 AA 08 EB 97 3F 8C 0A 19 F7 C2 42 41 1D 8A CC… 0,,8586,0:47.613.648,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,8587,0:47.628.653,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 09 8F AA 95 0A D1 53 7F 1E 60 15 CB 08 77 1E… 0,,8591,0:47.629.650,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,8592,0:47.643.655,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8596,0:47.644.652,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,8597,0:47.644.655,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 09 8F AA 95 0A D1 53 7F 1E 60 15 CB 08 77 1E… 0,,8601,0:47.645.652,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,8602,0:47.660.657,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3B 87 99 60 31 AA C5 A2 09 9C 61 36 04 62 71 0C… 0,,8606,0:47.661.654,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,8607,0:47.675.659,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8611,0:47.676.656,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,8612,0:47.676.660,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3B 87 99 60 31 AA C5 A2 09 9C 61 36 04 62 71 0C… 0,,8616,0:47.677.656,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,8617,0:47.692.662,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 DF 22 64 35 AB 09 45 8B 0D 84 1F E8 FF E6 15… 0,,8621,0:47.693.659,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,8622,0:47.707.664,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8626,0:47.708.661,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,8627,0:47.708.664,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 DF 22 64 35 AB 09 45 8B 0D 84 1F E8 FF E6 15… 0,,8631,0:47.709.661,15.004.916 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,8632,0:47.724.666,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 2C B3 55 23 D8 48 C3 05 E5 8C 59 69 E3 0F 47… 0,,8636,0:47.725.663,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,8637,0:47.739.668,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8641,0:47.740.665,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,8642,0:47.740.668,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 2C B3 55 23 D8 48 C3 05 E5 8C 59 69 E3 0F 47… 0,,8646,0:47.741.665,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,8647,0:47.756.671,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E F9 DA D2 70 DB 75 FD 63 B6 41 33 B1 68 CD AD… 0,,8651,0:47.757.667,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,8652,0:47.771.673,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8656,0:47.772.670,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,8657,0:47.772.673,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E F9 DA D2 70 DB 75 FD 63 B6 41 33 B1 68 CD AD… 0,,8661,0:47.773.670,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,8662,0:47.788.675,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 E8 2D 36 CA 38 AF 7A 8F 2C 03 6D C0 0C 10 7A… 0,,8666,0:47.789.672,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,8667,0:47.803.677,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8671,0:47.804.674,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,8672,0:47.804.677,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 E8 2D 36 CA 38 AF 7A 8F 2C 03 6D C0 0C 10 7A… 0,,8676,0:47.805.674,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,8677,0:47.820.679,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 58 93 0C D0 37 BA 15 57 13 DD BA 43 1F 05 35… 0,,8681,0:47.821.676,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,8682,0:47.835.682,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8686,0:47.836.678,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,8687,0:47.836.682,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 58 93 0C D0 37 BA 15 57 13 DD BA 43 1F 05 35… 0,,8691,0:47.837.679,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,8692,0:47.852.684,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 55 48 12 E3 14 49 CD 83 C0 74 30 39 8E 23 87… 0,,8696,0:47.853.681,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,8697,0:47.867.686,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8701,0:47.868.683,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,8702,0:47.868.686,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 55 48 12 E3 14 49 CD 83 C0 74 30 39 8E 23 87… 0,,8706,0:47.869.683,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,8707,0:47.884.688,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 7D BF 04 A6 FC C2 A8 1B 50 D7 CA D9 31 EB 17… 0,,8711,0:47.885.685,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,8712,0:47.899.690,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8716,0:47.900.687,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,8717,0:47.900.691,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 7D BF 04 A6 FC C2 A8 1B 50 D7 CA D9 31 EB 17… 0,,8721,0:47.901.687,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,8722,0:47.916.693,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 E3 DC DA D7 4F 8F 29 AE 25 53 6F 36 48 0E 11… 0,,8726,0:47.917.690,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,8727,0:47.931.695,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8731,0:47.932.692,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,8732,0:47.932.695,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 E3 DC DA D7 4F 8F 29 AE 25 53 6F 36 48 0E 11… 0,,8736,0:47.933.692,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,8737,0:47.948.697,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 20 58 1F 4F 72 71 2C 9E D3 A1 81 96 C3 94 5C 63… 0,,8741,0:47.949.694,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,8742,0:47.963.699,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8746,0:47.964.696,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,8747,0:47.964.699,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 20 58 1F 4F 72 71 2C 9E D3 A1 81 96 C3 94 5C 63… 0,,8751,0:47.965.696,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,8752,0:47.980.702,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 1E 5F F8 0C BF 01 71 9E 15 3F DC D7 BF D4 A5… 0,,8756,0:47.981.699,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,8757,0:47.995.704,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8761,0:47.996.701,16.005.041 ms,,,,,[17 SOF],[Frames: 833 - 849] 0,,8762,0:48.012.706,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3A 7B 83 81 70 B4 73 4D C9 30 6C 06 50 B2 89 68… 0,,8766,0:48.013.703,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,8767,0:48.027.708,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8771,0:48.028.705,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,8772,0:48.028.708,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3A 7B 83 81 70 B4 73 4D C9 30 6C 06 50 B2 89 68… 0,,8776,0:48.029.705,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,8777,0:48.044.711,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B B5 75 EE 4B 2B 7B 00 77 46 34 E0 8F 1A CB 9D… 0,,8781,0:48.045.707,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,8782,0:48.059.713,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8786,0:48.060.710,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,8787,0:48.060.713,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B B5 75 EE 4B 2B 7B 00 77 46 34 E0 8F 1A CB 9D… 0,,8791,0:48.061.710,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,8792,0:48.076.715,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 F2 C1 D6 65 4C 6C EA 60 37 48 5C 04 E8 56 7C… 0,,8796,0:48.077.712,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,8797,0:48.091.717,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8801,0:48.092.714,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,8802,0:48.092.717,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 F2 C1 D6 65 4C 6C EA 60 37 48 5C 04 E8 56 7C… 0,,8806,0:48.093.714,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,8807,0:48.108.719,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD CB 7E 16 B5 5B 61 D3 97 A7 5E 34 5B F7 ED 5B… 0,,8811,0:48.109.716,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,8812,0:48.123.722,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8816,0:48.124.718,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,8817,0:48.124.722,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD CB 7E 16 B5 5B 61 D3 97 A7 5E 34 5B F7 ED 5B… 0,,8821,0:48.125.719,15.004.916 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,8822,0:48.140.724,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 05 BF 21 49 13 48 CE 3A BF 85 5A BC 4F AA 73… 0,,8826,0:48.141.721,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,8827,0:48.155.726,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8831,0:48.156.723,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,8832,0:48.156.726,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 05 BF 21 49 13 48 CE 3A BF 85 5A BC 4F AA 73… 0,,8836,0:48.157.723,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,8837,0:48.172.728,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 E6 30 C4 8B BD C1 38 0D E2 AA 8B D8 35 BF A8… 0,,8841,0:48.173.725,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,8842,0:48.187.730,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8846,0:48.188.727,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,8847,0:48.188.731,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 E6 30 C4 8B BD C1 38 0D E2 AA 8B D8 35 BF A8… 0,,8851,0:48.189.727,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,8852,0:48.204.733,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 C5 BB 19 2C 22 7F 75 35 AD 95 A0 F6 B3 6D FB… 0,,8856,0:48.205.730,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,8857,0:48.219.735,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8861,0:48.220.732,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,8862,0:48.220.735,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 C5 BB 19 2C 22 7F 75 35 AD 95 A0 F6 B3 6D FB… 0,,8866,0:48.221.732,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,8867,0:48.236.737,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 4A 8B 35 AA 97 10 02 44 1D DD A1 82 13 2A 1B… 0,,8871,0:48.237.734,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,8872,0:48.251.739,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8876,0:48.252.736,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,8877,0:48.252.739,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 4A 8B 35 AA 97 10 02 44 1D DD A1 82 13 2A 1B… 0,,8881,0:48.253.736,15.004.916 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,8882,0:48.268.742,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C0 8D 3D 65 86 7E F3 B5 80 C9 CE 5B 30 E5 9B F9… 0,,8886,0:48.269.739,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,8887,0:48.283.744,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8891,0:48.284.741,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,8892,0:48.284.744,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C0 8D 3D 65 86 7E F3 B5 80 C9 CE 5B 30 E5 9B F9… 0,,8896,0:48.285.741,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,8897,0:48.300.746,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 03 AD DC 3C F2 60 8F FE DB 83 19 70 2A 9B A5 53… 0,,8901,0:48.301.743,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,8902,0:48.315.748,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8906,0:48.316.745,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,8907,0:48.316.748,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 03 AD DC 3C F2 60 8F FE DB 83 19 70 2A 9B A5 53… 0,,8911,0:48.317.745,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,8912,0:48.332.751,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3B 4E 92 82 49 A6 8F 1A 69 CE 82 07 5A 99 B1 9D… 0,,8916,0:48.333.747,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,8917,0:48.347.753,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8921,0:48.348.750,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,8922,0:48.348.753,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3B 4E 92 82 49 A6 8F 1A 69 CE 82 07 5A 99 B1 9D… 0,,8926,0:48.349.750,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,8927,0:48.364.755,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 C1 A1 61 56 11 59 7B 49 E4 20 63 E1 F9 1E B7… 0,,8931,0:48.365.752,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,8932,0:48.379.757,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8936,0:48.380.754,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,8937,0:48.380.757,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 C1 A1 61 56 11 59 7B 49 E4 20 63 E1 F9 1E B7… 0,,8941,0:48.381.754,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,8942,0:48.396.759,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 5E 4A 29 B7 68 21 49 02 62 B6 06 F0 71 49 7F… 0,,8946,0:48.397.756,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,8947,0:48.411.762,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8951,0:48.412.758,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,8952,0:48.412.762,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 5E 4A 29 B7 68 21 49 02 62 B6 06 F0 71 49 7F… 0,,8956,0:48.413.759,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,8957,0:48.428.764,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 55 20 CC F9 26 06 2B 8F 67 80 1B 3B A9 10 2F 79… 0,,8961,0:48.429.761,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,8962,0:48.443.766,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8966,0:48.444.763,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,8967,0:48.444.766,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 55 20 CC F9 26 06 2B 8F 67 80 1B 3B A9 10 2F 79… 0,,8971,0:48.445.763,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,8972,0:48.460.768,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A0 92 7F 03 52 A8 DA A1 5A AA 2D 30 E3 6E D7 18… 0,,8976,0:48.461.765,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,8977,0:48.475.770,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8981,0:48.476.767,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,8982,0:48.476.771,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A0 92 7F 03 52 A8 DA A1 5A AA 2D 30 E3 6E D7 18… 0,,8986,0:48.477.767,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,8987,0:48.492.773,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 DD 6D 63 98 60 58 54 B8 73 1D 3A A8 B6 FA A3… 0,,8991,0:48.493.770,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,8992,0:48.507.775,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,8996,0:48.508.772,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,8997,0:48.508.775,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 DD 6D 63 98 60 58 54 B8 73 1D 3A A8 B6 FA A3… 0,,9001,0:48.509.772,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,9002,0:48.524.777,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 D8 34 FF F3 85 D9 54 91 0F CE 86 F2 44 F0 63… 0,,9006,0:48.525.774,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,9007,0:48.539.779,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9011,0:48.540.776,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,9012,0:48.540.779,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 D8 34 FF F3 85 D9 54 91 0F CE 86 F2 44 F0 63… 0,,9016,0:48.541.776,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,9017,0:48.556.782,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 CB 27 8E 68 62 7B 06 41 BD CB 8C B8 31 73 6D… 0,,9021,0:48.557.779,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,9022,0:48.571.784,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9026,0:48.572.781,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,9027,0:48.572.784,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 CB 27 8E 68 62 7B 06 41 BD CB 8C B8 31 73 6D… 0,,9031,0:48.573.781,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,9032,0:48.588.786,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE C4 1F 84 D5 15 1F 44 76 9D 56 5E 5D DA 77 A4… 0,,9036,0:48.589.783,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,9037,0:48.603.788,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9041,0:48.604.785,16.005.041 ms,,,,,[17 SOF],[Frames: 1441 - 1457] 0,,9042,0:48.620.791,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D B1 E8 4F A2 1A 69 89 B8 3D 1F 90 E9 59 80 3E… 0,,9046,0:48.621.787,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,9047,0:48.635.793,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9051,0:48.636.790,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,9052,0:48.636.793,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D B1 E8 4F A2 1A 69 89 B8 3D 1F 90 E9 59 80 3E… 0,,9056,0:48.637.790,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,9057,0:48.652.795,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C3 32 DE 5F E4 40 1B CA 6B 6A 93 02 D6 7B 9F B9… 0,,9061,0:48.653.792,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,9062,0:48.667.797,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9066,0:48.668.794,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,9067,0:48.668.797,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C3 32 DE 5F E4 40 1B CA 6B 6A 93 02 D6 7B 9F B9… 0,,9071,0:48.669.794,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,9072,0:48.684.799,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4F FD 6F 0F 24 49 63 DB 08 C5 AC 77 EB 5E 19 C9… 0,,9076,0:48.685.796,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,9077,0:48.699.802,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9081,0:48.700.798,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,9082,0:48.700.802,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4F FD 6F 0F 24 49 63 DB 08 C5 AC 77 EB 5E 19 C9… 0,,9086,0:48.701.799,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,9087,0:48.716.804,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 17 5F D7 CF A7 46 D1 79 48 37 67 E4 42 A0 FF… 0,,9091,0:48.717.801,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,9092,0:48.731.806,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9096,0:48.732.803,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,9097,0:48.732.806,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 17 5F D7 CF A7 46 D1 79 48 37 67 E4 42 A0 FF… 0,,9101,0:48.733.803,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,9102,0:48.748.808,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3B DD B7 F0 CD A9 E9 C9 B6 10 85 F1 84 42 56 F7… 0,,9106,0:48.749.805,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,9107,0:48.763.810,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9111,0:48.764.807,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,9112,0:48.764.811,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3B DD B7 F0 CD A9 E9 C9 B6 10 85 F1 84 42 56 F7… 0,,9116,0:48.765.807,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,9117,0:48.780.813,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 1F 36 E2 77 C8 8B EF B6 BA 9E CC A8 FB D5 37… 0,,9121,0:48.781.810,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,9122,0:48.795.815,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9126,0:48.796.812,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,9127,0:48.796.815,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 1F 36 E2 77 C8 8B EF B6 BA 9E CC A8 FB D5 37… 0,,9131,0:48.797.812,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,9132,0:48.812.817,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 65 DB 99 9E 17 4E 46 06 3E E5 E6 76 CD DB F3 DB… 0,,9136,0:48.813.814,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,9137,0:48.827.819,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9141,0:48.828.816,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,9142,0:48.828.819,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 65 DB 99 9E 17 4E 46 06 3E E5 E6 76 CD DB F3 DB… 0,,9146,0:48.829.816,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,9147,0:48.844.822,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B EB 7B 76 20 69 8A D7 7E 51 F8 CA 84 7B 2E 91… 0,,9151,0:48.845.819,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,9152,0:48.859.824,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9156,0:48.860.821,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,9157,0:48.860.824,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B EB 7B 76 20 69 8A D7 7E 51 F8 CA 84 7B 2E 91… 0,,9161,0:48.861.821,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,9162,0:48.876.826,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D ED 8A B9 02 A8 DF 0C 44 B3 3E BD B2 90 15 04… 0,,9166,0:48.877.823,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,9167,0:48.891.828,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9171,0:48.892.825,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,9172,0:48.892.828,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D ED 8A B9 02 A8 DF 0C 44 B3 3E BD B2 90 15 04… 0,,9176,0:48.893.825,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,9177,0:48.908.831,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA E7 C6 DA 19 22 9A 03 BA 51 C8 05 3E 8B 1E E3… 0,,9181,0:48.909.827,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,9182,0:48.923.833,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9186,0:48.924.830,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,9187,0:48.924.833,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA E7 C6 DA 19 22 9A 03 BA 51 C8 05 3E 8B 1E E3… 0,,9191,0:48.925.830,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,9192,0:48.940.835,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D E4 0D C5 CE 4A C2 99 7F 0C A2 B8 5D 81 27 21… 0,,9196,0:48.941.832,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,9197,0:48.955.837,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9201,0:48.956.834,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,9202,0:48.956.837,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D E4 0D C5 CE 4A C2 99 7F 0C A2 B8 5D 81 27 21… 0,,9206,0:48.957.834,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,9207,0:48.972.839,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 13 6F 02 EB D6 6E B1 46 26 6A 76 E1 A7 46 3B… 0,,9211,0:48.973.836,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,9212,0:48.987.842,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9216,0:48.988.838,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,9217,0:48.988.842,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 13 6F 02 EB D6 6E B1 46 26 6A 76 E1 A7 46 3B… 0,,9221,0:48.989.839,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,9222,0:49.004.844,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 49 5A 42 60 C5 BC 1E A0 7F F5 CC F2 69 FF 85… 0,,9226,0:49.005.841,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,9227,0:49.019.846,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9231,0:49.020.843,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,9232,0:49.020.846,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 49 5A 42 60 C5 BC 1E A0 7F F5 CC F2 69 FF 85… 0,,9236,0:49.021.843,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,9237,0:49.036.848,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 5E 16 AE 21 C9 67 9C 3D 02 DE B4 39 EF 8A 7B… 0,,9241,0:49.037.845,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,9242,0:49.051.850,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9246,0:49.052.847,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,9247,0:49.052.851,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 5E 16 AE 21 C9 67 9C 3D 02 DE B4 39 EF 8A 7B… 0,,9251,0:49.053.847,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,9252,0:49.068.853,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 31 D6 F5 4A 05 44 5D C4 26 8A 50 45 B5 E7 46… 0,,9256,0:49.069.850,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,9257,0:49.083.855,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9261,0:49.084.852,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,9262,0:49.084.855,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 31 D6 F5 4A 05 44 5D C4 26 8A 50 45 B5 E7 46… 0,,9266,0:49.085.852,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,9267,0:49.100.857,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 52 8F 32 AB 23 2A 8A 3D 33 40 E3 03 2A 18 D0 CA… 0,,9271,0:49.101.854,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,9272,0:49.115.859,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9276,0:49.116.856,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,9277,0:49.116.859,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 52 8F 32 AB 23 2A 8A 3D 33 40 E3 03 2A 18 D0 CA… 0,,9281,0:49.117.856,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,9282,0:49.132.862,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 0B 52 4A 64 E0 B2 0F 3D CC 5C D0 9A 14 A6 03… 0,,9286,0:49.133.859,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,9287,0:49.147.864,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9291,0:49.148.861,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,9292,0:49.148.864,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 25 0B 52 4A 64 E0 B2 0F 3D CC 5C D0 9A 14 A6 03… 0,,9296,0:49.149.861,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,9297,0:49.164.866,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F9 DE A1 26 72 4E 14 69 C1 F3 C0 CE D6 6F D1 E9… 0,,9301,0:49.165.863,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,9302,0:49.179.868,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9306,0:49.180.865,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,9307,0:49.180.868,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F9 DE A1 26 72 4E 14 69 C1 F3 C0 CE D6 6F D1 E9… 0,,9311,0:49.181.865,15.005.000 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,9312,0:49.196.871,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 91 86 DF 44 17 5D 5A 37 1C 94 85 29 9F F8 01 B9… 0,,9316,0:49.197.867,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,9317,0:49.211.873,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9321,0:49.212.869,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,9322,0:49.212.873,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 91 86 DF 44 17 5D 5A 37 1C 94 85 29 9F F8 01 B9… 0,,9326,0:49.213.870,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,9327,0:49.228.875,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 B5 B9 44 A1 00 F9 B1 61 A7 C3 AD 02 3B 27 6F… 0,,9331,0:49.229.872,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,9332,0:49.243.877,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9336,0:49.244.874,16.005.041 ms,,,,,[17 SOF],[Frames: 33 - 49] 0,,9337,0:49.260.879,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3F 26 7C 8A F4 97 6F 4E FF 60 10 C7 32 83 59 4A… 0,,9341,0:49.261.876,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,9342,0:49.275.881,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9346,0:49.276.878,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,9347,0:49.276.882,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3F 26 7C 8A F4 97 6F 4E FF 60 10 C7 32 83 59 4A… 0,,9351,0:49.277.879,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,9352,0:49.292.884,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA 4B DE E4 9D 23 40 79 E3 A9 26 B8 52 94 35 4A… 0,,9356,0:49.293.881,14.004.750 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,9357,0:49.307.886,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9361,0:49.308.883,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,9362,0:49.308.886,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA 4B DE E4 9D 23 40 79 E3 A9 26 B8 52 94 35 4A… 0,,9366,0:49.309.883,15.004.916 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,9367,0:49.324.888,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 C7 F8 32 88 53 F6 7B FE C7 25 6A 03 B1 0A A7… 0,,9371,0:49.325.885,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,9372,0:49.339.890,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9376,0:49.340.887,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,9377,0:49.340.891,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 C7 F8 32 88 53 F6 7B FE C7 25 6A 03 B1 0A A7… 0,,9381,0:49.341.887,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,9382,0:49.356.893,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D 9F BE 0D AE 40 64 05 20 CD 2A 20 26 E1 54 F2… 0,,9386,0:49.357.890,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,9387,0:49.371.895,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9391,0:49.372.892,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,9392,0:49.372.895,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D 9F BE 0D AE 40 64 05 20 CD 2A 20 26 E1 54 F2… 0,,9396,0:49.373.892,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,9397,0:49.388.897,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 77 2F 26 47 C7 EE 79 C7 E6 67 26 03 88 FF F4 AC… 0,,9401,0:49.389.894,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,9402,0:49.403.899,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9406,0:49.404.896,2.833 us,,,,,[1 SOF],[Frame: 193] 0,,9407,0:49.404.899,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 77 2F 26 47 C7 EE 79 C7 E6 67 26 03 88 FF F4 AC… 0,,9411,0:49.405.896,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,9412,0:49.420.902,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B A4 87 D0 BD 0C 92 F9 A8 0D 48 14 64 08 BE 68… 0,,9416,0:49.421.899,14.004.750 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,9417,0:49.435.904,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9421,0:49.436.901,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,9422,0:49.436.904,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0B A4 87 D0 BD 0C 92 F9 A8 0D 48 14 64 08 BE 68… 0,,9426,0:49.437.901,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,9427,0:49.452.906,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D F2 D5 85 8B 73 E4 AB 34 C7 00 13 5B 62 7B AB… 0,,9431,0:49.453.903,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,9432,0:49.467.908,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9436,0:49.468.905,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,9437,0:49.468.908,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D F2 D5 85 8B 73 E4 AB 34 C7 00 13 5B 62 7B AB… 0,,9441,0:49.469.905,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,9442,0:49.484.910,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 ED 20 C7 6B 9B 96 AB C1 2C 1F 0E CF 99 E8 A0 8E… 0,,9446,0:49.485.907,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,9447,0:49.499.913,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9451,0:49.500.909,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,9452,0:49.500.913,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 ED 20 C7 6B 9B 96 AB C1 2C 1F 0E CF 99 E8 A0 8E… 0,,9456,0:49.501.910,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,9457,0:49.516.915,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 21 97 76 0F 80 04 25 15 91 80 8F A1 C7 C8 AE 8B… 0,,9461,0:49.517.912,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,9462,0:49.531.917,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9466,0:49.532.914,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,9467,0:49.532.917,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 21 97 76 0F 80 04 25 15 91 80 8F A1 C7 C8 AE 8B… 0,,9471,0:49.533.914,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,9472,0:49.548.919,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 7F E1 6A 03 E8 49 9E E2 90 FB B3 F2 98 49 37… 0,,9476,0:49.549.916,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,9477,0:49.563.921,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9481,0:49.564.918,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,9482,0:49.564.922,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 7F E1 6A 03 E8 49 9E E2 90 FB B3 F2 98 49 37… 0,,9486,0:49.565.918,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,9487,0:49.580.924,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 FE B0 71 3B 46 86 ED 26 2C D7 07 49 5A 8B 6F… 0,,9491,0:49.581.921,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,9492,0:49.595.926,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9496,0:49.596.923,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,9497,0:49.596.926,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 FE B0 71 3B 46 86 ED 26 2C D7 07 49 5A 8B 6F… 0,,9501,0:49.597.923,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,9502,0:49.612.928,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A B4 A2 BC 34 AA 17 F5 41 F1 77 64 92 75 D2 A7… 0,,9506,0:49.613.925,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,9507,0:49.627.930,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9511,0:49.628.927,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,9512,0:49.628.930,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A B4 A2 BC 34 AA 17 F5 41 F1 77 64 92 75 D2 A7… 0,,9516,0:49.629.927,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,9517,0:49.644.933,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A F2 7F 10 65 7B 31 E1 74 00 A2 AE B5 8B 4F F9… 0,,9521,0:49.645.930,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,9522,0:49.659.935,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9526,0:49.660.932,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,9527,0:49.660.935,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A F2 7F 10 65 7B 31 E1 74 00 A2 AE B5 8B 4F F9… 0,,9531,0:49.661.932,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,9532,0:49.676.937,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6B DC 37 4D 74 4C 3E 40 F0 7E 70 5B 63 EB 70 A0… 0,,9536,0:49.677.934,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,9537,0:49.691.939,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9541,0:49.692.936,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,9542,0:49.692.939,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6B DC 37 4D 74 4C 3E 40 F0 7E 70 5B 63 EB 70 A0… 0,,9546,0:49.693.936,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,9547,0:49.708.942,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 34 F2 B2 47 0A 9A 67 A5 4B 4C 95 ED 4E 8D 0B… 0,,9551,0:49.709.938,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,9552,0:49.723.944,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9556,0:49.724.941,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,9557,0:49.724.944,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC 34 F2 B2 47 0A 9A 67 A5 4B 4C 95 ED 4E 8D 0B… 0,,9561,0:49.725.941,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,9562,0:49.740.946,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B2 28 E2 E5 68 86 B7 7E 2D 16 3F E6 34 EB 01 2A… 0,,9566,0:49.741.943,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,9567,0:49.755.948,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9571,0:49.756.945,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,9572,0:49.756.948,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B2 28 E2 E5 68 86 B7 7E 2D 16 3F E6 34 EB 01 2A… 0,,9576,0:49.757.945,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,9577,0:49.772.950,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B DB 19 1E 00 5F 77 47 CC 68 3B 3B 2C 9F C2 70… 0,,9581,0:49.773.947,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,9582,0:49.787.953,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9586,0:49.788.949,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,9587,0:49.788.953,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B DB 19 1E 00 5F 77 47 CC 68 3B 3B 2C 9F C2 70… 0,,9591,0:49.789.950,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,9592,0:49.804.955,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E 88 54 DF A5 C7 35 01 8F CE 64 E2 1D 28 36 6E… 0,,9596,0:49.805.952,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,9597,0:49.819.957,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9601,0:49.820.954,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,9602,0:49.820.957,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E 88 54 DF A5 C7 35 01 8F CE 64 E2 1D 28 36 6E… 0,,9606,0:49.821.954,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,9607,0:49.836.959,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0E 77 25 8E 74 95 1A F7 92 21 89 93 56 F6 6A 99… 0,,9611,0:49.837.956,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,9612,0:49.851.961,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9616,0:49.852.958,16.005.041 ms,,,,,[17 SOF],[Frames: 641 - 657] 0,,9617,0:49.868.964,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 4C 51 C6 B9 A1 89 91 68 68 E7 0E C5 5F 7C 9D… 0,,9621,0:49.869.961,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,9622,0:49.883.966,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9626,0:49.884.963,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,9627,0:49.884.966,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 4C 51 C6 B9 A1 89 91 68 68 E7 0E C5 5F 7C 9D… 0,,9631,0:49.885.963,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,9632,0:49.900.968,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C 17 88 0C DE 3D 36 A9 24 35 0B 23 64 9F EF 54… 0,,9636,0:49.901.965,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,9637,0:49.915.970,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9641,0:49.916.967,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,9642,0:49.916.970,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C 17 88 0C DE 3D 36 A9 24 35 0B 23 64 9F EF 54… 0,,9646,0:49.917.967,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,9647,0:49.932.973,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF F3 1D F8 2A 49 CF EE DA ED 83 AD 82 6F 28 45… 0,,9651,0:49.933.970,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,9652,0:49.947.975,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9656,0:49.948.972,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,9657,0:49.948.975,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF F3 1D F8 2A 49 CF EE DA ED 83 AD 82 6F 28 45… 0,,9661,0:49.949.972,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,9662,0:49.964.977,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B 89 28 D5 73 5E 8E 40 7E 8B 0D 50 44 C0 F7 0A… 0,,9666,0:49.965.974,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,9667,0:49.979.979,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9671,0:49.980.976,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,9672,0:49.980.979,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0B 89 28 D5 73 5E 8E 40 7E 8B 0D 50 44 C0 F7 0A… 0,,9676,0:49.981.976,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,9677,0:49.996.982,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 07 9A 9E 17 74 84 6F E0 CD F8 F0 E5 4B F9 D8… 0,,9681,0:49.997.978,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,9682,0:50.011.984,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9686,0:50.012.981,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,9687,0:50.012.984,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 07 9A 9E 17 74 84 6F E0 CD F8 F0 E5 4B F9 D8… 0,,9691,0:50.013.981,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,9692,0:50.028.986,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 CA F5 B2 1D DF 0B 74 0A A2 0B 43 58 3B 98 4D… 0,,9696,0:50.029.983,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,9697,0:50.043.988,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9701,0:50.044.985,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,9702,0:50.044.988,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 CA F5 B2 1D DF 0B 74 0A A2 0B 43 58 3B 98 4D… 0,,9706,0:50.045.985,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,9707,0:50.060.990,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 9A D6 6A CC C5 E6 3F 26 25 0B 11 5C 04 15 19… 0,,9711,0:50.061.987,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,9712,0:50.075.993,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9716,0:50.076.989,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,9717,0:50.076.993,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 9A D6 6A CC C5 E6 3F 26 25 0B 11 5C 04 15 19… 0,,9721,0:50.077.990,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,9722,0:50.092.995,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3C D9 86 A2 C5 DD 30 6B 75 9F 61 22 62 89 2A DE… 0,,9726,0:50.093.992,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,9727,0:50.107.997,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9731,0:50.108.994,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,9732,0:50.108.997,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3C D9 86 A2 C5 DD 30 6B 75 9F 61 22 62 89 2A DE… 0,,9736,0:50.109.994,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,9737,0:50.124.999,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 12 0D 98 BA C4 8D F5 49 EF 49 97 BE 3A 97 25… 0,,9741,0:50.125.996,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,9742,0:50.140.001,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9746,0:50.140.998,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,9747,0:50.141.002,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 12 0D 98 BA C4 8D F5 49 EF 49 97 BE 3A 97 25… 0,,9751,0:50.141.998,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,9752,0:50.157.004,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9F 71 49 FB 29 02 65 C4 7B E6 F7 2E 40 6C 4D 35… 0,,9756,0:50.158.001,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,9757,0:50.172.006,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9761,0:50.173.003,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,9762,0:50.173.006,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9F 71 49 FB 29 02 65 C4 7B E6 F7 2E 40 6C 4D 35… 0,,9766,0:50.174.003,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,9767,0:50.189.008,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 C0 1A 13 50 3E B1 BC 13 55 18 09 54 7A 9B B5… 0,,9771,0:50.190.005,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,9772,0:50.204.010,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9776,0:50.205.007,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,9777,0:50.205.010,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 C0 1A 13 50 3E B1 BC 13 55 18 09 54 7A 9B B5… 0,,9781,0:50.206.007,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,9782,0:50.221.013,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 3B 85 9C 3C 02 CC 6E 9B 85 37 F0 FE CD 65 D1… 0,,9786,0:50.222.010,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,9787,0:50.236.015,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9791,0:50.237.012,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,9792,0:50.237.015,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 3B 85 9C 3C 02 CC 6E 9B 85 37 F0 FE CD 65 D1… 0,,9796,0:50.238.012,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,9797,0:50.253.017,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B 4F AB 80 6E E0 CA EC B2 A7 74 6C 64 64 5F 75… 0,,9801,0:50.254.014,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,9802,0:50.268.019,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9806,0:50.269.016,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,9807,0:50.269.019,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B 4F AB 80 6E E0 CA EC B2 A7 74 6C 64 64 5F 75… 0,,9811,0:50.270.016,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,9812,0:50.285.022,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 87 FD 73 89 5D 62 F2 EE 28 71 C4 07 9A 68 1A B9… 0,,9816,0:50.286.018,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,9817,0:50.300.024,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9821,0:50.301.021,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,9822,0:50.301.024,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 87 FD 73 89 5D 62 F2 EE 28 71 C4 07 9A 68 1A B9… 0,,9826,0:50.302.021,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,9827,0:50.317.026,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 3D 2D 70 AE BA 60 A8 5E ED 42 4E F8 35 5C FB… 0,,9831,0:50.318.023,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,9832,0:50.332.028,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9836,0:50.333.025,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,9837,0:50.333.028,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 3D 2D 70 AE BA 60 A8 5E ED 42 4E F8 35 5C FB… 0,,9841,0:50.334.025,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,9842,0:50.349.030,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C 7B C4 EB E8 CA 34 27 40 1C 62 92 06 F6 7C C0… 0,,9846,0:50.350.027,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,9847,0:50.364.033,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9851,0:50.365.029,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,9852,0:50.365.033,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C 7B C4 EB E8 CA 34 27 40 1C 62 92 06 F6 7C C0… 0,,9856,0:50.366.030,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,9857,0:50.381.035,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 E1 74 6F 65 8F 45 5A 1B 9A D7 C6 77 45 DC 2C… 0,,9861,0:50.382.032,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,9862,0:50.396.037,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9866,0:50.397.034,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,9867,0:50.397.037,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 E1 74 6F 65 8F 45 5A 1B 9A D7 C6 77 45 DC 2C… 0,,9871,0:50.398.034,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,9872,0:50.413.039,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE 63 DA E1 21 78 0C 18 A8 32 A7 77 7B 1A 38 22… 0,,9876,0:50.414.036,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,9877,0:50.428.041,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9881,0:50.429.038,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,9882,0:50.429.042,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE 63 DA E1 21 78 0C 18 A8 32 A7 77 7B 1A 38 22… 0,,9886,0:50.430.038,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,9887,0:50.445.044,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AD 21 B1 E2 9D E8 60 54 B6 67 08 5D 4D BD 0F F4… 0,,9891,0:50.446.041,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,9892,0:50.460.046,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9896,0:50.461.043,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,9897,0:50.461.046,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AD 21 B1 E2 9D E8 60 54 B6 67 08 5D 4D BD 0F F4… 0,,9901,0:50.462.043,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,9902,0:50.477.048,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 71 CD C1 F6 97 86 C2 A0 DE CB A3 3A 72 3D 25… 0,,9906,0:50.478.045,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,9907,0:50.492.050,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9911,0:50.493.047,16.005.041 ms,,,,,[17 SOF],[Frames: 1281 - 1297] 0,,9912,0:50.509.053,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 09 62 4C 5C 39 4D 2D 7F 67 44 00 2B 99 91 92 5D… 0,,9916,0:50.510.050,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,9917,0:50.524.055,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9921,0:50.525.052,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,9922,0:50.525.055,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 09 62 4C 5C 39 4D 2D 7F 67 44 00 2B 99 91 92 5D… 0,,9926,0:50.526.052,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,9927,0:50.541.057,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3C 7E F2 A6 BD A4 E2 68 28 EB 30 2B CE 4F D7 0E… 0,,9931,0:50.542.054,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,9932,0:50.556.059,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9936,0:50.557.056,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,9937,0:50.557.059,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3C 7E F2 A6 BD A4 E2 68 28 EB 30 2B CE 4F D7 0E… 0,,9941,0:50.558.056,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,9942,0:50.573.062,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 B0 26 1C D3 0F A8 4E 44 2C 8A 9F 69 4D 7F B1… 0,,9946,0:50.574.058,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,9947,0:50.588.064,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9951,0:50.589.061,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,9952,0:50.589.064,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C6 B0 26 1C D3 0F A8 4E 44 2C 8A 9F 69 4D 7F B1… 0,,9956,0:50.590.061,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,9957,0:50.605.066,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 A7 87 18 D8 2F 87 E0 54 97 D1 C8 FF 89 37 34… 0,,9961,0:50.606.063,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,9962,0:50.620.068,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9966,0:50.621.065,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,9967,0:50.621.068,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 A7 87 18 D8 2F 87 E0 54 97 D1 C8 FF 89 37 34… 0,,9971,0:50.622.065,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,9972,0:50.637.070,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C0 6B 57 40 27 E0 F4 A9 5A 21 93 B3 87 C5 39 66… 0,,9976,0:50.638.067,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,9977,0:50.652.073,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9981,0:50.653.069,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,9982,0:50.653.073,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C0 6B 57 40 27 E0 F4 A9 5A 21 93 B3 87 C5 39 66… 0,,9986,0:50.654.070,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,9987,0:50.669.075,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 E6 31 50 F3 9D 5D 67 0B 9C B5 D2 9A EE 5E EF… 0,,9991,0:50.670.072,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,9992,0:50.684.077,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,9996,0:50.685.074,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,9997,0:50.685.077,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 E6 31 50 F3 9D 5D 67 0B 9C B5 D2 9A EE 5E EF… 0,,10001,0:50.686.074,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,10002,0:50.701.079,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E A3 4D 38 80 DB E3 F1 04 6F 0E 4F 4B A7 20 11… 0,,10006,0:50.702.076,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,10007,0:50.716.081,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10011,0:50.717.078,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,10012,0:50.717.082,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E A3 4D 38 80 DB E3 F1 04 6F 0E 4F 4B A7 20 11… 0,,10016,0:50.718.078,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,10017,0:50.733.084,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 6B A3 45 A9 D9 CC A3 40 FC 50 4C 42 7B 0F D9… 0,,10021,0:50.734.081,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,10022,0:50.748.086,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10026,0:50.749.083,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,10027,0:50.749.086,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 6B A3 45 A9 D9 CC A3 40 FC 50 4C 42 7B 0F D9… 0,,10031,0:50.750.083,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,10032,0:50.765.088,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 A7 36 B0 2D AA 58 84 C4 98 43 67 6F A1 C3 57… 0,,10036,0:50.766.085,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,10037,0:50.780.090,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10041,0:50.781.087,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,10042,0:50.781.090,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 A7 36 B0 2D AA 58 84 C4 98 43 67 6F A1 C3 57… 0,,10046,0:50.782.087,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,10047,0:50.797.093,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 0B F6 B5 4A 36 C2 DD 75 D7 81 01 39 E7 38 5E… 0,,10051,0:50.798.090,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,10052,0:50.812.095,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10056,0:50.813.092,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,10057,0:50.813.095,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 0B F6 B5 4A 36 C2 DD 75 D7 81 01 39 E7 38 5E… 0,,10061,0:50.814.092,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,10062,0:50.829.097,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B7 29 D0 EF 80 7E 3F 41 74 82 E8 EC 90 12 86 4B… 0,,10066,0:50.830.094,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,10067,0:50.844.099,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10071,0:50.845.096,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,10072,0:50.845.099,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B7 29 D0 EF 80 7E 3F 41 74 82 E8 EC 90 12 86 4B… 0,,10076,0:50.846.096,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,10077,0:50.861.102,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF 5A FE 00 5C 4E 78 A4 7C 8E 22 98 6D CD ED F6… 0,,10081,0:50.862.098,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,10082,0:50.876.104,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10086,0:50.877.100,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,10087,0:50.877.104,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BF 5A FE 00 5C 4E 78 A4 7C 8E 22 98 6D CD ED F6… 0,,10091,0:50.878.101,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,10092,0:50.893.106,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CA 0F 19 C3 0B DF 60 C6 15 48 7A 96 35 3C 56 FA… 0,,10096,0:50.894.103,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,10097,0:50.908.108,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10101,0:50.909.105,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,10102,0:50.909.108,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CA 0F 19 C3 0B DF 60 C6 15 48 7A 96 35 3C 56 FA… 0,,10106,0:50.910.105,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,10107,0:50.925.110,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 3F 28 5B 51 A0 F4 A9 1E 3B BA 98 A2 BA 30 50… 0,,10111,0:50.926.107,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,10112,0:50.940.112,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10116,0:50.941.109,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,10117,0:50.941.113,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 3F 28 5B 51 A0 F4 A9 1E 3B BA 98 A2 BA 30 50… 0,,10121,0:50.942.110,15.004.916 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,10122,0:50.957.115,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 F9 DE 35 47 23 8E C7 16 69 02 1F B4 40 F0 28… 0,,10126,0:50.958.112,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,10127,0:50.972.117,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10131,0:50.973.114,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,10132,0:50.973.117,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 F9 DE 35 47 23 8E C7 16 69 02 1F B4 40 F0 28… 0,,10136,0:50.974.114,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,10137,0:50.989.119,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6E 2D 06 A9 F1 EA 3B 8C EA 05 19 89 75 33 8B 5F… 0,,10141,0:50.990.116,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,10142,0:51.004.121,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10146,0:51.005.118,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,10147,0:51.005.122,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6E 2D 06 A9 F1 EA 3B 8C EA 05 19 89 75 33 8B 5F… 0,,10151,0:51.006.118,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,10152,0:51.021.124,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D 1A 66 27 88 9A 4E B2 49 A9 F9 E1 F3 CA 2D 0F… 0,,10156,0:51.022.121,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,10157,0:51.036.126,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10161,0:51.037.123,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,10162,0:51.037.126,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 1A 66 27 88 9A 4E B2 49 A9 F9 E1 F3 CA 2D 0F… 0,,10166,0:51.038.123,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,10167,0:51.053.128,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F0 B6 73 CF 23 69 40 26 21 DE C4 B0 78 A3 43 B2… 0,,10171,0:51.054.125,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,10172,0:51.068.130,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10176,0:51.069.127,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,10177,0:51.069.130,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F0 B6 73 CF 23 69 40 26 21 DE C4 B0 78 A3 43 B2… 0,,10181,0:51.070.127,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,10182,0:51.085.133,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F 0C DA BC 78 60 33 30 60 EF F4 20 B8 71 E1 1C… 0,,10186,0:51.086.130,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,10187,0:51.100.135,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10191,0:51.101.132,16.005.041 ms,,,,,[17 SOF],[Frames: 1889 - 1905] 0,,10192,0:51.117.137,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 47 0F A2 15 57 A7 E7 B7 55 27 7B B9 62 6E E5 45… 0,,10196,0:51.118.134,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,10197,0:51.132.139,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10201,0:51.133.136,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,10202,0:51.133.139,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 47 0F A2 15 57 A7 E7 B7 55 27 7B B9 62 6E E5 45… 0,,10206,0:51.134.136,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,10207,0:51.149.142,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 C2 6F 6E 27 07 2C 43 A4 0A 60 C8 52 6A 68 B3… 0,,10211,0:51.150.138,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,10212,0:51.164.144,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10216,0:51.165.140,2.833 us,,,,,[1 SOF],[Frame: 1953] 0,,10217,0:51.165.144,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 C2 6F 6E 27 07 2C 43 A4 0A 60 C8 52 6A 68 B3… 0,,10221,0:51.166.141,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,10222,0:51.181.146,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E 8B FB 80 53 D9 E2 29 38 FA 13 5A 9C 4B 71 E9… 0,,10226,0:51.182.143,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,10227,0:51.196.148,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10231,0:51.197.145,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,10232,0:51.197.148,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E 8B FB 80 53 D9 E2 29 38 FA 13 5A 9C 4B 71 E9… 0,,10236,0:51.198.145,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,10237,0:51.213.150,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 76 E5 4D B5 7F D0 67 86 1D 5E B1 E6 3D A2 2E… 0,,10241,0:51.214.147,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,10242,0:51.228.153,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10246,0:51.229.149,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,10247,0:51.229.153,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 76 E5 4D B5 7F D0 67 86 1D 5E B1 E6 3D A2 2E… 0,,10251,0:51.230.149,15.005.000 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,10252,0:51.245.155,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0C B4 E2 F4 AF 86 66 88 23 9E BA E9 0D F1 69 8B… 0,,10256,0:51.246.152,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,10257,0:51.260.157,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10261,0:51.261.154,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,10262,0:51.261.157,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0C B4 E2 F4 AF 86 66 88 23 9E BA E9 0D F1 69 8B… 0,,10266,0:51.262.154,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,10267,0:51.277.159,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B7 0A 64 76 AB 99 AA 20 34 7B 7D A8 C9 C9 8B BC… 0,,10271,0:51.278.156,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,10272,0:51.292.161,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10276,0:51.293.158,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,10277,0:51.293.161,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B7 0A 64 76 AB 99 AA 20 34 7B 7D A8 C9 C9 8B BC… 0,,10281,0:51.294.158,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,10282,0:51.309.164,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D 08 82 C6 B9 BF 6A C4 59 99 D4 DD 9D 39 90 2F… 0,,10286,0:51.310.161,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,10287,0:51.324.166,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10291,0:51.325.163,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,10292,0:51.325.166,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D 08 82 C6 B9 BF 6A C4 59 99 D4 DD 9D 39 90 2F… 0,,10296,0:51.326.163,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,10297,0:51.341.168,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E8 3D 97 BA 83 4D 56 DC BB 89 4E 55 98 27 6E 41… 0,,10301,0:51.342.165,14.004.750 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,10302,0:51.356.170,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10306,0:51.357.167,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,10307,0:51.357.170,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E8 3D 97 BA 83 4D 56 DC BB 89 4E 55 98 27 6E 41… 0,,10311,0:51.358.167,15.004.916 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,10312,0:51.373.173,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B FC C3 92 42 49 25 51 E2 06 9A 3B AD A8 F5 16… 0,,10316,0:51.374.169,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,10317,0:51.388.175,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10321,0:51.389.172,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,10322,0:51.389.175,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B FC C3 92 42 49 25 51 E2 06 9A 3B AD A8 F5 16… 0,,10326,0:51.390.172,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,10327,0:51.405.177,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 1E F7 41 7A 92 97 58 DE F9 9F 7E D2 D9 25 E8… 0,,10331,0:51.406.174,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,10332,0:51.420.179,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10336,0:51.421.176,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,10337,0:51.421.179,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 1E F7 41 7A 92 97 58 DE F9 9F 7E D2 D9 25 E8… 0,,10341,0:51.422.176,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,10342,0:51.437.181,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D BD 8C BB D9 20 75 D0 A8 9B 1A 4E C3 3A B5 3E… 0,,10346,0:51.438.178,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,10347,0:51.452.184,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10351,0:51.453.180,2.833 us,,,,,[1 SOF],[Frame: 193] 0,,10352,0:51.453.184,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D BD 8C BB D9 20 75 D0 A8 9B 1A 4E C3 3A B5 3E… 0,,10356,0:51.454.181,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,10357,0:51.469.186,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D 38 63 A7 F7 4C 65 D2 2C 68 A2 BF 73 01 8E B8… 0,,10361,0:51.470.183,14.004.750 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,10362,0:51.484.188,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10366,0:51.485.185,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,10367,0:51.485.188,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D 38 63 A7 F7 4C 65 D2 2C 68 A2 BF 73 01 8E B8… 0,,10371,0:51.486.185,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,10372,0:51.501.190,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6B DC A4 16 EF 7D BC F5 B3 C3 A6 73 30 BA 00 DE… 0,,10376,0:51.502.187,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,10377,0:51.516.192,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10381,0:51.517.189,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,10382,0:51.517.193,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6B DC A4 16 EF 7D BC F5 B3 C3 A6 73 30 BA 00 DE… 0,,10386,0:51.518.189,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,10387,0:51.533.195,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD 35 94 D2 EB 22 8F EE A8 4C C4 A5 B0 2F 51 7C… 0,,10391,0:51.534.192,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,10392,0:51.548.197,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10396,0:51.549.194,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,10397,0:51.549.197,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD 35 94 D2 EB 22 8F EE A8 4C C4 A5 B0 2F 51 7C… 0,,10401,0:51.550.194,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,10402,0:51.565.199,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 99 8A 40 E4 EC 87 46 3D 8B 64 2E B5 47 89 21 24… 0,,10406,0:51.566.196,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,10407,0:51.580.201,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10411,0:51.581.198,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,10412,0:51.581.201,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 99 8A 40 E4 EC 87 46 3D 8B 64 2E B5 47 89 21 24… 0,,10416,0:51.582.198,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,10417,0:51.597.204,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D 60 EF 07 D1 5A 48 6A 2A 23 5E 86 13 92 C5 52… 0,,10421,0:51.598.201,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,10422,0:51.612.206,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10426,0:51.613.203,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,10427,0:51.613.206,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D 60 EF 07 D1 5A 48 6A 2A 23 5E 86 13 92 C5 52… 0,,10431,0:51.614.203,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,10432,0:51.629.208,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E 70 4E C3 93 AB 2F 92 BC 3A 4F 48 12 9F B4 89… 0,,10436,0:51.630.205,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,10437,0:51.644.210,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10441,0:51.645.207,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,10442,0:51.645.210,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E 70 4E C3 93 AB 2F 92 BC 3A 4F 48 12 9F B4 89… 0,,10446,0:51.646.207,15.004.916 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,10447,0:51.661.213,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 30 BD DC 25 FE 45 37 C7 39 A5 0D 17 7E E6 4F… 0,,10451,0:51.662.209,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,10452,0:51.676.215,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10456,0:51.677.212,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,10457,0:51.677.215,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 30 BD DC 25 FE 45 37 C7 39 A5 0D 17 7E E6 4F… 0,,10461,0:51.678.212,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,10462,0:51.693.217,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 29 9C 3F FB 18 1B 7F 93 3F F1 2F 15 52 03 F9… 0,,10466,0:51.694.214,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,10467,0:51.708.219,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10471,0:51.709.216,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,10472,0:51.709.219,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 29 9C 3F FB 18 1B 7F 93 3F F1 2F 15 52 03 F9… 0,,10476,0:51.710.216,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,10477,0:51.725.221,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 58 1C 43 A4 A7 F5 C4 98 53 CC 5C 3A D8 36 03… 0,,10481,0:51.726.218,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,10482,0:51.740.224,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10486,0:51.741.220,16.005.041 ms,,,,,[17 SOF],[Frames: 481 - 497] 0,,10487,0:51.757.226,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3B 71 17 4E 0D 01 D3 9C 34 49 2E 10 D1 9A 12 B4… 0,,10491,0:51.758.223,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,10492,0:51.772.228,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10496,0:51.773.225,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,10497,0:51.773.228,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3B 71 17 4E 0D 01 D3 9C 34 49 2E 10 D1 9A 12 B4… 0,,10501,0:51.774.225,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,10502,0:51.789.230,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 5B 72 BC B4 0E 2D 92 84 D7 D4 0D 33 80 20 42… 0,,10506,0:51.790.227,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,10507,0:51.804.232,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10511,0:51.805.229,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,10512,0:51.805.233,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 5B 72 BC B4 0E 2D 92 84 D7 D4 0D 33 80 20 42… 0,,10516,0:51.806.229,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,10517,0:51.821.235,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 B6 EA C9 BC B5 A5 19 A9 F1 D6 F2 64 26 08 E2… 0,,10521,0:51.822.232,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,10522,0:51.836.237,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10526,0:51.837.234,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,10527,0:51.837.237,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 B6 EA C9 BC B5 A5 19 A9 F1 D6 F2 64 26 08 E2… 0,,10531,0:51.838.234,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,10532,0:51.853.239,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB ED 73 FA BA FD 77 D8 3B 9D B0 90 EB BE 21 CC… 0,,10536,0:51.854.236,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,10537,0:51.868.241,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10541,0:51.869.238,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,10542,0:51.869.241,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB ED 73 FA BA FD 77 D8 3B 9D B0 90 EB BE 21 CC… 0,,10546,0:51.870.238,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,10547,0:51.885.244,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 39 E5 B0 5E 0B 75 1F 32 3C B7 3F 96 4C 11 9F… 0,,10551,0:51.886.241,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,10552,0:51.900.246,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10556,0:51.901.243,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,10557,0:51.901.246,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 39 E5 B0 5E 0B 75 1F 32 3C B7 3F 96 4C 11 9F… 0,,10561,0:51.902.243,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,10562,0:51.917.248,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 59 4B F4 29 69 EE C8 29 E1 B4 0B B3 0F 17 3A 24… 0,,10566,0:51.918.245,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,10567,0:51.932.250,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10571,0:51.933.247,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,10572,0:51.933.250,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 59 4B F4 29 69 EE C8 29 E1 B4 0B B3 0F 17 3A 24… 0,,10576,0:51.934.247,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,10577,0:51.949.253,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 A2 31 B6 00 88 D4 71 6A 9C A9 A5 59 DB C8 D7… 0,,10581,0:51.950.249,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,10582,0:51.964.255,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10586,0:51.965.252,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,10587,0:51.965.255,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 A2 31 B6 00 88 D4 71 6A 9C A9 A5 59 DB C8 D7… 0,,10591,0:51.966.252,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,10592,0:51.981.257,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 1E C5 D5 2A D7 B1 E8 D9 17 93 96 C8 C3 3F 1B… 0,,10596,0:51.982.254,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,10597,0:51.996.259,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10601,0:51.997.256,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,10602,0:51.997.259,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 1E C5 D5 2A D7 B1 E8 D9 17 93 96 C8 C3 3F 1B… 0,,10606,0:51.998.256,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,10607,0:52.013.261,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 E3 CD 8C D0 A2 A4 94 C1 0B F4 F0 22 01 48 84… 0,,10611,0:52.014.258,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,10612,0:52.028.264,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10616,0:52.029.260,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,10617,0:52.029.264,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 E3 CD 8C D0 A2 A4 94 C1 0B F4 F0 22 01 48 84… 0,,10621,0:52.030.261,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,10622,0:52.045.266,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 09 32 F4 63 DB 39 29 2C EA 84 90 CC 87 F8 27… 0,,10626,0:52.046.263,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,10627,0:52.060.268,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10631,0:52.061.265,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,10632,0:52.061.268,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 09 32 F4 63 DB 39 29 2C EA 84 90 CC 87 F8 27… 0,,10636,0:52.062.265,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,10637,0:52.077.270,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E AB 9D 40 E0 E8 0B 31 26 F2 DF 7E 6D 18 03 40… 0,,10641,0:52.078.267,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,10642,0:52.092.272,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10646,0:52.093.269,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,10647,0:52.093.273,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E AB 9D 40 E0 E8 0B 31 26 F2 DF 7E 6D 18 03 40… 0,,10651,0:52.094.269,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,10652,0:52.109.275,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A E2 9D 68 F0 BB 46 98 2A 72 B4 56 28 21 A4 8C… 0,,10656,0:52.110.272,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,10657,0:52.124.277,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10661,0:52.125.274,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,10662,0:52.125.277,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A E2 9D 68 F0 BB 46 98 2A 72 B4 56 28 21 A4 8C… 0,,10666,0:52.126.274,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,10667,0:52.141.279,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 02 65 2F 78 7F FA 05 B5 14 C3 7A 22 43 5B 71… 0,,10671,0:52.142.276,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,10672,0:52.156.281,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10676,0:52.157.278,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,10677,0:52.157.281,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 02 65 2F 78 7F FA 05 B5 14 C3 7A 22 43 5B 71… 0,,10681,0:52.158.278,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,10682,0:52.173.284,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9F C5 70 63 BA 60 CD B7 A9 F1 9C 19 02 68 60 48… 0,,10686,0:52.174.281,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,10687,0:52.188.286,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10691,0:52.189.283,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,10692,0:52.189.286,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9F C5 70 63 BA 60 CD B7 A9 F1 9C 19 02 68 60 48… 0,,10696,0:52.190.283,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,10697,0:52.205.288,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF 60 8A 92 B8 A7 11 3D A4 BB F2 4F 77 2C E1 AF… 0,,10701,0:52.206.285,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,10702,0:52.220.290,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10706,0:52.221.287,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,10707,0:52.221.290,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BF 60 8A 92 B8 A7 11 3D A4 BB F2 4F 77 2C E1 AF… 0,,10711,0:52.222.287,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,10712,0:52.237.293,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D 90 85 D3 F5 0D 28 C4 96 73 87 5F 55 6D 3C B0… 0,,10716,0:52.238.289,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,10717,0:52.252.295,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10721,0:52.253.292,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,10722,0:52.253.295,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D 90 85 D3 F5 0D 28 C4 96 73 87 5F 55 6D 3C B0… 0,,10726,0:52.254.292,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,10727,0:52.269.297,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 8E 74 90 6A 8D 04 95 B2 E9 5D 7B 19 32 CD 34… 0,,10731,0:52.270.294,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,10732,0:52.284.299,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10736,0:52.285.296,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,10737,0:52.285.299,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 8E 74 90 6A 8D 04 95 B2 E9 5D 7B 19 32 CD 34… 0,,10741,0:52.286.296,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,10742,0:52.301.301,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 E0 16 6D A0 17 F6 11 A4 64 AA B8 FA A9 B9 11… 0,,10746,0:52.302.298,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,10747,0:52.316.304,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10751,0:52.317.300,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,10752,0:52.317.304,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 E0 16 6D A0 17 F6 11 A4 64 AA B8 FA A9 B9 11… 0,,10756,0:52.318.301,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,10757,0:52.333.306,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 12 33 CF BB A2 B8 0E FC 1C BB 68 B0 74 78 43 65… 0,,10761,0:52.334.303,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,10762,0:52.348.308,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10766,0:52.349.305,16.005.041 ms,,,,,[17 SOF],[Frames: 1089 - 1105] 0,,10767,0:52.365.310,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 78 65 C7 8D 0D D6 9F 05 DC 73 B9 45 11 BD 96 BD… 0,,10771,0:52.366.307,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,10772,0:52.380.312,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10776,0:52.381.309,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,10777,0:52.381.313,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 78 65 C7 8D 0D D6 9F 05 DC 73 B9 45 11 BD 96 BD… 0,,10781,0:52.382.309,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,10782,0:52.397.315,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 1C E9 B4 3C 50 79 2C 6E 04 19 B5 88 E0 36 88… 0,,10786,0:52.398.312,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,10787,0:52.412.317,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10791,0:52.413.314,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,10792,0:52.413.317,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 1C E9 B4 3C 50 79 2C 6E 04 19 B5 88 E0 36 88… 0,,10796,0:52.414.314,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,10797,0:52.429.319,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 0C 3E BF BA 61 AC 52 CF 0A C5 B0 5B 31 D2 16… 0,,10801,0:52.430.316,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,10802,0:52.444.321,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10806,0:52.445.318,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,10807,0:52.445.321,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 0C 3E BF BA 61 AC 52 CF 0A C5 B0 5B 31 D2 16… 0,,10811,0:52.446.318,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,10812,0:52.461.324,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D6 6A 60 72 E8 35 CD 0B D5 99 79 FE 20 72 2A E1… 0,,10816,0:52.462.321,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,10817,0:52.476.326,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10821,0:52.477.323,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,10822,0:52.477.326,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D6 6A 60 72 E8 35 CD 0B D5 99 79 FE 20 72 2A E1… 0,,10826,0:52.478.323,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,10827,0:52.493.328,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 FF 82 9C 38 5A 9C 36 E6 3B 74 C3 31 F4 23 B8… 0,,10831,0:52.494.325,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,10832,0:52.508.330,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10836,0:52.509.327,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,10837,0:52.509.330,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 FF 82 9C 38 5A 9C 36 E6 3B 74 C3 31 F4 23 B8… 0,,10841,0:52.510.327,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,10842,0:52.525.333,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5C 1B F0 EC 10 46 82 A5 E1 87 A3 51 AB 6D 77 F9… 0,,10846,0:52.526.329,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,10847,0:52.540.335,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10851,0:52.541.331,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,10852,0:52.541.335,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5C 1B F0 EC 10 46 82 A5 E1 87 A3 51 AB 6D 77 F9… 0,,10856,0:52.542.332,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,10857,0:52.557.337,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 CF 1B 38 3E D0 24 B3 1E 8E 8B FD BD 79 30 68… 0,,10861,0:52.558.334,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,10862,0:52.572.339,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10866,0:52.573.336,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,10867,0:52.573.339,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 CF 1B 38 3E D0 24 B3 1E 8E 8B FD BD 79 30 68… 0,,10871,0:52.574.336,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,10872,0:52.589.341,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AE 1A 15 2B CD 84 6A A9 9B 68 CB A5 BE 33 D0 0B… 0,,10876,0:52.590.338,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,10877,0:52.604.343,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10881,0:52.605.340,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,10882,0:52.605.344,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AE 1A 15 2B CD 84 6A A9 9B 68 CB A5 BE 33 D0 0B… 0,,10886,0:52.606.341,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,10887,0:52.621.346,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 00 11 87 7B 5E 61 34 E4 DF B9 1F DC 40 44 05… 0,,10891,0:52.622.343,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,10892,0:52.636.348,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10896,0:52.637.345,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,10897,0:52.637.348,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 00 11 87 7B 5E 61 34 E4 DF B9 1F DC 40 44 05… 0,,10901,0:52.638.345,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,10902,0:52.653.350,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 AE 18 2E F6 34 F2 93 66 F3 D6 9E ED 1A 2B C2… 0,,10906,0:52.654.347,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,10907,0:52.668.352,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10911,0:52.669.349,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,10912,0:52.669.353,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 25 AE 18 2E F6 34 F2 93 66 F3 D6 9E ED 1A 2B C2… 0,,10916,0:52.670.349,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,10917,0:52.685.355,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF F5 E2 D2 0D 49 E3 FD 97 8E 79 9D 55 13 C4 B4… 0,,10921,0:52.686.352,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,10922,0:52.700.357,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10926,0:52.701.354,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,10927,0:52.701.357,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF F5 E2 D2 0D 49 E3 FD 97 8E 79 9D 55 13 C4 B4… 0,,10931,0:52.702.354,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,10932,0:52.717.359,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AA B6 C4 F9 9E 2A C1 E3 E2 A5 EB FF AA 14 91 C0… 0,,10936,0:52.718.356,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,10937,0:52.732.361,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10941,0:52.733.358,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,10942,0:52.733.361,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AA B6 C4 F9 9E 2A C1 E3 E2 A5 EB FF AA 14 91 C0… 0,,10946,0:52.734.358,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,10947,0:52.749.364,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 13 3A BC 18 A1 D9 25 E0 3C 01 44 A8 4D 8D 7F BD… 0,,10951,0:52.750.361,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,10952,0:52.764.366,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10956,0:52.765.363,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,10957,0:52.765.366,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 13 3A BC 18 A1 D9 25 E0 3C 01 44 A8 4D 8D 7F BD… 0,,10961,0:52.766.363,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,10962,0:52.781.368,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 4E D6 F2 6F 47 E0 1C C9 70 4B 1D 14 E7 70 84… 0,,10966,0:52.782.365,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,10967,0:52.796.370,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10971,0:52.797.367,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,10972,0:52.797.370,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 4E D6 F2 6F 47 E0 1C C9 70 4B 1D 14 E7 70 84… 0,,10976,0:52.798.367,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,10977,0:52.813.373,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 77 79 59 8B 3A 05 C5 E1 9E 36 BA 91 61 27 6C… 0,,10981,0:52.814.369,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,10982,0:52.828.375,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,10986,0:52.829.371,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,10987,0:52.829.375,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 77 79 59 8B 3A 05 C5 E1 9E 36 BA 91 61 27 6C… 0,,10991,0:52.830.372,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,10992,0:52.845.377,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A6 02 F8 4B 7D CE 75 B1 E3 01 F4 CC 00 9A EC 50… 0,,10996,0:52.846.374,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,10997,0:52.860.379,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11001,0:52.861.376,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,11002,0:52.861.379,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A6 02 F8 4B 7D CE 75 B1 E3 01 F4 CC 00 9A EC 50… 0,,11006,0:52.862.376,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,11007,0:52.877.381,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E 0F C0 F5 01 8D 6B B4 96 00 A3 C7 CF 39 0D 3B… 0,,11011,0:52.878.378,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,11012,0:52.892.383,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11016,0:52.893.380,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,11017,0:52.893.384,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E 0F C0 F5 01 8D 6B B4 96 00 A3 C7 CF 39 0D 3B… 0,,11021,0:52.894.380,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,11022,0:52.909.386,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 67 A7 7A 84 5F F2 2C 6D 25 2D 5F 65 A7 4E 41… 0,,11026,0:52.910.383,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,11027,0:52.924.388,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11031,0:52.925.385,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,11032,0:52.925.388,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 67 A7 7A 84 5F F2 2C 6D 25 2D 5F 65 A7 4E 41… 0,,11036,0:52.926.385,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,11037,0:52.941.390,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1A 2D 21 ED E9 E7 68 51 4C 13 A8 E5 2D 5C E2 EE… 0,,11041,0:52.942.387,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,11042,0:52.956.392,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11046,0:52.957.389,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,11047,0:52.957.392,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1A 2D 21 ED E9 E7 68 51 4C 13 A8 E5 2D 5C E2 EE… 0,,11051,0:52.958.389,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,11052,0:52.973.395,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D4 9A 9B 2C 9B A0 7D 48 9F 15 76 79 A2 74 3A 33… 0,,11056,0:52.974.392,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,11057,0:52.988.397,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11061,0:52.989.394,16.005.041 ms,,,,,[17 SOF],[Frames: 1729 - 1745] 0,,11062,0:53.005.399,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 89 AE 78 DA 78 17 3B 67 C3 2A D8 BE BE FB 40 E7… 0,,11066,0:53.006.396,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,11067,0:53.020.401,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11071,0:53.021.398,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,11072,0:53.021.401,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 89 AE 78 DA 78 17 3B 67 C3 2A D8 BE BE FB 40 E7… 0,,11076,0:53.022.398,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,11077,0:53.037.404,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 29 4A 18 01 A2 F8 4D 82 D2 30 DD 96 48 FC 62… 0,,11081,0:53.038.400,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,11082,0:53.052.406,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11086,0:53.053.403,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,11087,0:53.053.406,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 29 4A 18 01 A2 F8 4D 82 D2 30 DD 96 48 FC 62… 0,,11091,0:53.054.403,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,11092,0:53.069.408,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 19 32 DF 8F CE 0E A0 41 1B 86 B7 6D 47 96 84 01… 0,,11096,0:53.070.405,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,11097,0:53.084.410,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11101,0:53.085.407,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,11102,0:53.085.410,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 19 32 DF 8F CE 0E A0 41 1B 86 B7 6D 47 96 84 01… 0,,11106,0:53.086.407,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,11107,0:53.101.412,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A 69 E3 46 29 32 21 48 DB 26 8C 03 D9 25 1F B1… 0,,11111,0:53.102.409,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,11112,0:53.116.415,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11116,0:53.117.411,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,11117,0:53.117.415,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A 69 E3 46 29 32 21 48 DB 26 8C 03 D9 25 1F B1… 0,,11121,0:53.118.412,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,11122,0:53.133.417,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 12 04 06 56 C9 2D ED C7 AF 6C AC B0 10 1E 23 88… 0,,11126,0:53.134.414,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,11127,0:53.148.419,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11131,0:53.149.416,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,11132,0:53.149.419,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 12 04 06 56 C9 2D ED C7 AF 6C AC B0 10 1E 23 88… 0,,11136,0:53.150.416,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,11137,0:53.165.421,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 A8 A8 BA 6B 8B 67 01 11 51 4D 2E E4 76 79 71… 0,,11141,0:53.166.418,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,11142,0:53.180.424,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11146,0:53.181.420,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,11147,0:53.181.424,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 A8 A8 BA 6B 8B 67 01 11 51 4D 2E E4 76 79 71… 0,,11151,0:53.182.420,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,11152,0:53.197.426,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 91 2A C4 A6 69 12 BF 90 36 BB 3A F0 41 66 38 CD… 0,,11156,0:53.198.423,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,11157,0:53.212.428,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11161,0:53.213.425,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,11162,0:53.213.428,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 91 2A C4 A6 69 12 BF 90 36 BB 3A F0 41 66 38 CD… 0,,11166,0:53.214.425,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,11167,0:53.229.430,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 8E 15 B0 F8 4D E9 A9 C2 B2 89 12 B7 7C 04 57… 0,,11171,0:53.230.427,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,11172,0:53.244.432,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11176,0:53.245.429,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,11177,0:53.245.433,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 8E 15 B0 F8 4D E9 A9 C2 B2 89 12 B7 7C 04 57… 0,,11181,0:53.246.429,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,11182,0:53.261.435,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0C 3A 6F 98 AD 5E DC 07 73 EA A6 ED F2 A6 C7 F5… 0,,11186,0:53.262.432,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,11187,0:53.276.437,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11191,0:53.277.434,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,11192,0:53.277.437,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0C 3A 6F 98 AD 5E DC 07 73 EA A6 ED F2 A6 C7 F5… 0,,11196,0:53.278.434,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,11197,0:53.293.439,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB AF 23 FC 31 7F 38 B0 9D DA BF 54 C2 51 56 AB… 0,,11201,0:53.294.436,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,11202,0:53.308.441,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11206,0:53.309.438,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,11207,0:53.309.441,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB AF 23 FC 31 7F 38 B0 9D DA BF 54 C2 51 56 AB… 0,,11211,0:53.310.438,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,11212,0:53.325.444,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 28 3C 63 D0 93 EA 5A 3C 7E 81 D8 ED C4 0C 5C 97… 0,,11216,0:53.326.440,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,11217,0:53.340.446,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11221,0:53.341.443,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,11222,0:53.341.446,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 28 3C 63 D0 93 EA 5A 3C 7E 81 D8 ED C4 0C 5C 97… 0,,11226,0:53.342.443,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,11227,0:53.357.448,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF BE 71 BF 68 64 CE 22 77 29 60 8B 7E CD 27 CE… 0,,11231,0:53.358.445,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,11232,0:53.372.450,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11236,0:53.373.447,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,11237,0:53.373.450,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF BE 71 BF 68 64 CE 22 77 29 60 8B 7E CD 27 CE… 0,,11241,0:53.374.447,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,11242,0:53.389.452,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E D8 D2 75 F2 91 32 0C B9 C0 11 F0 FD B6 DE 51… 0,,11246,0:53.390.449,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,11247,0:53.404.455,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11251,0:53.405.451,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,11252,0:53.405.455,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E D8 D2 75 F2 91 32 0C B9 C0 11 F0 FD B6 DE 51… 0,,11256,0:53.406.452,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,11257,0:53.421.457,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E DC 3D F9 90 98 B3 EA 29 64 62 DE E5 00 33 EF… 0,,11261,0:53.422.454,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,11262,0:53.436.459,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11266,0:53.437.456,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,11267,0:53.437.459,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E DC 3D F9 90 98 B3 EA 29 64 62 DE E5 00 33 EF… 0,,11271,0:53.438.456,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,11272,0:53.453.461,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B0 E3 C1 66 89 28 19 4D C7 3C 5B B6 23 EB 1A 2E… 0,,11276,0:53.454.458,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,11277,0:53.468.463,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11281,0:53.469.460,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,11282,0:53.469.464,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B0 E3 C1 66 89 28 19 4D C7 3C 5B B6 23 EB 1A 2E… 0,,11286,0:53.470.460,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,11287,0:53.485.466,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 55 36 78 41 70 85 E5 87 B3 04 DE 23 61 5B 1C 3F… 0,,11291,0:53.486.463,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,11292,0:53.500.468,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11296,0:53.501.465,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,11297,0:53.501.468,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 55 36 78 41 70 85 E5 87 B3 04 DE 23 61 5B 1C 3F… 0,,11301,0:53.502.465,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,11302,0:53.517.470,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 E7 88 64 A4 17 97 71 71 ED 42 DC CC EA 8E 81… 0,,11306,0:53.518.467,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,11307,0:53.532.472,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11311,0:53.533.469,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,11312,0:53.533.472,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 E7 88 64 A4 17 97 71 71 ED 42 DC CC EA 8E 81… 0,,11316,0:53.534.469,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,11317,0:53.549.475,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 60 A4 09 5D B6 75 6D 36 93 33 A8 77 21 EC 6A… 0,,11321,0:53.550.472,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,11322,0:53.564.477,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11326,0:53.565.474,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,11327,0:53.565.477,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 60 A4 09 5D B6 75 6D 36 93 33 A8 77 21 EC 6A… 0,,11331,0:53.566.474,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,11332,0:53.581.479,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 6D 05 D3 30 67 5D 14 3F 84 3A 3D 14 59 9C 4E… 0,,11336,0:53.582.476,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,11337,0:53.596.481,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11341,0:53.597.478,16.005.041 ms,,,,,[17 SOF],[Frames: 289 - 305] 0,,11342,0:53.613.484,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E9 93 AD C3 87 63 A5 B9 38 9B 3A 26 C7 26 68 59… 0,,11346,0:53.614.480,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,11347,0:53.628.486,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11351,0:53.629.483,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,11352,0:53.629.486,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E9 93 AD C3 87 63 A5 B9 38 9B 3A 26 C7 26 68 59… 0,,11356,0:53.630.483,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,11357,0:53.645.488,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 6F 6D D3 D8 88 CC 69 DE FD 5E 01 D1 71 8B 03… 0,,11361,0:53.646.485,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,11362,0:53.660.490,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11366,0:53.661.487,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,11367,0:53.661.490,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 6F 6D D3 D8 88 CC 69 DE FD 5E 01 D1 71 8B 03… 0,,11371,0:53.662.487,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,11372,0:53.677.492,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C 05 38 4F F1 C0 89 78 21 B5 95 64 72 94 15 0E… 0,,11376,0:53.678.489,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,11377,0:53.692.495,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11381,0:53.693.491,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,11382,0:53.693.495,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C 05 38 4F F1 C0 89 78 21 B5 95 64 72 94 15 0E… 0,,11386,0:53.694.492,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,11387,0:53.709.497,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 67 81 C1 35 D3 1C 85 2D 2F 41 5A 28 AD 6D 90… 0,,11391,0:53.710.494,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,11392,0:53.724.499,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11396,0:53.725.496,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,11397,0:53.725.499,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 67 81 C1 35 D3 1C 85 2D 2F 41 5A 28 AD 6D 90… 0,,11401,0:53.726.496,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,11402,0:53.741.501,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B DF C0 79 CD 18 82 85 C6 2B 0F 3E 86 0D 4B 76… 0,,11406,0:53.742.498,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,11407,0:53.756.503,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11411,0:53.757.500,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,11412,0:53.757.504,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B DF C0 79 CD 18 82 85 C6 2B 0F 3E 86 0D 4B 76… 0,,11416,0:53.758.500,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,11417,0:53.773.506,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AC 2E 88 4B 57 3F 90 F6 8B FC B2 81 47 FE 15 14… 0,,11421,0:53.774.503,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,11422,0:53.788.508,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11426,0:53.789.505,2.833 us,,,,,[1 SOF],[Frame: 481] 0,,11427,0:53.789.508,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AC 2E 88 4B 57 3F 90 F6 8B FC B2 81 47 FE 15 14… 0,,11431,0:53.790.505,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,11432,0:53.805.510,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 87 D6 EA FE 0C 00 A6 AA 28 FF 96 B2 E7 33 07… 0,,11436,0:53.806.507,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,11437,0:53.820.512,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11441,0:53.821.509,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,11442,0:53.821.512,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 87 D6 EA FE 0C 00 A6 AA 28 FF 96 B2 E7 33 07… 0,,11446,0:53.822.509,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,11447,0:53.837.515,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C1 DD 29 31 A0 AE 97 0B 8A C5 E4 1C 68 12 AE 16… 0,,11451,0:53.838.512,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,11452,0:53.852.517,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11456,0:53.853.514,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,11457,0:53.853.517,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C1 DD 29 31 A0 AE 97 0B 8A C5 E4 1C 68 12 AE 16… 0,,11461,0:53.854.514,15.004.916 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,11462,0:53.869.519,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 DB 39 E3 F9 92 52 74 33 2D 5F 37 6C 45 67 02… 0,,11466,0:53.870.516,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,11467,0:53.884.521,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11471,0:53.885.518,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,11472,0:53.885.521,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 DB 39 E3 F9 92 52 74 33 2D 5F 37 6C 45 67 02… 0,,11476,0:53.886.518,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,11477,0:53.901.524,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 73 80 F2 90 F2 40 55 E4 B3 D3 55 3C 5D EA 22… 0,,11481,0:53.902.520,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,11482,0:53.916.526,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11486,0:53.917.523,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,11487,0:53.917.526,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 73 80 F2 90 F2 40 55 E4 B3 D3 55 3C 5D EA 22… 0,,11491,0:53.918.523,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,11492,0:53.933.528,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 39 46 60 59 8A BC 08 B0 57 43 1F 18 AA 11 8A… 0,,11496,0:53.934.525,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,11497,0:53.948.530,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11501,0:53.949.527,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,11502,0:53.949.530,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 39 46 60 59 8A BC 08 B0 57 43 1F 18 AA 11 8A… 0,,11506,0:53.950.527,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,11507,0:53.965.532,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 6A 63 4F 0F DB DA 23 7F CC E9 A4 12 19 F2 3A… 0,,11511,0:53.966.529,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,11512,0:53.980.535,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11516,0:53.981.531,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,11517,0:53.981.535,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E3 6A 63 4F 0F DB DA 23 7F CC E9 A4 12 19 F2 3A… 0,,11521,0:53.982.532,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,11522,0:53.997.537,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 55 7D 5F 8B 35 8C D8 A3 EA AC B6 12 0E CD B7… 0,,11526,0:53.998.534,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,11527,0:54.012.539,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11531,0:54.013.536,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,11532,0:54.013.539,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 55 7D 5F 8B 35 8C D8 A3 EA AC B6 12 0E CD B7… 0,,11536,0:54.014.536,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,11537,0:54.029.541,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 5D 7A 31 8B 71 D6 80 4A E8 03 15 F7 77 18 46… 0,,11541,0:54.030.538,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,11542,0:54.044.543,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11546,0:54.045.540,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,11547,0:54.045.544,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 5D 7A 31 8B 71 D6 80 4A E8 03 15 F7 77 18 46… 0,,11551,0:54.046.540,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,11552,0:54.061.546,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 91 D5 43 8D 64 BB C9 03 E0 09 42 2F 77 68 60… 0,,11556,0:54.062.543,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,11557,0:54.076.548,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11561,0:54.077.545,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,11562,0:54.077.548,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 91 D5 43 8D 64 BB C9 03 E0 09 42 2F 77 68 60… 0,,11566,0:54.078.545,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,11567,0:54.093.550,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C BD F2 9F 20 14 CE BA 74 74 61 30 AD 5E C0 1D… 0,,11571,0:54.094.547,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,11572,0:54.108.552,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11576,0:54.109.549,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,11577,0:54.109.552,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C BD F2 9F 20 14 CE BA 74 74 61 30 AD 5E C0 1D… 0,,11581,0:54.110.549,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,11582,0:54.125.555,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 80 01 05 56 BA 19 3F B8 F2 5A E8 11 65 CE 8B… 0,,11586,0:54.126.552,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,11587,0:54.140.557,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11591,0:54.141.554,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,11592,0:54.141.557,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 80 01 05 56 BA 19 3F B8 F2 5A E8 11 65 CE 8B… 0,,11596,0:54.142.554,15.004.916 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,11597,0:54.157.559,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 AC 5E ED 11 D6 CC 7C E2 2D C2 E0 0B D8 27 56… 0,,11601,0:54.158.556,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,11602,0:54.172.561,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11606,0:54.173.558,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,11607,0:54.173.561,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 AC 5E ED 11 D6 CC 7C E2 2D C2 E0 0B D8 27 56… 0,,11611,0:54.174.558,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,11612,0:54.189.564,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8B A1 02 05 F8 1B CD 5C 05 BE B3 F0 99 0D 47 EF… 0,,11616,0:54.190.560,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,11617,0:54.204.566,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11621,0:54.205.562,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,11622,0:54.205.566,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8B A1 02 05 F8 1B CD 5C 05 BE B3 F0 99 0D 47 EF… 0,,11626,0:54.206.563,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,11627,0:54.221.568,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 97 56 CC 23 95 31 5E 08 3D 95 71 BC AF 90 5A… 0,,11631,0:54.222.565,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,11632,0:54.236.570,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11636,0:54.237.567,16.005.041 ms,,,,,[17 SOF],[Frames: 929 - 945] 0,,11637,0:54.253.572,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 97 56 CC 23 95 31 5E 08 3D 95 71 BC AF 90 5A… 0,,11641,0:54.254.569,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,11642,0:54.268.574,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11646,0:54.269.571,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,11647,0:54.269.575,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 97 56 CC 23 95 31 5E 08 3D 95 71 BC AF 90 5A… 0,,11651,0:54.270.572,15.004.916 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,11652,0:54.285.577,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1F E2 D1 02 E0 D5 B3 D9 12 7D 3E 93 E8 D5 A0 D9… 0,,11656,0:54.286.574,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,11657,0:54.300.579,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11661,0:54.301.576,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,11662,0:54.301.579,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1F E2 D1 02 E0 D5 B3 D9 12 7D 3E 93 E8 D5 A0 D9… 0,,11666,0:54.302.576,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,11667,0:54.317.581,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D6 2D 06 3D F9 A1 DA D6 D9 36 DF A4 FD F5 75 EE… 0,,11671,0:54.318.578,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,11672,0:54.332.583,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11676,0:54.333.580,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,11677,0:54.333.584,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D6 2D 06 3D F9 A1 DA D6 D9 36 DF A4 FD F5 75 EE… 0,,11681,0:54.334.580,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,11682,0:54.349.586,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B3 D7 3E 80 A7 48 54 AF 58 1C 6F F1 21 BA FF C0… 0,,11686,0:54.350.583,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,11687,0:54.364.588,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11691,0:54.365.585,2.833 us,,,,,[1 SOF],[Frame: 1057] 0,,11692,0:54.365.588,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B3 D7 3E 80 A7 48 54 AF 58 1C 6F F1 21 BA FF C0… 0,,11696,0:54.366.585,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,11697,0:54.381.590,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC A4 9E 28 64 3A D9 38 0B 56 E7 8F 42 4B E2 6D… 0,,11701,0:54.382.587,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,11702,0:54.396.592,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11706,0:54.397.589,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,11707,0:54.397.592,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC A4 9E 28 64 3A D9 38 0B 56 E7 8F 42 4B E2 6D… 0,,11711,0:54.398.589,15.004.916 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,11712,0:54.413.595,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3C F5 85 5B 45 D4 30 C7 D9 57 C8 32 F1 93 5F 54… 0,,11716,0:54.414.592,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,11717,0:54.428.597,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11721,0:54.429.594,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,11722,0:54.429.597,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3C F5 85 5B 45 D4 30 C7 D9 57 C8 32 F1 93 5F 54… 0,,11726,0:54.430.594,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,11727,0:54.445.599,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FF E3 A6 07 EA 72 A4 7B 41 67 95 74 2E C9 F0 C0… 0,,11731,0:54.446.596,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,11732,0:54.460.601,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11736,0:54.461.598,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,11737,0:54.461.601,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FF E3 A6 07 EA 72 A4 7B 41 67 95 74 2E C9 F0 C0… 0,,11741,0:54.462.598,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,11742,0:54.477.604,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5B DA ED FB D8 54 23 73 77 07 25 AA E4 F1 17 B6… 0,,11746,0:54.478.600,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,11747,0:54.492.606,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11751,0:54.493.602,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,11752,0:54.493.606,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5B DA ED FB D8 54 23 73 77 07 25 AA E4 F1 17 B6… 0,,11756,0:54.494.603,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,11757,0:54.509.608,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A A7 CC 56 BC 72 B7 DF D9 A0 8B 65 DD 75 B8 0C… 0,,11761,0:54.510.605,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,11762,0:54.524.610,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11766,0:54.525.607,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,11767,0:54.525.610,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A A7 CC 56 BC 72 B7 DF D9 A0 8B 65 DD 75 B8 0C… 0,,11771,0:54.526.607,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,11772,0:54.541.612,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 49 92 E1 4C 02 2B B6 67 E5 EF 35 12 36 BE 68 07… 0,,11776,0:54.542.609,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,11777,0:54.556.614,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11781,0:54.557.611,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,11782,0:54.557.615,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 49 92 E1 4C 02 2B B6 67 E5 EF 35 12 36 BE 68 07… 0,,11786,0:54.558.611,15.004.916 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,11787,0:54.573.617,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7F D8 35 A5 EE 86 8D C2 B2 99 1A 20 E0 F5 7C DF… 0,,11791,0:54.574.614,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,11792,0:54.588.619,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11796,0:54.589.616,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,11797,0:54.589.619,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7F D8 35 A5 EE 86 8D C2 B2 99 1A 20 E0 F5 7C DF… 0,,11801,0:54.590.616,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,11802,0:54.605.621,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A 4A E0 9F 93 A2 59 06 DF D0 34 A8 F0 B2 6B FA… 0,,11806,0:54.606.618,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,11807,0:54.620.623,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11811,0:54.621.620,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,11812,0:54.621.623,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A 4A E0 9F 93 A2 59 06 DF D0 34 A8 F0 B2 6B FA… 0,,11816,0:54.622.620,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,11817,0:54.637.626,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 B6 EA 66 B2 63 66 3F BA 15 AF F7 B7 93 F3 39… 0,,11821,0:54.638.623,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,11822,0:54.652.628,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11826,0:54.653.625,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,11827,0:54.653.628,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 B6 EA 66 B2 63 66 3F BA 15 AF F7 B7 93 F3 39… 0,,11831,0:54.654.625,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,11832,0:54.669.630,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C 8C C0 E3 EC AD 69 2F F1 EF 05 30 94 B2 83 E8… 0,,11836,0:54.670.627,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,11837,0:54.684.632,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11841,0:54.685.629,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,11842,0:54.685.632,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C 8C C0 E3 EC AD 69 2F F1 EF 05 30 94 B2 83 E8… 0,,11846,0:54.686.629,15.004.916 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,11847,0:54.701.635,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7E CF E0 4F 06 F7 C1 28 A6 C2 C4 48 B7 B6 90 CF… 0,,11851,0:54.702.631,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,11852,0:54.716.637,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11856,0:54.717.634,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,11857,0:54.717.637,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7E CF E0 4F 06 F7 C1 28 A6 C2 C4 48 B7 B6 90 CF… 0,,11861,0:54.718.634,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,11862,0:54.733.639,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC A8 0C 95 76 CB 2B 5B 55 37 0C 72 14 EF 4E AB… 0,,11866,0:54.734.636,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,11867,0:54.748.641,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11871,0:54.749.638,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,11872,0:54.749.641,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EC A8 0C 95 76 CB 2B 5B 55 37 0C 72 14 EF 4E AB… 0,,11876,0:54.750.638,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,11877,0:54.765.643,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 F7 CE 2A DD FE C1 79 5D 79 53 E9 6E 6A 37 8F… 0,,11881,0:54.766.640,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,11882,0:54.780.646,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11886,0:54.781.642,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,11887,0:54.781.646,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 F7 CE 2A DD FE C1 79 5D 79 53 E9 6E 6A 37 8F… 0,,11891,0:54.782.643,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,11892,0:54.797.648,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 52 6B 32 91 E2 C8 C1 A1 75 28 41 72 F6 D8 6B B3… 0,,11896,0:54.798.645,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,11897,0:54.812.650,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11901,0:54.813.647,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,11902,0:54.813.650,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 52 6B 32 91 E2 C8 C1 A1 75 28 41 72 F6 D8 6B B3… 0,,11906,0:54.814.647,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,11907,0:54.829.652,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 FA 2E E2 A9 97 68 37 04 F4 3E 60 E0 73 FA 15… 0,,11911,0:54.830.649,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,11912,0:54.844.654,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11916,0:54.845.651,16.005.125 ms,,,,,[17 SOF],[Frames: 1537 - 1553] 0,,11917,0:54.861.657,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 B7 10 D5 6B 7F FA 36 63 7F 68 80 F4 BB 76 01… 0,,11921,0:54.862.654,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,11922,0:54.876.659,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11926,0:54.877.656,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,11927,0:54.877.659,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 B7 10 D5 6B 7F FA 36 63 7F 68 80 F4 BB 76 01… 0,,11931,0:54.878.656,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,11932,0:54.893.661,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 02 11 47 A7 D4 3B 76 1A E1 A8 E1 3B AC BE 66 C3… 0,,11936,0:54.894.658,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,11937,0:54.908.663,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11941,0:54.909.660,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,11942,0:54.909.663,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 02 11 47 A7 D4 3B 76 1A E1 A8 E1 3B AC BE 66 C3… 0,,11946,0:54.910.660,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,11947,0:54.925.666,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 52 5F FA 13 80 94 91 01 58 30 53 AE 11 93 6F… 0,,11951,0:54.926.663,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,11952,0:54.940.668,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11956,0:54.941.665,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,11957,0:54.941.668,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 52 5F FA 13 80 94 91 01 58 30 53 AE 11 93 6F… 0,,11961,0:54.942.665,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,11962,0:54.957.670,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 12 47 71 77 FB 26 2E 25 F0 EC B6 67 DD 12 10… 0,,11966,0:54.958.667,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,11967,0:54.972.672,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11971,0:54.973.669,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,11972,0:54.973.672,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9A 12 47 71 77 FB 26 2E 25 F0 EC B6 67 DD 12 10… 0,,11976,0:54.974.669,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,11977,0:54.989.675,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E7 16 5F 4E 67 DF D9 AA 91 3B C2 89 2A E9 52 10… 0,,11981,0:54.990.671,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,11982,0:55.004.677,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,11986,0:55.005.674,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,11987,0:55.005.677,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E7 16 5F 4E 67 DF D9 AA 91 3B C2 89 2A E9 52 10… 0,,11991,0:55.006.674,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,11992,0:55.021.679,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9D 53 49 DC EE 71 63 CC 24 5D 33 4D 7D 1A 9E 8D… 0,,11996,0:55.022.676,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,11997,0:55.036.681,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12001,0:55.037.678,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,12002,0:55.037.681,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9D 53 49 DC EE 71 63 CC 24 5D 33 4D 7D 1A 9E 8D… 0,,12006,0:55.038.678,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,12007,0:55.053.683,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 11 6D A7 48 2D E2 F9 43 B4 6A 7A D9 D0 F6 51… 0,,12011,0:55.054.680,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,12012,0:55.068.686,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12016,0:55.069.682,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,12017,0:55.069.686,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 11 6D A7 48 2D E2 F9 43 B4 6A 7A D9 D0 F6 51… 0,,12021,0:55.070.683,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,12022,0:55.085.688,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 98 EF EC F0 E8 82 5C A7 A5 75 04 26 9E 6C DA… 0,,12026,0:55.086.685,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,12027,0:55.100.690,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12031,0:55.101.687,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,12032,0:55.101.690,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 98 EF EC F0 E8 82 5C A7 A5 75 04 26 9E 6C DA… 0,,12036,0:55.102.687,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,12037,0:55.117.692,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 54 2E 30 DC E1 E4 C9 63 97 9A 2B 21 E2 F9 4B 6D… 0,,12041,0:55.118.689,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,12042,0:55.132.694,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12046,0:55.133.691,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,12047,0:55.133.695,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 54 2E 30 DC E1 E4 C9 63 97 9A 2B 21 E2 F9 4B 6D… 0,,12051,0:55.134.691,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,12052,0:55.149.697,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1A 8D 2E A3 E6 A6 7D 50 C0 14 88 06 80 BF 76 D7… 0,,12056,0:55.150.694,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,12057,0:55.164.699,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12061,0:55.165.696,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,12062,0:55.165.699,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1A 8D 2E A3 E6 A6 7D 50 C0 14 88 06 80 BF 76 D7… 0,,12066,0:55.166.696,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,12067,0:55.181.701,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 03 A1 28 5F B4 36 A5 50 DD 8A 4F F3 81 D2 BE… 0,,12071,0:55.182.698,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,12072,0:55.196.703,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12076,0:55.197.700,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,12077,0:55.197.703,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 03 A1 28 5F B4 36 A5 50 DD 8A 4F F3 81 D2 BE… 0,,12081,0:55.198.700,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,12082,0:55.213.706,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C 73 D1 F9 0E 53 16 69 FA 43 3A 13 EF 2D 56 9B… 0,,12086,0:55.214.703,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,12087,0:55.228.708,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12091,0:55.229.705,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,12092,0:55.229.708,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C 73 D1 F9 0E 53 16 69 FA 43 3A 13 EF 2D 56 9B… 0,,12096,0:55.230.705,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,12097,0:55.245.710,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D B8 2C 45 27 5B 5C 22 AE 55 B3 09 9D C5 09 63… 0,,12101,0:55.246.707,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,12102,0:55.260.712,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12106,0:55.261.709,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,12107,0:55.261.712,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D B8 2C 45 27 5B 5C 22 AE 55 B3 09 9D C5 09 63… 0,,12111,0:55.262.709,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,12112,0:55.277.715,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E 1D CB 55 B0 1C 71 77 AF 92 01 47 83 67 A3 C2… 0,,12116,0:55.278.711,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,12117,0:55.292.717,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12121,0:55.293.714,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,12122,0:55.293.717,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E 1D CB 55 B0 1C 71 77 AF 92 01 47 83 67 A3 C2… 0,,12126,0:55.294.714,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,12127,0:55.309.719,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 77 A7 CA 82 80 7F 10 A1 02 7E 1F 9E 23 BA 6D 6C… 0,,12131,0:55.310.716,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,12132,0:55.324.721,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12136,0:55.325.718,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,12137,0:55.325.721,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 77 A7 CA 82 80 7F 10 A1 02 7E 1F 9E 23 BA 6D 6C… 0,,12141,0:55.326.718,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,12142,0:55.341.724,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D 11 72 EB F7 73 8A 60 70 5A E9 B1 99 57 CE 90… 0,,12146,0:55.342.720,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,12147,0:55.356.726,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12151,0:55.357.722,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,12152,0:55.357.726,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D 11 72 EB F7 73 8A 60 70 5A E9 B1 99 57 CE 90… 0,,12156,0:55.358.723,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,12157,0:55.373.728,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA C8 C1 72 5A 59 96 CB 80 54 D2 DB 8C 0A 5E 73… 0,,12161,0:55.374.725,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,12162,0:55.388.730,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12166,0:55.389.727,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,12167,0:55.389.730,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA C8 C1 72 5A 59 96 CB 80 54 D2 DB 8C 0A 5E 73… 0,,12171,0:55.390.727,15.004.916 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,12172,0:55.405.732,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D 9C 2F 59 73 4D 78 55 01 D0 AE D7 FB 09 1E 4E… 0,,12176,0:55.406.729,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,12177,0:55.420.734,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12181,0:55.421.731,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,12182,0:55.421.735,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D 9C 2F 59 73 4D 78 55 01 D0 AE D7 FB 09 1E 4E… 0,,12186,0:55.422.731,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,12187,0:55.437.737,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 88 A3 90 F4 8F 48 80 E2 26 73 75 61 DD 06 C8… 0,,12191,0:55.438.734,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,12192,0:55.452.739,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12196,0:55.453.736,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,12197,0:55.453.739,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 88 A3 90 F4 8F 48 80 E2 26 73 75 61 DD 06 C8… 0,,12201,0:55.454.736,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,12202,0:55.469.741,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC CA E3 65 0B 9F 7D 05 A6 16 A1 A6 CF 40 B2 65… 0,,12206,0:55.470.738,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,12207,0:55.484.743,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12211,0:55.485.740,16.005.041 ms,,,,,[17 SOF],[Frames: 129 - 145] 0,,12212,0:55.501.746,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC CA E3 65 0B 9F 7D 05 A6 16 A1 A6 CF 40 B2 65… 0,,12216,0:55.502.743,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,12217,0:55.516.748,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12221,0:55.517.745,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,12222,0:55.517.748,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E 6C 19 26 EB 30 0B 73 7C 7A DD 90 99 3E 42 85… 0,,12226,0:55.518.745,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,12227,0:55.533.750,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B C3 1C E2 4C B4 CB 63 47 12 E2 E4 1B FC EC D6… 0,,12231,0:55.534.747,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,12232,0:55.548.752,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12236,0:55.549.749,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,12237,0:55.549.752,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B C3 1C E2 4C B4 CB 63 47 12 E2 E4 1B FC EC D6… 0,,12241,0:55.550.749,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,12242,0:55.565.755,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A 4A B4 79 2D DE 85 D6 27 C5 06 DB DC EF 77 74… 0,,12246,0:55.566.751,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,12247,0:55.580.757,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12251,0:55.581.754,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,12252,0:55.581.757,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A 4A B4 79 2D DE 85 D6 27 C5 06 DB DC EF 77 74… 0,,12256,0:55.582.754,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,12257,0:55.597.759,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E5 0B 51 41 20 D6 5B 39 32 C8 B6 80 D9 8A E9 41… 0,,12261,0:55.598.756,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,12262,0:55.612.761,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12266,0:55.613.758,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,12267,0:55.613.761,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E5 0B 51 41 20 D6 5B 39 32 C8 B6 80 D9 8A E9 41… 0,,12271,0:55.614.758,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,12272,0:55.629.763,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B BC 67 12 5B 2B 99 59 44 D2 15 95 2E 0A BA 5D… 0,,12276,0:55.630.760,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,12277,0:55.644.766,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12281,0:55.645.762,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,12282,0:55.645.766,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B BC 67 12 5B 2B 99 59 44 D2 15 95 2E 0A BA 5D… 0,,12286,0:55.646.763,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,12287,0:55.661.768,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E7 C2 87 EF 15 B6 D6 9D E6 66 0D 29 A4 28 9A 3F… 0,,12291,0:55.662.765,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,12292,0:55.676.770,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12296,0:55.677.767,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,12297,0:55.677.770,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E7 C2 87 EF 15 B6 D6 9D E6 66 0D 29 A4 28 9A 3F… 0,,12301,0:55.678.767,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,12302,0:55.693.772,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E 63 EB 94 62 6A 75 DA 03 0B C1 D2 A4 0B CD 44… 0,,12306,0:55.694.769,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,12307,0:55.708.774,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12311,0:55.709.771,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,12312,0:55.709.775,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E 63 EB 94 62 6A 75 DA 03 0B C1 D2 A4 0B CD 44… 0,,12316,0:55.710.771,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,12317,0:55.725.777,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D 95 CD 2E A7 7B 61 DF BE 7E 92 E3 48 A5 82 6B… 0,,12321,0:55.726.774,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,12322,0:55.740.779,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12326,0:55.741.776,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,12327,0:55.741.779,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D 95 CD 2E A7 7B 61 DF BE 7E 92 E3 48 A5 82 6B… 0,,12331,0:55.742.776,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,12332,0:55.757.781,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B 0F 05 71 5F 64 57 4C 80 0A 63 C0 A6 91 90 89… 0,,12336,0:55.758.778,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,12337,0:55.772.783,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12341,0:55.773.780,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,12342,0:55.773.783,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B 0F 05 71 5F 64 57 4C 80 0A 63 C0 A6 91 90 89… 0,,12346,0:55.774.780,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,12347,0:55.789.786,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 70 FF 73 DE E3 40 F3 B0 81 F5 D3 34 3E 36 3F 8B… 0,,12351,0:55.790.783,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,12352,0:55.804.788,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12356,0:55.805.785,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,12357,0:55.805.788,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 70 FF 73 DE E3 40 F3 B0 81 F5 D3 34 3E 36 3F 8B… 0,,12361,0:55.806.785,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,12362,0:55.821.790,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB 6E 8F B6 68 13 F8 51 13 76 31 33 E8 F0 85 33… 0,,12366,0:55.822.787,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,12367,0:55.836.792,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12371,0:55.837.789,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,12372,0:55.837.792,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB 6E 8F B6 68 13 F8 51 13 76 31 33 E8 F0 85 33… 0,,12376,0:55.838.789,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,12377,0:55.853.795,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 21 E2 93 6D 49 A5 53 F7 59 74 01 2E CE FF AF… 0,,12381,0:55.854.791,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,12382,0:55.868.797,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12386,0:55.869.793,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,12387,0:55.869.797,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 21 E2 93 6D 49 A5 53 F7 59 74 01 2E CE FF AF… 0,,12391,0:55.870.794,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,12392,0:55.885.799,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 31 1C FF 17 D1 33 38 66 A0 1A 04 C3 FF F4 6E… 0,,12396,0:55.886.796,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,12397,0:55.900.801,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12401,0:55.901.798,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,12402,0:55.901.801,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 31 1C FF 17 D1 33 38 66 A0 1A 04 C3 FF F4 6E… 0,,12406,0:55.902.798,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,12407,0:55.917.803,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 D5 09 95 42 C1 CC 20 CD 2E 84 67 74 38 48 46… 0,,12411,0:55.918.800,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,12412,0:55.932.805,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12416,0:55.933.802,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,12417,0:55.933.806,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 D5 09 95 42 C1 CC 20 CD 2E 84 67 74 38 48 46… 0,,12421,0:55.934.803,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,12422,0:55.949.808,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 37 88 C4 94 5F EE 82 A0 AC A8 A6 2D 03 50 A8 DD… 0,,12426,0:55.950.805,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,12427,0:55.964.810,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12431,0:55.965.807,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,12432,0:55.965.810,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 37 88 C4 94 5F EE 82 A0 AC A8 A6 2D 03 50 A8 DD… 0,,12436,0:55.966.807,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,12437,0:55.981.812,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 55 D4 03 84 BE 79 51 D5 C1 C5 9D 50 EA BA CC… 0,,12441,0:55.982.809,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,12442,0:55.996.814,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12446,0:55.997.811,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,12447,0:55.997.815,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 55 D4 03 84 BE 79 51 D5 C1 C5 9D 50 EA BA CC… 0,,12451,0:55.998.811,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,12452,0:56.013.817,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 BA 9E 66 08 C8 53 3B B5 43 4F 10 DD D6 78 19… 0,,12456,0:56.014.814,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,12457,0:56.028.819,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12461,0:56.029.816,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,12462,0:56.029.819,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 BA 9E 66 08 C8 53 3B B5 43 4F 10 DD D6 78 19… 0,,12466,0:56.030.816,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,12467,0:56.045.821,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 28 B9 79 BE A2 B7 79 1F B8 42 E6 CA 96 44 E5… 0,,12471,0:56.046.818,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,12472,0:56.060.823,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12476,0:56.061.820,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,12477,0:56.061.823,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 28 B9 79 BE A2 B7 79 1F B8 42 E6 CA 96 44 E5… 0,,12481,0:56.062.820,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,12482,0:56.077.826,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 77 92 BC 20 4F 0E 17 4B C9 69 CC 85 50 89 74 BB… 0,,12486,0:56.078.823,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,12487,0:56.092.828,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12491,0:56.093.825,16.005.041 ms,,,,,[17 SOF],[Frames: 737 - 753] 0,,12492,0:56.109.830,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 7E 22 A0 2C 04 70 74 56 0D 4D FA 0B E8 E3 25… 0,,12496,0:56.110.827,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,12497,0:56.124.832,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12501,0:56.125.829,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,12502,0:56.125.832,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 7E 22 A0 2C 04 70 74 56 0D 4D FA 0B E8 E3 25… 0,,12506,0:56.126.829,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,12507,0:56.141.835,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 68 43 7B 3C 5B EC 32 A7 62 C4 6C 5F 2E 3F 7F… 0,,12511,0:56.142.831,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,12512,0:56.156.837,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12516,0:56.157.833,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,12517,0:56.157.837,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 68 43 7B 3C 5B EC 32 A7 62 C4 6C 5F 2E 3F 7F… 0,,12521,0:56.158.834,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,12522,0:56.173.839,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 94 D0 4B 76 10 94 64 50 07 DA 53 6A F9 18 CF… 0,,12526,0:56.174.836,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,12527,0:56.188.841,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12531,0:56.189.838,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,12532,0:56.189.841,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 94 D0 4B 76 10 94 64 50 07 DA 53 6A F9 18 CF… 0,,12536,0:56.190.838,15.004.916 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,12537,0:56.205.843,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 29 6D 0A 6C EC 3F 96 B8 31 B7 6D 17 94 34 6C 19… 0,,12541,0:56.206.840,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,12542,0:56.220.845,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12546,0:56.221.842,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,12547,0:56.221.846,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 29 6D 0A 6C EC 3F 96 B8 31 B7 6D 17 94 34 6C 19… 0,,12551,0:56.222.842,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,12552,0:56.237.848,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F0 48 7B 6E FA AF AA 11 82 DD E5 3A 5A 3B A0 DB… 0,,12556,0:56.238.845,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,12557,0:56.252.850,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12561,0:56.253.847,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,12562,0:56.253.850,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F0 48 7B 6E FA AF AA 11 82 DD E5 3A 5A 3B A0 DB… 0,,12566,0:56.254.847,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,12567,0:56.269.852,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF 47 FD 2F F0 DD 50 5A 86 3B B9 81 43 96 96 65… 0,,12571,0:56.270.849,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,12572,0:56.284.854,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12576,0:56.285.851,2.833 us,,,,,[1 SOF],[Frame: 929] 0,,12577,0:56.285.854,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF 47 FD 2F F0 DD 50 5A 86 3B B9 81 43 96 96 65… 0,,12581,0:56.286.851,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,12582,0:56.301.857,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 2F 0E 5B F2 A8 F0 CB 06 B2 9D 8A 00 6B 32 70… 0,,12586,0:56.302.854,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,12587,0:56.316.859,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12591,0:56.317.856,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,12592,0:56.317.859,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 2F 0E 5B F2 A8 F0 CB 06 B2 9D 8A 00 6B 32 70… 0,,12596,0:56.318.856,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,12597,0:56.333.861,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 34 44 F1 2F D4 F0 79 2D 00 65 3E 30 C7 72 3B… 0,,12601,0:56.334.858,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,12602,0:56.348.863,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12606,0:56.349.860,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,12607,0:56.349.863,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 34 44 F1 2F D4 F0 79 2D 00 65 3E 30 C7 72 3B… 0,,12611,0:56.350.860,15.005.000 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,12612,0:56.365.866,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 FB 05 89 92 CD B2 FC AB 7B 3A 19 35 54 32 9D… 0,,12616,0:56.366.862,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,12617,0:56.380.868,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12621,0:56.381.865,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,12622,0:56.381.868,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 FB 05 89 92 CD B2 FC AB 7B 3A 19 35 54 32 9D… 0,,12626,0:56.382.865,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,12627,0:56.397.870,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 50 F5 84 C3 A9 60 F7 A8 08 BC E2 86 55 74 F2… 0,,12631,0:56.398.867,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,12632,0:56.412.872,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12636,0:56.413.869,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,12637,0:56.413.872,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B5 50 F5 84 C3 A9 60 F7 A8 08 BC E2 86 55 74 F2… 0,,12641,0:56.414.869,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,12642,0:56.429.874,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C4 92 71 EE 62 BF F1 66 36 B6 FD 72 B2 32 BC BC… 0,,12646,0:56.430.871,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,12647,0:56.444.877,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12651,0:56.445.873,2.833 us,,,,,[1 SOF],[Frame: 1089] 0,,12652,0:56.445.877,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C4 92 71 EE 62 BF F1 66 36 B6 FD 72 B2 32 BC BC… 0,,12656,0:56.446.874,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,12657,0:56.461.879,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 76 7A 51 7D 3B A6 81 37 56 18 36 81 3F FE 19… 0,,12661,0:56.462.876,14.004.750 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,12662,0:56.476.881,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12666,0:56.477.878,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,12667,0:56.477.881,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 76 7A 51 7D 3B A6 81 37 56 18 36 81 3F FE 19… 0,,12671,0:56.478.878,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,12672,0:56.493.883,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 1F 05 E9 46 8F E7 9C FC 88 CA FB 51 1B 61 C3… 0,,12676,0:56.494.880,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,12677,0:56.508.885,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12681,0:56.509.882,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,12682,0:56.509.886,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 1F 05 E9 46 8F E7 9C FC 88 CA FB 51 1B 61 C3… 0,,12686,0:56.510.882,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,12687,0:56.525.888,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 40 47 63 B6 F9 EC 7A 39 C3 D8 80 44 FF 35 47… 0,,12691,0:56.526.885,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,12692,0:56.540.890,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12696,0:56.541.887,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,12697,0:56.541.890,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 40 47 63 B6 F9 EC 7A 39 C3 D8 80 44 FF 35 47… 0,,12701,0:56.542.887,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,12702,0:56.557.892,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 B7 32 A3 BB D4 0A 72 5D 15 99 6F 12 C2 78 F2… 0,,12706,0:56.558.889,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,12707,0:56.572.894,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12711,0:56.573.891,2.833 us,,,,,[1 SOF],[Frame: 1217] 0,,12712,0:56.573.894,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 25 B7 32 A3 BB D4 0A 72 5D 15 99 6F 12 C2 78 F2… 0,,12716,0:56.574.891,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,12717,0:56.589.897,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 E6 94 C1 A1 C3 B1 D0 FA 0B 63 69 99 E4 BC 05… 0,,12721,0:56.590.894,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,12722,0:56.604.899,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12726,0:56.605.896,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,12727,0:56.605.899,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 E6 94 C1 A1 C3 B1 D0 FA 0B 63 69 99 E4 BC 05… 0,,12731,0:56.606.896,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,12732,0:56.621.901,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 07 BA 49 3C 19 43 23 86 FB 41 FA 31 B1 93 7F 2C… 0,,12736,0:56.622.898,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,12737,0:56.636.903,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12741,0:56.637.900,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,12742,0:56.637.903,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 07 BA 49 3C 19 43 23 86 FB 41 FA 31 B1 93 7F 2C… 0,,12746,0:56.638.900,15.004.916 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,12747,0:56.653.906,50.937 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 88 62 6C 7F 28 14 AE 95 F9 63 FE C7 6B 09 CA F7… 0,,12751,0:56.654.902,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,12752,0:56.668.908,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12756,0:56.669.905,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,12757,0:56.669.908,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 88 62 6C 7F 28 14 AE 95 F9 63 FE C7 6B 09 CA F7… 0,,12761,0:56.670.905,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,12762,0:56.685.910,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 8B 9C 31 FE 85 0F 96 9D E8 30 5B 76 B6 31 39… 0,,12766,0:56.686.907,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,12767,0:56.700.912,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12771,0:56.701.909,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,12772,0:56.701.912,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 8B 9C 31 FE 85 0F 96 9D E8 30 5B 76 B6 31 39… 0,,12776,0:56.702.909,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,12777,0:56.717.914,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 35 8F C3 1A 29 A7 43 D7 35 97 4F 61 E2 65 12… 0,,12781,0:56.718.911,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,12782,0:56.732.917,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12786,0:56.733.913,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,12787,0:56.733.917,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 35 8F C3 1A 29 A7 43 D7 35 97 4F 61 E2 65 12… 0,,12791,0:56.734.914,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,12792,0:56.749.919,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D0 01 04 43 62 19 97 AE F6 46 BB 11 5B E6 C3 AC… 0,,12796,0:56.750.916,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,12797,0:56.764.921,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12801,0:56.765.918,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,12802,0:56.765.921,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D0 01 04 43 62 19 97 AE F6 46 BB 11 5B E6 C3 AC… 0,,12806,0:56.766.918,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,12807,0:56.781.923,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 69 9F 51 D3 EA E8 BD EC 2B 2A CC C5 B7 E6 83… 0,,12811,0:56.782.920,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,12812,0:56.796.925,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12816,0:56.797.922,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,12817,0:56.797.926,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 69 9F 51 D3 EA E8 BD EC 2B 2A CC C5 B7 E6 83… 0,,12821,0:56.798.922,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,12822,0:56.813.928,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E BB 9B D6 C9 98 10 23 67 5D DE 5A 30 C7 CB E7… 0,,12826,0:56.814.925,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,12827,0:56.828.930,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12831,0:56.829.927,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,12832,0:56.829.930,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E BB 9B D6 C9 98 10 23 67 5D DE 5A 30 C7 CB E7… 0,,12836,0:56.830.927,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,12837,0:56.845.932,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 6B A1 A6 50 5B F3 46 92 24 7B FF FA 1A 6E F5… 0,,12841,0:56.846.929,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,12842,0:56.860.934,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12846,0:56.861.931,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,12847,0:56.861.934,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 6B A1 A6 50 5B F3 46 92 24 7B FF FA 1A 6E F5… 0,,12851,0:56.862.931,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,12852,0:56.877.937,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 88 BA B0 FC E6 E3 DD 7B D6 7E D3 F7 10 89 70 07… 0,,12856,0:56.878.934,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,12857,0:56.892.939,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12861,0:56.893.936,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,12862,0:56.893.939,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 88 BA B0 FC E6 E3 DD 7B D6 7E D3 F7 10 89 70 07… 0,,12866,0:56.894.936,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,12867,0:56.909.941,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 50 DD 00 5C CB FC 1C 3E 01 44 EC D2 F0 11 BF D2… 0,,12871,0:56.910.938,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,12872,0:56.924.943,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12876,0:56.925.940,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,12877,0:56.925.943,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 50 DD 00 5C CB FC 1C 3E 01 44 EC D2 F0 11 BF D2… 0,,12881,0:56.926.940,15.004.916 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,12882,0:56.941.946,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 45 27 C2 D8 AF 15 EA EE 8F 68 02 BB 27 6B 70 51… 0,,12886,0:56.942.942,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,12887,0:56.956.948,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12891,0:56.957.945,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,12892,0:56.957.948,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 45 27 C2 D8 AF 15 EA EE 8F 68 02 BB 27 6B 70 51… 0,,12896,0:56.958.945,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,12897,0:56.973.950,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4C 73 66 C1 B3 48 38 9F 4A 34 69 02 BD 0F 0C 08… 0,,12901,0:56.974.947,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,12902,0:56.988.952,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12906,0:56.989.949,2.833 us,,,,,[1 SOF],[Frame: 1633] 0,,12907,0:56.989.952,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4C 73 66 C1 B3 48 38 9F 4A 34 69 02 BD 0F 0C 08… 0,,12911,0:56.990.949,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,12912,0:57.005.954,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 43 5E 6F 7F AB C6 88 78 1F BF 48 AC 25 67 D7 3C… 0,,12916,0:57.006.951,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,12917,0:57.020.957,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12921,0:57.021.953,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,12922,0:57.021.957,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 43 5E 6F 7F AB C6 88 78 1F BF 48 AC 25 67 D7 3C… 0,,12926,0:57.022.954,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,12927,0:57.037.959,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0C BC DC 6C A5 42 1F 17 AB 15 D8 0F 15 6A 55 E9… 0,,12931,0:57.038.956,14.004.750 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,12932,0:57.052.961,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12936,0:57.053.958,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,12937,0:57.053.961,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0C BC DC 6C A5 42 1F 17 AB 15 D8 0F 15 6A 55 E9… 0,,12941,0:57.054.958,15.004.916 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,12942,0:57.069.963,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 C5 C7 F2 34 6C 7E 69 9D 66 C6 78 B1 4D 34 07… 0,,12946,0:57.070.960,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,12947,0:57.084.965,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12951,0:57.085.962,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,12952,0:57.085.966,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E3 C5 C7 F2 34 6C 7E 69 9D 66 C6 78 B1 4D 34 07… 0,,12956,0:57.086.962,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,12957,0:57.101.968,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 BE DE A6 A8 7F 2F C8 9D 98 DE F5 F2 40 DC 95… 0,,12961,0:57.102.965,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,12962,0:57.116.970,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12966,0:57.117.967,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,12967,0:57.117.970,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 BE DE A6 A8 7F 2F C8 9D 98 DE F5 F2 40 DC 95… 0,,12971,0:57.118.967,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,12972,0:57.133.972,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 A7 9E 6A D6 31 B3 60 19 37 68 02 91 0A ED 03… 0,,12976,0:57.134.969,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,12977,0:57.148.974,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12981,0:57.149.971,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,12982,0:57.149.974,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 A7 9E 6A D6 31 B3 60 19 37 68 02 91 0A ED 03… 0,,12986,0:57.150.971,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,12987,0:57.165.977,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B B1 6B F4 0B 8A 01 47 76 BF 8B 2A 2E 30 90 C3… 0,,12991,0:57.166.974,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,12992,0:57.180.979,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,12996,0:57.181.976,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,12997,0:57.181.979,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B B1 6B F4 0B 8A 01 47 76 BF 8B 2A 2E 30 90 C3… 0,,13001,0:57.182.976,15.004.916 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,13002,0:57.197.981,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 07 4E 82 40 74 7B D4 7E 54 FE D1 7C 0D 35 4A 7B… 0,,13006,0:57.198.978,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,13007,0:57.212.983,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13011,0:57.213.980,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,13012,0:57.213.983,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 07 4E 82 40 74 7B D4 7E 54 FE D1 7C 0D 35 4A 7B… 0,,13016,0:57.214.980,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,13017,0:57.229.986,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 BF 77 8C DE AF 68 29 9B BE 48 EB 93 18 76 8F… 0,,13021,0:57.230.982,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,13022,0:57.244.988,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13026,0:57.245.985,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,13027,0:57.245.988,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 BF 77 8C DE AF 68 29 9B BE 48 EB 93 18 76 8F… 0,,13031,0:57.246.985,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,13032,0:57.261.990,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7B E3 22 CD 98 7B AE 34 F1 B3 FD 3D FC D6 F4 F8… 0,,13036,0:57.262.987,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,13037,0:57.276.992,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13041,0:57.277.989,2.833 us,,,,,[1 SOF],[Frame: 1921] 0,,13042,0:57.277.992,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7B E3 22 CD 98 7B AE 34 F1 B3 FD 3D FC D6 F4 F8… 0,,13046,0:57.278.989,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,13047,0:57.293.994,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD CE B4 BE F0 04 36 4C 0E 74 AF 47 B5 E1 57 63… 0,,13051,0:57.294.991,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,13052,0:57.308.997,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13056,0:57.309.993,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,13057,0:57.309.997,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD CE B4 BE F0 04 36 4C 0E 74 AF 47 B5 E1 57 63… 0,,13061,0:57.310.994,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,13062,0:57.325.999,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B5 E8 F0 A1 E3 0E 00 DF 40 A5 DF 31 49 F4 A6 9C… 0,,13066,0:57.326.996,14.004.750 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,13067,0:57.341.001,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13071,0:57.341.998,16.005.125 ms,,,,,[17 SOF],[Frames: 1985 - 2001] 0,,13072,0:57.358.003,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 87 EC 76 25 F1 71 FA FD FD 75 34 E8 2A 08 E7… 0,,13076,0:57.359.000,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,13077,0:57.373.005,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13081,0:57.374.002,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,13082,0:57.374.006,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 87 EC 76 25 F1 71 FA FD FD 75 34 E8 2A 08 E7… 0,,13086,0:57.375.002,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,13087,0:57.390.008,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 26 6C 7C E3 C0 0B F5 64 89 A3 0E 60 D9 B1 67… 0,,13091,0:57.391.005,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,13092,0:57.405.010,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13096,0:57.406.007,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,13097,0:57.406.010,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 26 6C 7C E3 C0 0B F5 64 89 A3 0E 60 D9 B1 67… 0,,13101,0:57.407.007,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,13102,0:57.422.012,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 C7 CC 5B A5 D2 4F 09 04 04 79 FC 70 F1 B4 71… 0,,13106,0:57.423.009,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,13107,0:57.437.014,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13111,0:57.438.011,2.833 us,,,,,[1 SOF],[Frame: 33] 0,,13112,0:57.438.014,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 C7 CC 5B A5 D2 4F 09 04 04 79 FC 70 F1 B4 71… 0,,13116,0:57.439.011,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,13117,0:57.454.017,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 13 BE E8 BE 41 62 CD 47 1B D2 87 2D 75 DA 7D 17… 0,,13121,0:57.455.014,14.004.750 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,13122,0:57.469.019,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13126,0:57.470.016,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,13127,0:57.470.019,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 13 BE E8 BE 41 62 CD 47 1B D2 87 2D 75 DA 7D 17… 0,,13131,0:57.471.016,15.004.916 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,13132,0:57.486.021,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 D4 82 85 A2 15 29 01 8F DA 72 F7 73 25 64 63… 0,,13136,0:57.487.018,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,13137,0:57.501.023,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13141,0:57.502.020,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,13142,0:57.502.023,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 D4 82 85 A2 15 29 01 8F DA 72 F7 73 25 64 63… 0,,13146,0:57.503.020,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,13147,0:57.518.026,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D 39 F7 93 BC 66 06 1D 43 CB 57 65 48 2E EA 87… 0,,13151,0:57.519.022,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,13152,0:57.533.028,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13156,0:57.534.024,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,13157,0:57.534.028,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D 39 F7 93 BC 66 06 1D 43 CB 57 65 48 2E EA 87… 0,,13161,0:57.535.025,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,13162,0:57.550.030,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF 82 9D A9 C8 7A CF 59 D9 A5 38 B9 F7 FD 19 90… 0,,13166,0:57.551.027,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,13167,0:57.565.032,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13171,0:57.566.029,2.833 us,,,,,[1 SOF],[Frame: 161] 0,,13172,0:57.566.032,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF 82 9D A9 C8 7A CF 59 D9 A5 38 B9 F7 FD 19 90… 0,,13176,0:57.567.029,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,13177,0:57.582.034,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 02 02 09 66 F7 B1 3A 51 61 3D 22 EF 62 84 15… 0,,13181,0:57.583.031,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,13182,0:57.597.036,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13186,0:57.598.033,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,13187,0:57.598.037,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 02 02 09 66 F7 B1 3A 51 61 3D 22 EF 62 84 15… 0,,13191,0:57.599.034,15.004.916 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,13192,0:57.614.039,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A6 AB AF DE 7B 8C A2 C1 CE 9B 76 22 EE BB E5 15… 0,,13196,0:57.615.036,14.004.750 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,13197,0:57.629.041,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13201,0:57.630.038,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,13202,0:57.630.041,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A6 AB AF DE 7B 8C A2 C1 CE 9B 76 22 EE BB E5 15… 0,,13206,0:57.631.038,15.004.916 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,13207,0:57.646.043,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C 59 A8 E4 03 6B 89 98 9E 0A 32 21 24 7D 6B 37… 0,,13211,0:57.647.040,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,13212,0:57.661.045,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13216,0:57.662.042,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,13217,0:57.662.046,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C 59 A8 E4 03 6B 89 98 9E 0A 32 21 24 7D 6B 37… 0,,13221,0:57.663.042,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,13222,0:57.678.048,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B7 EE C3 09 35 73 48 31 95 67 D5 6A E4 E9 76 41… 0,,13226,0:57.679.045,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,13227,0:57.693.050,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13231,0:57.694.047,2.833 us,,,,,[1 SOF],[Frame: 289] 0,,13232,0:57.694.050,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B7 EE C3 09 35 73 48 31 95 67 D5 6A E4 E9 76 41… 0,,13236,0:57.695.047,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,13237,0:57.710.052,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 A3 58 A4 44 90 54 81 53 B5 6A 93 C2 AC 49 0A… 0,,13241,0:57.711.049,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,13242,0:57.725.054,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13246,0:57.726.051,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,13247,0:57.726.054,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 A3 58 A4 44 90 54 81 53 B5 6A 93 C2 AC 49 0A… 0,,13251,0:57.727.051,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,13252,0:57.742.057,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF E6 65 D0 CC C5 60 4C 18 9A CC 2A D4 1F EF 81… 0,,13256,0:57.743.054,14.004.750 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,13257,0:57.757.059,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13261,0:57.758.056,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,13262,0:57.758.059,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF E6 65 D0 CC C5 60 4C 18 9A CC 2A D4 1F EF 81… 0,,13266,0:57.759.056,15.004.916 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,13267,0:57.774.061,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 ED CF 00 AE 03 E9 D0 B6 AC 24 19 66 F4 D9 6A 7E… 0,,13271,0:57.775.058,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,13272,0:57.789.063,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13276,0:57.790.060,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,13277,0:57.790.063,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 ED CF 00 AE 03 E9 D0 B6 AC 24 19 66 F4 D9 6A 7E… 0,,13281,0:57.791.060,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,13282,0:57.806.066,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AB C3 FB 17 AE 53 28 FF 78 23 FF 35 BD 4E B5 A3… 0,,13286,0:57.807.062,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,13287,0:57.821.068,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13291,0:57.822.064,2.833 us,,,,,[1 SOF],[Frame: 417] 0,,13292,0:57.822.068,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AB C3 FB 17 AE 53 28 FF 78 23 FF 35 BD 4E B5 A3… 0,,13296,0:57.823.065,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,13297,0:57.838.070,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 82 52 19 CA EC 51 FA A7 31 4B 0F 44 51 D7 C5… 0,,13301,0:57.839.067,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,13302,0:57.853.072,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13306,0:57.854.069,2.833 us,,,,,[1 SOF],[Frame: 449] 0,,13307,0:57.854.072,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 82 52 19 CA EC 51 FA A7 31 4B 0F 44 51 D7 C5… 0,,13311,0:57.855.069,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,13312,0:57.870.074,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 92 12 0B EA 92 90 9C 78 BA D8 7C 15 A3 CF 16 1D… 0,,13316,0:57.871.071,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,13317,0:57.885.076,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13321,0:57.886.073,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,13322,0:57.886.077,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 92 12 0B EA 92 90 9C 78 BA D8 7C 15 A3 CF 16 1D… 0,,13326,0:57.887.073,15.004.916 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,13327,0:57.902.079,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 56 C2 A5 FF 14 74 F4 C0 AA 67 CA AF 87 7C F9 FC… 0,,13331,0:57.903.076,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,13332,0:57.917.081,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13336,0:57.918.078,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,13337,0:57.918.081,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 56 C2 A5 FF 14 74 F4 C0 AA 67 CA AF 87 7C F9 FC… 0,,13341,0:57.919.078,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,13342,0:57.934.083,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 58 78 A4 49 F6 67 8C F5 AC 54 4C B4 C5 35 0B… 0,,13346,0:57.935.080,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,13347,0:57.949.085,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13351,0:57.950.082,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,13352,0:57.950.085,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 58 78 A4 49 F6 67 8C F5 AC 54 4C B4 C5 35 0B… 0,,13356,0:57.951.082,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,13357,0:57.966.088,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 81 8E 0A EB F4 AD 65 F4 9B 02 00 84 52 12 E2… 0,,13361,0:57.967.085,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,13362,0:57.981.090,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13366,0:57.982.087,2.833 us,,,,,[1 SOF],[Frame: 577] 0,,13367,0:57.982.090,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 81 8E 0A EB F4 AD 65 F4 9B 02 00 84 52 12 E2… 0,,13371,0:57.983.087,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,13372,0:57.998.092,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 3E 68 F5 C5 84 49 DE 02 76 69 5D A4 09 3B 0A… 0,,13376,0:57.999.089,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,13377,0:58.013.094,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13381,0:58.014.091,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,13382,0:58.014.094,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 3E 68 F5 C5 84 49 DE 02 76 69 5D A4 09 3B 0A… 0,,13386,0:58.015.091,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,13387,0:58.030.097,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE C9 F5 A4 15 8C 6C 42 C5 B7 E9 94 43 38 8B 87… 0,,13391,0:58.031.093,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,13392,0:58.045.099,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13396,0:58.046.096,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,13397,0:58.046.099,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE C9 F5 A4 15 8C 6C 42 C5 B7 E9 94 43 38 8B 87… 0,,13401,0:58.047.096,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,13402,0:58.062.101,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 30 23 FB B0 B1 10 BC C0 AD 78 E6 AD 42 FD B7… 0,,13406,0:58.063.098,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,13407,0:58.077.103,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13411,0:58.078.100,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,13412,0:58.078.103,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 30 23 FB B0 B1 10 BC C0 AD 78 E6 AD 42 FD B7… 0,,13416,0:58.079.100,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,13417,0:58.094.105,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 3A AD 68 DC 67 3B 0D F3 82 93 CD 28 AF 2B 68… 0,,13421,0:58.095.102,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,13422,0:58.109.108,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13426,0:58.110.104,2.833 us,,,,,[1 SOF],[Frame: 705] 0,,13427,0:58.110.108,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 3A AD 68 DC 67 3B 0D F3 82 93 CD 28 AF 2B 68… 0,,13431,0:58.111.105,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,13432,0:58.126.110,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3C 92 D6 A4 E3 04 AB 02 A0 59 5C FA 91 27 09 34… 0,,13436,0:58.127.107,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,13437,0:58.141.112,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13441,0:58.142.109,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,13442,0:58.142.112,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3C 92 D6 A4 E3 04 AB 02 A0 59 5C FA 91 27 09 34… 0,,13446,0:58.143.109,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,13447,0:58.158.114,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 04 90 D7 54 BB 34 B2 D2 A7 CF CF FE 07 C5 AE… 0,,13451,0:58.159.111,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,13452,0:58.173.116,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13456,0:58.174.113,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,13457,0:58.174.117,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 04 90 D7 54 BB 34 B2 D2 A7 CF CF FE 07 C5 AE… 0,,13461,0:58.175.113,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,13462,0:58.190.119,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 B1 F3 BB ED D1 EE 25 3E 42 10 69 12 E6 11 DD… 0,,13466,0:58.191.116,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,13467,0:58.205.121,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13471,0:58.206.118,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,13472,0:58.206.121,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 B1 F3 BB ED D1 EE 25 3E 42 10 69 12 E6 11 DD… 0,,13476,0:58.207.118,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,13477,0:58.222.123,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA 02 5F 46 50 96 D5 F8 5D 7F ED 13 B6 16 2D F7… 0,,13481,0:58.223.120,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,13482,0:58.237.125,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13486,0:58.238.122,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,13487,0:58.238.125,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA 02 5F 46 50 96 D5 F8 5D 7F ED 13 B6 16 2D F7… 0,,13491,0:58.239.122,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,13492,0:58.254.128,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C 27 54 52 67 04 52 04 AC 87 A5 4D E3 5C 7B A3… 0,,13496,0:58.255.125,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,13497,0:58.269.130,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13501,0:58.270.127,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,13502,0:58.270.130,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C 27 54 52 67 04 52 04 AC 87 A5 4D E3 5C 7B A3… 0,,13506,0:58.271.127,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,13507,0:58.286.132,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6C 61 05 89 02 D4 11 E7 9B B1 76 B0 F9 E6 F3 86… 0,,13511,0:58.287.129,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,13512,0:58.301.134,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13516,0:58.302.131,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,13517,0:58.302.134,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6C 61 05 89 02 D4 11 E7 9B B1 76 B0 F9 E6 F3 86… 0,,13521,0:58.303.131,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,13522,0:58.318.137,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 45 DD 4F 9F E9 78 63 B3 1B 2A 2A CC 17 33 7F… 0,,13526,0:58.319.133,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,13527,0:58.333.139,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13531,0:58.334.136,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,13532,0:58.334.139,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 45 DD 4F 9F E9 78 63 B3 1B 2A 2A CC 17 33 7F… 0,,13536,0:58.335.136,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,13537,0:58.350.141,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 48 8D F6 26 C7 A9 F8 B7 2E 76 31 F7 4E CB 2B… 0,,13541,0:58.351.138,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,13542,0:58.365.143,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13546,0:58.366.140,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,13547,0:58.366.143,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 48 8D F6 26 C7 A9 F8 B7 2E 76 31 F7 4E CB 2B… 0,,13551,0:58.367.140,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,13552,0:58.382.145,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C B3 94 99 5B D6 DC 61 D8 D4 B2 7E 31 55 7C 62… 0,,13556,0:58.383.142,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,13557,0:58.397.148,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13561,0:58.398.144,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,13562,0:58.398.148,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C B3 94 99 5B D6 DC 61 D8 D4 B2 7E 31 55 7C 62… 0,,13566,0:58.399.145,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,13567,0:58.414.150,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 32 A5 DA 10 60 62 FA 8C 51 AF CF 3E 2F 76 94… 0,,13571,0:58.415.147,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,13572,0:58.429.152,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13576,0:58.430.149,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,13577,0:58.430.152,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 32 A5 DA 10 60 62 FA 8C 51 AF CF 3E 2F 76 94… 0,,13581,0:58.431.149,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,13582,0:58.446.154,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 84 33 8E 69 C3 D4 86 9D 17 39 12 2C 8C DF FF 2D… 0,,13586,0:58.447.151,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,13587,0:58.461.156,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13591,0:58.462.153,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,13592,0:58.462.157,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 84 33 8E 69 C3 D4 86 9D 17 39 12 2C 8C DF FF 2D… 0,,13596,0:58.463.153,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,13597,0:58.478.159,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 4D E5 3E 1B 27 2E EA C6 E1 39 B3 A7 34 6F A9… 0,,13601,0:58.479.156,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,13602,0:58.493.161,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13606,0:58.494.158,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,13607,0:58.494.161,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 4D E5 3E 1B 27 2E EA C6 E1 39 B3 A7 34 6F A9… 0,,13611,0:58.495.158,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,13612,0:58.510.163,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 60 59 D8 DF AA FC 8F FE 17 37 9B 11 66 22 D2 15… 0,,13616,0:58.511.160,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,13617,0:58.525.165,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13621,0:58.526.162,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,13622,0:58.526.165,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 59 D8 DF AA FC 8F FE 17 37 9B 11 66 22 D2 15… 0,,13626,0:58.527.162,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,13627,0:58.542.168,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 25 4E 12 E6 27 E4 8B F1 0B 0C 19 B0 36 D7 46… 0,,13631,0:58.543.165,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,13632,0:58.557.170,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13636,0:58.558.167,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,13637,0:58.558.170,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 25 4E 12 E6 27 E4 8B F1 0B 0C 19 B0 36 D7 46… 0,,13641,0:58.559.167,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,13642,0:58.574.172,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 A8 D4 6A 58 9E A9 38 21 EE 00 02 38 B5 16 3D… 0,,13646,0:58.575.169,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,13647,0:58.589.174,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13651,0:58.590.171,16.005.041 ms,,,,,[17 SOF],[Frames: 1185 - 1201] 0,,13652,0:58.606.177,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 29 07 12 B0 03 62 1B 0B BA 83 50 AF A0 46 6F… 0,,13656,0:58.607.173,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,13657,0:58.621.179,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13661,0:58.622.176,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,13662,0:58.622.179,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 29 07 12 B0 03 62 1B 0B BA 83 50 AF A0 46 6F… 0,,13666,0:58.623.176,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,13667,0:58.638.181,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9D D8 48 83 BA 37 1E 1D 31 49 DE 6B 7C 07 30 47… 0,,13671,0:58.639.178,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,13672,0:58.653.183,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13676,0:58.654.180,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,13677,0:58.654.183,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9D D8 48 83 BA 37 1E 1D 31 49 DE 6B 7C 07 30 47… 0,,13681,0:58.655.180,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,13682,0:58.670.185,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 3E B3 BA 57 FE 81 18 FF 23 4C 8B F0 06 76 48… 0,,13686,0:58.671.182,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,13687,0:58.685.188,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13691,0:58.686.184,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,13692,0:58.686.188,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 3E B3 BA 57 FE 81 18 FF 23 4C 8B F0 06 76 48… 0,,13696,0:58.687.185,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,13697,0:58.702.190,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD 1C 2D 60 9E E2 FD 6A 30 61 4A 62 9B A1 95 C9… 0,,13701,0:58.703.187,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,13702,0:58.717.192,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13706,0:58.718.189,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,13707,0:58.718.192,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD 1C 2D 60 9E E2 FD 6A 30 61 4A 62 9B A1 95 C9… 0,,13711,0:58.719.189,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,13712,0:58.734.194,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EB 5C B3 F2 DD BA 0B 54 F6 C0 57 20 2C 5E 87 12… 0,,13716,0:58.735.191,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,13717,0:58.749.196,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13721,0:58.750.193,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,13722,0:58.750.197,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EB 5C B3 F2 DD BA 0B 54 F6 C0 57 20 2C 5E 87 12… 0,,13726,0:58.751.193,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,13727,0:58.766.199,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E EE D2 F6 BD 67 96 87 F7 00 6E A2 27 EB 04 BE… 0,,13731,0:58.767.196,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,13732,0:58.781.201,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13736,0:58.782.198,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,13737,0:58.782.201,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E EE D2 F6 BD 67 96 87 F7 00 6E A2 27 EB 04 BE… 0,,13741,0:58.783.198,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,13742,0:58.798.203,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 F0 73 77 31 6F 29 7B 48 7E 5E 07 7A 7D FD D2… 0,,13746,0:58.799.200,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,13747,0:58.813.205,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13751,0:58.814.202,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,13752,0:58.814.205,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 F0 73 77 31 6F 29 7B 48 7E 5E 07 7A 7D FD D2… 0,,13756,0:58.815.202,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,13757,0:58.830.208,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D 42 2F F4 9C 2E D2 B0 5C 10 96 8E 74 02 C0 3D… 0,,13761,0:58.831.205,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,13762,0:58.845.210,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13766,0:58.846.207,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,13767,0:58.846.210,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D 42 2F F4 9C 2E D2 B0 5C 10 96 8E 74 02 C0 3D… 0,,13771,0:58.847.207,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,13772,0:58.862.212,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 65 6A FA F4 E9 C5 C7 50 03 60 76 2D B6 B6 36… 0,,13776,0:58.863.209,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,13777,0:58.877.214,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13781,0:58.878.211,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,13782,0:58.878.214,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 65 6A FA F4 E9 C5 C7 50 03 60 76 2D B6 B6 36… 0,,13786,0:58.879.211,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,13787,0:58.894.217,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 AC 61 B3 38 A1 AD 0D 46 AE 56 C3 CA BA E0 2D… 0,,13791,0:58.895.213,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,13792,0:58.909.219,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13796,0:58.910.216,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,13797,0:58.910.219,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 AC 61 B3 38 A1 AD 0D 46 AE 56 C3 CA BA E0 2D… 0,,13801,0:58.911.216,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,13802,0:58.926.221,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 8F 31 EF 29 1E DC F6 A0 9F E7 38 86 E6 71 6F… 0,,13806,0:58.927.218,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,13807,0:58.941.223,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13811,0:58.942.220,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,13812,0:58.942.223,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 8F 31 EF 29 1E DC F6 A0 9F E7 38 86 E6 71 6F… 0,,13816,0:58.943.220,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,13817,0:58.958.226,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C 96 55 0C EF EE 2D B6 D5 1C 30 F8 17 27 20 65… 0,,13821,0:58.959.222,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,13822,0:58.973.228,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13826,0:58.974.224,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,13827,0:58.974.228,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C 96 55 0C EF EE 2D B6 D5 1C 30 F8 17 27 20 65… 0,,13831,0:58.975.225,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,13832,0:58.990.230,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FA 2A FE 82 FB D3 30 86 5A 95 3B FD 7A E6 FC 48… 0,,13836,0:58.991.227,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,13837,0:59.005.232,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13841,0:59.006.229,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,13842,0:59.006.232,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FA 2A FE 82 FB D3 30 86 5A 95 3B FD 7A E6 FC 48… 0,,13846,0:59.007.229,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,13847,0:59.022.234,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 3D E4 AC A5 8F BE 64 B4 8E 1C 8F 0D B9 CC EB… 0,,13851,0:59.023.231,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,13852,0:59.037.236,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13856,0:59.038.233,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,13857,0:59.038.237,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 3D E4 AC A5 8F BE 64 B4 8E 1C 8F 0D B9 CC EB… 0,,13861,0:59.039.233,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,13862,0:59.054.239,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5B 88 B0 5B 4B B7 62 93 88 3B 9E 9A 68 C5 B8 51… 0,,13866,0:59.055.236,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,13867,0:59.069.241,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13871,0:59.070.238,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,13872,0:59.070.241,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5B 88 B0 5B 4B B7 62 93 88 3B 9E 9A 68 C5 B8 51… 0,,13876,0:59.071.238,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,13877,0:59.086.243,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 E9 4F 96 CE 41 56 96 64 2C EE 3F 1F A2 C2 B4… 0,,13881,0:59.087.240,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,13882,0:59.101.245,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13886,0:59.102.242,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,13887,0:59.102.245,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 E9 4F 96 CE 41 56 96 64 2C EE 3F 1F A2 C2 B4… 0,,13891,0:59.103.242,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,13892,0:59.118.248,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9F B3 21 90 58 D7 97 59 2E 9B B8 A3 FB 83 2A 14… 0,,13896,0:59.119.245,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,13897,0:59.133.250,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13901,0:59.134.247,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,13902,0:59.134.250,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9F B3 21 90 58 D7 97 59 2E 9B B8 A3 FB 83 2A 14… 0,,13906,0:59.135.247,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,13907,0:59.150.252,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AF FC 6D 0D 80 1C 4B 33 F5 E8 FF 90 93 6A 9B 56… 0,,13911,0:59.151.249,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,13912,0:59.165.254,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13916,0:59.166.251,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,13917,0:59.166.254,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AF FC 6D 0D 80 1C 4B 33 F5 E8 FF 90 93 6A 9B 56… 0,,13921,0:59.167.251,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,13922,0:59.182.257,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D9 78 5A 3B 72 26 04 F2 56 5D B8 8B 43 05 88 0F… 0,,13926,0:59.183.253,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,13927,0:59.197.259,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13931,0:59.198.255,16.005.041 ms,,,,,[17 SOF],[Frames: 1793 - 1809] 0,,13932,0:59.214.261,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC C1 CD 25 8B 42 D1 54 51 5B 31 20 57 C1 2F AC… 0,,13936,0:59.215.258,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,13937,0:59.229.263,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13941,0:59.230.260,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,13942,0:59.230.263,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC C1 CD 25 8B 42 D1 54 51 5B 31 20 57 C1 2F AC… 0,,13946,0:59.231.260,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,13947,0:59.246.265,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 F8 9D 3B 32 9C 97 C2 84 B0 28 CE 0B F1 F9 31… 0,,13951,0:59.247.262,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,13952,0:59.261.267,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13956,0:59.262.264,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,13957,0:59.262.268,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 F8 9D 3B 32 9C 97 C2 84 B0 28 CE 0B F1 F9 31… 0,,13961,0:59.263.265,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,13962,0:59.278.270,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E E5 BB 92 B1 3D D8 C2 17 FD 99 5A 93 AA 8C 79… 0,,13966,0:59.279.267,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,13967,0:59.293.272,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13971,0:59.294.269,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,13972,0:59.294.272,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E E5 BB 92 B1 3D D8 C2 17 FD 99 5A 93 AA 8C 79… 0,,13976,0:59.295.269,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,13977,0:59.310.274,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 F0 9E 99 40 C8 B6 E6 91 2E 49 73 6A 56 DC 0C… 0,,13981,0:59.311.271,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,13982,0:59.325.276,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,13986,0:59.326.273,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,13987,0:59.326.277,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 F0 9E 99 40 C8 B6 E6 91 2E 49 73 6A 56 DC 0C… 0,,13991,0:59.327.273,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,13992,0:59.342.279,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 FC FB AD EF 9D EA C2 A9 98 AE E5 F9 01 55 9B… 0,,13996,0:59.343.276,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,13997,0:59.357.281,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14001,0:59.358.278,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,14002,0:59.358.281,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 FC FB AD EF 9D EA C2 A9 98 AE E5 F9 01 55 9B… 0,,14006,0:59.359.278,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,14007,0:59.374.283,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 FF F0 06 56 33 E4 D2 2E 41 74 94 CE 15 A5 E0… 0,,14011,0:59.375.280,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,14012,0:59.389.285,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14016,0:59.390.282,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,14017,0:59.390.285,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 FF F0 06 56 33 E4 D2 2E 41 74 94 CE 15 A5 E0… 0,,14021,0:59.391.282,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,14022,0:59.406.288,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 4D 33 94 8F 10 68 AF EA 2D DE 3B EF E2 BA F5… 0,,14026,0:59.407.285,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,14027,0:59.421.290,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14031,0:59.422.287,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,14032,0:59.422.290,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 4D 33 94 8F 10 68 AF EA 2D DE 3B EF E2 BA F5… 0,,14036,0:59.423.287,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,14037,0:59.438.292,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 00 3E D6 04 E6 DD E1 A6 51 75 3F 1B 33 85 19… 0,,14041,0:59.439.289,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,14042,0:59.453.294,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14046,0:59.454.291,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,14047,0:59.454.294,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 00 3E D6 04 E6 DD E1 A6 51 75 3F 1B 33 85 19… 0,,14051,0:59.455.291,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,14052,0:59.470.296,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 F4 1B 2E 9F 51 EB CD 16 25 19 82 65 DD 49 20… 0,,14056,0:59.471.293,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,14057,0:59.485.299,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14061,0:59.486.295,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,14062,0:59.486.299,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 F4 1B 2E 9F 51 EB CD 16 25 19 82 65 DD 49 20… 0,,14066,0:59.487.296,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,14067,0:59.502.301,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 AA 10 C9 DD E6 C5 DF 1B B5 8B 6E 62 E5 F9 91… 0,,14071,0:59.503.298,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,14072,0:59.517.303,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14076,0:59.518.300,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,14077,0:59.518.303,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 AA 10 C9 DD E6 C5 DF 1B B5 8B 6E 62 E5 F9 91… 0,,14081,0:59.519.300,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,14082,0:59.534.305,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 8B 25 E1 1F DF 7F 0F 4B FA AA 7E E9 DF 05 4F… 0,,14086,0:59.535.302,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,14087,0:59.549.307,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14091,0:59.550.304,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,14092,0:59.550.308,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 8B 25 E1 1F DF 7F 0F 4B FA AA 7E E9 DF 05 4F… 0,,14096,0:59.551.304,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,14097,0:59.566.310,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 40 7E A4 49 6E B2 75 FA 3F 2F 69 1E 36 6D B4… 0,,14101,0:59.567.307,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,14102,0:59.581.312,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14106,0:59.582.309,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,14107,0:59.582.312,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 40 7E A4 49 6E B2 75 FA 3F 2F 69 1E 36 6D B4… 0,,14111,0:59.583.309,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,14112,0:59.598.314,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 60 AA 33 F6 B2 45 81 76 60 FA D1 73 7F 16 17… 0,,14116,0:59.599.311,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,14117,0:59.613.316,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14121,0:59.614.313,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,14122,0:59.614.316,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 60 AA 33 F6 B2 45 81 76 60 FA D1 73 7F 16 17… 0,,14126,0:59.615.313,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,14127,0:59.630.319,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FB 0F 98 87 94 E2 61 6B D6 7C 4B A5 5B 91 AD 93… 0,,14131,0:59.631.316,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,14132,0:59.645.321,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14136,0:59.646.318,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,14137,0:59.646.321,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FB 0F 98 87 94 E2 61 6B D6 7C 4B A5 5B 91 AD 93… 0,,14141,0:59.647.318,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,14142,0:59.662.323,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 6A 89 B2 10 92 FA C0 8A C5 47 1C 2E BF D3 A7… 0,,14146,0:59.663.320,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,14147,0:59.677.325,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14151,0:59.678.322,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,14152,0:59.678.325,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 6A 89 B2 10 92 FA C0 8A C5 47 1C 2E BF D3 A7… 0,,14156,0:59.679.322,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,14157,0:59.694.328,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 1A E3 E5 5A B0 EA 93 EE A4 4E 8F C4 1B 10 DC… 0,,14161,0:59.695.324,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,14162,0:59.709.330,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14166,0:59.710.327,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,14167,0:59.710.330,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 1A E3 E5 5A B0 EA 93 EE A4 4E 8F C4 1B 10 DC… 0,,14171,0:59.711.327,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,14172,0:59.726.332,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 C5 C6 83 04 27 B5 55 05 EA 73 BE 1D 9C BD A1… 0,,14176,0:59.727.329,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,14177,0:59.741.334,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14181,0:59.742.331,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,14182,0:59.742.334,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 C5 C6 83 04 27 B5 55 05 EA 73 BE 1D 9C BD A1… 0,,14186,0:59.743.331,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,14187,0:59.758.336,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A D5 35 BF E1 A4 27 4B F8 E7 79 97 BE 42 DB 40… 0,,14191,0:59.759.333,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,14192,0:59.773.339,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14196,0:59.774.335,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,14197,0:59.774.339,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A D5 35 BF E1 A4 27 4B F8 E7 79 97 BE 42 DB 40… 0,,14201,0:59.775.336,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,14202,0:59.790.341,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 DA 4C D8 9C 5E 5D 41 16 B5 70 81 01 B0 A8 90… 0,,14206,0:59.791.338,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,14207,0:59.805.343,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14211,0:59.806.340,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,14212,0:59.806.343,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 DA 4C D8 9C 5E 5D 41 16 B5 70 81 01 B0 A8 90… 0,,14216,0:59.807.340,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,14217,0:59.822.345,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B 6E C6 DF 08 51 55 9F 46 F1 C6 2B CE 33 F7 8D… 0,,14221,0:59.823.342,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,14222,0:59.837.347,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14226,0:59.838.344,16.005.041 ms,,,,,[17 SOF],[Frames: 385 - 401] 0,,14227,0:59.854.350,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 CC A5 F7 CD A5 BC EF 7E D3 2F B7 95 C9 FD CB… 0,,14231,0:59.855.347,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,14232,0:59.869.352,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14236,0:59.870.349,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,14237,0:59.870.352,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 CC A5 F7 CD A5 BC EF 7E D3 2F B7 95 C9 FD CB… 0,,14241,0:59.871.349,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,14242,0:59.886.354,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 72 95 34 65 17 8B BE DF A1 4F 64 5A BD A4 55 5E… 0,,14246,0:59.887.351,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,14247,0:59.901.356,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14251,0:59.902.353,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,14252,0:59.902.356,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 72 95 34 65 17 8B BE DF A1 4F 64 5A BD A4 55 5E… 0,,14256,0:59.903.353,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,14257,0:59.918.359,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 A5 C8 AD FD AA 19 A0 77 B7 91 C9 B7 0C 44 AF… 0,,14261,0:59.919.356,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,14262,0:59.933.361,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14266,0:59.934.358,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,14267,0:59.934.361,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 A5 C8 AD FD AA 19 A0 77 B7 91 C9 B7 0C 44 AF… 0,,14271,0:59.935.358,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,14272,0:59.950.363,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 8F 13 AC C2 39 B2 0C F5 D5 9E E4 7D C8 B5 8C… 0,,14276,0:59.951.360,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,14277,0:59.965.365,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14281,0:59.966.362,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,14282,0:59.966.365,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 8F 13 AC C2 39 B2 0C F5 D5 9E E4 7D C8 B5 8C… 0,,14286,0:59.967.362,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,14287,0:59.982.368,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 5B 36 4B 1F 41 DB 0A 21 3D 47 DF 7C 3D 0D 8E… 0,,14291,0:59.983.364,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,14292,0:59.997.370,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14296,0:59.998.367,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,14297,0:59.998.370,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 5B 36 4B 1F 41 DB 0A 21 3D 47 DF 7C 3D 0D 8E… 0,,14301,0:59.999.367,15.004.916 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,14302,1:00.014.372,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 CB 3C D5 38 B7 0A 34 87 45 B7 E2 77 06 38 88… 0,,14306,1:00.015.369,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,14307,1:00.029.374,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14311,1:00.030.371,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,14312,1:00.030.374,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 CB 3C D5 38 B7 0A 34 87 45 B7 E2 77 06 38 88… 0,,14316,1:00.031.371,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,14317,1:00.046.376,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 7C A7 C1 75 66 AB FE 8E 8A 35 3C E5 72 16 2D… 0,,14321,1:00.047.373,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,14322,1:00.061.379,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14326,1:00.062.375,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,14327,1:00.062.379,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 7C A7 C1 75 66 AB FE 8E 8A 35 3C E5 72 16 2D… 0,,14331,1:00.063.376,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,14332,1:00.078.381,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C0 94 D3 29 9D 93 91 41 1A 87 87 86 ED FF 0C 47… 0,,14336,1:00.079.378,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,14337,1:00.093.383,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14341,1:00.094.380,2.833 us,,,,,[1 SOF],[Frame: 641] 0,,14342,1:00.094.383,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C0 94 D3 29 9D 93 91 41 1A 87 87 86 ED FF 0C 47… 0,,14346,1:00.095.380,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,14347,1:00.110.385,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD 04 75 3B CE 1B 91 C5 8A 4D C1 9D 20 B1 A7 82… 0,,14351,1:00.111.382,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,14352,1:00.125.387,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14356,1:00.126.384,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,14357,1:00.126.388,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD 04 75 3B CE 1B 91 C5 8A 4D C1 9D 20 B1 A7 82… 0,,14361,1:00.127.384,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,14362,1:00.142.390,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 9B CE 5C BB CF 54 58 B5 05 2A E3 88 8D 33 05… 0,,14366,1:00.143.387,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,14367,1:00.157.392,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14371,1:00.158.389,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,14372,1:00.158.392,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 9B CE 5C BB CF 54 58 B5 05 2A E3 88 8D 33 05… 0,,14376,1:00.159.389,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,14377,1:00.174.394,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FE A9 0C 64 CB 65 C8 5E 5E 0C 00 28 6C F9 8E D4… 0,,14381,1:00.175.391,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,14382,1:00.189.396,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14386,1:00.190.393,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,14387,1:00.190.396,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FE A9 0C 64 CB 65 C8 5E 5E 0C 00 28 6C F9 8E D4… 0,,14391,1:00.191.393,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,14392,1:00.206.399,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 13 7B B5 84 19 C8 52 42 BF 8F 97 B5 C9 73 95 DC… 0,,14396,1:00.207.396,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,14397,1:00.221.401,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14401,1:00.222.398,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,14402,1:00.222.401,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 13 7B B5 84 19 C8 52 42 BF 8F 97 B5 C9 73 95 DC… 0,,14406,1:00.223.398,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,14407,1:00.238.403,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 E8 30 29 0B 41 D2 6D B0 10 00 33 87 6A 9C CD… 0,,14411,1:00.239.400,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,14412,1:00.253.405,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14416,1:00.254.402,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,14417,1:00.254.405,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 E8 30 29 0B 41 D2 6D B0 10 00 33 87 6A 9C CD… 0,,14421,1:00.255.402,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,14422,1:00.270.408,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 29 86 33 8A CE E2 E7 F9 0B E4 97 B7 B2 70 93 73… 0,,14426,1:00.271.404,14.004.750 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,14427,1:00.285.410,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14431,1:00.286.407,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,14432,1:00.286.410,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 29 86 33 8A CE E2 E7 F9 0B E4 97 B7 B2 70 93 73… 0,,14436,1:00.287.407,15.004.916 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,14437,1:00.302.412,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 A9 1C AC 75 DB 1E D4 81 77 FF 29 65 A3 F8 9B… 0,,14441,1:00.303.409,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,14442,1:00.317.414,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14446,1:00.318.411,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,14447,1:00.318.414,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 A9 1C AC 75 DB 1E D4 81 77 FF 29 65 A3 F8 9B… 0,,14451,1:00.319.411,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,14452,1:00.334.416,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A 7E 1A 71 94 AC FF 8B 9A A4 FA 2A 31 19 BA B2… 0,,14456,1:00.335.413,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,14457,1:00.349.419,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14461,1:00.350.415,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,14462,1:00.350.419,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A 7E 1A 71 94 AC FF 8B 9A A4 FA 2A 31 19 BA B2… 0,,14466,1:00.351.416,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,14467,1:00.366.421,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 57 E7 8A 23 7D 7B 9A 4D 03 99 8A 5D 48 08 D8… 0,,14471,1:00.367.418,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,14472,1:00.381.423,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14476,1:00.382.420,2.833 us,,,,,[1 SOF],[Frame: 929] 0,,14477,1:00.382.423,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 57 E7 8A 23 7D 7B 9A 4D 03 99 8A 5D 48 08 D8… 0,,14481,1:00.383.420,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,14482,1:00.398.425,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 AD CD F1 93 1C 5D 6F AF 81 97 5E 3E BC 93 09… 0,,14486,1:00.399.422,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,14487,1:00.413.427,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14491,1:00.414.424,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,14492,1:00.414.428,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 AD CD F1 93 1C 5D 6F AF 81 97 5E 3E BC 93 09… 0,,14496,1:00.415.424,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,14497,1:00.430.430,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 3A 4A 65 5B 4B 00 47 78 01 F2 74 2F 9E 70 7A… 0,,14501,1:00.431.427,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,14502,1:00.445.432,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14506,1:00.446.429,16.005.125 ms,,,,,[17 SOF],[Frames: 993 - 1009] 0,,14507,1:00.462.434,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 A8 5B 71 D7 90 78 2B 52 B5 A6 51 26 D7 50 33… 0,,14511,1:00.463.431,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,14512,1:00.477.436,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14516,1:00.478.433,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,14517,1:00.478.436,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 25 A8 5B 71 D7 90 78 2B 52 B5 A6 51 26 D7 50 33… 0,,14521,1:00.479.433,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,14522,1:00.494.439,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC DB E5 83 0B BE 60 B4 F2 AD 1D 48 06 48 F8 C0… 0,,14526,1:00.495.436,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,14527,1:00.509.441,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14531,1:00.510.438,2.833 us,,,,,[1 SOF],[Frame: 1057] 0,,14532,1:00.510.441,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC DB E5 83 0B BE 60 B4 F2 AD 1D 48 06 48 F8 C0… 0,,14536,1:00.511.438,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,14537,1:00.526.443,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 FF 94 46 AE B5 9B B7 49 0F D9 AE C4 C1 38 B6… 0,,14541,1:00.527.440,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,14542,1:00.541.445,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14546,1:00.542.442,2.833 us,,,,,[1 SOF],[Frame: 1089] 0,,14547,1:00.542.445,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 FF 94 46 AE B5 9B B7 49 0F D9 AE C4 C1 38 B6… 0,,14551,1:00.543.442,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,14552,1:00.558.448,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 49 E6 39 E3 26 AD 68 9B 47 5D CE 67 17 A0 7A… 0,,14556,1:00.559.444,14.004.750 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,14557,1:00.573.450,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14561,1:00.574.447,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,14562,1:00.574.450,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 49 E6 39 E3 26 AD 68 9B 47 5D CE 67 17 A0 7A… 0,,14566,1:00.575.447,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,14567,1:00.590.452,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 E1 FB 10 18 9C EC 4A A6 C6 6F 00 18 AA 61 0E… 0,,14571,1:00.591.449,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,14572,1:00.605.454,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14576,1:00.606.451,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,14577,1:00.606.454,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 E1 FB 10 18 9C EC 4A A6 C6 6F 00 18 AA 61 0E… 0,,14581,1:00.607.451,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,14582,1:00.622.456,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D3 77 EC B5 99 22 BE 0D 3F D7 4E 04 9F 8F 4E 4C… 0,,14586,1:00.623.453,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,14587,1:00.637.458,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14591,1:00.638.455,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,14592,1:00.638.459,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D3 77 EC B5 99 22 BE 0D 3F D7 4E 04 9F 8F 4E 4C… 0,,14596,1:00.639.456,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,14597,1:00.654.461,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 47 85 B0 96 B0 19 C8 6A B0 97 98 AB 92 79 A4 1D… 0,,14601,1:00.655.458,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,14602,1:00.669.463,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14606,1:00.670.460,2.833 us,,,,,[1 SOF],[Frame: 1217] 0,,14607,1:00.670.463,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 47 85 B0 96 B0 19 C8 6A B0 97 98 AB 92 79 A4 1D… 0,,14611,1:00.671.460,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,14612,1:00.686.465,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2F D1 91 A5 A9 AF C5 91 F6 47 A9 2D 68 B4 CE 9F… 0,,14616,1:00.687.462,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,14617,1:00.701.467,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14621,1:00.702.464,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,14622,1:00.702.468,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2F D1 91 A5 A9 AF C5 91 F6 47 A9 2D 68 B4 CE 9F… 0,,14626,1:00.703.464,15.004.916 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,14627,1:00.718.470,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 E1 03 91 F8 25 C3 B6 FC 79 C2 74 38 9C CE 45… 0,,14631,1:00.719.467,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,14632,1:00.733.472,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14636,1:00.734.469,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,14637,1:00.734.472,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 E1 03 91 F8 25 C3 B6 FC 79 C2 74 38 9C CE 45… 0,,14641,1:00.735.469,15.004.916 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,14642,1:00.750.474,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B B9 99 12 66 4A E0 4D 65 B3 10 11 7C AC 0D 92… 0,,14646,1:00.751.471,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,14647,1:00.765.476,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14651,1:00.766.473,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,14652,1:00.766.476,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B B9 99 12 66 4A E0 4D 65 B3 10 11 7C AC 0D 92… 0,,14656,1:00.767.473,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,14657,1:00.782.479,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 22 60 42 B2 B5 44 B1 D9 D2 43 01 E1 02 01 3D… 0,,14661,1:00.783.476,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,14662,1:00.797.481,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14666,1:00.798.478,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,14667,1:00.798.481,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A 22 60 42 B2 B5 44 B1 D9 D2 43 01 E1 02 01 3D… 0,,14671,1:00.799.478,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,14672,1:00.814.483,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D C2 29 56 03 85 A6 C4 50 5A 83 75 E6 27 96 D8… 0,,14676,1:00.815.480,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,14677,1:00.829.485,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14681,1:00.830.482,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,14682,1:00.830.485,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D C2 29 56 03 85 A6 C4 50 5A 83 75 E6 27 96 D8… 0,,14686,1:00.831.482,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,14687,1:00.846.488,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 97 C0 8A 17 B0 97 51 9D 7A FB E1 84 22 98 19 DF… 0,,14691,1:00.847.484,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,14692,1:00.861.490,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14696,1:00.862.486,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,14697,1:00.862.490,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 97 C0 8A 17 B0 97 51 9D 7A FB E1 84 22 98 19 DF… 0,,14701,1:00.863.487,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,14702,1:00.878.492,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 26 00 57 A6 06 25 C8 83 6C D5 C9 4F 0E 31 2B… 0,,14706,1:00.879.489,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,14707,1:00.893.494,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14711,1:00.894.491,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,14712,1:00.894.494,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 26 00 57 A6 06 25 C8 83 6C D5 C9 4F 0E 31 2B… 0,,14716,1:00.895.491,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,14717,1:00.910.496,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 2B D1 35 C3 23 73 5A 9D 0E 91 E0 C6 D1 DE 29… 0,,14721,1:00.911.493,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,14722,1:00.925.498,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14726,1:00.926.495,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,14727,1:00.926.499,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 2B D1 35 C3 23 73 5A 9D 0E 91 E0 C6 D1 DE 29… 0,,14731,1:00.927.496,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,14732,1:00.942.501,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5D DF 3E 35 FE A1 A7 A9 12 54 04 9D 80 72 20 53… 0,,14736,1:00.943.498,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,14737,1:00.957.503,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14741,1:00.958.500,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,14742,1:00.958.503,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5D DF 3E 35 FE A1 A7 A9 12 54 04 9D 80 72 20 53… 0,,14746,1:00.959.500,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,14747,1:00.974.505,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D8 23 26 D9 4D E3 89 38 D6 6C 8F 1B C3 C3 46 17… 0,,14751,1:00.975.502,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,14752,1:00.989.507,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14756,1:00.990.504,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,14757,1:00.990.508,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D8 23 26 D9 4D E3 89 38 D6 6C 8F 1B C3 C3 46 17… 0,,14761,1:00.991.504,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,14762,1:01.006.510,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 B1 A7 B8 8F C6 A8 5B D4 91 92 76 74 4C 03 CF… 0,,14766,1:01.007.507,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,14767,1:01.021.512,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14771,1:01.022.509,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,14772,1:01.022.512,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 B1 A7 B8 8F C6 A8 5B D4 91 92 76 74 4C 03 CF… 0,,14776,1:01.023.509,15.004.916 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,14777,1:01.038.514,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C CB BD A7 42 6A EC 1A 21 58 4A C6 C8 3E D7 86… 0,,14781,1:01.039.511,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,14782,1:01.053.516,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14786,1:01.054.513,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,14787,1:01.054.516,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C CB BD A7 42 6A EC 1A 21 58 4A C6 C8 3E D7 86… 0,,14791,1:01.055.513,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,14792,1:01.070.519,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 47 6B 3D 7E F8 88 75 34 22 5E A4 AF EF 55 22 FA… 0,,14796,1:01.071.515,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,14797,1:01.085.521,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14801,1:01.086.518,16.005.041 ms,,,,,[17 SOF],[Frames: 1633 - 1649] 0,,14802,1:01.102.523,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 00 69 F6 C1 E2 5D 97 AB 26 85 37 F9 95 9F 61… 0,,14806,1:01.103.520,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,14807,1:01.117.525,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14811,1:01.118.522,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,14812,1:01.118.525,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 00 69 F6 C1 E2 5D 97 AB 26 85 37 F9 95 9F 61… 0,,14816,1:01.119.522,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,14817,1:01.134.527,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 12 3F 7D 76 7B CC 31 5D 0B 16 A3 AD 9D F4 B8 A7… 0,,14821,1:01.135.524,14.004.750 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,14822,1:01.149.530,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14826,1:01.150.526,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,14827,1:01.150.530,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 12 3F 7D 76 7B CC 31 5D 0B 16 A3 AD 9D F4 B8 A7… 0,,14831,1:01.151.527,15.004.916 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,14832,1:01.166.532,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 EB B8 2D CD 5E BC 97 56 59 F8 9A 22 24 9A 3A… 0,,14836,1:01.167.529,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,14837,1:01.181.534,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14841,1:01.182.531,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,14842,1:01.182.534,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 EB B8 2D CD 5E BC 97 56 59 F8 9A 22 24 9A 3A… 0,,14846,1:01.183.531,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,14847,1:01.198.536,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 ED C3 61 39 92 E3 F7 43 24 77 93 85 B1 5F 6E… 0,,14851,1:01.199.533,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,14852,1:01.213.538,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14856,1:01.214.535,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,14857,1:01.214.539,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 ED C3 61 39 92 E3 F7 43 24 77 93 85 B1 5F 6E… 0,,14861,1:01.215.535,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,14862,1:01.230.541,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E AE 84 53 38 06 8B 31 28 3B 03 6B 89 60 33 5F… 0,,14866,1:01.231.538,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,14867,1:01.245.543,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14871,1:01.246.540,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,14872,1:01.246.543,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E AE 84 53 38 06 8B 31 28 3B 03 6B 89 60 33 5F… 0,,14876,1:01.247.540,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,14877,1:01.262.545,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 2B 86 F9 F9 29 42 DF FB E5 DB A0 63 6C 01 1D… 0,,14881,1:01.263.542,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,14882,1:01.277.547,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14886,1:01.278.544,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,14887,1:01.278.548,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 2B 86 F9 F9 29 42 DF FB E5 DB A0 63 6C 01 1D… 0,,14891,1:01.279.544,15.004.916 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,14892,1:01.294.550,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 B8 89 67 00 AA D2 77 3F 0E 8E 37 72 61 4F B8… 0,,14896,1:01.295.547,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,14897,1:01.309.552,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14901,1:01.310.549,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,14902,1:01.310.552,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 B8 89 67 00 AA D2 77 3F 0E 8E 37 72 61 4F B8… 0,,14906,1:01.311.549,15.004.916 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,14907,1:01.326.554,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C7 E7 AB C9 E7 8B CA 69 61 00 AB A2 81 B6 05 5C… 0,,14911,1:01.327.551,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,14912,1:01.341.556,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14916,1:01.342.553,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,14917,1:01.342.556,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C7 E7 AB C9 E7 8B CA 69 61 00 AB A2 81 B6 05 5C… 0,,14921,1:01.343.553,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,14922,1:01.358.559,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 F2 8F 71 00 4B 5E DC D7 EC D3 A4 88 95 26 8B… 0,,14926,1:01.359.555,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,14927,1:01.373.561,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14931,1:01.374.558,2.833 us,,,,,[1 SOF],[Frame: 1921] 0,,14932,1:01.374.561,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 F2 8F 71 00 4B 5E DC D7 EC D3 A4 88 95 26 8B… 0,,14936,1:01.375.558,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,14937,1:01.390.563,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D 51 F7 D2 25 8A 93 B8 20 AF C2 4C 36 4A 35 43… 0,,14941,1:01.391.560,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,14942,1:01.405.565,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14946,1:01.406.562,2.833 us,,,,,[1 SOF],[Frame: 1953] 0,,14947,1:01.406.565,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D 51 F7 D2 25 8A 93 B8 20 AF C2 4C 36 4A 35 43… 0,,14951,1:01.407.562,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,14952,1:01.422.567,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 B4 76 DF 35 FB 35 3F 49 3C 48 42 64 2C 86 2C… 0,,14956,1:01.423.564,14.004.750 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,14957,1:01.437.570,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14961,1:01.438.566,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,14962,1:01.438.570,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 B4 76 DF 35 FB 35 3F 49 3C 48 42 64 2C 86 2C… 0,,14966,1:01.439.567,15.005.000 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,14967,1:01.454.572,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 17 0B 91 D2 11 79 4A 15 08 FC 30 DA A6 5C 6B 6A… 0,,14971,1:01.455.569,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,14972,1:01.469.574,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14976,1:01.470.571,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,14977,1:01.470.574,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 17 0B 91 D2 11 79 4A 15 08 FC 30 DA A6 5C 6B 6A… 0,,14981,1:01.471.571,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,14982,1:01.486.576,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CB 6C 49 70 38 03 C2 A9 AB 61 19 C8 0A 6C 0E C0… 0,,14986,1:01.487.573,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,14987,1:01.501.578,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,14991,1:01.502.575,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,14992,1:01.502.579,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CB 6C 49 70 38 03 C2 A9 AB 61 19 C8 0A 6C 0E C0… 0,,14996,1:01.503.575,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,14997,1:01.518.581,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C 7A 36 91 19 50 72 A5 A5 B4 45 70 C6 15 41 5C… 0,,15001,1:01.519.578,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,15002,1:01.533.583,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15006,1:01.534.580,2.833 us,,,,,[1 SOF],[Frame: 33] 0,,15007,1:01.534.583,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C 7A 36 91 19 50 72 A5 A5 B4 45 70 C6 15 41 5C… 0,,15011,1:01.535.580,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,15012,1:01.550.585,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B3 8B 4C 44 7B 44 D3 D4 1A 5D 2F 47 38 74 B1 C8… 0,,15016,1:01.551.582,14.004.750 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,15017,1:01.565.587,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15021,1:01.566.584,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,15022,1:01.566.587,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B3 8B 4C 44 7B 44 D3 D4 1A 5D 2F 47 38 74 B1 C8… 0,,15026,1:01.567.584,15.004.916 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,15027,1:01.582.590,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 98 4E AA D4 EE B6 4E 77 64 6D 33 B6 AD 90 6B 85… 0,,15031,1:01.583.587,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,15032,1:01.597.592,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15036,1:01.598.589,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,15037,1:01.598.592,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 98 4E AA D4 EE B6 4E 77 64 6D 33 B6 AD 90 6B 85… 0,,15041,1:01.599.589,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,15042,1:01.614.594,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC 87 51 44 BA 92 ED 5D 20 CB A9 0B 1E E6 AC 56… 0,,15046,1:01.615.591,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,15047,1:01.629.596,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15051,1:01.630.593,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,15052,1:01.630.596,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC 87 51 44 BA 92 ED 5D 20 CB A9 0B 1E E6 AC 56… 0,,15056,1:01.631.593,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,15057,1:01.646.599,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 37 E9 D6 59 C9 4F A5 83 BE F8 F8 9E 4C 8D 20 FB… 0,,15061,1:01.647.595,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,15062,1:01.661.601,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15066,1:01.662.598,2.833 us,,,,,[1 SOF],[Frame: 161] 0,,15067,1:01.662.601,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 37 E9 D6 59 C9 4F A5 83 BE F8 F8 9E 4C 8D 20 FB… 0,,15071,1:01.663.598,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,15072,1:01.678.603,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 0A 23 44 E2 5F 80 44 2F 4E 5A 1A 66 90 A9 D2… 0,,15076,1:01.679.600,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,15077,1:01.693.605,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15081,1:01.694.602,16.005.020 ms,,,,,[17 SOF],[Frames: 193 - 209] 0,,15082,1:01.710.607,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 AA 21 83 3F BF 8F D7 AD 30 FD CA 18 F6 CF 2F… 0,,15086,1:01.711.604,14.004.750 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,15087,1:01.725.610,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15091,1:01.726.606,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,15092,1:01.726.610,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 26 AA 21 83 3F BF 8F D7 AD 30 FD CA 18 F6 CF 2F… 0,,15096,1:01.727.607,15.004.916 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,15097,1:01.742.612,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BB 89 2E 9D 28 EA 47 FD A3 D5 B2 57 F0 13 84 60… 0,,15101,1:01.743.609,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,15102,1:01.757.614,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15106,1:01.758.611,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,15107,1:01.758.614,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BB 89 2E 9D 28 EA 47 FD A3 D5 B2 57 F0 13 84 60… 0,,15111,1:01.759.611,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,15112,1:01.774.616,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C 56 DF DC 1F 04 01 78 81 25 F3 20 45 50 44 0C… 0,,15116,1:01.775.613,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,15117,1:01.789.618,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15121,1:01.790.615,2.833 us,,,,,[1 SOF],[Frame: 289] 0,,15122,1:01.790.619,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C 56 DF DC 1F 04 01 78 81 25 F3 20 45 50 44 0C… 0,,15126,1:01.791.615,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,15127,1:01.806.621,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 6B CD 07 97 CC 80 03 B4 F1 AC D1 2D 00 A4 4E… 0,,15131,1:01.807.618,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,15132,1:01.821.623,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15136,1:01.822.620,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,15137,1:01.822.623,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 6B CD 07 97 CC 80 03 B4 F1 AC D1 2D 00 A4 4E… 0,,15141,1:01.823.620,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,15142,1:01.838.625,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 45 8B BA A6 D5 57 16 89 66 78 D1 43 8A 23 05 4A… 0,,15146,1:01.839.622,14.004.750 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,15147,1:01.853.627,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15151,1:01.854.624,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,15152,1:01.854.627,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 45 8B BA A6 D5 57 16 89 66 78 D1 43 8A 23 05 4A… 0,,15156,1:01.855.624,15.004.916 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,15157,1:01.870.630,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 EE 3E 24 12 7D 8B 6A EF C4 74 6B 1E 00 EF 5B… 0,,15161,1:01.871.627,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,15162,1:01.885.632,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15166,1:01.886.629,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,15167,1:01.886.632,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 EE 3E 24 12 7D 8B 6A EF C4 74 6B 1E 00 EF 5B… 0,,15171,1:01.887.629,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,15172,1:01.902.634,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 81 40 7C 15 08 CD C6 35 FA A7 17 62 DF BB B3 9A… 0,,15176,1:01.903.631,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,15177,1:01.917.636,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15181,1:01.918.633,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,15182,1:01.918.636,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 81 40 7C 15 08 CD C6 35 FA A7 17 62 DF BB B3 9A… 0,,15186,1:01.919.633,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,15187,1:01.934.639,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EA D6 FD 6F 15 55 FA 4C FD 39 03 64 9C AD 94 27… 0,,15191,1:01.935.635,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,15192,1:01.949.641,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15196,1:01.950.638,2.833 us,,,,,[1 SOF],[Frame: 449] 0,,15197,1:01.950.641,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EA D6 FD 6F 15 55 FA 4C FD 39 03 64 9C AD 94 27… 0,,15201,1:01.951.638,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,15202,1:01.966.643,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D C2 32 30 B9 31 F9 E3 8A EF CA 24 23 AB 65 89… 0,,15206,1:01.967.640,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,15207,1:01.981.645,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15211,1:01.982.642,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,15212,1:01.982.645,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D C2 32 30 B9 31 F9 E3 8A EF CA 24 23 AB 65 89… 0,,15216,1:01.983.642,15.004.916 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,15217,1:01.998.647,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C7 68 68 B8 96 0A 4B C3 A4 62 CB CA 86 66 52 C9… 0,,15221,1:01.999.644,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,15222,1:02.013.650,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15226,1:02.014.646,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,15227,1:02.014.650,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C7 68 68 B8 96 0A 4B C3 A4 62 CB CA 86 66 52 C9… 0,,15231,1:02.015.647,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,15232,1:02.030.652,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 66 EB 57 27 C3 9B 53 59 8D 85 07 70 FA BB 61 B6… 0,,15236,1:02.031.649,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,15237,1:02.045.654,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15241,1:02.046.651,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,15242,1:02.046.654,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 66 EB 57 27 C3 9B 53 59 8D 85 07 70 FA BB 61 B6… 0,,15246,1:02.047.651,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,15247,1:02.062.656,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 5C 55 18 A4 B5 88 05 F1 D2 27 D8 A4 2E 11 C3… 0,,15251,1:02.063.653,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,15252,1:02.077.658,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15256,1:02.078.655,2.833 us,,,,,[1 SOF],[Frame: 577] 0,,15257,1:02.078.659,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 5C 55 18 A4 B5 88 05 F1 D2 27 D8 A4 2E 11 C3… 0,,15261,1:02.079.655,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,15262,1:02.094.661,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 15 02 5E 98 30 CD 42 33 13 5A B8 F8 FE 84 F9 81… 0,,15266,1:02.095.658,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,15267,1:02.109.663,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15271,1:02.110.660,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,15272,1:02.110.663,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 15 02 5E 98 30 CD 42 33 13 5A B8 F8 FE 84 F9 81… 0,,15276,1:02.111.660,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,15277,1:02.126.665,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7F F0 23 4F 3D 03 3C 3E D2 2A 67 B7 26 94 DE E8… 0,,15281,1:02.127.662,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,15282,1:02.141.667,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15286,1:02.142.664,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,15287,1:02.142.667,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7F F0 23 4F 3D 03 3C 3E D2 2A 67 B7 26 94 DE E8… 0,,15291,1:02.143.664,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,15292,1:02.158.670,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F7 5E 34 D9 4B BA 76 12 3C E6 08 B2 A4 66 17 35… 0,,15296,1:02.159.667,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,15297,1:02.173.672,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15301,1:02.174.669,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,15302,1:02.174.672,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F7 5E 34 D9 4B BA 76 12 3C E6 08 B2 A4 66 17 35… 0,,15306,1:02.175.669,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,15307,1:02.190.674,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 7E 31 9C 71 1D 60 A7 F8 56 87 A7 D0 78 3F F9… 0,,15311,1:02.191.671,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,15312,1:02.205.676,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15316,1:02.206.673,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,15317,1:02.206.676,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 7E 31 9C 71 1D 60 A7 F8 56 87 A7 D0 78 3F F9… 0,,15321,1:02.207.673,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,15322,1:02.222.679,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 EB 41 21 13 A1 FE DD 3C 16 16 3E 18 EE F8 CB… 0,,15326,1:02.223.675,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,15327,1:02.237.681,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15331,1:02.238.677,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,15332,1:02.238.681,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 EB 41 21 13 A1 FE DD 3C 16 16 3E 18 EE F8 CB… 0,,15336,1:02.239.678,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,15337,1:02.254.683,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 87 F0 9C 48 E5 60 AB 95 07 79 2C 8C 17 98 0C 79… 0,,15341,1:02.255.680,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,15342,1:02.269.685,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15346,1:02.270.682,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,15347,1:02.270.685,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 87 F0 9C 48 E5 60 AB 95 07 79 2C 8C 17 98 0C 79… 0,,15351,1:02.271.682,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,15352,1:02.286.687,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0E BC 64 B6 A0 F3 DA 64 B1 8B AB 9F D8 EC 44 92… 0,,15356,1:02.287.684,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,15357,1:02.301.689,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15361,1:02.302.686,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,15362,1:02.302.690,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0E BC 64 B6 A0 F3 DA 64 B1 8B AB 9F D8 EC 44 92… 0,,15366,1:02.303.687,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,15367,1:02.318.692,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C4 D9 CD 17 D3 82 72 08 C9 E9 0D 22 8F 06 06 1D… 0,,15371,1:02.319.689,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,15372,1:02.333.694,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15376,1:02.334.691,16.005.041 ms,,,,,[17 SOF],[Frames: 833 - 849] 0,,15377,1:02.350.696,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A FE BD 5A 72 35 1F 8B A8 59 47 70 25 6B B7 10… 0,,15381,1:02.351.693,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,15382,1:02.365.698,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15386,1:02.366.695,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,15387,1:02.366.699,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A FE BD 5A 72 35 1F 8B A8 59 47 70 25 6B B7 10… 0,,15391,1:02.367.695,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,15392,1:02.382.701,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 A9 12 61 72 D7 E1 28 C4 BE 7B 66 10 F3 F5 1D… 0,,15396,1:02.383.698,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,15397,1:02.397.703,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15401,1:02.398.700,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,15402,1:02.398.703,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 A9 12 61 72 D7 E1 28 C4 BE 7B 66 10 F3 F5 1D… 0,,15406,1:02.399.700,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,15407,1:02.414.705,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 AC DA 91 A2 42 EA 19 91 F5 66 77 7A 0F 2B 65… 0,,15411,1:02.415.702,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,15412,1:02.429.707,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15416,1:02.430.704,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,15417,1:02.430.707,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 AC DA 91 A2 42 EA 19 91 F5 66 77 7A 0F 2B 65… 0,,15421,1:02.431.704,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,15422,1:02.446.710,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 C0 EE E5 20 A5 0F 8E 0B 44 55 32 E7 32 D7 57… 0,,15426,1:02.447.707,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,15427,1:02.461.712,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15431,1:02.462.709,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,15432,1:02.462.712,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 C0 EE E5 20 A5 0F 8E 0B 44 55 32 E7 32 D7 57… 0,,15436,1:02.463.709,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,15437,1:02.478.714,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 74 03 73 C4 7D C3 21 03 39 51 D3 E3 4C 64 B0… 0,,15441,1:02.479.711,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,15442,1:02.493.716,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15446,1:02.494.713,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,15447,1:02.494.716,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 74 03 73 C4 7D C3 21 03 39 51 D3 E3 4C 64 B0… 0,,15451,1:02.495.713,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,15452,1:02.510.719,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 4D 4A CD 19 40 D8 68 94 27 E2 E6 11 C7 26 7A… 0,,15456,1:02.511.715,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,15457,1:02.525.721,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15461,1:02.526.717,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,15462,1:02.526.721,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 4D 4A CD 19 40 D8 68 94 27 E2 E6 11 C7 26 7A… 0,,15466,1:02.527.718,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,15467,1:02.542.723,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B 4B CB 9B 06 FE E2 49 12 B4 57 63 A2 FB F8 CA… 0,,15471,1:02.543.720,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,15472,1:02.557.725,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15476,1:02.558.722,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,15477,1:02.558.725,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B 4B CB 9B 06 FE E2 49 12 B4 57 63 A2 FB F8 CA… 0,,15481,1:02.559.722,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,15482,1:02.574.727,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E C6 DC BD 80 6A 7C 39 C5 2C 30 D0 C7 80 69 C4… 0,,15486,1:02.575.724,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,15487,1:02.589.729,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15491,1:02.590.726,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,15492,1:02.590.730,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E C6 DC BD 80 6A 7C 39 C5 2C 30 D0 C7 80 69 C4… 0,,15496,1:02.591.726,15.004.916 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,15497,1:02.606.732,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 30 A8 92 05 AE E3 E2 B1 37 65 40 94 FC E8 DF… 0,,15501,1:02.607.729,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,15502,1:02.621.734,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15506,1:02.622.731,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,15507,1:02.622.734,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 30 A8 92 05 AE E3 E2 B1 37 65 40 94 FC E8 DF… 0,,15511,1:02.623.731,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,15512,1:02.638.736,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B0 96 69 4B 73 CC 00 69 63 B5 94 D3 AE 3D 81 83… 0,,15516,1:02.639.733,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,15517,1:02.653.738,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15521,1:02.654.735,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,15522,1:02.654.739,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B0 96 69 4B 73 CC 00 69 63 B5 94 D3 AE 3D 81 83… 0,,15526,1:02.655.735,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,15527,1:02.670.741,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C4 6E 8F 0E FF 4C 55 5C 0E 51 46 E8 23 E7 1B 0E… 0,,15531,1:02.671.738,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,15532,1:02.685.743,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15536,1:02.686.740,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,15537,1:02.686.743,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C4 6E 8F 0E FF 4C 55 5C 0E 51 46 E8 23 E7 1B 0E… 0,,15541,1:02.687.740,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,15542,1:02.702.745,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E1 07 D9 53 79 72 51 EB 6A B8 01 CC 2E 47 D9 9D… 0,,15546,1:02.703.742,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,15547,1:02.717.747,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15551,1:02.718.744,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,15552,1:02.718.747,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E1 07 D9 53 79 72 51 EB 6A B8 01 CC 2E 47 D9 9D… 0,,15556,1:02.719.744,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,15557,1:02.734.750,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 78 14 0A 66 1C 91 2A 0F ED 0E F5 39 DF 18 82 B2… 0,,15561,1:02.735.746,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,15562,1:02.749.752,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15566,1:02.750.749,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,15567,1:02.750.752,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 78 14 0A 66 1C 91 2A 0F ED 0E F5 39 DF 18 82 B2… 0,,15571,1:02.751.749,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,15572,1:02.766.754,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CE A8 58 E1 23 5C 1E 41 3E 46 D0 EE AC B0 14 27… 0,,15576,1:02.767.751,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,15577,1:02.781.756,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15581,1:02.782.753,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,15582,1:02.782.756,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CE A8 58 E1 23 5C 1E 41 3E 46 D0 EE AC B0 14 27… 0,,15586,1:02.783.753,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,15587,1:02.798.758,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 7B 95 D9 83 9F 40 93 63 60 D0 0D AE 31 04 C0… 0,,15591,1:02.799.755,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,15592,1:02.813.761,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15596,1:02.814.757,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,15597,1:02.814.761,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 7B 95 D9 83 9F 40 93 63 60 D0 0D AE 31 04 C0… 0,,15601,1:02.815.758,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,15602,1:02.830.763,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A1 D7 94 02 18 69 EA 9C C7 83 A3 7E 38 C1 4C 36… 0,,15606,1:02.831.760,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,15607,1:02.845.765,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15611,1:02.846.762,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,15612,1:02.846.765,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A1 D7 94 02 18 69 EA 9C C7 83 A3 7E 38 C1 4C 36… 0,,15616,1:02.847.762,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,15617,1:02.862.767,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D0 BB BA 54 F9 64 FF AC 6A 0F A6 CF A2 24 B2 D3… 0,,15621,1:02.863.764,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,15622,1:02.877.769,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15626,1:02.878.766,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,15627,1:02.878.770,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D0 BB BA 54 F9 64 FF AC 6A 0F A6 CF A2 24 B2 D3… 0,,15631,1:02.879.766,15.004.916 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,15632,1:02.894.772,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3D 5F 9E 1B 85 0D 43 F9 E4 C1 08 3D 17 E5 15 1D… 0,,15636,1:02.895.769,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,15637,1:02.909.774,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15641,1:02.910.771,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,15642,1:02.910.774,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3D 5F 9E 1B 85 0D 43 F9 E4 C1 08 3D 17 E5 15 1D… 0,,15646,1:02.911.771,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,15647,1:02.926.776,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A1 19 E0 85 16 84 E2 B4 12 80 39 8F 90 D7 3E 9E… 0,,15651,1:02.927.773,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,15652,1:02.941.778,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15656,1:02.942.775,16.005.041 ms,,,,,[17 SOF],[Frames: 1441 - 1457] 0,,15657,1:02.958.781,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 9A 1D FA 02 6E 49 4A 6A 05 84 E0 A3 67 AF 33… 0,,15661,1:02.959.778,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,15662,1:02.973.783,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15666,1:02.974.780,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,15667,1:02.974.783,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 9A 1D FA 02 6E 49 4A 6A 05 84 E0 A3 67 AF 33… 0,,15671,1:02.975.780,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,15672,1:02.990.785,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A4 CE 09 8A 58 A7 13 17 AA 5D 55 7E 74 F2 7A 29… 0,,15676,1:02.991.782,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,15677,1:03.005.787,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15681,1:03.006.784,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,15682,1:03.006.787,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A4 CE 09 8A 58 A7 13 17 AA 5D 55 7E 74 F2 7A 29… 0,,15686,1:03.007.784,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,15687,1:03.022.790,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 8C 28 96 5F 15 5B C5 7F E1 0E 21 83 5B 9A 70… 0,,15691,1:03.023.786,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,15692,1:03.037.792,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15696,1:03.038.789,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,15697,1:03.038.792,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 8C 28 96 5F 15 5B C5 7F E1 0E 21 83 5B 9A 70… 0,,15701,1:03.039.789,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,15702,1:03.054.794,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 67 62 B2 F8 6D 8A E5 B3 34 7D 0D DA 8A D8 0A… 0,,15706,1:03.055.791,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,15707,1:03.069.796,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15711,1:03.070.793,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,15712,1:03.070.796,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 67 62 B2 F8 6D 8A E5 B3 34 7D 0D DA 8A D8 0A… 0,,15716,1:03.071.793,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,15717,1:03.086.798,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F5 EF 58 F8 2C 03 56 2D AF CF 4B 02 06 38 29 49… 0,,15721,1:03.087.795,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,15722,1:03.101.801,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15726,1:03.102.797,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,15727,1:03.102.801,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F5 EF 58 F8 2C 03 56 2D AF CF 4B 02 06 38 29 49… 0,,15731,1:03.103.798,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,15732,1:03.118.803,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 43 AA DD CC F6 DD 98 60 07 8A 02 E1 DE 4F E7… 0,,15736,1:03.119.800,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,15737,1:03.133.805,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15741,1:03.134.802,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,15742,1:03.134.805,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 43 AA DD CC F6 DD 98 60 07 8A 02 E1 DE 4F E7… 0,,15746,1:03.135.802,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,15747,1:03.150.807,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 32 0D 46 52 22 B6 1B 28 2A BE 93 EB DC 14 15… 0,,15751,1:03.151.804,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,15752,1:03.165.809,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15756,1:03.166.806,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,15757,1:03.166.810,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 32 0D 46 52 22 B6 1B 28 2A BE 93 EB DC 14 15… 0,,15761,1:03.167.806,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,15762,1:03.182.812,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 3E 3D 93 18 65 92 3C AE 1D 34 91 0C 8C 9F 36… 0,,15766,1:03.183.809,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,15767,1:03.197.814,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15771,1:03.198.811,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,15772,1:03.198.814,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 3E 3D 93 18 65 92 3C AE 1D 34 91 0C 8C 9F 36… 0,,15776,1:03.199.811,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,15777,1:03.214.816,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B6 A4 F4 CA E6 71 1E B4 3E 02 55 58 3D 2C E4 03… 0,,15781,1:03.215.813,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,15782,1:03.229.818,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15786,1:03.230.815,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,15787,1:03.230.818,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B6 A4 F4 CA E6 71 1E B4 3E 02 55 58 3D 2C E4 03… 0,,15791,1:03.231.815,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,15792,1:03.246.821,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1E D2 F4 CB 98 28 F0 F5 FE 17 9A EB C3 14 F7 6F… 0,,15796,1:03.247.818,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,15797,1:03.261.823,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15801,1:03.262.820,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,15802,1:03.262.823,50.729 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1E D2 F4 CB 98 28 F0 F5 FE 17 9A EB C3 14 F7 6F… 0,,15806,1:03.263.820,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,15807,1:03.278.825,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 28 C5 A5 B3 FD 53 C7 07 D2 A3 90 C9 B8 BA B4 AE… 0,,15811,1:03.279.822,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,15812,1:03.293.827,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15816,1:03.294.824,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,15817,1:03.294.827,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 28 C5 A5 B3 FD 53 C7 07 D2 A3 90 C9 B8 BA B4 AE… 0,,15821,1:03.295.824,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,15822,1:03.310.830,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D8 95 37 7A 21 A7 F3 95 56 FD 07 97 46 5E 43 0E… 0,,15826,1:03.311.826,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,15827,1:03.325.832,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15831,1:03.326.829,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,15832,1:03.326.832,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D8 95 37 7A 21 A7 F3 95 56 FD 07 97 46 5E 43 0E… 0,,15836,1:03.327.829,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,15837,1:03.342.834,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 BB 1A C4 51 D4 AD CC 45 9B 7E B2 96 95 B6 D1… 0,,15841,1:03.343.831,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,15842,1:03.357.836,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15846,1:03.358.833,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,15847,1:03.358.836,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 BB 1A C4 51 D4 AD CC 45 9B 7E B2 96 95 B6 D1… 0,,15851,1:03.359.833,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,15852,1:03.374.838,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 B5 14 25 71 89 2D B1 BF 0F 2F 18 44 50 1D 7E… 0,,15856,1:03.375.835,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,15857,1:03.389.841,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15861,1:03.390.837,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,15862,1:03.390.841,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 B5 14 25 71 89 2D B1 BF 0F 2F 18 44 50 1D 7E… 0,,15866,1:03.391.838,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,15867,1:03.406.843,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 81 BE 30 80 EB 56 D1 91 75 59 77 33 D3 B3 05… 0,,15871,1:03.407.840,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,15872,1:03.421.845,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15876,1:03.422.842,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,15877,1:03.422.845,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 81 BE 30 80 EB 56 D1 91 75 59 77 33 D3 B3 05… 0,,15881,1:03.423.842,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,15882,1:03.438.847,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2F 64 DD E4 37 00 F2 A3 8B CB 42 51 50 86 F6 F0… 0,,15886,1:03.439.844,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,15887,1:03.453.849,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15891,1:03.454.846,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,15892,1:03.454.850,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2F 64 DD E4 37 00 F2 A3 8B CB 42 51 50 86 F6 F0… 0,,15896,1:03.455.846,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,15897,1:03.470.852,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 03 04 8D 4C F5 7F 85 F8 72 27 93 51 76 8A F4 5C… 0,,15901,1:03.471.849,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,15902,1:03.485.854,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15906,1:03.486.851,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,15907,1:03.486.854,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 03 04 8D 4C F5 7F 85 F8 72 27 93 51 76 8A F4 5C… 0,,15911,1:03.487.851,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,15912,1:03.502.856,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 03 27 DE 89 32 91 FC 59 2F 73 52 72 3B 89 77 3E… 0,,15916,1:03.503.853,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,15917,1:03.517.858,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15921,1:03.518.855,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,15922,1:03.518.859,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 03 27 DE 89 32 91 FC 59 2F 73 52 72 3B 89 77 3E… 0,,15926,1:03.519.855,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,15927,1:03.534.861,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 29 07 11 66 78 97 08 3B 8A 7C B4 C6 51 2A D7 28… 0,,15931,1:03.535.858,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,15932,1:03.549.863,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15936,1:03.550.860,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,15937,1:03.550.863,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 29 07 11 66 78 97 08 3B 8A 7C B4 C6 51 2A D7 28… 0,,15941,1:03.551.860,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,15942,1:03.566.865,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C CA A0 F2 21 8B B4 C0 4D 70 4F 6C 18 93 7D 46… 0,,15946,1:03.567.862,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,15947,1:03.581.867,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15951,1:03.582.864,16.005.041 ms,,,,,[17 SOF],[Frames: 33 - 49] 0,,15952,1:03.598.870,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 A8 BB 58 27 50 E8 1C A2 D1 3F 86 54 98 51 1A… 0,,15956,1:03.599.866,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,15957,1:03.613.872,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15961,1:03.614.869,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,15962,1:03.614.872,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 A8 BB 58 27 50 E8 1C A2 D1 3F 86 54 98 51 1A… 0,,15966,1:03.615.869,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,15967,1:03.630.874,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 02 9D 34 D6 7A FD 42 6E AF 0F 76 93 64 FD 30… 0,,15971,1:03.631.871,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,15972,1:03.645.876,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15976,1:03.646.873,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,15977,1:03.646.876,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 02 9D 34 D6 7A FD 42 6E AF 0F 76 93 64 FD 30… 0,,15981,1:03.647.873,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,15982,1:03.662.878,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D CA 16 BD D8 19 A6 C6 39 80 84 C6 44 41 9B 69… 0,,15986,1:03.663.875,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,15987,1:03.677.881,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,15991,1:03.678.877,2.833 us,,,,,[1 SOF],[Frame: 129] 0,,15992,1:03.678.881,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D CA 16 BD D8 19 A6 C6 39 80 84 C6 44 41 9B 69… 0,,15996,1:03.679.878,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,15997,1:03.694.883,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B0 DF FF C6 42 B9 CF 7B 00 A9 B7 B7 3E B3 22 49… 0,,16001,1:03.695.880,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,16002,1:03.709.885,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16006,1:03.710.882,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,16007,1:03.710.885,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B0 DF FF C6 42 B9 CF 7B 00 A9 B7 B7 3E B3 22 49… 0,,16011,1:03.711.882,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,16012,1:03.726.887,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 67 2B 25 A2 FB 68 DA 16 E4 51 4A 45 76 CF 56… 0,,16016,1:03.727.884,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,16017,1:03.741.889,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16021,1:03.742.886,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,16022,1:03.742.890,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 67 2B 25 A2 FB 68 DA 16 E4 51 4A 45 76 CF 56… 0,,16026,1:03.743.886,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,16027,1:03.758.892,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 43 51 E7 62 43 A9 76 DA 40 B6 17 8D 3E C3 D6 90… 0,,16031,1:03.759.889,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,16032,1:03.773.894,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16036,1:03.774.891,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,16037,1:03.774.894,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 43 51 E7 62 43 A9 76 DA 40 B6 17 8D 3E C3 D6 90… 0,,16041,1:03.775.891,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,16042,1:03.790.896,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 E2 CD C7 09 5D C4 13 E4 63 D7 B7 D5 3A 69 E2… 0,,16046,1:03.791.893,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,16047,1:03.805.898,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16051,1:03.806.895,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,16052,1:03.806.898,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 E2 CD C7 09 5D C4 13 E4 63 D7 B7 D5 3A 69 E2… 0,,16056,1:03.807.895,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,16057,1:03.822.901,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 36 56 7F DD 07 EF 1A 17 BD B0 56 D5 93 A3 33… 0,,16061,1:03.823.898,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,16062,1:03.837.903,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16066,1:03.838.900,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,16067,1:03.838.903,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 36 56 7F DD 07 EF 1A 17 BD B0 56 D5 93 A3 33… 0,,16071,1:03.839.900,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,16072,1:03.854.905,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 6D FF 35 11 FC DA EF A3 20 F2 47 95 0E DD C6… 0,,16076,1:03.855.902,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,16077,1:03.869.907,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16081,1:03.870.904,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,16082,1:03.870.907,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 6D FF 35 11 FC DA EF A3 20 F2 47 95 0E DD C6… 0,,16086,1:03.871.904,15.004.916 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,16087,1:03.886.910,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 68 42 B0 9E 4E 78 96 1A A9 1E F2 CB DB 35 9F… 0,,16091,1:03.887.906,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,16092,1:03.901.912,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16096,1:03.902.908,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,16097,1:03.902.912,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 68 42 B0 9E 4E 78 96 1A A9 1E F2 CB DB 35 9F… 0,,16101,1:03.903.909,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,16102,1:03.918.914,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D0 19 26 82 87 70 8F FE 95 37 4D 00 AE 17 11 DF… 0,,16106,1:03.919.911,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,16107,1:03.933.916,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16111,1:03.934.913,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,16112,1:03.934.916,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D0 19 26 82 87 70 8F FE 95 37 4D 00 AE 17 11 DF… 0,,16116,1:03.935.913,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,16117,1:03.950.918,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A1 53 5D B6 4A E2 67 5F 84 21 01 29 67 5F 1C A2… 0,,16121,1:03.951.915,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,16122,1:03.965.920,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16126,1:03.966.917,2.833 us,,,,,[1 SOF],[Frame: 417] 0,,16127,1:03.966.921,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A1 53 5D B6 4A E2 67 5F 84 21 01 29 67 5F 1C A2… 0,,16131,1:03.967.918,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,16132,1:03.982.923,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B6 C1 46 F9 09 A8 F5 D5 66 9D D5 9F 24 98 84 48… 0,,16136,1:03.983.920,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,16137,1:03.997.925,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16141,1:03.998.922,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,16142,1:03.998.925,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B6 C1 46 F9 09 A8 F5 D5 66 9D D5 9F 24 98 84 48… 0,,16146,1:03.999.922,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,16147,1:04.014.927,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E7 91 98 AD E2 C7 B3 4B 09 D9 80 39 F8 E9 D3 B6… 0,,16151,1:04.015.924,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,16152,1:04.029.929,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16156,1:04.030.926,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,16157,1:04.030.930,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E7 91 98 AD E2 C7 B3 4B 09 D9 80 39 F8 E9 D3 B6… 0,,16161,1:04.031.926,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,16162,1:04.046.932,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 78 DC 02 19 2B FB 86 AE D0 BC 47 9D DD A1 D0 22… 0,,16166,1:04.047.929,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,16167,1:04.061.934,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16171,1:04.062.931,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,16172,1:04.062.934,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 78 DC 02 19 2B FB 86 AE D0 BC 47 9D DD A1 D0 22… 0,,16176,1:04.063.931,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,16177,1:04.078.936,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5B C5 D2 08 35 9D 82 66 F0 EB CE 9D 2E 00 7B EF… 0,,16181,1:04.079.933,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,16182,1:04.093.938,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16186,1:04.094.935,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,16187,1:04.094.938,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5B C5 D2 08 35 9D 82 66 F0 EB CE 9D 2E 00 7B EF… 0,,16191,1:04.095.935,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,16192,1:04.110.941,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 9A F0 24 13 DF CC 45 FF 9D 3B D1 06 D6 8A EE… 0,,16196,1:04.111.938,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,16197,1:04.125.943,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16201,1:04.126.940,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,16202,1:04.126.943,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 9A F0 24 13 DF CC 45 FF 9D 3B D1 06 D6 8A EE… 0,,16206,1:04.127.940,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,16207,1:04.142.945,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 2E 67 21 35 E1 3F 58 1F 0D 26 0D 27 1C FD 63… 0,,16211,1:04.143.942,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,16212,1:04.157.947,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16216,1:04.158.944,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,16217,1:04.158.947,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 2E 67 21 35 E1 3F 58 1F 0D 26 0D 27 1C FD 63… 0,,16221,1:04.159.944,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,16222,1:04.174.949,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 35 E5 7A 44 C7 F5 C8 6C A9 4B 0D 57 1D 04 B8… 0,,16226,1:04.175.946,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,16227,1:04.189.952,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16231,1:04.190.948,16.005.041 ms,,,,,[17 SOF],[Frames: 641 - 657] 0,,16232,1:04.206.954,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6B D3 53 DD 36 C7 29 20 19 6E 73 EF 42 5E B0 83… 0,,16236,1:04.207.951,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,16237,1:04.221.956,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16241,1:04.222.953,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,16242,1:04.222.956,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6B D3 53 DD 36 C7 29 20 19 6E 73 EF 42 5E B0 83… 0,,16246,1:04.223.953,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,16247,1:04.238.958,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 40 A0 72 11 6C 73 82 D3 71 05 A3 4C 95 4A C2… 0,,16251,1:04.239.955,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,16252,1:04.253.960,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16256,1:04.254.957,2.833 us,,,,,[1 SOF],[Frame: 705] 0,,16257,1:04.254.961,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 40 A0 72 11 6C 73 82 D3 71 05 A3 4C 95 4A C2… 0,,16261,1:04.255.957,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,16262,1:04.270.963,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 65 AB 3E B4 33 02 76 C1 73 9B 5E E1 1C 65 EA 5B… 0,,16266,1:04.271.960,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,16267,1:04.285.965,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16271,1:04.286.962,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,16272,1:04.286.965,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 65 AB 3E B4 33 02 76 C1 73 9B 5E E1 1C 65 EA 5B… 0,,16276,1:04.287.962,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,16277,1:04.302.967,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 12 1A 6B 35 2D 54 7E 80 FA 3D F0 4F E2 52 4A 15… 0,,16281,1:04.303.964,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,16282,1:04.317.969,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16286,1:04.318.966,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,16287,1:04.318.969,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 12 1A 6B 35 2D 54 7E 80 FA 3D F0 4F E2 52 4A 15… 0,,16291,1:04.319.966,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,16292,1:04.334.972,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 2F 2A A9 6C 53 56 59 99 31 67 2D E8 10 4D 56… 0,,16296,1:04.335.969,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,16297,1:04.349.974,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16301,1:04.350.971,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,16302,1:04.350.974,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 2F 2A A9 6C 53 56 59 99 31 67 2D E8 10 4D 56… 0,,16306,1:04.351.971,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,16307,1:04.366.976,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 07 C9 02 C9 F3 BF 6D 76 26 B8 B9 76 97 34 11 47… 0,,16311,1:04.367.973,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,16312,1:04.381.978,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16316,1:04.382.975,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,16317,1:04.382.978,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 07 C9 02 C9 F3 BF 6D 76 26 B8 B9 76 97 34 11 47… 0,,16321,1:04.383.975,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,16322,1:04.398.981,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 63 B5 C3 84 7A 91 C3 E7 DC 28 EA 24 2D 5C CD… 0,,16326,1:04.399.977,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,16327,1:04.413.983,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16331,1:04.414.980,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,16332,1:04.414.983,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 63 B5 C3 84 7A 91 C3 E7 DC 28 EA 24 2D 5C CD… 0,,16336,1:04.415.980,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,16337,1:04.430.985,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E8 28 D9 F5 6E BD DD 44 A9 AC 72 CB 22 C5 28 D9… 0,,16341,1:04.431.982,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,16342,1:04.445.987,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16346,1:04.446.984,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,16347,1:04.446.987,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E8 28 D9 F5 6E BD DD 44 A9 AC 72 CB 22 C5 28 D9… 0,,16351,1:04.447.984,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,16352,1:04.462.989,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 90 F6 36 CC 16 61 DB A0 3E 04 46 1D 89 67 2A C8… 0,,16356,1:04.463.986,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,16357,1:04.477.992,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16361,1:04.478.988,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,16362,1:04.478.992,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 90 F6 36 CC 16 61 DB A0 3E 04 46 1D 89 67 2A C8… 0,,16366,1:04.479.989,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,16367,1:04.494.994,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 58 BB 2B 60 9D 1E A1 9E 89 8D 47 12 62 E3 DC B7… 0,,16371,1:04.495.991,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,16372,1:04.509.996,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16376,1:04.510.993,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,16377,1:04.510.996,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 58 BB 2B 60 9D 1E A1 9E 89 8D 47 12 62 E3 DC B7… 0,,16381,1:04.511.993,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,16382,1:04.526.998,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 33 4F C2 7D 86 98 10 76 35 7F 94 76 97 C6 7B… 0,,16386,1:04.527.995,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,16387,1:04.542.000,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16391,1:04.542.997,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,16392,1:04.543.001,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9A 33 4F C2 7D 86 98 10 76 35 7F 94 76 97 C6 7B… 0,,16396,1:04.543.997,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,16397,1:04.559.003,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 05 E1 17 18 00 FD C0 C0 F2 0B 7C DA 3F 39 F5… 0,,16401,1:04.560.000,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,16402,1:04.574.005,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16406,1:04.575.002,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,16407,1:04.575.005,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 05 E1 17 18 00 FD C0 C0 F2 0B 7C DA 3F 39 F5… 0,,16411,1:04.576.002,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,16412,1:04.591.007,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3A A8 19 0F 41 52 78 F1 66 A6 EB 0E 9C A4 E1 EB… 0,,16416,1:04.592.004,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,16417,1:04.606.009,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16421,1:04.607.006,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,16422,1:04.607.009,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3A A8 19 0F 41 52 78 F1 66 A6 EB 0E 9C A4 E1 EB… 0,,16426,1:04.608.006,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,16427,1:04.623.012,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8D BC 57 07 DA 03 0E 75 77 34 C0 54 F4 84 B7 2A… 0,,16431,1:04.624.009,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,16432,1:04.638.014,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16436,1:04.639.011,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,16437,1:04.639.014,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8D BC 57 07 DA 03 0E 75 77 34 C0 54 F4 84 B7 2A… 0,,16441,1:04.640.011,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,16442,1:04.655.016,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 B0 08 B4 2B 1E 96 0A C8 96 4F 3D C1 02 9E 1C… 0,,16446,1:04.656.013,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,16447,1:04.670.018,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16451,1:04.671.015,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,16452,1:04.671.018,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 B0 08 B4 2B 1E 96 0A C8 96 4F 3D C1 02 9E 1C… 0,,16456,1:04.672.015,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,16457,1:04.687.021,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 25 7A 6D 21 03 BD 40 40 42 D8 8A DF 33 72 05 96… 0,,16461,1:04.688.017,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,16462,1:04.702.023,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16466,1:04.703.020,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,16467,1:04.703.023,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 25 7A 6D 21 03 BD 40 40 42 D8 8A DF 33 72 05 96… 0,,16471,1:04.704.020,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,16472,1:04.719.025,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 CE AA B6 3D 29 1F 46 87 66 FC AA 65 EA 4F E1… 0,,16476,1:04.720.022,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,16477,1:04.734.027,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16481,1:04.735.024,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,16482,1:04.735.027,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 CE AA B6 3D 29 1F 46 87 66 FC AA 65 EA 4F E1… 0,,16486,1:04.736.024,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,16487,1:04.751.029,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 02 BA 7C C6 3C 94 98 7F B2 01 C4 BA 66 AE F0 8E… 0,,16491,1:04.752.026,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,16492,1:04.766.032,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16496,1:04.767.028,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,16497,1:04.767.032,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 02 BA 7C C6 3C 94 98 7F B2 01 C4 BA 66 AE F0 8E… 0,,16501,1:04.768.029,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,16502,1:04.783.034,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C DD C6 96 D1 CA 68 AC 02 8B 0D BB 88 64 2E E9… 0,,16506,1:04.784.031,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,16507,1:04.798.036,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16511,1:04.799.033,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,16512,1:04.799.036,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C DD C6 96 D1 CA 68 AC 02 8B 0D BB 88 64 2E E9… 0,,16516,1:04.800.033,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,16517,1:04.815.038,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 72 36 1D 5C 09 1D 8F 9B 25 99 A0 78 DD BB DB 30… 0,,16521,1:04.816.035,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,16522,1:04.830.040,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16526,1:04.831.037,16.005.041 ms,,,,,[17 SOF],[Frames: 1281 - 1297] 0,,16527,1:04.847.043,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C5 6F AC 62 10 7D DB 19 4F ED 81 8D 53 7A 56 62… 0,,16531,1:04.848.040,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,16532,1:04.862.045,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16536,1:04.863.042,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,16537,1:04.863.045,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C5 6F AC 62 10 7D DB 19 4F ED 81 8D 53 7A 56 62… 0,,16541,1:04.864.042,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,16542,1:04.879.047,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C7 6E 59 BF 13 D8 D0 8C 61 21 E0 D1 EB E3 47 84… 0,,16546,1:04.880.044,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,16547,1:04.894.049,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16551,1:04.895.046,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,16552,1:04.895.049,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C7 6E 59 BF 13 D8 D0 8C 61 21 E0 D1 EB E3 47 84… 0,,16556,1:04.896.046,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,16557,1:04.911.052,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 C3 54 80 E1 3C DD E7 46 9F C8 96 76 18 C7 71… 0,,16561,1:04.912.049,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,16562,1:04.926.054,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16566,1:04.927.051,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,16567,1:04.927.054,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 C3 54 80 E1 3C DD E7 46 9F C8 96 76 18 C7 71… 0,,16571,1:04.928.051,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,16572,1:04.943.056,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 46 F8 AF BC 93 D2 A5 F0 94 46 CC E8 94 49 E1 35… 0,,16576,1:04.944.053,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,16577,1:04.958.058,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16581,1:04.959.055,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,16582,1:04.959.058,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 46 F8 AF BC 93 D2 A5 F0 94 46 CC E8 94 49 E1 35… 0,,16586,1:04.960.055,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,16587,1:04.975.061,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 FF CA D0 DD 10 DD 07 F1 5E 5A 60 E6 83 97 4F… 0,,16591,1:04.976.057,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,16592,1:04.990.063,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16596,1:04.991.060,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,16597,1:04.991.063,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 FF CA D0 DD 10 DD 07 F1 5E 5A 60 E6 83 97 4F… 0,,16601,1:04.992.060,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,16602,1:05.007.065,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C 09 CB A1 D1 9D BE F5 70 00 68 D4 BD DC 62 0B… 0,,16606,1:05.008.062,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,16607,1:05.022.067,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16611,1:05.023.064,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,16612,1:05.023.067,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C 09 CB A1 D1 9D BE F5 70 00 68 D4 BD DC 62 0B… 0,,16616,1:05.024.064,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,16617,1:05.039.069,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 F7 D8 44 05 D2 E0 FA ED 57 3E E2 04 4C 9C 83… 0,,16621,1:05.040.066,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,16622,1:05.054.072,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16626,1:05.055.068,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,16627,1:05.055.072,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 F7 D8 44 05 D2 E0 FA ED 57 3E E2 04 4C 9C 83… 0,,16631,1:05.056.069,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,16632,1:05.071.074,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 43 B7 E4 91 64 E3 7D 97 55 52 28 BD 18 8D F6… 0,,16636,1:05.072.071,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,16637,1:05.086.076,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16641,1:05.087.073,2.833 us,,,,,[1 SOF],[Frame: 1537] 0,,16642,1:05.087.076,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 43 B7 E4 91 64 E3 7D 97 55 52 28 BD 18 8D F6… 0,,16646,1:05.088.073,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,16647,1:05.103.078,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DF FE 78 73 92 02 A1 33 AF ED 9C 7C 46 7E F5 DC… 0,,16651,1:05.104.075,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,16652,1:05.118.080,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16656,1:05.119.077,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,16657,1:05.119.081,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DF FE 78 73 92 02 A1 33 AF ED 9C 7C 46 7E F5 DC… 0,,16661,1:05.120.077,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,16662,1:05.135.083,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 64 D5 30 FD C1 4B 46 2D B0 A8 93 C4 F8 EE B7 9F… 0,,16666,1:05.136.080,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,16667,1:05.150.085,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16671,1:05.151.082,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,16672,1:05.151.085,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 64 D5 30 FD C1 4B 46 2D B0 A8 93 C4 F8 EE B7 9F… 0,,16676,1:05.152.082,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,16677,1:05.167.087,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 E7 47 D8 24 F7 B7 52 4C 2A 58 EE F1 31 67 26… 0,,16681,1:05.168.084,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,16682,1:05.182.089,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16686,1:05.183.086,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,16687,1:05.183.089,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 E7 47 D8 24 F7 B7 52 4C 2A 58 EE F1 31 67 26… 0,,16691,1:05.184.086,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,16692,1:05.199.092,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 F9 A1 C2 93 3D 0D 74 CC A9 E3 63 17 A6 44 DE… 0,,16696,1:05.200.089,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,16697,1:05.214.094,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16701,1:05.215.091,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,16702,1:05.215.094,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 F9 A1 C2 93 3D 0D 74 CC A9 E3 63 17 A6 44 DE… 0,,16706,1:05.216.091,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,16707,1:05.231.096,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F6 43 62 4C F0 DD B4 9A 93 17 5D E7 CF C0 D1 C2… 0,,16711,1:05.232.093,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,16712,1:05.246.098,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16716,1:05.247.095,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,16717,1:05.247.098,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F6 43 62 4C F0 DD B4 9A 93 17 5D E7 CF C0 D1 C2… 0,,16721,1:05.248.095,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,16722,1:05.263.101,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 D6 8A 38 3B 70 C5 06 9F 4E F5 5C 23 0B 88 2A… 0,,16726,1:05.264.097,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,16727,1:05.278.103,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16731,1:05.279.100,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,16732,1:05.279.103,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 D6 8A 38 3B 70 C5 06 9F 4E F5 5C 23 0B 88 2A… 0,,16736,1:05.280.100,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,16737,1:05.295.105,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0E 8E 51 74 85 A3 D4 23 9B 79 65 75 E7 1C 62 B8… 0,,16741,1:05.296.102,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,16742,1:05.310.107,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16746,1:05.311.104,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,16747,1:05.311.107,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0E 8E 51 74 85 A3 D4 23 9B 79 65 75 E7 1C 62 B8… 0,,16751,1:05.312.104,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,16752,1:05.327.109,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 54 DE 2E 46 B4 52 CD F0 D3 5D 8C 49 50 65 5B 48… 0,,16756,1:05.328.106,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,16757,1:05.342.111,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16761,1:05.343.108,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,16762,1:05.343.112,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 54 DE 2E 46 B4 52 CD F0 D3 5D 8C 49 50 65 5B 48… 0,,16766,1:05.344.109,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,16767,1:05.359.114,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D F7 45 A4 E2 87 A9 62 D9 7D E0 E5 FA 8F FE 09… 0,,16771,1:05.360.111,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,16772,1:05.374.116,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16776,1:05.375.113,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,16777,1:05.375.116,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D F7 45 A4 E2 87 A9 62 D9 7D E0 E5 FA 8F FE 09… 0,,16781,1:05.376.113,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,16782,1:05.391.118,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 E8 4A D4 D8 49 15 8A 46 0A 83 B3 07 9A 08 91… 0,,16786,1:05.392.115,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,16787,1:05.406.120,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16791,1:05.407.117,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,16792,1:05.407.121,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 E8 4A D4 D8 49 15 8A 46 0A 83 B3 07 9A 08 91… 0,,16796,1:05.408.117,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,16797,1:05.423.123,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 B7 C5 E8 41 51 AC 7C 6C F0 B7 5B 08 3E 4F B0… 0,,16801,1:05.424.120,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,16802,1:05.438.125,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16806,1:05.439.122,16.005.041 ms,,,,,[17 SOF],[Frames: 1889 - 1905] 0,,16807,1:05.455.127,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 76 53 16 70 52 72 DE BA 90 BA 26 5A 8E BC A3 4B… 0,,16811,1:05.456.124,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,16812,1:05.470.129,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16816,1:05.471.126,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,16817,1:05.471.129,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 76 53 16 70 52 72 DE BA 90 BA 26 5A 8E BC A3 4B… 0,,16821,1:05.472.126,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,16822,1:05.487.132,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EA BD A1 09 F4 93 1B 18 92 E2 AA B3 FB 59 13 58… 0,,16826,1:05.488.129,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,16827,1:05.502.134,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16831,1:05.503.131,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,16832,1:05.503.134,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EA BD A1 09 F4 93 1B 18 92 E2 AA B3 FB 59 13 58… 0,,16836,1:05.504.131,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,16837,1:05.519.136,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF F4 A6 18 88 5E 35 53 BD 0F EC 8E 97 F0 B0 81… 0,,16841,1:05.520.133,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,16842,1:05.534.138,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16846,1:05.535.135,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,16847,1:05.535.138,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BF F4 A6 18 88 5E 35 53 BD 0F EC 8E 97 F0 B0 81… 0,,16851,1:05.536.135,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,16852,1:05.551.141,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 DE E0 EB 28 99 6E 7F 82 60 E3 3D BA 21 E2 27… 0,,16856,1:05.552.137,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,16857,1:05.566.143,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16861,1:05.567.139,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,16862,1:05.567.143,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 DE E0 EB 28 99 6E 7F 82 60 E3 3D BA 21 E2 27… 0,,16866,1:05.568.140,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,16867,1:05.583.145,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 4E 32 0D FB B1 87 D4 E4 F2 18 8E B7 17 DD AE… 0,,16871,1:05.584.142,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,16872,1:05.598.147,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16876,1:05.599.144,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,16877,1:05.599.147,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 4E 32 0D FB B1 87 D4 E4 F2 18 8E B7 17 DD AE… 0,,16881,1:05.600.144,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,16882,1:05.615.149,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C C7 76 8B B0 4A B1 C7 6A CC 88 93 AE 16 3D 67… 0,,16886,1:05.616.146,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,16887,1:05.630.151,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16891,1:05.631.148,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,16892,1:05.631.152,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C C7 76 8B B0 4A B1 C7 6A CC 88 93 AE 16 3D 67… 0,,16896,1:05.632.149,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,16897,1:05.647.154,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 FC E7 D0 33 01 36 18 BD 52 C9 2B 1A 1D F1 7B… 0,,16901,1:05.648.151,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,16902,1:05.662.156,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16906,1:05.663.153,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,16907,1:05.663.156,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 FC E7 D0 33 01 36 18 BD 52 C9 2B 1A 1D F1 7B… 0,,16911,1:05.664.153,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,16912,1:05.679.158,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 95 F1 A9 EA 73 92 80 5C 9A 57 16 FB 78 87 F3 4A… 0,,16916,1:05.680.155,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,16917,1:05.694.160,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16921,1:05.695.157,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,16922,1:05.695.160,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 95 F1 A9 EA 73 92 80 5C 9A 57 16 FB 78 87 F3 4A… 0,,16926,1:05.696.157,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,16927,1:05.711.163,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 50 F0 8B 82 AA 4A AF C4 3A 9C 3C A0 44 25 21… 0,,16931,1:05.712.160,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,16932,1:05.726.165,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16936,1:05.727.162,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,16937,1:05.727.165,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A 50 F0 8B 82 AA 4A AF C4 3A 9C 3C A0 44 25 21… 0,,16941,1:05.728.162,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,16942,1:05.743.167,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FE DA 18 41 D9 64 DC 35 05 06 B6 DF C7 8A A2 61… 0,,16946,1:05.744.164,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,16947,1:05.758.169,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16951,1:05.759.166,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,16952,1:05.759.169,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FE DA 18 41 D9 64 DC 35 05 06 B6 DF C7 8A A2 61… 0,,16956,1:05.760.166,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,16957,1:05.775.172,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C3 AB D2 9F 6E A0 88 E4 CA 05 86 54 AE 89 32 43… 0,,16961,1:05.776.168,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,16962,1:05.790.174,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16966,1:05.791.171,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,16967,1:05.791.174,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C3 AB D2 9F 6E A0 88 E4 CA 05 86 54 AE 89 32 43… 0,,16971,1:05.792.171,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,16972,1:05.807.176,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 97 6B 0D EC 05 54 26 67 95 DD 53 5D 3C 31 F1… 0,,16976,1:05.808.173,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,16977,1:05.822.178,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16981,1:05.823.175,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,16982,1:05.823.178,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 97 6B 0D EC 05 54 26 67 95 DD 53 5D 3C 31 F1… 0,,16986,1:05.824.175,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,16987,1:05.839.180,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 04 F3 DE DD 31 E6 97 11 89 92 25 82 DA 1E 1B… 0,,16991,1:05.840.177,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,16992,1:05.854.183,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,16996,1:05.855.179,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,16997,1:05.855.183,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 04 F3 DE DD 31 E6 97 11 89 92 25 82 DA 1E 1B… 0,,17001,1:05.856.180,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,17002,1:05.871.185,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FD 03 90 EE 8B 24 2C F3 EA 53 CF 9F 2A A4 B5 B6… 0,,17006,1:05.872.182,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,17007,1:05.886.187,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17011,1:05.887.184,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,17012,1:05.887.187,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FD 03 90 EE 8B 24 2C F3 EA 53 CF 9F 2A A4 B5 B6… 0,,17016,1:05.888.184,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,17017,1:05.903.189,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C A8 60 EB 4C D1 74 0A DD 6A 16 B1 8F CA BF 5D… 0,,17021,1:05.904.186,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,17022,1:05.918.191,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17026,1:05.919.188,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,17027,1:05.919.192,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C A8 60 EB 4C D1 74 0A DD 6A 16 B1 8F CA BF 5D… 0,,17031,1:05.920.188,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,17032,1:05.935.194,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 76 9F 28 0E B4 FE 34 96 42 2F 20 E4 2E 3E C3… 0,,17036,1:05.936.191,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,17037,1:05.950.196,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17041,1:05.951.193,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,17042,1:05.951.196,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 76 9F 28 0E B4 FE 34 96 42 2F 20 E4 2E 3E C3… 0,,17046,1:05.952.193,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,17047,1:05.967.198,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D0 BA A2 13 AF DF 3E 80 AB 88 C2 F7 78 45 AA B5… 0,,17051,1:05.968.195,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,17052,1:05.982.200,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17056,1:05.983.197,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,17057,1:05.983.200,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D0 BA A2 13 AF DF 3E 80 AB 88 C2 F7 78 45 AA B5… 0,,17061,1:05.984.197,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,17062,1:05.999.203,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 10 02 58 A6 E5 D0 28 0F 48 CF 49 65 E3 B0 66… 0,,17066,1:06.000.200,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,17067,1:06.014.205,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17071,1:06.015.202,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,17072,1:06.015.205,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 10 02 58 A6 E5 D0 28 0F 48 CF 49 65 E3 B0 66… 0,,17076,1:06.016.202,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,17077,1:06.031.207,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 57 A0 4F F8 97 12 9A DA 47 70 4E F6 FC 84 63… 0,,17081,1:06.032.204,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,17082,1:06.046.209,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17086,1:06.047.206,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,17087,1:06.047.209,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 57 A0 4F F8 97 12 9A DA 47 70 4E F6 FC 84 63… 0,,17091,1:06.048.206,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,17092,1:06.063.212,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D BC 07 94 71 65 5C BA 46 73 97 98 20 41 C5 FA… 0,,17096,1:06.064.208,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,17097,1:06.078.214,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17101,1:06.079.211,16.005.041 ms,,,,,[17 SOF],[Frames: 481 - 497] 0,,17102,1:06.095.216,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 67 B1 8F 38 2F DB 76 8C 52 26 3E 5B AC 8A F4… 0,,17106,1:06.096.213,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,17107,1:06.110.218,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17111,1:06.111.215,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,17112,1:06.111.218,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 67 B1 8F 38 2F DB 76 8C 52 26 3E 5B AC 8A F4… 0,,17116,1:06.112.215,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,17117,1:06.127.220,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 53 B6 58 13 27 F2 14 6F 48 1A FF 78 6A 26 03… 0,,17121,1:06.128.217,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,17122,1:06.142.223,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17126,1:06.143.219,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,17127,1:06.143.223,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 53 B6 58 13 27 F2 14 6F 48 1A FF 78 6A 26 03… 0,,17131,1:06.144.220,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,17132,1:06.159.225,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B BD CD 61 06 AF 73 47 01 17 A9 5D 0A 56 99 B8… 0,,17136,1:06.160.222,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,17137,1:06.174.227,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17141,1:06.175.224,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,17142,1:06.175.227,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B BD CD 61 06 AF 73 47 01 17 A9 5D 0A 56 99 B8… 0,,17146,1:06.176.224,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,17147,1:06.191.229,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 CB 27 64 A0 A0 EE C1 2D 2F 44 B2 E0 C1 2B EC… 0,,17151,1:06.192.226,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,17152,1:06.206.231,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17156,1:06.207.228,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,17157,1:06.207.232,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 CB 27 64 A0 A0 EE C1 2D 2F 44 B2 E0 C1 2B EC… 0,,17161,1:06.208.228,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,17162,1:06.223.234,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FE C2 4A C2 FA 11 7E AE 12 60 05 1A D8 2E 0B F5… 0,,17166,1:06.224.231,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,17167,1:06.238.236,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17171,1:06.239.233,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,17172,1:06.239.236,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FE C2 4A C2 FA 11 7E AE 12 60 05 1A D8 2E 0B F5… 0,,17176,1:06.240.233,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,17177,1:06.255.238,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 30 2E F6 D8 80 A8 C2 8B A5 C2 96 3F 3B C6 8A CE… 0,,17181,1:06.256.235,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,17182,1:06.270.240,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17186,1:06.271.237,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,17187,1:06.271.240,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 30 2E F6 D8 80 A8 C2 8B A5 C2 96 3F 3B C6 8A CE… 0,,17191,1:06.272.237,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,17192,1:06.287.243,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F7 85 59 4A FA 12 1F DD 24 5F F3 1C CD 17 FF 15… 0,,17196,1:06.288.240,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,17197,1:06.302.245,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17201,1:06.303.242,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,17202,1:06.303.245,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F7 85 59 4A FA 12 1F DD 24 5F F3 1C CD 17 FF 15… 0,,17206,1:06.304.242,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,17207,1:06.319.247,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 47 D7 4A 0E D1 E6 51 B8 E0 70 08 56 0D 46 8C… 0,,17211,1:06.320.244,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,17212,1:06.334.249,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17216,1:06.335.246,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,17217,1:06.335.249,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 47 D7 4A 0E D1 E6 51 B8 E0 70 08 56 0D 46 8C… 0,,17221,1:06.336.246,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,17222,1:06.351.252,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C6 E5 46 FF F1 DE 45 01 CB 2B 51 83 F1 40 FF BA… 0,,17226,1:06.352.248,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,17227,1:06.366.254,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17231,1:06.367.251,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,17232,1:06.367.254,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C6 E5 46 FF F1 DE 45 01 CB 2B 51 83 F1 40 FF BA… 0,,17236,1:06.368.251,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,17237,1:06.383.256,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E 71 F2 21 96 C6 35 E0 27 00 D9 9A 8D DD 55 CD… 0,,17241,1:06.384.253,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,17242,1:06.398.258,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17246,1:06.399.255,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,17247,1:06.399.258,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E 71 F2 21 96 C6 35 E0 27 00 D9 9A 8D DD 55 CD… 0,,17251,1:06.400.255,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,17252,1:06.415.260,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 27 5E 81 10 BC CA 3F 77 40 6B 81 74 A2 C2 7B 1B… 0,,17256,1:06.416.257,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,17257,1:06.430.263,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17261,1:06.431.259,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,17262,1:06.431.263,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 27 5E 81 10 BC CA 3F 77 40 6B 81 74 A2 C2 7B 1B… 0,,17266,1:06.432.260,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,17267,1:06.447.265,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 9F EF C6 D6 BA 2B 8D 03 CD E0 FA 22 EF C5 46… 0,,17271,1:06.448.262,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,17272,1:06.462.267,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17276,1:06.463.264,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,17277,1:06.463.267,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 9F EF C6 D6 BA 2B 8D 03 CD E0 FA 22 EF C5 46… 0,,17281,1:06.464.264,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,17282,1:06.479.269,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 1E 3F 5F CB D3 EA 1C D2 AC 00 A4 52 9A 1F F4… 0,,17286,1:06.480.266,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,17287,1:06.494.271,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17291,1:06.495.268,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,17292,1:06.495.272,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 1E 3F 5F CB D3 EA 1C D2 AC 00 A4 52 9A 1F F4… 0,,17296,1:06.496.268,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,17297,1:06.511.274,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 8F 1D C2 3A E2 66 AA 46 80 C1 F5 E4 96 BF B8… 0,,17301,1:06.512.271,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,17302,1:06.526.276,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17306,1:06.527.273,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,17307,1:06.527.276,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 8F 1D C2 3A E2 66 AA 46 80 C1 F5 E4 96 BF B8… 0,,17311,1:06.528.273,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,17312,1:06.543.278,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 BB 1F 5C 0A 7E 97 A3 0E 33 66 3E 8F A8 A6 EF… 0,,17316,1:06.544.275,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,17317,1:06.558.280,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17321,1:06.559.277,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,17322,1:06.559.280,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 BB 1F 5C 0A 7E 97 A3 0E 33 66 3E 8F A8 A6 EF… 0,,17326,1:06.560.277,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,17327,1:06.575.283,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 D8 18 51 38 D4 05 B2 C6 B5 D4 5B 2F BD 3C CC… 0,,17331,1:06.576.280,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,17332,1:06.590.285,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17336,1:06.591.282,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,17337,1:06.591.285,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 D8 18 51 38 D4 05 B2 C6 B5 D4 5B 2F BD 3C CC… 0,,17341,1:06.592.282,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,17342,1:06.607.287,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E8 6C 70 32 30 7D 5E 85 99 42 63 50 8C DC 98 71… 0,,17346,1:06.608.284,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,17347,1:06.622.289,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17351,1:06.623.286,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,17352,1:06.623.289,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E8 6C 70 32 30 7D 5E 85 99 42 63 50 8C DC 98 71… 0,,17356,1:06.624.286,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,17357,1:06.639.292,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 59 B2 3B 82 0F 4C DA C0 0F 88 5E D9 D2 B1 9E 00… 0,,17361,1:06.640.288,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,17362,1:06.654.294,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17366,1:06.655.291,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,17367,1:06.655.294,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 59 B2 3B 82 0F 4C DA C0 0F 88 5E D9 D2 B1 9E 00… 0,,17371,1:06.656.291,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,17372,1:06.671.296,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 BD 54 2C E8 99 16 2D 1D EA C6 9D BC A2 FA 65… 0,,17376,1:06.672.293,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,17377,1:06.686.298,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17381,1:06.687.295,16.005.041 ms,,,,,[17 SOF],[Frames: 1089 - 1105] 0,,17382,1:06.703.300,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 20 9F 6D 57 E5 AE 21 90 1D 25 4F 1E FC 1B 9A… 0,,17386,1:06.704.297,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,17387,1:06.718.303,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17391,1:06.719.299,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,17392,1:06.719.303,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 20 9F 6D 57 E5 AE 21 90 1D 25 4F 1E FC 1B 9A… 0,,17396,1:06.720.300,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,17397,1:06.735.305,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 1A 3A 59 EF 4B 52 5C D8 B9 EB 7B D4 BC 5E BF… 0,,17401,1:06.736.302,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,17402,1:06.750.307,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17406,1:06.751.304,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,17407,1:06.751.307,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 1A 3A 59 EF 4B 52 5C D8 B9 EB 7B D4 BC 5E BF… 0,,17411,1:06.752.304,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,17412,1:06.767.309,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 59 89 84 26 D2 DF 13 C3 E4 DD 5A D9 03 82 CD 27… 0,,17416,1:06.768.306,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,17417,1:06.782.311,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17421,1:06.783.308,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,17422,1:06.783.312,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 59 89 84 26 D2 DF 13 C3 E4 DD 5A D9 03 82 CD 27… 0,,17426,1:06.784.308,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,17427,1:06.799.314,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A9 7B 27 66 6F D3 28 CA F7 16 44 9A 61 EE 15 22… 0,,17431,1:06.800.311,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,17432,1:06.814.316,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17436,1:06.815.313,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,17437,1:06.815.316,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A9 7B 27 66 6F D3 28 CA F7 16 44 9A 61 EE 15 22… 0,,17441,1:06.816.313,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,17442,1:06.831.318,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 44 EC 00 46 AD D7 1C F9 C9 43 F7 FE 62 39 AD 0E… 0,,17446,1:06.832.315,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,17447,1:06.846.320,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17451,1:06.847.317,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,17452,1:06.847.320,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 44 EC 00 46 AD D7 1C F9 C9 43 F7 FE 62 39 AD 0E… 0,,17456,1:06.848.317,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,17457,1:06.863.323,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 C7 1A AF 5F 25 11 39 12 E3 60 F6 EA EE 34 0A… 0,,17461,1:06.864.320,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,17462,1:06.878.325,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17466,1:06.879.322,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,17467,1:06.879.325,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 C7 1A AF 5F 25 11 39 12 E3 60 F6 EA EE 34 0A… 0,,17471,1:06.880.322,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,17472,1:06.895.327,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC 0E 9B 14 35 B0 1F A0 9C 8A 3B 22 E1 98 39 D8… 0,,17476,1:06.896.324,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,17477,1:06.910.329,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17481,1:06.911.326,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,17482,1:06.911.329,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EC 0E 9B 14 35 B0 1F A0 9C 8A 3B 22 E1 98 39 D8… 0,,17486,1:06.912.326,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,17487,1:06.927.332,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B2 C5 AA 25 6E 47 1E F9 FE BD 17 43 BC CC 2B F1… 0,,17491,1:06.928.328,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,17492,1:06.942.334,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17496,1:06.943.330,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,17497,1:06.943.334,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B2 C5 AA 25 6E 47 1E F9 FE BD 17 43 BC CC 2B F1… 0,,17501,1:06.944.331,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,17502,1:06.959.336,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 56 4D 6C 3A CB D1 1D 1F C7 12 F3 96 8A B3 D4 0D… 0,,17506,1:06.960.333,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,17507,1:06.974.338,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17511,1:06.975.335,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,17512,1:06.975.338,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 56 4D 6C 3A CB D1 1D 1F C7 12 F3 96 8A B3 D4 0D… 0,,17516,1:06.976.335,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,17517,1:06.991.340,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C DE 8F 01 AB 23 8F 10 8C E4 82 88 CE F1 56 77… 0,,17521,1:06.992.337,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,17522,1:07.006.342,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17526,1:07.007.339,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,17527,1:07.007.343,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C DE 8F 01 AB 23 8F 10 8C E4 82 88 CE F1 56 77… 0,,17531,1:07.008.340,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,17532,1:07.023.345,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E7 2C 8A 61 81 4B 0E 14 AD 3A E8 0C B5 94 C3 D8… 0,,17536,1:07.024.342,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,17537,1:07.038.347,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17541,1:07.039.344,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,17542,1:07.039.347,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E7 2C 8A 61 81 4B 0E 14 AD 3A E8 0C B5 94 C3 D8… 0,,17546,1:07.040.344,15.004.916 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,17547,1:07.055.349,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 37 B1 D0 5A C7 69 B1 1B EC 29 34 78 82 37 D2 00… 0,,17551,1:07.056.346,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,17552,1:07.070.351,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17556,1:07.071.348,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,17557,1:07.071.352,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 37 B1 D0 5A C7 69 B1 1B EC 29 34 78 82 37 D2 00… 0,,17561,1:07.072.348,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,17562,1:07.087.354,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2E 18 C8 AA F2 A0 14 A3 09 56 62 51 CD 88 73 7D… 0,,17566,1:07.088.351,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,17567,1:07.102.356,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17571,1:07.103.353,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,17572,1:07.103.356,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2E 18 C8 AA F2 A0 14 A3 09 56 62 51 CD 88 73 7D… 0,,17576,1:07.104.353,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,17577,1:07.119.358,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 C4 C4 21 3A 83 97 7C 45 48 E1 AC 4B CC DD BF… 0,,17581,1:07.120.355,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,17582,1:07.134.360,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17586,1:07.135.357,2.833 us,,,,,[1 SOF],[Frame: 1537] 0,,17587,1:07.135.360,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 C4 C4 21 3A 83 97 7C 45 48 E1 AC 4B CC DD BF… 0,,17591,1:07.136.357,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,17592,1:07.151.363,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D6 28 E0 C0 43 9B DC 36 22 67 D3 0E E8 D3 ED ED… 0,,17596,1:07.152.360,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,17597,1:07.166.365,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17601,1:07.167.362,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,17602,1:07.167.365,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D6 28 E0 C0 43 9B DC 36 22 67 D3 0E E8 D3 ED ED… 0,,17606,1:07.168.362,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,17607,1:07.183.367,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A6 97 F6 92 F5 DE FB 31 80 32 75 61 BD DD 65 54… 0,,17611,1:07.184.364,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,17612,1:07.198.369,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17616,1:07.199.366,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,17617,1:07.199.369,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A6 97 F6 92 F5 DE FB 31 80 32 75 61 BD DD 65 54… 0,,17621,1:07.200.366,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,17622,1:07.215.371,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CE 1C B9 AE 4D B4 B0 D4 21 E4 80 EA 5B E6 51 9B… 0,,17626,1:07.216.368,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,17627,1:07.230.374,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17631,1:07.231.370,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,17632,1:07.231.374,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CE 1C B9 AE 4D B4 B0 D4 21 E4 80 EA 5B E6 51 9B… 0,,17636,1:07.232.371,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,17637,1:07.247.376,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 9E A6 BB 81 4E AE 01 72 F2 74 1E 5E 0D 92 7E… 0,,17641,1:07.248.373,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,17642,1:07.262.378,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17646,1:07.263.375,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,17647,1:07.263.378,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E3 9E A6 BB 81 4E AE 01 72 F2 74 1E 5E 0D 92 7E… 0,,17651,1:07.264.375,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,17652,1:07.279.380,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 2A 13 44 49 11 59 D8 26 E4 97 5D 70 79 8B 72… 0,,17656,1:07.280.377,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,17657,1:07.294.382,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17661,1:07.295.379,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,17662,1:07.295.383,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 2A 13 44 49 11 59 D8 26 E4 97 5D 70 79 8B 72… 0,,17666,1:07.296.379,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,17667,1:07.311.385,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4D 43 F9 BE AD 1A 48 54 FE 9E 63 E9 F2 60 C8 C6… 0,,17671,1:07.312.382,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,17672,1:07.326.387,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17676,1:07.327.384,16.005.041 ms,,,,,[17 SOF],[Frames: 1729 - 1745] 0,,17677,1:07.343.389,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 43 F9 BE AD 1A 48 54 FE 9E 63 E9 F2 60 C8 C6… 0,,17681,1:07.344.386,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,17682,1:07.358.391,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17686,1:07.359.388,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,17687,1:07.359.392,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4D 43 F9 BE AD 1A 48 54 FE 9E 63 E9 F2 60 C8 C6… 0,,17691,1:07.360.388,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,17692,1:07.375.394,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4A 2F 48 F7 B8 48 C5 82 7D 43 2B B0 7B B6 F8 CD… 0,,17696,1:07.376.391,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,17697,1:07.390.396,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17701,1:07.391.393,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,17702,1:07.391.396,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4A 2F 48 F7 B8 48 C5 82 7D 43 2B B0 7B B6 F8 CD… 0,,17706,1:07.392.393,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,17707,1:07.407.398,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 66 30 E5 CF 47 05 27 B9 C1 EE 30 AC CA 5D 50 09… 0,,17711,1:07.408.395,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,17712,1:07.422.400,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17716,1:07.423.397,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,17717,1:07.423.400,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 66 30 E5 CF 47 05 27 B9 C1 EE 30 AC CA 5D 50 09… 0,,17721,1:07.424.397,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,17722,1:07.439.403,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6E 73 1C F0 5A 69 AE E7 E7 8E 9F 3E 6D 41 4F B6… 0,,17726,1:07.440.399,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,17727,1:07.454.405,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17731,1:07.455.402,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,17732,1:07.455.405,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6E 73 1C F0 5A 69 AE E7 E7 8E 9F 3E 6D 41 4F B6… 0,,17736,1:07.456.402,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,17737,1:07.471.407,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 FF 6F FB 95 C4 A0 A6 0E 3E 47 15 5B 7D A4 7C… 0,,17741,1:07.472.404,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,17742,1:07.486.409,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17746,1:07.487.406,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,17747,1:07.487.409,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 FF 6F FB 95 C4 A0 A6 0E 3E 47 15 5B 7D A4 7C… 0,,17751,1:07.488.406,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,17752,1:07.503.411,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C B0 B0 D0 6E 80 14 51 A7 23 F1 75 5F 86 45 17… 0,,17756,1:07.504.408,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,17757,1:07.518.414,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17761,1:07.519.410,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,17762,1:07.519.414,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C B0 B0 D0 6E 80 14 51 A7 23 F1 75 5F 86 45 17… 0,,17766,1:07.520.411,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,17767,1:07.535.416,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 07 06 70 1E 70 9F 21 13 5B B2 95 35 04 CC BF BC… 0,,17771,1:07.536.413,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,17772,1:07.550.418,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17776,1:07.551.415,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,17777,1:07.551.418,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 07 06 70 1E 70 9F 21 13 5B B2 95 35 04 CC BF BC… 0,,17781,1:07.552.415,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,17782,1:07.567.420,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF 34 03 10 11 8F 0B D2 EA D2 A6 51 90 03 A2 03… 0,,17786,1:07.568.417,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,17787,1:07.582.422,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17791,1:07.583.419,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,17792,1:07.583.423,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF 34 03 10 11 8F 0B D2 EA D2 A6 51 90 03 A2 03… 0,,17796,1:07.584.419,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,17797,1:07.599.425,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9F E9 85 F6 72 F2 8C 4F 2B 63 FA D1 38 D8 2C 42… 0,,17801,1:07.600.422,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,17802,1:07.614.427,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17806,1:07.615.424,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,17807,1:07.615.427,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9F E9 85 F6 72 F2 8C 4F 2B 63 FA D1 38 D8 2C 42… 0,,17811,1:07.616.424,15.005.000 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,17812,1:07.631.429,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD E1 68 01 65 83 25 59 78 5B 6D 73 D7 32 2D BA… 0,,17816,1:07.632.426,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,17817,1:07.646.431,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17821,1:07.647.428,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,17822,1:07.647.431,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD E1 68 01 65 83 25 59 78 5B 6D 73 D7 32 2D BA… 0,,17826,1:07.648.428,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,17827,1:07.663.434,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5E BD CF 63 62 71 AE 5D B8 87 FE C3 DB 5D FB 42… 0,,17831,1:07.664.431,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,17832,1:07.678.436,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17836,1:07.679.433,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,17837,1:07.679.436,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5E BD CF 63 62 71 AE 5D B8 87 FE C3 DB 5D FB 42… 0,,17841,1:07.680.433,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,17842,1:07.695.438,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 27 70 D2 A0 C8 47 8F 99 51 DF 86 0D 0F B8 85… 0,,17846,1:07.696.435,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,17847,1:07.710.440,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17851,1:07.711.437,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,17852,1:07.711.440,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 27 70 D2 A0 C8 47 8F 99 51 DF 86 0D 0F B8 85… 0,,17856,1:07.712.437,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,17857,1:07.727.443,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 2D 06 DA 2A 83 D6 C9 BD 81 6F DB 56 92 F6 30… 0,,17861,1:07.728.439,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,17862,1:07.742.445,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17866,1:07.743.442,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,17867,1:07.743.445,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 2D 06 DA 2A 83 D6 C9 BD 81 6F DB 56 92 F6 30… 0,,17871,1:07.744.442,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,17872,1:07.759.447,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 D3 79 8A C8 0D 6D 4C 8D 54 B9 7C D8 C7 92 1C… 0,,17876,1:07.760.444,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,17877,1:07.774.449,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17881,1:07.775.446,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,17882,1:07.775.449,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 D3 79 8A C8 0D 6D 4C 8D 54 B9 7C D8 C7 92 1C… 0,,17886,1:07.776.446,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,17887,1:07.791.451,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 C4 D8 48 BE 1E 6D 51 7B 23 F4 E3 96 18 A6 F5… 0,,17891,1:07.792.448,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,17892,1:07.806.454,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17896,1:07.807.450,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,17897,1:07.807.454,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 C4 D8 48 BE 1E 6D 51 7B 23 F4 E3 96 18 A6 F5… 0,,17901,1:07.808.451,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,17902,1:07.823.456,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC 1E 73 E6 DF 74 79 15 89 C8 C3 D5 85 B3 44 4E… 0,,17906,1:07.824.453,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,17907,1:07.838.458,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17911,1:07.839.455,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,17912,1:07.839.458,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EC 1E 73 E6 DF 74 79 15 89 C8 C3 D5 85 B3 44 4E… 0,,17916,1:07.840.455,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,17917,1:07.855.460,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1A FC 3B 71 24 4E 77 2D 9E A3 E3 D4 2F FB D0 E3… 0,,17921,1:07.856.457,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,17922,1:07.870.462,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17926,1:07.871.459,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,17927,1:07.871.463,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1A FC 3B 71 24 4E 77 2D 9E A3 E3 D4 2F FB D0 E3… 0,,17931,1:07.872.459,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,17932,1:07.887.465,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C B1 3F 6F E5 4E 26 DB 93 B8 75 1D F4 99 CA B4… 0,,17936,1:07.888.462,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,17937,1:07.902.467,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17941,1:07.903.464,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,17942,1:07.903.467,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C B1 3F 6F E5 4E 26 DB 93 B8 75 1D F4 99 CA B4… 0,,17946,1:07.904.464,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,17947,1:07.919.469,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B F8 23 4A 15 77 C0 2C 5B EF 4B A9 15 B3 E6 77… 0,,17951,1:07.920.466,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,17952,1:07.934.471,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17956,1:07.935.468,16.005.041 ms,,,,,[17 SOF],[Frames: 289 - 305] 0,,17957,1:07.951.474,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 0C 3A A1 27 6B 96 4F 48 AD 5C C6 AD 64 DD 5E… 0,,17961,1:07.952.471,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,17962,1:07.966.476,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17966,1:07.967.473,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,17967,1:07.967.476,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 0C 3A A1 27 6B 96 4F 48 AD 5C C6 AD 64 DD 5E… 0,,17971,1:07.968.473,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,17972,1:07.983.478,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A7 78 B1 68 00 4E AF D5 6D 21 22 5D BE 95 11 51… 0,,17976,1:07.984.475,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,17977,1:07.998.480,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17981,1:07.999.477,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,17982,1:07.999.480,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A7 78 B1 68 00 4E AF D5 6D 21 22 5D BE 95 11 51… 0,,17986,1:08.000.477,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,17987,1:08.015.483,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 22 0F 74 29 F9 DF 04 99 D4 B1 FC DF C2 7E EF 47… 0,,17991,1:08.016.479,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,17992,1:08.030.485,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,17996,1:08.031.482,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,17997,1:08.031.485,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 22 0F 74 29 F9 DF 04 99 D4 B1 FC DF C2 7E EF 47… 0,,18001,1:08.032.482,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,18002,1:08.047.487,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B6 0D B8 3B 7A B0 30 8C D9 24 AC 21 0A 3C 06 44… 0,,18006,1:08.048.484,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,18007,1:08.062.489,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18011,1:08.063.486,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,18012,1:08.063.489,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B6 0D B8 3B 7A B0 30 8C D9 24 AC 21 0A 3C 06 44… 0,,18016,1:08.064.486,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,18017,1:08.079.491,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 88 66 C8 A9 EB 09 54 1C 4D 27 69 44 90 2F 0D 23… 0,,18021,1:08.080.488,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,18022,1:08.094.494,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18026,1:08.095.490,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,18027,1:08.095.494,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 88 66 C8 A9 EB 09 54 1C 4D 27 69 44 90 2F 0D 23… 0,,18031,1:08.096.491,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,18032,1:08.111.496,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D D7 31 5D C3 99 84 66 A4 F1 A8 E7 17 2D 48 A7… 0,,18036,1:08.112.493,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,18037,1:08.126.498,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18041,1:08.127.495,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,18042,1:08.127.498,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D D7 31 5D C3 99 84 66 A4 F1 A8 E7 17 2D 48 A7… 0,,18046,1:08.128.495,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,18047,1:08.143.500,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F0 3E 0E E4 C8 D6 4E BF 31 37 E6 4C 00 8F 8C 44… 0,,18051,1:08.144.497,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,18052,1:08.158.502,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18056,1:08.159.499,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,18057,1:08.159.503,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F0 3E 0E E4 C8 D6 4E BF 31 37 E6 4C 00 8F 8C 44… 0,,18061,1:08.160.499,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,18062,1:08.175.505,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F7 72 86 17 F1 47 C9 C0 9F 64 35 99 23 3C 82 0F… 0,,18066,1:08.176.502,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,18067,1:08.190.507,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18071,1:08.191.504,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,18072,1:08.191.507,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F7 72 86 17 F1 47 C9 C0 9F 64 35 99 23 3C 82 0F… 0,,18076,1:08.192.504,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,18077,1:08.207.509,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F0 61 02 18 18 28 9D EF 9F E3 77 89 F2 2F 54 A9… 0,,18081,1:08.208.506,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,18082,1:08.222.511,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18086,1:08.223.508,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,18087,1:08.223.511,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F0 61 02 18 18 28 9D EF 9F E3 77 89 F2 2F 54 A9… 0,,18091,1:08.224.508,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,18092,1:08.239.514,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CB 4C 67 95 7F 74 F5 F8 5E 54 47 00 2B BB 3E 60… 0,,18096,1:08.240.511,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,18097,1:08.254.516,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18101,1:08.255.513,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,18102,1:08.255.516,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CB 4C 67 95 7F 74 F5 F8 5E 54 47 00 2B BB 3E 60… 0,,18106,1:08.256.513,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,18107,1:08.271.518,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 5B C0 7A E8 9A 4D 91 5A 2A AD CD 48 37 62 A6… 0,,18111,1:08.272.515,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,18112,1:08.286.520,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18116,1:08.287.517,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,18117,1:08.287.520,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 5B C0 7A E8 9A 4D 91 5A 2A AD CD 48 37 62 A6… 0,,18121,1:08.288.517,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,18122,1:08.303.523,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 10 0B 80 06 FA BC 06 59 AF 89 36 EE 59 7A 6D C0… 0,,18126,1:08.304.519,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,18127,1:08.318.525,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18131,1:08.319.521,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,18132,1:08.319.525,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 10 0B 80 06 FA BC 06 59 AF 89 36 EE 59 7A 6D C0… 0,,18136,1:08.320.522,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,18137,1:08.335.527,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AE E1 38 0E 2A 74 D7 FB 1F 72 94 84 C8 07 2C AB… 0,,18141,1:08.336.524,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,18142,1:08.350.529,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18146,1:08.351.526,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,18147,1:08.351.529,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AE E1 38 0E 2A 74 D7 FB 1F 72 94 84 C8 07 2C AB… 0,,18151,1:08.352.526,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,18152,1:08.367.531,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 58 53 C0 65 E1 48 CF 67 F1 58 48 30 19 08 02… 0,,18156,1:08.368.528,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,18157,1:08.382.533,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18161,1:08.383.530,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,18162,1:08.383.534,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 58 53 C0 65 E1 48 CF 67 F1 58 48 30 19 08 02… 0,,18166,1:08.384.531,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,18167,1:08.399.536,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 B1 B2 66 62 FA CD 71 BE E8 C4 57 D6 7D 22 E8… 0,,18171,1:08.400.533,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,18172,1:08.414.538,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18176,1:08.415.535,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,18177,1:08.415.538,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 B1 B2 66 62 FA CD 71 BE E8 C4 57 D6 7D 22 E8… 0,,18181,1:08.416.535,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,18182,1:08.431.540,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B1 D2 B0 A2 86 FC F3 94 E2 C2 9A 8B E0 16 B4 31… 0,,18186,1:08.432.537,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,18187,1:08.446.542,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18191,1:08.447.539,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,18192,1:08.447.543,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B1 D2 B0 A2 86 FC F3 94 E2 C2 9A 8B E0 16 B4 31… 0,,18196,1:08.448.539,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,18197,1:08.463.545,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 37 0B 9B 51 FB 95 A7 FB 0F 19 51 2F DB BA AD 02… 0,,18201,1:08.464.542,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,18202,1:08.478.547,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18206,1:08.479.544,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,18207,1:08.479.547,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 37 0B 9B 51 FB 95 A7 FB 0F 19 51 2F DB BA AD 02… 0,,18211,1:08.480.544,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,18212,1:08.495.549,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 AE 5B 45 E0 78 8D 6D 0C 30 C6 88 71 D9 E3 65… 0,,18216,1:08.496.546,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,18217,1:08.510.551,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18221,1:08.511.548,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,18222,1:08.511.551,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 AE 5B 45 E0 78 8D 6D 0C 30 C6 88 71 D9 E3 65… 0,,18226,1:08.512.548,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,18227,1:08.527.554,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 A5 BB FD 97 80 4E F8 4B D5 B9 72 3F E7 02 A4… 0,,18231,1:08.528.551,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,18232,1:08.542.556,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18236,1:08.543.553,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,18237,1:08.543.556,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 A5 BB FD 97 80 4E F8 4B D5 B9 72 3F E7 02 A4… 0,,18241,1:08.544.553,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,18242,1:08.559.558,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA D4 0F 83 00 D7 AB C9 71 6C DA BB 7E 5D 0B 3A… 0,,18246,1:08.560.555,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,18247,1:08.574.560,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18251,1:08.575.557,16.005.041 ms,,,,,[17 SOF],[Frames: 929 - 945] 0,,18252,1:08.591.563,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA D4 0F 83 00 D7 AB C9 71 6C DA BB 7E 5D 0B 3A… 0,,18256,1:08.592.559,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,18257,1:08.606.565,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18261,1:08.607.561,16.005.041 ms,,,,,[17 SOF],[Frames: 961 - 977] 0,,18262,1:08.623.567,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9A 33 11 6B D5 3B D9 EF ED DB 1F 25 56 30 92 0E… 0,,18266,1:08.624.564,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,18267,1:08.638.569,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18271,1:08.639.566,2.812 us,,,,,[1 SOF],[Frame: 993] 0,,18272,1:08.639.569,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9A 33 11 6B D5 3B D9 EF ED DB 1F 25 56 30 92 0E… 0,,18276,1:08.640.566,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,18277,1:08.655.571,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EE 12 5E A3 AF B6 80 8B 15 97 87 43 AF DF 86 09… 0,,18281,1:08.656.568,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,18282,1:08.670.573,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18286,1:08.671.570,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,18287,1:08.671.574,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EE 12 5E A3 AF B6 80 8B 15 97 87 43 AF DF 86 09… 0,,18291,1:08.672.570,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,18292,1:08.687.576,50.937 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 62 0F 75 FB CF BB E0 2F 90 BE DE 5F DE E3 EC… 0,,18296,1:08.688.573,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,18297,1:08.702.578,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18301,1:08.703.575,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,18302,1:08.703.578,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC 62 0F 75 FB CF BB E0 2F 90 BE DE 5F DE E3 EC… 0,,18306,1:08.704.575,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,18307,1:08.719.580,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8C 8F C2 0F 91 9A 21 07 6A 65 B0 5E E8 10 19 D7… 0,,18311,1:08.720.577,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,18312,1:08.734.582,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18316,1:08.735.579,2.833 us,,,,,[1 SOF],[Frame: 1089] 0,,18317,1:08.735.582,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8C 8F C2 0F 91 9A 21 07 6A 65 B0 5E E8 10 19 D7… 0,,18321,1:08.736.579,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,18322,1:08.751.585,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 2D 07 2B 76 C1 DF 74 84 B4 A7 00 98 2E 90 8C… 0,,18326,1:08.752.582,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,18327,1:08.766.587,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18331,1:08.767.584,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,18332,1:08.767.587,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 2D 07 2B 76 C1 DF 74 84 B4 A7 00 98 2E 90 8C… 0,,18336,1:08.768.584,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,18337,1:08.783.589,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 66 6B A6 C6 E4 E1 64 D3 3F 38 86 ED D0 21 13 5C… 0,,18341,1:08.784.586,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,18342,1:08.798.591,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18346,1:08.799.588,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,18347,1:08.799.591,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 66 6B A6 C6 E4 E1 64 D3 3F 38 86 ED D0 21 13 5C… 0,,18351,1:08.800.588,15.004.916 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,18352,1:08.815.594,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 BB 43 CE 14 FD FC 7F A1 10 1F 77 71 71 AC 3D… 0,,18356,1:08.816.590,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,18357,1:08.830.596,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18361,1:08.831.593,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,18362,1:08.831.596,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 BB 43 CE 14 FD FC 7F A1 10 1F 77 71 71 AC 3D… 0,,18366,1:08.832.593,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,18367,1:08.847.598,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B 92 EB EE 8F 64 E3 42 B8 12 8A C8 90 B9 36 28… 0,,18371,1:08.848.595,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,18372,1:08.862.600,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18376,1:08.863.597,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,18377,1:08.863.600,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B 92 EB EE 8F 64 E3 42 B8 12 8A C8 90 B9 36 28… 0,,18381,1:08.864.597,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,18382,1:08.879.602,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 53 4D 73 22 25 86 EB 68 3E B7 DF 76 03 5E 27 FD… 0,,18386,1:08.880.599,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,18387,1:08.894.605,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18391,1:08.895.601,2.833 us,,,,,[1 SOF],[Frame: 1249] 0,,18392,1:08.895.605,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 53 4D 73 22 25 86 EB 68 3E B7 DF 76 03 5E 27 FD… 0,,18396,1:08.896.602,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,18397,1:08.911.607,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC 08 38 32 3F 86 D8 2E 25 82 9D A6 A3 67 40 A1… 0,,18401,1:08.912.604,14.004.750 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,18402,1:08.926.609,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18406,1:08.927.606,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,18407,1:08.927.609,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC 08 38 32 3F 86 D8 2E 25 82 9D A6 A3 67 40 A1… 0,,18411,1:08.928.606,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,18412,1:08.943.611,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 65 FB 75 33 D9 68 93 64 18 D2 DB 9C 46 93 BB 9C… 0,,18416,1:08.944.608,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,18417,1:08.958.613,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18421,1:08.959.610,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,18422,1:08.959.614,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 65 FB 75 33 D9 68 93 64 18 D2 DB 9C 46 93 BB 9C… 0,,18426,1:08.960.610,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,18427,1:08.975.616,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 35 F1 4E 7D 3F E0 42 99 57 FF 42 14 8D 29 3A 74… 0,,18431,1:08.976.613,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,18432,1:08.990.618,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18436,1:08.991.615,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,18437,1:08.991.618,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 35 F1 4E 7D 3F E0 42 99 57 FF 42 14 8D 29 3A 74… 0,,18441,1:08.992.615,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,18442,1:09.007.620,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C2 D4 27 C6 CE 85 DC 90 1F D7 71 AC FF FB 31 67… 0,,18446,1:09.008.617,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,18447,1:09.022.622,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18451,1:09.023.619,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,18452,1:09.023.622,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C2 D4 27 C6 CE 85 DC 90 1F D7 71 AC FF FB 31 67… 0,,18456,1:09.024.619,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,18457,1:09.039.625,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FE 34 08 49 7B E8 8D 30 31 A6 4D 83 29 52 63 C8… 0,,18461,1:09.040.622,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,18462,1:09.054.627,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18466,1:09.055.624,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,18467,1:09.055.627,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FE 34 08 49 7B E8 8D 30 31 A6 4D 83 29 52 63 C8… 0,,18471,1:09.056.624,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,18472,1:09.071.629,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC 9B 3F 15 93 AC D0 05 84 92 64 D3 B7 C9 70 28… 0,,18476,1:09.072.626,14.004.750 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,18477,1:09.086.631,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18481,1:09.087.628,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,18482,1:09.087.631,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC 9B 3F 15 93 AC D0 05 84 92 64 D3 B7 C9 70 28… 0,,18486,1:09.088.628,15.004.916 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,18487,1:09.103.634,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 21 0B 29 4C 5B 9C 02 A2 8F 5B 5E 42 19 8D 09 C8… 0,,18491,1:09.104.630,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,18492,1:09.118.636,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18496,1:09.119.633,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,18497,1:09.119.636,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 21 0B 29 4C 5B 9C 02 A2 8F 5B 5E 42 19 8D 09 C8… 0,,18501,1:09.120.633,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,18502,1:09.135.638,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 C4 56 C3 81 59 15 A6 5F B2 ED A1 55 40 6F 16… 0,,18506,1:09.136.635,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,18507,1:09.150.640,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18511,1:09.151.637,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,18512,1:09.151.640,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 C4 56 C3 81 59 15 A6 5F B2 ED A1 55 40 6F 16… 0,,18516,1:09.152.637,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,18517,1:09.167.642,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 99 CC F3 EA 8B 83 34 3A 49 A9 9A 3F 5C B3 44… 0,,18521,1:09.168.639,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,18522,1:09.182.645,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18526,1:09.183.641,16.005.125 ms,,,,,[17 SOF],[Frames: 1537 - 1553] 0,,18527,1:09.199.647,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7C ED 54 00 F2 EF BA C9 73 8F D7 B7 2F 33 83 00… 0,,18531,1:09.200.644,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,18532,1:09.214.649,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18536,1:09.215.646,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,18537,1:09.215.649,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7C ED 54 00 F2 EF BA C9 73 8F D7 B7 2F 33 83 00… 0,,18541,1:09.216.646,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,18542,1:09.231.651,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 99 4D 00 99 00 C7 FD 83 9A D0 46 F2 33 77 A6… 0,,18546,1:09.232.648,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,18547,1:09.246.653,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18551,1:09.247.650,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,18552,1:09.247.654,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 99 4D 00 99 00 C7 FD 83 9A D0 46 F2 33 77 A6… 0,,18556,1:09.248.650,15.004.916 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,18557,1:09.263.656,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 45 99 05 8B 27 86 9E 4B 72 BF F7 0C ED 34 5D… 0,,18561,1:09.264.653,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,18562,1:09.278.658,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18566,1:09.279.655,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,18567,1:09.279.658,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 45 99 05 8B 27 86 9E 4B 72 BF F7 0C ED 34 5D… 0,,18571,1:09.280.655,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,18572,1:09.295.660,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 99 37 70 FA 41 7D C2 AB CB 50 66 12 00 2B 25 92… 0,,18576,1:09.296.657,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,18577,1:09.310.662,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18581,1:09.311.659,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,18582,1:09.311.662,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 99 37 70 FA 41 7D C2 AB CB 50 66 12 00 2B 25 92… 0,,18586,1:09.312.659,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,18587,1:09.327.665,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B 25 C9 B1 D5 DE 8B 77 44 0D 67 1F F2 A2 D1 4A… 0,,18591,1:09.328.662,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,18592,1:09.342.667,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18596,1:09.343.664,2.833 us,,,,,[1 SOF],[Frame: 1697] 0,,18597,1:09.343.667,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B 25 C9 B1 D5 DE 8B 77 44 0D 67 1F F2 A2 D1 4A… 0,,18601,1:09.344.664,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,18602,1:09.359.669,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D9 55 F0 13 AF 30 41 98 95 F8 9B 3F 9D DE 24 82… 0,,18606,1:09.360.666,14.004.750 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,18607,1:09.374.671,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18611,1:09.375.668,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,18612,1:09.375.671,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D9 55 F0 13 AF 30 41 98 95 F8 9B 3F 9D DE 24 82… 0,,18616,1:09.376.668,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,18617,1:09.391.674,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 56 39 BB 99 B8 DC 0C 7F BD 25 C6 24 90 EC 06 EB… 0,,18621,1:09.392.670,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,18622,1:09.406.676,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18626,1:09.407.673,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,18627,1:09.407.676,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 56 39 BB 99 B8 DC 0C 7F BD 25 C6 24 90 EC 06 EB… 0,,18631,1:09.408.673,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,18632,1:09.423.678,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 0C 2C C4 C4 0E C7 C1 D0 07 1C 06 27 47 B3 FD… 0,,18636,1:09.424.675,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,18637,1:09.438.680,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18641,1:09.439.677,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,18642,1:09.439.680,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 0C 2C C4 C4 0E C7 C1 D0 07 1C 06 27 47 B3 FD… 0,,18646,1:09.440.677,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,18647,1:09.455.682,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 64 14 7D 9D 6F AB A5 6C 57 60 79 B1 3E 9D EF C5… 0,,18651,1:09.456.679,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,18652,1:09.470.685,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18656,1:09.471.681,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,18657,1:09.471.685,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 64 14 7D 9D 6F AB A5 6C 57 60 79 B1 3E 9D EF C5… 0,,18661,1:09.472.682,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,18662,1:09.487.687,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 7B B4 45 E4 62 08 8F 91 D3 7E 8B 29 81 81 4D… 0,,18666,1:09.488.684,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,18667,1:09.502.689,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18671,1:09.503.686,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,18672,1:09.503.689,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 7B B4 45 E4 62 08 8F 91 D3 7E 8B 29 81 81 4D… 0,,18676,1:09.504.686,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,18677,1:09.519.691,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 FD 5A FB 23 33 AF 8E D4 D1 31 BF D4 66 54 BA… 0,,18681,1:09.520.688,14.004.750 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,18682,1:09.534.693,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18686,1:09.535.690,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,18687,1:09.535.694,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 FD 5A FB 23 33 AF 8E D4 D1 31 BF D4 66 54 BA… 0,,18691,1:09.536.690,15.004.916 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,18692,1:09.551.696,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D2 B3 08 77 1C 13 C6 07 BB A7 EF 99 5B 5C A6 82… 0,,18696,1:09.552.693,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,18697,1:09.566.698,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18701,1:09.567.695,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,18702,1:09.567.698,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D2 B3 08 77 1C 13 C6 07 BB A7 EF 99 5B 5C A6 82… 0,,18706,1:09.568.695,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,18707,1:09.583.700,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 20 B9 B9 39 BC 48 F1 CF 16 A6 95 27 DA F1 C5… 0,,18711,1:09.584.697,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,18712,1:09.598.702,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18716,1:09.599.699,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,18717,1:09.599.702,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 20 B9 B9 39 BC 48 F1 CF 16 A6 95 27 DA F1 C5… 0,,18721,1:09.600.699,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,18722,1:09.615.705,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C 79 56 6D AD C1 3B 25 61 98 6A 9A 11 A8 5D BB… 0,,18726,1:09.616.702,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,18727,1:09.630.707,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18731,1:09.631.704,2.916 us,,,,,[1 SOF],[Frame: 1985] 0,,18732,1:09.631.707,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C 79 56 6D AD C1 3B 25 61 98 6A 9A 11 A8 5D BB… 0,,18736,1:09.632.704,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,18737,1:09.647.709,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E B9 02 08 A7 61 67 FA 7E 62 B0 81 76 B4 7D 74… 0,,18741,1:09.648.706,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,18742,1:09.662.711,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18746,1:09.663.708,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,18747,1:09.663.711,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E B9 02 08 A7 61 67 FA 7E 62 B0 81 76 B4 7D 74… 0,,18751,1:09.664.708,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,18752,1:09.679.714,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 76 CF 8B 96 8E 79 07 89 EC 4A 18 59 45 11 59… 0,,18756,1:09.680.710,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,18757,1:09.694.716,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18761,1:09.695.713,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,18762,1:09.695.716,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 76 CF 8B 96 8E 79 07 89 EC 4A 18 59 45 11 59… 0,,18766,1:09.696.713,15.004.916 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,18767,1:09.711.718,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 6B 0F BC 19 ED CB 29 29 D0 37 2B 3D 90 C9 E0… 0,,18771,1:09.712.715,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,18772,1:09.726.720,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18776,1:09.727.717,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,18777,1:09.727.720,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 6B 0F BC 19 ED CB 29 29 D0 37 2B 3D 90 C9 E0… 0,,18781,1:09.728.717,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,18782,1:09.743.722,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3F CB D7 4A E9 15 A2 30 02 BB A2 BD F2 A6 C4 4F… 0,,18786,1:09.744.719,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,18787,1:09.758.724,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18791,1:09.759.721,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,18792,1:09.759.725,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3F CB D7 4A E9 15 A2 30 02 BB A2 BD F2 A6 C4 4F… 0,,18796,1:09.760.722,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,18797,1:09.775.727,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 2C 0D 49 8E 0D DE 77 B0 32 9B 49 0F 10 E2 96… 0,,18801,1:09.776.724,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,18802,1:09.790.729,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18806,1:09.791.726,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,18807,1:09.791.729,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 2C 0D 49 8E 0D DE 77 B0 32 9B 49 0F 10 E2 96… 0,,18811,1:09.792.726,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,18812,1:09.807.731,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4F 6E 71 5B E1 87 D8 60 73 46 EC 05 55 49 AC AD… 0,,18816,1:09.808.728,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,18817,1:09.822.733,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18821,1:09.823.730,16.005.041 ms,,,,,[17 SOF],[Frames: 129 - 145] 0,,18822,1:09.839.736,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4F 6E 71 5B E1 87 D8 60 73 46 EC 05 55 49 AC AD… 0,,18826,1:09.840.733,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,18827,1:09.854.738,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18831,1:09.855.735,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,18832,1:09.855.738,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4F 6E 71 5B E1 87 D8 60 73 46 EC 05 55 49 AC AD… 0,,18836,1:09.856.735,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,18837,1:09.871.740,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF 7D 6E 49 70 CB 2D 33 08 D2 8C 28 67 24 C4 E4… 0,,18841,1:09.872.737,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,18842,1:09.886.742,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18846,1:09.887.739,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,18847,1:09.887.742,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF 7D 6E 49 70 CB 2D 33 08 D2 8C 28 67 24 C4 E4… 0,,18851,1:09.888.739,15.004.895 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,18852,1:09.903.745,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D 77 BD 62 FC 3B 04 DC 1B 6D 7D 8F F4 BE 3C 05… 0,,18856,1:09.904.742,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,18857,1:09.918.747,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18861,1:09.919.744,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,18862,1:09.919.747,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D 77 BD 62 FC 3B 04 DC 1B 6D 7D 8F F4 BE 3C 05… 0,,18866,1:09.920.744,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,18867,1:09.935.749,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 89 D1 3B E7 8B 10 15 A1 EA 2A 55 E8 04 F4 5A… 0,,18871,1:09.936.746,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,18872,1:09.950.751,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18876,1:09.951.748,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,18877,1:09.951.751,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 89 D1 3B E7 8B 10 15 A1 EA 2A 55 E8 04 F4 5A… 0,,18881,1:09.952.748,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,18882,1:09.967.754,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 84 50 7C E2 45 56 44 84 51 E8 C0 06 D8 67 E3… 0,,18886,1:09.968.750,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,18887,1:09.982.756,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18891,1:09.983.752,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,18892,1:09.983.756,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 84 50 7C E2 45 56 44 84 51 E8 C0 06 D8 67 E3… 0,,18896,1:09.984.753,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,18897,1:09.999.758,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 02 A0 EE 57 73 0F EF C1 9B 4E 3A F1 FA 65 35 F3… 0,,18901,1:10.000.755,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,18902,1:10.014.760,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18906,1:10.015.757,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,18907,1:10.015.760,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 02 A0 EE 57 73 0F EF C1 9B 4E 3A F1 FA 65 35 F3… 0,,18911,1:10.016.757,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,18912,1:10.031.762,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 26 25 0C 16 72 D6 D3 5E 3A 17 17 A6 F0 32 68 77… 0,,18916,1:10.032.759,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,18917,1:10.046.764,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18921,1:10.047.761,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,18922,1:10.047.765,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 26 25 0C 16 72 D6 D3 5E 3A 17 17 A6 F0 32 68 77… 0,,18926,1:10.048.762,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,18927,1:10.063.767,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 9E D7 B7 DD 5C 6D F7 87 94 52 1D D8 19 CF 43… 0,,18931,1:10.064.764,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,18932,1:10.078.769,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18936,1:10.079.766,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,18937,1:10.079.769,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 9E D7 B7 DD 5C 6D F7 87 94 52 1D D8 19 CF 43… 0,,18941,1:10.080.766,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,18942,1:10.095.771,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 8D 8C E3 93 41 E4 4F 05 B1 F0 57 65 44 7C 5F… 0,,18946,1:10.096.768,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,18947,1:10.110.773,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18951,1:10.111.770,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,18952,1:10.111.774,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 8D 8C E3 93 41 E4 4F 05 B1 F0 57 65 44 7C 5F… 0,,18956,1:10.112.770,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,18957,1:10.127.776,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 CA 6E DC CC 23 A7 08 E4 5E 1C F6 2B 02 15 C4… 0,,18961,1:10.128.773,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,18962,1:10.142.778,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18966,1:10.143.775,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,18967,1:10.143.778,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 CA 6E DC CC 23 A7 08 E4 5E 1C F6 2B 02 15 C4… 0,,18971,1:10.144.775,15.004.916 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,18972,1:10.159.780,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B9 0A 8D BD AF 36 EE 5D 6F 3C 75 E1 11 B6 78 63… 0,,18976,1:10.160.777,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,18977,1:10.174.782,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18981,1:10.175.779,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,18982,1:10.175.782,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B9 0A 8D BD AF 36 EE 5D 6F 3C 75 E1 11 B6 78 63… 0,,18986,1:10.176.779,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,18987,1:10.191.785,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2F AD D4 D8 D1 2F E5 82 E2 5C AC 2D A6 C2 88 48… 0,,18991,1:10.192.781,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,18992,1:10.206.787,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,18996,1:10.207.784,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,18997,1:10.207.787,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2F AD D4 D8 D1 2F E5 82 E2 5C AC 2D A6 C2 88 48… 0,,19001,1:10.208.784,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,19002,1:10.223.789,50.916 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 11 90 93 FD 55 DB EF 2E D0 C0 ED FD CB 52 7F… 0,,19006,1:10.224.786,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,19007,1:10.238.791,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19011,1:10.239.788,2.833 us,,,,,[1 SOF],[Frame: 545] 0,,19012,1:10.239.791,50.916 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 11 90 93 FD 55 DB EF 2E D0 C0 ED FD CB 52 7F… 0,,19016,1:10.240.788,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,19017,1:10.255.793,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D6 BC F5 5B 73 FA 49 CF 8E 76 55 C1 B1 0A CA 9E… 0,,19021,1:10.256.790,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,19022,1:10.270.796,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19026,1:10.271.792,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,19027,1:10.271.796,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D6 BC F5 5B 73 FA 49 CF 8E 76 55 C1 B1 0A CA 9E… 0,,19031,1:10.272.793,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,19032,1:10.287.798,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 03 48 A2 27 9A 84 B7 B5 5E C2 B2 A9 25 AA 49 5F… 0,,19036,1:10.288.795,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,19037,1:10.302.800,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19041,1:10.303.797,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,19042,1:10.303.800,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 03 48 A2 27 9A 84 B7 B5 5E C2 B2 A9 25 AA 49 5F… 0,,19046,1:10.304.797,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,19047,1:10.319.802,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 86 AF E9 C6 3A 38 14 F3 A3 8E 4C 8C FD F5 C9 62… 0,,19051,1:10.320.799,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,19052,1:10.334.804,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19056,1:10.335.801,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,19057,1:10.335.805,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 86 AF E9 C6 3A 38 14 F3 A3 8E 4C 8C FD F5 C9 62… 0,,19061,1:10.336.801,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,19062,1:10.351.807,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 7D 87 D9 E4 E3 95 FC 58 CF BF 3E 2C 4A 3F B7… 0,,19066,1:10.352.804,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,19067,1:10.366.809,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19071,1:10.367.806,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,19072,1:10.367.809,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 7D 87 D9 E4 E3 95 FC 58 CF BF 3E 2C 4A 3F B7… 0,,19076,1:10.368.806,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,19077,1:10.383.811,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 AE F7 54 C2 39 BD 5B 71 6C C7 AC 71 C8 36 C8… 0,,19081,1:10.384.808,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,19082,1:10.398.813,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19086,1:10.399.810,2.833 us,,,,,[1 SOF],[Frame: 705] 0,,19087,1:10.399.813,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 AE F7 54 C2 39 BD 5B 71 6C C7 AC 71 C8 36 C8… 0,,19091,1:10.400.810,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,19092,1:10.415.816,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3F 79 50 12 8E 43 7E 6B EC 7B E8 87 26 7C DC F5… 0,,19096,1:10.416.813,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,19097,1:10.430.818,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19101,1:10.431.815,16.005.041 ms,,,,,[17 SOF],[Frames: 737 - 753] 0,,19102,1:10.447.820,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 39 45 8F B8 17 67 A8 B3 77 87 1A CF E1 B5 FA 3F… 0,,19106,1:10.448.817,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,19107,1:10.462.822,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19111,1:10.463.819,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,19112,1:10.463.822,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 39 45 8F B8 17 67 A8 B3 77 87 1A CF E1 B5 FA 3F… 0,,19116,1:10.464.819,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,19117,1:10.479.825,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BB D3 F4 FB 57 C9 3A B4 B4 D0 50 9D C1 F6 58 48… 0,,19121,1:10.480.821,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,19122,1:10.494.827,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19126,1:10.495.824,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,19127,1:10.495.827,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BB D3 F4 FB 57 C9 3A B4 B4 D0 50 9D C1 F6 58 48… 0,,19131,1:10.496.824,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,19132,1:10.511.829,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 B9 E8 B6 6E 6D D1 7E 85 F2 C8 2A C5 DA 7A 0D… 0,,19136,1:10.512.826,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,19137,1:10.526.831,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19141,1:10.527.828,2.833 us,,,,,[1 SOF],[Frame: 833] 0,,19142,1:10.527.831,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 B9 E8 B6 6E 6D D1 7E 85 F2 C8 2A C5 DA 7A 0D… 0,,19146,1:10.528.828,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,19147,1:10.543.833,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF 3B 8B 2A A0 A6 84 C8 AA F5 F1 BE 2B C3 F9 8C… 0,,19151,1:10.544.830,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,19152,1:10.558.836,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19156,1:10.559.832,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,19157,1:10.559.836,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF 3B 8B 2A A0 A6 84 C8 AA F5 F1 BE 2B C3 F9 8C… 0,,19161,1:10.560.833,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,19162,1:10.575.838,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 0C CA AD 2A 36 7E 63 3D 82 1A CE E2 02 A5 D5… 0,,19166,1:10.576.835,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,19167,1:10.590.840,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19171,1:10.591.837,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,19172,1:10.591.840,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 0C CA AD 2A 36 7E 63 3D 82 1A CE E2 02 A5 D5… 0,,19176,1:10.592.837,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,19177,1:10.607.842,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 2C 49 95 8C E3 41 4A D4 FF 80 F4 F6 E6 27 99… 0,,19181,1:10.608.839,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,19182,1:10.622.844,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19186,1:10.623.841,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,19187,1:10.623.845,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 2C 49 95 8C E3 41 4A D4 FF 80 F4 F6 E6 27 99… 0,,19191,1:10.624.841,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,19192,1:10.639.847,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 79 DE 60 8D E8 A7 41 25 A8 74 5F 42 A7 40 A1… 0,,19196,1:10.640.844,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,19197,1:10.654.849,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19201,1:10.655.846,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,19202,1:10.655.849,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 79 DE 60 8D E8 A7 41 25 A8 74 5F 42 A7 40 A1… 0,,19206,1:10.656.846,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,19207,1:10.671.851,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 99 96 78 6E C6 0C 1D BC 33 2B 17 9E 38 F0 B3 67… 0,,19211,1:10.672.848,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,19212,1:10.686.853,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19216,1:10.687.850,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,19217,1:10.687.853,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 99 96 78 6E C6 0C 1D BC 33 2B 17 9E 38 F0 B3 67… 0,,19221,1:10.688.850,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,19222,1:10.703.856,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 60 8D 79 6D 4D C9 FD 5E D1 31 68 E2 15 FC 07 9C… 0,,19226,1:10.704.853,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,19227,1:10.718.858,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19231,1:10.719.855,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,19232,1:10.719.858,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 8D 79 6D 4D C9 FD 5E D1 31 68 E2 15 FC 07 9C… 0,,19236,1:10.720.855,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,19237,1:10.735.860,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 60 6D ED E4 E1 10 28 C9 46 42 92 68 EB 94 36 83… 0,,19241,1:10.736.857,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,19242,1:10.750.862,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19246,1:10.751.859,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,19247,1:10.751.862,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 6D ED E4 E1 10 28 C9 46 42 92 68 EB 94 36 83… 0,,19251,1:10.752.859,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,19252,1:10.767.865,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD B8 DF 89 01 83 30 50 29 2D 34 87 F9 99 9E C4… 0,,19256,1:10.768.861,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,19257,1:10.782.867,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19261,1:10.783.864,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,19262,1:10.783.867,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD B8 DF 89 01 83 30 50 29 2D 34 87 F9 99 9E C4… 0,,19266,1:10.784.864,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,19267,1:10.799.869,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 52 69 71 6E CC 73 70 27 06 99 01 F6 76 60 25 35… 0,,19271,1:10.800.866,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,19272,1:10.814.871,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19276,1:10.815.868,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,19277,1:10.815.871,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 52 69 71 6E CC 73 70 27 06 99 01 F6 76 60 25 35… 0,,19281,1:10.816.868,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,19282,1:10.831.873,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BA 5E 05 FC 9D B4 3E D0 DA 5C C1 3D 23 42 CA 5F… 0,,19286,1:10.832.870,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,19287,1:10.846.876,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19291,1:10.847.872,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,19292,1:10.847.876,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BA 5E 05 FC 9D B4 3E D0 DA 5C C1 3D 23 42 CA 5F… 0,,19296,1:10.848.873,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,19297,1:10.863.878,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 9E 8A 53 D0 DC 4E 9B 64 DE DB 4B 82 B2 F4 46… 0,,19301,1:10.864.875,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,19302,1:10.878.880,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19306,1:10.879.877,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,19307,1:10.879.880,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 9E 8A 53 D0 DC 4E 9B 64 DE DB 4B 82 B2 F4 46… 0,,19311,1:10.880.877,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,19312,1:10.895.882,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 84 CD 2F AC 62 CA F6 E8 11 3C 7D 14 31 78 DE DC… 0,,19316,1:10.896.879,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,19317,1:10.910.884,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19321,1:10.911.881,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,19322,1:10.911.885,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 84 CD 2F AC 62 CA F6 E8 11 3C 7D 14 31 78 DE DC… 0,,19326,1:10.912.881,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,19327,1:10.927.887,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 08 8E 8F 67 9C FA C0 0B D7 65 E4 03 3E 1C B6 E0… 0,,19331,1:10.928.884,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,19332,1:10.942.889,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19336,1:10.943.886,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,19337,1:10.943.889,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 08 8E 8F 67 9C FA C0 0B D7 65 E4 03 3E 1C B6 E0… 0,,19341,1:10.944.886,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,19342,1:10.959.891,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 2A DE 3F 8A 78 2D B6 3B 27 A9 2D DF 2A 01 53… 0,,19346,1:10.960.888,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,19347,1:10.974.893,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19351,1:10.975.890,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,19352,1:10.975.893,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A 2A DE 3F 8A 78 2D B6 3B 27 A9 2D DF 2A 01 53… 0,,19356,1:10.976.890,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,19357,1:10.991.896,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AC 48 C2 EE B3 A2 B4 8A 83 B3 85 3E 9D 7D C7 5A… 0,,19361,1:10.992.893,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,19362,1:11.006.898,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19366,1:11.007.895,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,19367,1:11.007.898,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AC 48 C2 EE B3 A2 B4 8A 83 B3 85 3E 9D 7D C7 5A… 0,,19371,1:11.008.895,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,19372,1:11.023.900,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7A 42 3E B4 A5 A6 A6 88 96 95 E5 B4 75 29 C4 84… 0,,19376,1:11.024.897,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,19377,1:11.038.902,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19381,1:11.039.899,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,19382,1:11.039.902,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7A 42 3E B4 A5 A6 A6 88 96 95 E5 B4 75 29 C4 84… 0,,19386,1:11.040.899,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,19387,1:11.055.905,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F2 E7 A6 25 8E 13 74 8C C3 FA 6F 18 02 D8 69 18… 0,,19391,1:11.056.901,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,19392,1:11.070.907,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19396,1:11.071.904,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,19397,1:11.071.907,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F2 E7 A6 25 8E 13 74 8C C3 FA 6F 18 02 D8 69 18… 0,,19401,1:11.072.904,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,19402,1:11.087.909,50.645 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 E2 61 AF 01 D3 36 D1 12 54 FE 24 BD 80 FD 6A… 0,,19406,1:11.088.906,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,19407,1:11.102.911,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19411,1:11.103.908,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,19412,1:11.103.911,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 E2 61 AF 01 D3 36 D1 12 54 FE 24 BD 80 FD 6A… 0,,19416,1:11.104.908,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,19417,1:11.119.913,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 8B 5A FF 44 67 7E 34 C8 9D 01 6A D3 F1 E8 51… 0,,19421,1:11.120.910,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,19422,1:11.134.916,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19426,1:11.135.912,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,19427,1:11.135.916,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 8B 5A FF 44 67 7E 34 C8 9D 01 6A D3 F1 E8 51… 0,,19431,1:11.136.913,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,19432,1:11.151.918,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 E8 D0 5D E8 4A D6 84 8E CE 87 30 AD 00 54 CC… 0,,19436,1:11.152.915,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,19437,1:11.166.920,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19441,1:11.167.917,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,19442,1:11.167.920,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 E8 D0 5D E8 4A D6 84 8E CE 87 30 AD 00 54 CC… 0,,19446,1:11.168.917,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,19447,1:11.183.922,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 BB F4 0C A1 9E 85 20 C0 71 66 4F 06 22 6C 62… 0,,19451,1:11.184.919,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,19452,1:11.198.924,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19456,1:11.199.921,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,19457,1:11.199.925,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 BB F4 0C A1 9E 85 20 C0 71 66 4F 06 22 6C 62… 0,,19461,1:11.200.921,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,19462,1:11.215.927,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E9 9E 04 A0 87 1B F3 08 A2 DB C4 2F 4E DF B3 25… 0,,19466,1:11.216.924,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,19467,1:11.230.929,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19471,1:11.231.926,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,19472,1:11.231.929,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E9 9E 04 A0 87 1B F3 08 A2 DB C4 2F 4E DF B3 25… 0,,19476,1:11.232.926,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,19477,1:11.247.931,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9E 14 B3 32 D9 CB 77 44 94 5D 86 AC 9A FC DA 0D… 0,,19481,1:11.248.928,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,19482,1:11.262.933,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19486,1:11.263.930,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,19487,1:11.263.933,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9E 14 B3 32 D9 CB 77 44 94 5D 86 AC 9A FC DA 0D… 0,,19491,1:11.264.930,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,19492,1:11.279.936,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 BE EC 97 B1 67 73 47 67 EF 9A A9 E4 F3 E6 74… 0,,19496,1:11.280.933,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,19497,1:11.294.938,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19501,1:11.295.935,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,19502,1:11.295.938,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 BE EC 97 B1 67 73 47 67 EF 9A A9 E4 F3 E6 74… 0,,19506,1:11.296.935,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,19507,1:11.311.940,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 4D E0 19 F6 7A 38 17 11 BF 94 DD 04 88 79 BE… 0,,19511,1:11.312.937,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,19512,1:11.326.942,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19516,1:11.327.939,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,19517,1:11.327.942,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 4D E0 19 F6 7A 38 17 11 BF 94 DD 04 88 79 BE… 0,,19521,1:11.328.939,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,19522,1:11.343.945,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C9 61 BB 82 E6 2F 87 63 F8 7C C6 27 10 26 7C 0B… 0,,19526,1:11.344.941,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,19527,1:11.358.947,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19531,1:11.359.943,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,19532,1:11.359.947,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C9 61 BB 82 E6 2F 87 63 F8 7C C6 27 10 26 7C 0B… 0,,19536,1:11.360.944,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,19537,1:11.375.949,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B DD 5B AC D6 71 2D BB E7 CB FB 31 C0 81 31 16… 0,,19541,1:11.376.946,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,19542,1:11.390.951,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19546,1:11.391.948,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,19547,1:11.391.951,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B DD 5B AC D6 71 2D BB E7 CB FB 31 C0 81 31 16… 0,,19551,1:11.392.948,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,19552,1:11.407.953,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A6 88 F9 0C 87 7D 79 82 0B 94 BA FD EF 2F 8C D1… 0,,19556,1:11.408.950,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,19557,1:11.422.955,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19561,1:11.423.952,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,19562,1:11.423.956,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A6 88 F9 0C 87 7D 79 82 0B 94 BA FD EF 2F 8C D1… 0,,19566,1:11.424.953,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,19567,1:11.439.958,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F1 0A B2 4F E0 02 61 0D B9 0E 5D EE 76 5A 12 3A… 0,,19571,1:11.440.955,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,19572,1:11.454.960,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19576,1:11.455.957,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,19577,1:11.455.960,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F1 0A B2 4F E0 02 61 0D B9 0E 5D EE 76 5A 12 3A… 0,,19581,1:11.456.957,15.004.916 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,19582,1:11.471.962,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 C8 43 34 79 28 F2 E6 E9 48 7D 98 18 56 6F 63… 0,,19586,1:11.472.959,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,19587,1:11.486.964,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19591,1:11.487.961,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,19592,1:11.487.965,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 C8 43 34 79 28 F2 E6 E9 48 7D 98 18 56 6F 63… 0,,19596,1:11.488.961,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,19597,1:11.503.967,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 96 FD B4 23 3B 70 24 10 58 47 66 0C 61 49 0D 26… 0,,19601,1:11.504.964,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,19602,1:11.518.969,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19606,1:11.519.966,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,19607,1:11.519.969,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 96 FD B4 23 3B 70 24 10 58 47 66 0C 61 49 0D 26… 0,,19611,1:11.520.966,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,19612,1:11.535.971,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 67 F5 56 FA 58 5A 3E 81 36 FE DF D3 1D 6F 84… 0,,19616,1:11.536.968,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,19617,1:11.550.973,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19621,1:11.551.970,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,19622,1:11.551.973,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 67 F5 56 FA 58 5A 3E 81 36 FE DF D3 1D 6F 84… 0,,19626,1:11.552.970,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,19627,1:11.567.976,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0B 61 4F C7 1C 9B 25 BA D5 DF EA AC 3C 9F 55 85… 0,,19631,1:11.568.972,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,19632,1:11.582.978,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19636,1:11.583.975,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,19637,1:11.583.978,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0B 61 4F C7 1C 9B 25 BA D5 DF EA AC 3C 9F 55 85… 0,,19641,1:11.584.975,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,19642,1:11.599.980,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1F 89 9A B3 36 EB 27 8F 1C 7A B0 2E 93 04 71 35… 0,,19646,1:11.600.977,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,19647,1:11.614.982,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19651,1:11.615.979,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,19652,1:11.615.982,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1F 89 9A B3 36 EB 27 8F 1C 7A B0 2E 93 04 71 35… 0,,19656,1:11.616.979,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,19657,1:11.631.984,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 84 5E A8 C1 0B AF 16 D9 29 EE 65 23 FE F9 C0 BD… 0,,19661,1:11.632.981,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,19662,1:11.646.987,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19666,1:11.647.983,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,19667,1:11.647.987,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 84 5E A8 C1 0B AF 16 D9 29 EE 65 23 FE F9 C0 BD… 0,,19671,1:11.648.984,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,19672,1:11.663.989,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 50 A6 65 9F 73 55 82 3C C1 1C E0 4D FB 30 51… 0,,19676,1:11.664.986,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,19677,1:11.678.991,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19681,1:11.679.988,16.005.125 ms,,,,,[17 SOF],[Frames: 1985 - 2001] 0,,19682,1:11.695.993,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6A 15 0D 46 17 6C 6C 7B FF 71 D7 46 D9 B6 B8 A2… 0,,19686,1:11.696.990,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,19687,1:11.710.996,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19691,1:11.711.992,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,19692,1:11.711.996,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6A 15 0D 46 17 6C 6C 7B FF 71 D7 46 D9 B6 B8 A2… 0,,19696,1:11.712.992,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,19697,1:11.727.998,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 AD 97 37 22 80 A1 7F 83 77 EA AF 16 DB 47 9C… 0,,19701,1:11.728.995,14.004.750 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,19702,1:11.743.000,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19706,1:11.743.997,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,19707,1:11.744.000,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 AD 97 37 22 80 A1 7F 83 77 EA AF 16 DB 47 9C… 0,,19711,1:11.744.997,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,19712,1:11.760.002,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE 33 BD A2 B8 59 58 85 2C 41 F1 DE 6D 6C E5 FF… 0,,19716,1:11.760.999,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,19717,1:11.775.004,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19721,1:11.776.001,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,19722,1:11.776.004,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE 33 BD A2 B8 59 58 85 2C 41 F1 DE 6D 6C E5 FF… 0,,19726,1:11.777.001,15.004.916 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,19727,1:11.792.007,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6A DD 2B 58 66 06 2C E6 9E 01 CE B9 BA 54 C7 F8… 0,,19731,1:11.793.004,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,19732,1:11.807.009,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19736,1:11.808.006,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,19737,1:11.808.009,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6A DD 2B 58 66 06 2C E6 9E 01 CE B9 BA 54 C7 F8… 0,,19741,1:11.809.006,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,19742,1:11.824.011,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC 7B 1C 59 BE 2B 70 C3 B4 F6 A9 4F E1 74 5B A1… 0,,19746,1:11.825.008,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,19747,1:11.839.013,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19751,1:11.840.010,2.833 us,,,,,[1 SOF],[Frame: 97] 0,,19752,1:11.840.013,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC 7B 1C 59 BE 2B 70 C3 B4 F6 A9 4F E1 74 5B A1… 0,,19756,1:11.841.010,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,19757,1:11.856.016,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A 0B F6 6E 3D CB 74 2F F0 EC 9A FD 84 CC 0B 9E… 0,,19761,1:11.857.012,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,19762,1:11.871.018,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19766,1:11.872.015,2.833 us,,,,,[1 SOF],[Frame: 129] 0,,19767,1:11.872.018,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A 0B F6 6E 3D CB 74 2F F0 EC 9A FD 84 CC 0B 9E… 0,,19771,1:11.873.015,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,19772,1:11.888.020,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E 69 60 99 31 E9 DC FF 64 CF 85 48 13 27 C9 08… 0,,19776,1:11.889.017,14.004.750 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,19777,1:11.903.022,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19781,1:11.904.019,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,19782,1:11.904.022,50.645 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E 69 60 99 31 E9 DC FF 64 CF 85 48 13 27 C9 08… 0,,19786,1:11.905.019,15.004.916 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,19787,1:11.920.024,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B 16 E7 4B F6 8D C7 B7 B3 14 C9 94 4C 9C 8A 00… 0,,19791,1:11.921.021,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,19792,1:11.935.027,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19796,1:11.936.023,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,19797,1:11.936.027,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B 16 E7 4B F6 8D C7 B7 B3 14 C9 94 4C 9C 8A 00… 0,,19801,1:11.937.024,15.004.916 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,19802,1:11.952.029,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 22 44 B2 54 44 A1 3B 99 0F DF 21 CC FE 56 E6… 0,,19806,1:11.953.026,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,19807,1:11.967.031,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19811,1:11.968.028,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,19812,1:11.968.031,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 22 44 B2 54 44 A1 3B 99 0F DF 21 CC FE 56 E6… 0,,19816,1:11.969.028,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,19817,1:11.984.033,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 74 D6 2E 62 9F E7 7F A6 B4 21 BE C2 6A E5 5E… 0,,19821,1:11.985.030,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,19822,1:11.999.035,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19826,1:12.000.032,2.833 us,,,,,[1 SOF],[Frame: 257] 0,,19827,1:12.000.036,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 74 D6 2E 62 9F E7 7F A6 B4 21 BE C2 6A E5 5E… 0,,19831,1:12.001.032,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,19832,1:12.016.038,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DA 67 8F 2D C4 AF A3 E1 5C C4 A4 3E 68 00 90 D1… 0,,19836,1:12.017.035,14.004.750 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,19837,1:12.031.040,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19841,1:12.032.037,2.833 us,,,,,[1 SOF],[Frame: 289] 0,,19842,1:12.032.040,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DA 67 8F 2D C4 AF A3 E1 5C C4 A4 3E 68 00 90 D1… 0,,19846,1:12.033.037,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,19847,1:12.048.042,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 A1 5C EE DE 5C 90 9B 4D 61 0E 2C 73 A5 91 2B… 0,,19851,1:12.049.039,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,19852,1:12.063.044,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19856,1:12.064.041,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,19857,1:12.064.044,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 A1 5C EE DE 5C 90 9B 4D 61 0E 2C 73 A5 91 2B… 0,,19861,1:12.065.041,15.004.916 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,19862,1:12.080.047,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CB 0D C3 51 E4 74 17 86 8B 47 71 7D 44 45 4B 9B… 0,,19866,1:12.081.044,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,19867,1:12.095.049,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19871,1:12.096.046,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,19872,1:12.096.049,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CB 0D C3 51 E4 74 17 86 8B 47 71 7D 44 45 4B 9B… 0,,19876,1:12.097.046,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,19877,1:12.112.051,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 29 F5 B4 0B E2 AB B9 DD CA AC F9 E1 F2 34 8B 61… 0,,19881,1:12.113.048,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,19882,1:12.127.053,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19886,1:12.128.050,2.812 us,,,,,[1 SOF],[Frame: 385] 0,,19887,1:12.128.053,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 29 F5 B4 0B E2 AB B9 DD CA AC F9 E1 F2 34 8B 61… 0,,19891,1:12.129.050,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,19892,1:12.144.056,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD B6 CA 57 21 C4 D3 BC 7C 63 E6 44 25 5D 75 65… 0,,19896,1:12.145.052,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,19897,1:12.159.058,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19901,1:12.160.055,2.833 us,,,,,[1 SOF],[Frame: 417] 0,,19902,1:12.160.058,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD B6 CA 57 21 C4 D3 BC 7C 63 E6 44 25 5D 75 65… 0,,19906,1:12.161.055,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,19907,1:12.176.060,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8F D0 37 0F 53 0E 76 05 F4 2C F7 F7 54 72 9A 85… 0,,19911,1:12.177.057,14.004.750 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,19912,1:12.191.062,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19916,1:12.192.059,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,19917,1:12.192.062,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8F D0 37 0F 53 0E 76 05 F4 2C F7 F7 54 72 9A 85… 0,,19921,1:12.193.059,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,19922,1:12.208.064,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 30 D1 F2 DB 5D 2E E6 1B 52 EC 80 6A 40 87 52… 0,,19926,1:12.209.061,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,19927,1:12.223.067,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19931,1:12.224.063,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,19932,1:12.224.067,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 30 D1 F2 DB 5D 2E E6 1B 52 EC 80 6A 40 87 52… 0,,19936,1:12.225.064,15.004.916 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,19937,1:12.240.069,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8F 99 57 D2 1C 65 7E 46 4D 22 89 4A F4 D7 14 24… 0,,19941,1:12.241.066,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,19942,1:12.255.071,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19946,1:12.256.068,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,19947,1:12.256.071,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8F 99 57 D2 1C 65 7E 46 4D 22 89 4A F4 D7 14 24… 0,,19951,1:12.257.068,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,19952,1:12.272.073,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC C9 B4 C2 8B ED A6 E1 74 22 F5 46 3D C0 0B FF… 0,,19956,1:12.273.070,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,19957,1:12.287.075,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19961,1:12.288.072,16.005.041 ms,,,,,[17 SOF],[Frames: 545 - 561] 0,,19962,1:12.304.078,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 9D 15 49 9C 27 DC 86 44 B9 89 2F 22 B9 CE 96… 0,,19966,1:12.305.075,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,19967,1:12.319.080,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19971,1:12.320.077,2.833 us,,,,,[1 SOF],[Frame: 577] 0,,19972,1:12.320.080,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 9D 15 49 9C 27 DC 86 44 B9 89 2F 22 B9 CE 96… 0,,19976,1:12.321.077,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,19977,1:12.336.082,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 8C 86 59 7D A0 27 D7 C8 A8 C5 8D D8 D1 A7 92… 0,,19981,1:12.337.079,14.004.750 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,19982,1:12.351.084,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,19986,1:12.352.081,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,19987,1:12.352.084,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 8C 86 59 7D A0 27 D7 C8 A8 C5 8D D8 D1 A7 92… 0,,19991,1:12.353.081,15.004.916 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,19992,1:12.368.087,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BB 02 9B 66 6E 92 E6 5B 9A 1E 75 5C 55 B6 1D 86… 0,,19996,1:12.369.084,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,19997,1:12.383.089,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20001,1:12.384.086,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,20002,1:12.384.089,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BB 02 9B 66 6E 92 E6 5B 9A 1E 75 5C 55 B6 1D 86… 0,,20006,1:12.385.086,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,20007,1:12.400.091,50.687 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 A8 56 51 DC 9E A2 8E 24 A2 69 ED DC 22 09 94… 0,,20011,1:12.401.088,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,20012,1:12.415.093,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20016,1:12.416.090,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,20017,1:12.416.093,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 A8 56 51 DC 9E A2 8E 24 A2 69 ED DC 22 09 94… 0,,20021,1:12.417.090,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,20022,1:12.432.096,50.312 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 D0 2C 6A F0 56 CE CB 04 B1 94 41 12 5D BB E7… 0,,20026,1:12.433.092,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,20027,1:12.447.098,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20031,1:12.448.095,2.833 us,,,,,[1 SOF],[Frame: 705] 0,,20032,1:12.448.098,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 D0 2C 6A F0 56 CE CB 04 B1 94 41 12 5D BB E7… 0,,20036,1:12.449.095,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,20037,1:12.464.100,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 14 A8 AE 80 AE 7C 46 AE 67 1D 89 A3 11 8D 4C 8F… 0,,20041,1:12.465.097,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,20042,1:12.479.102,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20046,1:12.480.099,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,20047,1:12.480.102,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 14 A8 AE 80 AE 7C 46 AE 67 1D 89 A3 11 8D 4C 8F… 0,,20051,1:12.481.099,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,20052,1:12.496.104,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 96 CC 54 A9 38 F9 00 B3 DF 0A CC CE BE 39 51… 0,,20056,1:12.497.101,14.004.750 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,20057,1:12.511.107,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20061,1:12.512.103,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,20062,1:12.512.107,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2A 96 CC 54 A9 38 F9 00 B3 DF 0A CC CE BE 39 51… 0,,20066,1:12.513.104,15.004.916 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,20067,1:12.528.109,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CC 3C EC AA 7C 23 2E 93 8B A6 42 DA 84 4A 05 9F… 0,,20071,1:12.529.106,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,20072,1:12.543.111,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20076,1:12.544.108,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,20077,1:12.544.111,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CC 3C EC AA 7C 23 2E 93 8B A6 42 DA 84 4A 05 9F… 0,,20081,1:12.545.108,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,20082,1:12.560.113,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BD D0 50 FA 0E 95 FA CD 74 92 31 28 A5 64 87 2D… 0,,20086,1:12.561.110,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,20087,1:12.575.115,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20091,1:12.576.112,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,20092,1:12.576.116,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BD D0 50 FA 0E 95 FA CD 74 92 31 28 A5 64 87 2D… 0,,20096,1:12.577.112,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,20097,1:12.592.118,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 32 B5 A4 CA 9F FC F7 C8 81 8E AA AB C6 85 DC BA… 0,,20101,1:12.593.115,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,20102,1:12.607.120,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20106,1:12.608.117,2.833 us,,,,,[1 SOF],[Frame: 865] 0,,20107,1:12.608.120,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 32 B5 A4 CA 9F FC F7 C8 81 8E AA AB C6 85 DC BA… 0,,20111,1:12.609.117,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,20112,1:12.624.122,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D B6 80 1E D9 76 E0 65 70 14 95 FF 21 89 39 29… 0,,20116,1:12.625.119,14.004.750 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,20117,1:12.639.124,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20121,1:12.640.121,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,20122,1:12.640.124,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D B6 80 1E D9 76 E0 65 70 14 95 FF 21 89 39 29… 0,,20126,1:12.641.121,15.004.916 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,20127,1:12.656.127,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 72 2B 44 AF ED 17 62 A7 36 16 AD 65 69 C7 7E 79… 0,,20131,1:12.657.124,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,20132,1:12.671.129,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20136,1:12.672.126,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,20137,1:12.672.129,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 72 2B 44 AF ED 17 62 A7 36 16 AD 65 69 C7 7E 79… 0,,20141,1:12.673.126,15.004.916 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,20142,1:12.688.131,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 F4 AE 4F 47 D2 F6 97 1E C1 5D 16 99 F4 67 70… 0,,20146,1:12.689.128,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,20147,1:12.703.133,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20151,1:12.704.130,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,20152,1:12.704.133,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 F4 AE 4F 47 D2 F6 97 1E C1 5D 16 99 F4 67 70… 0,,20156,1:12.705.130,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,20157,1:12.720.136,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DB 39 CC 87 8F 6B EE EB C8 72 C1 C1 6C 16 3F 8F… 0,,20161,1:12.721.132,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,20162,1:12.735.138,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20166,1:12.736.134,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,20167,1:12.736.138,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DB 39 CC 87 8F 6B EE EB C8 72 C1 C1 6C 16 3F 8F… 0,,20171,1:12.737.135,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,20172,1:12.752.140,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 94 F4 6D 99 85 0D 86 C5 54 52 1B BD 52 81 C3 13… 0,,20176,1:12.753.137,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,20177,1:12.767.142,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20181,1:12.768.139,2.833 us,,,,,[1 SOF],[Frame: 1025] 0,,20182,1:12.768.142,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 94 F4 6D 99 85 0D 86 C5 54 52 1B BD 52 81 C3 13… 0,,20186,1:12.769.139,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,20187,1:12.784.144,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 47 8D C0 6D EB E2 D6 75 83 57 EC DE 26 D7 60… 0,,20191,1:12.785.141,14.004.750 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,20192,1:12.799.146,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20196,1:12.800.143,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,20197,1:12.800.147,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 47 8D C0 6D EB E2 D6 75 83 57 EC DE 26 D7 60… 0,,20201,1:12.801.144,15.004.916 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,20202,1:12.816.149,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 06 1A E6 CB 76 01 F4 DC 50 38 59 41 43 E2 A2 16… 0,,20206,1:12.817.146,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,20207,1:12.831.151,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20211,1:12.832.148,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,20212,1:12.832.151,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 06 1A E6 CB 76 01 F4 DC 50 38 59 41 43 E2 A2 16… 0,,20216,1:12.833.148,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,20217,1:12.848.153,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E 58 10 07 7F 52 63 19 50 67 A7 87 53 49 0D 11… 0,,20221,1:12.849.150,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,20222,1:12.863.155,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20226,1:12.864.152,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,20227,1:12.864.156,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E 58 10 07 7F 52 63 19 50 67 A7 87 53 49 0D 11… 0,,20231,1:12.865.152,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,20232,1:12.880.158,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BF 52 1C E2 C1 CC 5A 39 96 59 CF 5B F3 95 95 1E… 0,,20236,1:12.881.155,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,20237,1:12.895.160,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20241,1:12.896.157,2.916 us,,,,,[1 SOF],[Frame: 1153] 0,,20242,1:12.896.160,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BF 52 1C E2 C1 CC 5A 39 96 59 CF 5B F3 95 95 1E… 0,,20246,1:12.897.157,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,20247,1:12.912.162,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 5D 7B 48 56 3A D4 97 B5 C9 04 E8 6F 7F 6E 86… 0,,20251,1:12.913.159,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,20252,1:12.927.164,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20256,1:12.928.161,16.005.020 ms,,,,,[17 SOF],[Frames: 1185 - 1201] 0,,20257,1:12.944.167,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 67 E9 99 B4 1A 38 05 69 AD 64 3A 04 F4 71 E6 9B… 0,,20261,1:12.945.164,14.004.750 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,20262,1:12.959.169,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20266,1:12.960.166,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,20267,1:12.960.169,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 67 E9 99 B4 1A 38 05 69 AD 64 3A 04 F4 71 E6 9B… 0,,20271,1:12.961.166,15.004.916 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,20272,1:12.976.171,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 C6 C2 51 5D 49 76 7A 74 47 3B 7E 17 4E 13 61… 0,,20276,1:12.977.168,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,20277,1:12.991.173,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20281,1:12.992.170,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,20282,1:12.992.173,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 C6 C2 51 5D 49 76 7A 74 47 3B 7E 17 4E 13 61… 0,,20286,1:12.993.170,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,20287,1:13.008.176,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5F 53 C4 23 BD 4F 74 8E B9 0A 41 26 D6 DC 1E 24… 0,,20291,1:13.009.172,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,20292,1:13.023.178,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20296,1:13.024.174,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,20297,1:13.024.178,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5F 53 C4 23 BD 4F 74 8E B9 0A 41 26 D6 DC 1E 24… 0,,20301,1:13.025.175,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,20302,1:13.040.180,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D E3 77 31 4C 2D EF CD 96 2B 55 7E EB C3 93 4F… 0,,20306,1:13.041.177,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,20307,1:13.055.182,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20311,1:13.056.179,2.833 us,,,,,[1 SOF],[Frame: 1313] 0,,20312,1:13.056.182,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D E3 77 31 4C 2D EF CD 96 2B 55 7E EB C3 93 4F… 0,,20316,1:13.057.179,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,20317,1:13.072.184,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF 07 9C 44 8B 04 EA AC 7F 02 99 89 6E 9C 78 A7… 0,,20321,1:13.073.181,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,20322,1:13.087.186,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20326,1:13.088.183,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,20327,1:13.088.187,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF 07 9C 44 8B 04 EA AC 7F 02 99 89 6E 9C 78 A7… 0,,20331,1:13.089.183,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,20332,1:13.104.189,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4E BE 8A F7 08 C7 C5 C3 7C B3 20 AA 56 B1 8A 2E… 0,,20336,1:13.105.186,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,20337,1:13.119.191,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20341,1:13.120.188,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,20342,1:13.120.191,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4E BE 8A F7 08 C7 C5 C3 7C B3 20 AA 56 B1 8A 2E… 0,,20346,1:13.121.188,15.004.916 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,20347,1:13.136.193,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 16 8F 6C A7 3B D8 D1 C2 0C 5C 92 84 C0 66 5A 2B… 0,,20351,1:13.137.190,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,20352,1:13.151.195,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20356,1:13.152.192,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,20357,1:13.152.195,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 16 8F 6C A7 3B D8 D1 C2 0C 5C 92 84 C0 66 5A 2B… 0,,20361,1:13.153.192,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,20362,1:13.168.198,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 49 82 96 5D 1C 67 62 F7 A4 9A F5 47 B6 36 93… 0,,20366,1:13.169.195,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,20367,1:13.183.200,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20371,1:13.184.197,2.833 us,,,,,[1 SOF],[Frame: 1441] 0,,20372,1:13.184.200,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 49 82 96 5D 1C 67 62 F7 A4 9A F5 47 B6 36 93… 0,,20376,1:13.185.197,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,20377,1:13.200.202,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 31 29 EB 13 90 68 28 CB 35 F9 4A 08 DE 72 3E 29… 0,,20381,1:13.201.199,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,20382,1:13.215.204,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20386,1:13.216.201,2.833 us,,,,,[1 SOF],[Frame: 1473] 0,,20387,1:13.216.204,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 31 29 EB 13 90 68 28 CB 35 F9 4A 08 DE 72 3E 29… 0,,20391,1:13.217.201,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,20392,1:13.232.207,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FB 65 78 5F BE 1C CE 81 48 4B 71 B7 10 11 D7 27… 0,,20396,1:13.233.203,14.004.833 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,20397,1:13.247.209,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20401,1:13.248.206,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,20402,1:13.248.209,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FB 65 78 5F BE 1C CE 81 48 4B 71 B7 10 11 D7 27… 0,,20406,1:13.249.206,15.004.916 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,20407,1:13.264.211,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 83 02 D3 BE 02 9E 0E 81 08 4F 84 2D E9 6A 0A E6… 0,,20411,1:13.265.208,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,20412,1:13.279.213,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20416,1:13.280.210,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,20417,1:13.280.213,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 83 02 D3 BE 02 9E 0E 81 08 4F 84 2D E9 6A 0A E6… 0,,20421,1:13.281.210,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,20422,1:13.296.216,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B4 9C 3D 1B 3E 6C 99 17 39 E5 45 FF B7 F1 4E 30… 0,,20426,1:13.297.212,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,20427,1:13.311.218,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20431,1:13.312.214,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,20432,1:13.312.218,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B4 9C 3D 1B 3E 6C 99 17 39 E5 45 FF B7 F1 4E 30… 0,,20436,1:13.313.215,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,20437,1:13.328.220,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 ED 92 7D F1 7E 70 9B E0 8F 79 40 45 33 89 57… 0,,20441,1:13.329.217,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,20442,1:13.343.222,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20446,1:13.344.219,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,20447,1:13.344.222,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 ED 92 7D F1 7E 70 9B E0 8F 79 40 45 33 89 57… 0,,20451,1:13.345.219,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,20452,1:13.360.224,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 48 DB A4 5C 1F 9D 26 A3 C5 21 D5 8A 25 59 99 AB… 0,,20456,1:13.361.221,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,20457,1:13.375.226,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20461,1:13.376.223,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,20462,1:13.376.227,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 48 DB A4 5C 1F 9D 26 A3 C5 21 D5 8A 25 59 99 AB… 0,,20466,1:13.377.223,15.004.895 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,20467,1:13.392.229,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C1 23 1E 4C 27 4D EC E1 8C 3E D5 9E 29 29 97 DD… 0,,20471,1:13.393.226,14.004.750 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,20472,1:13.407.231,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20476,1:13.408.228,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,20477,1:13.408.231,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C1 23 1E 4C 27 4D EC E1 8C 3E D5 9E 29 29 97 DD… 0,,20481,1:13.409.228,15.004.916 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,20482,1:13.424.233,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1B 47 8C 4D 58 22 C5 E7 EB F9 54 71 B3 0A 5C 6B… 0,,20486,1:13.425.230,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,20487,1:13.439.235,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20491,1:13.440.232,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,20492,1:13.440.235,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1B 47 8C 4D 58 22 C5 E7 EB F9 54 71 B3 0A 5C 6B… 0,,20496,1:13.441.232,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,20497,1:13.456.238,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 39 AB FC 72 F4 51 93 59 D1 6E 46 B7 42 67 BB E7… 0,,20501,1:13.457.235,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,20502,1:13.471.240,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20506,1:13.472.237,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,20507,1:13.472.240,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 39 AB FC 72 F4 51 93 59 D1 6E 46 B7 42 67 BB E7… 0,,20511,1:13.473.237,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,20512,1:13.488.242,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3B 59 06 9F FF A3 0B 67 B3 1E C3 47 F1 26 37 94… 0,,20516,1:13.489.239,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,20517,1:13.503.244,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20521,1:13.504.241,2.916 us,,,,,[1 SOF],[Frame: 1761] 0,,20522,1:13.504.244,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3B 59 06 9F FF A3 0B 67 B3 1E C3 47 F1 26 37 94… 0,,20526,1:13.505.241,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,20527,1:13.520.247,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A0 31 7A 6C 5F 37 F1 E5 6D 67 98 02 74 46 52 FE… 0,,20531,1:13.521.243,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,20532,1:13.535.249,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20536,1:13.536.246,16.005.041 ms,,,,,[17 SOF],[Frames: 1793 - 1809] 0,,20537,1:13.552.251,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D3 46 E6 F2 A2 60 38 B1 7C A6 99 4F 81 2D B1 3B… 0,,20541,1:13.553.248,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,20542,1:13.567.253,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20546,1:13.568.250,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,20547,1:13.568.253,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D3 46 E6 F2 A2 60 38 B1 7C A6 99 4F 81 2D B1 3B… 0,,20551,1:13.569.250,15.004.916 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,20552,1:13.584.255,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 07 FC 18 32 17 3C DF 42 39 8B DE 10 46 48 B4… 0,,20556,1:13.585.252,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,20557,1:13.599.258,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20561,1:13.600.254,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,20562,1:13.600.258,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 07 FC 18 32 17 3C DF 42 39 8B DE 10 46 48 B4… 0,,20566,1:13.601.255,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,20567,1:13.616.260,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 97 8A 86 DC ED 40 03 DE A4 81 F9 77 E9 E2 1E 9B… 0,,20571,1:13.617.257,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,20572,1:13.631.262,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20576,1:13.632.259,16.005.041 ms,,,,,[17 SOF],[Frames: 1889 - 1905] 0,,20577,1:13.648.264,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0F 9D 62 3A 92 A7 E4 8D 2C 6B 45 E7 28 69 D9 D9… 0,,20581,1:13.649.261,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,20582,1:13.663.267,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20586,1:13.664.263,2.833 us,,,,,[1 SOF],[Frame: 1921] 0,,20587,1:13.664.267,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0F 9D 62 3A 92 A7 E4 8D 2C 6B 45 E7 28 69 D9 D9… 0,,20591,1:13.665.263,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,20592,1:13.680.269,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 04 4B 95 5F 50 05 F3 A2 83 C9 DF 32 17 63 FB 32… 0,,20596,1:13.681.266,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,20597,1:13.695.271,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20601,1:13.696.268,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,20602,1:13.696.271,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 04 4B 95 5F 50 05 F3 A2 83 C9 DF 32 17 63 FB 32… 0,,20606,1:13.697.268,15.004.916 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,20607,1:13.712.273,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0E 33 4E 28 7A 72 3F 79 29 E6 63 1C 34 F8 6F 57… 0,,20611,1:13.713.270,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,20612,1:13.727.275,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20616,1:13.728.272,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,20617,1:13.728.276,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0E 33 4E 28 7A 72 3F 79 29 E6 63 1C 34 F8 6F 57… 0,,20621,1:13.729.272,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,20622,1:13.744.278,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A 88 63 FF 53 9F 63 84 B2 26 91 71 79 6F 18 72… 0,,20626,1:13.745.275,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,20627,1:13.759.280,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20631,1:13.760.277,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,20632,1:13.760.280,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A 88 63 FF 53 9F 63 84 B2 26 91 71 79 6F 18 72… 0,,20636,1:13.761.277,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,20637,1:13.776.282,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE 15 BF 71 4C 95 BC 45 26 D8 7C 80 0D FA 78 F8… 0,,20641,1:13.777.279,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,20642,1:13.791.284,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20646,1:13.792.281,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,20647,1:13.792.284,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE 15 BF 71 4C 95 BC 45 26 D8 7C 80 0D FA 78 F8… 0,,20651,1:13.793.281,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,20652,1:13.808.287,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 32 2F 65 B1 C0 97 A0 DA E4 B9 04 3B 47 47 22… 0,,20656,1:13.809.283,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,20657,1:13.823.289,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20661,1:13.824.286,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,20662,1:13.824.289,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 32 2F 65 B1 C0 97 A0 DA E4 B9 04 3B 47 47 22… 0,,20666,1:13.825.286,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,20667,1:13.840.291,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 88 16 89 95 61 AB 9D EA 12 A0 10 47 9A D1 6A 6D… 0,,20671,1:13.841.288,14.004.750 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,20672,1:13.855.293,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20676,1:13.856.290,2.812 us,,,,,[1 SOF],[Frame: 65] 0,,20677,1:13.856.293,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 88 16 89 95 61 AB 9D EA 12 A0 10 47 9A D1 6A 6D… 0,,20681,1:13.857.290,15.004.916 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,20682,1:13.872.295,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 60 33 AB 7F A0 97 8C D8 D9 E9 D7 61 56 B2 E9 4C… 0,,20686,1:13.873.292,14.004.770 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,20687,1:13.887.298,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20691,1:13.888.294,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,20692,1:13.888.298,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 60 33 AB 7F A0 97 8C D8 D9 E9 D7 61 56 B2 E9 4C… 0,,20696,1:13.889.295,15.004.895 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,20697,1:13.904.300,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D F8 B7 CC D0 E6 01 05 81 19 08 71 AE 75 57 77… 0,,20701,1:13.905.297,14.004.770 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,20702,1:13.919.302,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20706,1:13.920.299,2.833 us,,,,,[1 SOF],[Frame: 129] 0,,20707,1:13.920.302,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D F8 B7 CC D0 E6 01 05 81 19 08 71 AE 75 57 77… 0,,20711,1:13.921.299,15.004.895 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,20712,1:13.936.304,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0D E2 10 C3 04 10 84 3B 8D 36 E4 AD 21 E2 97 BB… 0,,20716,1:13.937.301,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,20717,1:13.951.306,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20721,1:13.952.303,2.833 us,,,,,[1 SOF],[Frame: 161] 0,,20722,1:13.952.307,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0D E2 10 C3 04 10 84 3B 8D 36 E4 AD 21 E2 97 BB… 0,,20726,1:13.953.303,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,20727,1:13.968.309,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A DF EE 09 F5 F4 EB AE A2 80 89 D4 22 89 68 71… 0,,20731,1:13.969.306,14.004.750 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,20732,1:13.983.311,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20736,1:13.984.308,2.812 us,,,,,[1 SOF],[Frame: 193] 0,,20737,1:13.984.311,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A DF EE 09 F5 F4 EB AE A2 80 89 D4 22 89 68 71… 0,,20741,1:13.985.308,15.004.916 ms,,,,,[16 SOF],[Frames: 194 - 209] 0,,20742,1:14.000.313,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 39 EC FC 01 A8 42 4A 30 BF C0 1C D4 71 1B FB 17… 0,,20746,1:14.001.310,14.004.750 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,20747,1:14.015.315,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20751,1:14.016.312,2.812 us,,,,,[1 SOF],[Frame: 225] 0,,20752,1:14.016.315,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 39 EC FC 01 A8 42 4A 30 BF C0 1C D4 71 1B FB 17… 0,,20756,1:14.017.312,15.004.916 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,20757,1:14.032.318,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 CF B9 8B 71 DB F4 9C 48 B8 3F 46 F2 2A 3A 07 91… 0,,20761,1:14.033.315,14.004.770 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,20762,1:14.047.320,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20766,1:14.048.317,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,20767,1:14.048.320,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 CF B9 8B 71 DB F4 9C 48 B8 3F 46 F2 2A 3A 07 91… 0,,20771,1:14.049.317,15.004.895 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,20772,1:14.064.322,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 47 44 F8 65 20 F3 4B 67 5B F4 EE 63 DB DD C9… 0,,20776,1:14.065.319,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,20777,1:14.079.324,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20781,1:14.080.321,2.833 us,,,,,[1 SOF],[Frame: 289] 0,,20782,1:14.080.324,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 47 44 F8 65 20 F3 4B 67 5B F4 EE 63 DB DD C9… 0,,20786,1:14.081.321,15.004.895 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,20787,1:14.096.327,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C8 E0 BD A5 59 01 65 0A 31 C8 C6 D5 7D 69 68 48… 0,,20791,1:14.097.323,14.004.750 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,20792,1:14.111.329,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20796,1:14.112.325,2.833 us,,,,,[1 SOF],[Frame: 321] 0,,20797,1:14.112.329,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 C8 E0 BD A5 59 01 65 0A 31 C8 C6 D5 7D 69 68 48… 0,,20801,1:14.113.326,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,20802,1:14.128.331,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 D4 88 FA 6D D4 DC 95 E1 26 88 1F 73 A0 CD 9A… 0,,20806,1:14.129.328,14.004.750 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,20807,1:14.143.333,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20811,1:14.144.330,2.812 us,,,,,[1 SOF],[Frame: 353] 0,,20812,1:14.144.333,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 D4 88 FA 6D D4 DC 95 E1 26 88 1F 73 A0 CD 9A… 0,,20816,1:14.145.330,15.004.916 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,20817,1:14.160.335,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 3F 16 1E 42 B3 54 61 9F B5 DC 2A A5 6A 05 DE… 0,,20821,1:14.161.332,14.004.770 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,20822,1:14.175.337,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20826,1:14.176.334,16.005.041 ms,,,,,[17 SOF],[Frames: 385 - 401] 0,,20827,1:14.192.340,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D BF CC 9C A0 9A 9A B0 D9 EC 6E 90 D8 B5 E4 5D… 0,,20831,1:14.193.337,14.004.770 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,20832,1:14.207.342,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20836,1:14.208.339,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,20837,1:14.208.342,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D BF CC 9C A0 9A 9A B0 D9 EC 6E 90 D8 B5 E4 5D… 0,,20841,1:14.209.339,15.004.895 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,20842,1:14.224.344,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 91 A2 A1 7F 6C F5 23 E1 4F 2A F8 42 74 A0 32… 0,,20846,1:14.225.341,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,20847,1:14.239.346,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20851,1:14.240.343,2.833 us,,,,,[1 SOF],[Frame: 449] 0,,20852,1:14.240.347,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 91 A2 A1 7F 6C F5 23 E1 4F 2A F8 42 74 A0 32… 0,,20856,1:14.241.343,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,20857,1:14.256.349,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A5 DB E5 E8 DA FA 2D 63 3E 41 4A 34 C2 F7 EA C0… 0,,20861,1:14.257.346,14.004.750 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,20862,1:14.271.351,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20866,1:14.272.348,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,20867,1:14.272.351,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A5 DB E5 E8 DA FA 2D 63 3E 41 4A 34 C2 F7 EA C0… 0,,20871,1:14.273.348,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,20872,1:14.288.353,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC 54 8B C2 FB 87 39 26 4D 99 29 22 7E C6 42 F7… 0,,20876,1:14.289.350,14.004.750 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,20877,1:14.303.355,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20881,1:14.304.352,2.812 us,,,,,[1 SOF],[Frame: 513] 0,,20882,1:14.304.355,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC 54 8B C2 FB 87 39 26 4D 99 29 22 7E C6 42 F7… 0,,20886,1:14.305.352,15.004.916 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,20887,1:14.320.358,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6E 8E F9 6C D1 BF 3A 65 30 5E 71 0E 49 A9 5D 31… 0,,20891,1:14.321.355,14.004.770 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,20892,1:14.335.360,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20896,1:14.336.357,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,20897,1:14.336.360,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6E 8E F9 6C D1 BF 3A 65 30 5E 71 0E 49 A9 5D 31… 0,,20901,1:14.337.357,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,20902,1:14.352.362,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 39 73 BD A6 B8 74 2A 31 B2 2E 37 81 2D 8F C4 95… 0,,20906,1:14.353.359,14.004.770 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,20907,1:14.367.364,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20911,1:14.368.361,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,20912,1:14.368.364,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 39 73 BD A6 B8 74 2A 31 B2 2E 37 81 2D 8F C4 95… 0,,20916,1:14.369.361,15.004.895 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,20917,1:14.384.367,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 23 41 61 82 54 97 64 0E A3 93 30 38 39 02 CF 4D… 0,,20921,1:14.385.363,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,20922,1:14.399.369,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20926,1:14.400.365,2.833 us,,,,,[1 SOF],[Frame: 609] 0,,20927,1:14.400.369,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 23 41 61 82 54 97 64 0E A3 93 30 38 39 02 CF 4D… 0,,20931,1:14.401.366,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,20932,1:14.416.371,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 4D 91 D4 0F 75 94 95 D4 E2 72 6D BD CF DE 1F… 0,,20936,1:14.417.368,14.004.750 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,20937,1:14.431.373,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20941,1:14.432.370,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,20942,1:14.432.373,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 4D 91 D4 0F 75 94 95 D4 E2 72 6D BD CF DE 1F… 0,,20946,1:14.433.370,15.004.916 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,20947,1:14.448.375,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2C 2D F7 42 1D F4 AD FB 0A 13 DE 16 81 EB EE 3F… 0,,20951,1:14.449.372,14.004.750 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,20952,1:14.463.377,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20956,1:14.464.374,2.812 us,,,,,[1 SOF],[Frame: 673] 0,,20957,1:14.464.378,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2C 2D F7 42 1D F4 AD FB 0A 13 DE 16 81 EB EE 3F… 0,,20961,1:14.465.374,15.004.916 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,20962,1:14.480.380,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2D 94 A4 8D E6 C8 EB FF FC 90 B5 E7 01 A7 17 E2… 0,,20966,1:14.481.377,14.004.770 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,20967,1:14.495.382,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20971,1:14.496.379,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,20972,1:14.496.382,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2D 94 A4 8D E6 C8 EB FF FC 90 B5 E7 01 A7 17 E2… 0,,20976,1:14.497.379,15.004.895 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,20977,1:14.512.384,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 79 06 7F 0A 8F B1 B8 55 AC F1 04 AE C8 70 33 37… 0,,20981,1:14.513.381,14.004.770 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,20982,1:14.527.386,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,20986,1:14.528.383,2.833 us,,,,,[1 SOF],[Frame: 737] 0,,20987,1:14.528.386,50.687 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 79 06 7F 0A 8F B1 B8 55 AC F1 04 AE C8 70 33 37… 0,,20991,1:14.529.383,15.004.895 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,20992,1:14.544.389,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D1 43 C7 1F 09 71 BD 90 01 01 A6 35 62 E0 FD 53… 0,,20996,1:14.545.386,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,20997,1:14.559.391,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21001,1:14.560.388,2.833 us,,,,,[1 SOF],[Frame: 769] 0,,21002,1:14.560.391,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D1 43 C7 1F 09 71 BD 90 01 01 A6 35 62 E0 FD 53… 0,,21006,1:14.561.388,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,21007,1:14.576.393,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD E9 BA 67 6E CC 10 27 C7 37 F0 B4 FA 89 97 3B… 0,,21011,1:14.577.390,14.004.750 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,21012,1:14.591.395,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21016,1:14.592.392,2.812 us,,,,,[1 SOF],[Frame: 801] 0,,21017,1:14.592.395,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DD E9 BA 67 6E CC 10 27 C7 37 F0 B4 FA 89 97 3B… 0,,21021,1:14.593.392,15.004.916 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,21022,1:14.608.398,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 68 8A 13 25 18 69 82 95 8F 21 5E 7E C3 B6 10 FD… 0,,21026,1:14.609.394,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,21027,1:14.623.400,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21031,1:14.624.397,2.812 us,,,,,[1 SOF],[Frame: 833] 0,,21032,1:14.624.400,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 68 8A 13 25 18 69 82 95 8F 21 5E 7E C3 B6 10 FD… 0,,21036,1:14.625.397,15.004.895 ms,,,,,[16 SOF],[Frames: 834 - 849] 0,,21037,1:14.640.402,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 30 E5 33 EB F7 A9 7F CC 16 33 87 50 CE 98 8C 10… 0,,21041,1:14.641.399,14.004.770 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,21042,1:14.655.404,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21046,1:14.656.401,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,21047,1:14.656.404,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 30 E5 33 EB F7 A9 7F CC 16 33 87 50 CE 98 8C 10… 0,,21051,1:14.657.401,15.004.895 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,21052,1:14.672.406,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D F3 87 0D F4 E7 9F 63 3E D0 88 D1 B1 A9 63 24… 0,,21056,1:14.673.403,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,21057,1:14.687.409,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21061,1:14.688.405,2.833 us,,,,,[1 SOF],[Frame: 897] 0,,21062,1:14.688.409,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D F3 87 0D F4 E7 9F 63 3E D0 88 D1 B1 A9 63 24… 0,,21066,1:14.689.406,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,21067,1:14.704.411,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D7 45 E9 1D 4B 3D 33 1F A0 61 65 20 83 82 EB B8… 0,,21071,1:14.705.408,14.004.750 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,21072,1:14.719.413,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21076,1:14.720.410,2.833 us,,,,,[1 SOF],[Frame: 929] 0,,21077,1:14.720.413,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D7 45 E9 1D 4B 3D 33 1F A0 61 65 20 83 82 EB B8… 0,,21081,1:14.721.410,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,21082,1:14.736.415,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 E6 C0 28 7C 44 21 7C EE CC E9 08 2A C1 BC 0D… 0,,21086,1:14.737.412,14.004.750 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,21087,1:14.751.417,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21091,1:14.752.414,2.812 us,,,,,[1 SOF],[Frame: 961] 0,,21092,1:14.752.418,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 E6 C0 28 7C 44 21 7C EE CC E9 08 2A C1 BC 0D… 0,,21096,1:14.753.414,15.004.916 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,21097,1:14.768.420,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 C5 66 20 1A 85 55 45 0C D1 4F 9A 78 12 AA 7A 62… 0,,21101,1:14.769.417,14.004.770 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,21102,1:14.783.422,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21106,1:14.784.419,16.005.125 ms,,,,,[17 SOF],[Frames: 993 - 1009] 0,,21107,1:14.800.424,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 36 CC 29 A8 FA A0 81 CF 9A 91 1F B4 51 C1 A4 D4… 0,,21111,1:14.801.421,14.004.770 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,21112,1:14.815.426,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21116,1:14.816.423,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,21117,1:14.816.426,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 36 CC 29 A8 FA A0 81 CF 9A 91 1F B4 51 C1 A4 D4… 0,,21121,1:14.817.423,15.004.895 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,21122,1:14.832.429,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC F5 07 17 4E 6A 6D D9 98 9B C6 79 FB 7F F1 78… 0,,21126,1:14.833.426,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,21127,1:14.847.431,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21131,1:14.848.428,2.833 us,,,,,[1 SOF],[Frame: 1057] 0,,21132,1:14.848.431,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC F5 07 17 4E 6A 6D D9 98 9B C6 79 FB 7F F1 78… 0,,21136,1:14.849.428,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,21137,1:14.864.433,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6F C4 E6 66 07 55 80 8B A7 A8 CC 97 C9 83 56 53… 0,,21141,1:14.865.430,14.004.750 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,21142,1:14.879.435,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21146,1:14.880.432,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,21147,1:14.880.435,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6F C4 E6 66 07 55 80 8B A7 A8 CC 97 C9 83 56 53… 0,,21151,1:14.881.432,15.004.916 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,21152,1:14.896.438,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A4 C9 7C B0 EC FE 72 4A 36 35 F7 23 85 39 A4 79… 0,,21156,1:14.897.434,14.004.750 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,21157,1:14.911.440,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21161,1:14.912.437,2.812 us,,,,,[1 SOF],[Frame: 1121] 0,,21162,1:14.912.440,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A4 C9 7C B0 EC FE 72 4A 36 35 F7 23 85 39 A4 79… 0,,21166,1:14.913.437,15.004.916 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,21167,1:14.928.442,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 78 0C A9 A4 8C 95 30 CE 57 23 BE 4B AC FF 74… 0,,21171,1:14.929.439,14.004.770 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,21172,1:14.943.444,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21176,1:14.944.441,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,21177,1:14.944.444,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 78 0C A9 A4 8C 95 30 CE 57 23 BE 4B AC FF 74… 0,,21181,1:14.945.441,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,21182,1:14.960.446,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 0A EA 31 40 55 FF A6 C5 FA 22 37 69 EC 3F 3D E3… 0,,21186,1:14.961.443,14.004.770 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,21187,1:14.975.449,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21191,1:14.976.445,2.833 us,,,,,[1 SOF],[Frame: 1185] 0,,21192,1:14.976.449,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 0A EA 31 40 55 FF A6 C5 FA 22 37 69 EC 3F 3D E3… 0,,21196,1:14.977.446,15.004.895 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,21197,1:14.992.451,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B6 9C 6C EE D4 98 03 CE 55 77 13 95 DC 31 1C C4… 0,,21201,1:14.993.448,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,21202,1:15.007.453,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21206,1:15.008.450,2.833 us,,,,,[1 SOF],[Frame: 1217] 0,,21207,1:15.008.453,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B6 9C 6C EE D4 98 03 CE 55 77 13 95 DC 31 1C C4… 0,,21211,1:15.009.450,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,21212,1:15.024.455,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EF 4E 6D BC 3E 2B B9 51 8F 9A B9 EB E4 20 DD 83… 0,,21216,1:15.025.452,14.004.750 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,21217,1:15.039.457,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21221,1:15.040.454,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,21222,1:15.040.458,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 EF 4E 6D BC 3E 2B B9 51 8F 9A B9 EB E4 20 DD 83… 0,,21226,1:15.041.454,15.004.916 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,21227,1:15.056.460,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A E7 8F BA D5 27 AD B1 41 F0 E3 73 6D 18 7C 17… 0,,21231,1:15.057.457,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,21232,1:15.071.462,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21236,1:15.072.459,2.812 us,,,,,[1 SOF],[Frame: 1281] 0,,21237,1:15.072.462,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A E7 8F BA D5 27 AD B1 41 F0 E3 73 6D 18 7C 17… 0,,21241,1:15.073.459,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,21242,1:15.088.464,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 69 5A CF EE 0E AA 62 40 09 2A 1C EC 94 D1 A4 2D… 0,,21246,1:15.089.461,14.004.770 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,21247,1:15.103.466,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21251,1:15.104.463,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,21252,1:15.104.466,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 69 5A CF EE 0E AA 62 40 09 2A 1C EC 94 D1 A4 2D… 0,,21256,1:15.105.463,15.004.895 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,21257,1:15.120.469,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A2 7C 12 43 0A C2 EB 80 4A ED 40 D8 6C 39 95 34… 0,,21261,1:15.121.466,14.004.770 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,21262,1:15.135.471,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21266,1:15.136.468,2.833 us,,,,,[1 SOF],[Frame: 1345] 0,,21267,1:15.136.471,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A2 7C 12 43 0A C2 EB 80 4A ED 40 D8 6C 39 95 34… 0,,21271,1:15.137.468,15.004.895 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,21272,1:15.152.473,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4B E4 EB 24 2A 68 D3 6F BD 53 5F 21 02 6C 9B 8F… 0,,21276,1:15.153.470,14.004.750 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,21277,1:15.167.475,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21281,1:15.168.472,2.833 us,,,,,[1 SOF],[Frame: 1377] 0,,21282,1:15.168.475,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4B E4 EB 24 2A 68 D3 6F BD 53 5F 21 02 6C 9B 8F… 0,,21286,1:15.169.472,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,21287,1:15.184.478,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9B FF F4 08 0D C5 18 F3 CA CD 83 0F 1C 8D E7 C3… 0,,21291,1:15.185.474,14.004.750 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,21292,1:15.199.480,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21296,1:15.200.477,2.812 us,,,,,[1 SOF],[Frame: 1409] 0,,21297,1:15.200.480,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9B FF F4 08 0D C5 18 F3 CA CD 83 0F 1C 8D E7 C3… 0,,21301,1:15.201.477,15.004.916 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,21302,1:15.216.482,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D CA E9 F3 D2 F1 A1 99 AA C2 97 C8 55 22 D4 AC… 0,,21306,1:15.217.479,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,21307,1:15.231.484,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21311,1:15.232.481,2.812 us,,,,,[1 SOF],[Frame: 1441] 0,,21312,1:15.232.484,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D CA E9 F3 D2 F1 A1 99 AA C2 97 C8 55 22 D4 AC… 0,,21316,1:15.233.481,15.004.895 ms,,,,,[16 SOF],[Frames: 1442 - 1457] 0,,21317,1:15.248.486,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1C 90 FF 08 CA F0 AD E5 5A A9 48 26 BB 82 22 81… 0,,21321,1:15.249.483,14.004.770 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,21322,1:15.263.489,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21326,1:15.264.485,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,21327,1:15.264.489,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1C 90 FF 08 CA F0 AD E5 5A A9 48 26 BB 82 22 81… 0,,21331,1:15.265.486,15.004.895 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,21332,1:15.280.491,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 5A 0F 28 5F 1D 84 82 BB 4F E8 5F 32 A9 E0 05 71… 0,,21336,1:15.281.488,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,21337,1:15.295.493,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21341,1:15.296.490,2.833 us,,,,,[1 SOF],[Frame: 1505] 0,,21342,1:15.296.493,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 5A 0F 28 5F 1D 84 82 BB 4F E8 5F 32 A9 E0 05 71… 0,,21346,1:15.297.490,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,21347,1:15.312.495,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 4F D2 0D B9 0C 7B 01 D3 C2 74 18 AB E8 61 22 B3… 0,,21351,1:15.313.492,14.004.750 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,21352,1:15.327.497,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21356,1:15.328.494,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,21357,1:15.328.498,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 4F D2 0D B9 0C 7B 01 D3 C2 74 18 AB E8 61 22 B3… 0,,21361,1:15.329.494,15.005.000 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,21362,1:15.344.500,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 9C FC 8C 98 C5 D9 FC 19 60 EA FF 74 8C A8 73 A6… 0,,21366,1:15.345.497,14.004.750 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,21367,1:15.359.502,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21371,1:15.360.499,2.812 us,,,,,[1 SOF],[Frame: 1569] 0,,21372,1:15.360.502,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 9C FC 8C 98 C5 D9 FC 19 60 EA FF 74 8C A8 73 A6… 0,,21376,1:15.361.499,15.004.916 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,21377,1:15.376.504,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 94 D0 29 8F A8 1F 36 71 D2 09 29 9B EC 9E 36… 0,,21381,1:15.377.501,14.004.770 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,21382,1:15.391.506,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21386,1:15.392.503,2.812 us,,,,,[1 SOF],[Frame: 1601] 0,,21387,1:15.392.506,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 94 D0 29 8F A8 1F 36 71 D2 09 29 9B EC 9E 36… 0,,21391,1:15.393.503,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,21392,1:15.408.509,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7E 6F 7E 4D 0A 19 3E 84 F2 F4 23 D6 99 C8 5F 7C… 0,,21396,1:15.409.506,14.004.770 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,21397,1:15.423.511,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21401,1:15.424.508,16.005.041 ms,,,,,[17 SOF],[Frames: 1633 - 1649] 0,,21402,1:15.440.513,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 99 79 FA 26 25 B1 E2 FE 60 5C 3F E4 3E 8C C9… 0,,21406,1:15.441.510,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,21407,1:15.455.515,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21411,1:15.456.512,2.833 us,,,,,[1 SOF],[Frame: 1665] 0,,21412,1:15.456.515,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 99 79 FA 26 25 B1 E2 FE 60 5C 3F E4 3E 8C C9… 0,,21416,1:15.457.512,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,21417,1:15.472.518,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 57 87 DA 4D F9 23 FD BD 60 20 43 FA AD A7 4B 13… 0,,21421,1:15.473.514,14.004.750 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,21422,1:15.487.520,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21426,1:15.488.517,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,21427,1:15.488.520,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 57 87 DA 4D F9 23 FD BD 60 20 43 FA AD A7 4B 13… 0,,21431,1:15.489.517,15.004.916 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,21432,1:15.504.522,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 FC 4F 07 2A 20 D2 5D C4 D9 1B 24 9A 6F D5 DE 94… 0,,21436,1:15.505.519,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,21437,1:15.519.524,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21441,1:15.520.521,2.812 us,,,,,[1 SOF],[Frame: 1729] 0,,21442,1:15.520.524,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 FC 4F 07 2A 20 D2 5D C4 D9 1B 24 9A 6F D5 DE 94… 0,,21446,1:15.521.521,15.004.916 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,21447,1:15.536.526,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E7 99 96 87 38 8E 44 E3 7C 26 BA 0A 12 46 CA 82… 0,,21451,1:15.537.523,14.004.770 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,21452,1:15.551.528,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21456,1:15.552.525,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,21457,1:15.552.529,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E7 99 96 87 38 8E 44 E3 7C 26 BA 0A 12 46 CA 82… 0,,21461,1:15.553.526,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,21462,1:15.568.531,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 24 77 1E 0E 4F 2E D3 35 B5 81 18 B8 44 1D 88 23… 0,,21466,1:15.569.528,14.004.770 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,21467,1:15.583.533,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21471,1:15.584.530,2.833 us,,,,,[1 SOF],[Frame: 1793] 0,,21472,1:15.584.533,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 24 77 1E 0E 4F 2E D3 35 B5 81 18 B8 44 1D 88 23… 0,,21476,1:15.585.530,15.004.895 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,21477,1:15.600.535,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DC 18 AF F9 3F 69 90 47 94 7A AA D8 BF 1A B6 0F… 0,,21481,1:15.601.532,14.004.750 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,21482,1:15.615.537,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21486,1:15.616.534,2.916 us,,,,,[1 SOF],[Frame: 1825] 0,,21487,1:15.616.538,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DC 18 AF F9 3F 69 90 47 94 7A AA D8 BF 1A B6 0F… 0,,21491,1:15.617.534,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,21492,1:15.632.540,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 75 E8 0A C9 05 FA 44 20 9C BC 21 91 41 36 32 57… 0,,21496,1:15.633.537,14.004.750 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,21497,1:15.647.542,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21501,1:15.648.539,2.812 us,,,,,[1 SOF],[Frame: 1857] 0,,21502,1:15.648.542,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 75 E8 0A C9 05 FA 44 20 9C BC 21 91 41 36 32 57… 0,,21506,1:15.649.539,15.004.916 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,21507,1:15.664.544,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 62 E8 93 28 C8 9E 42 FC 8A 63 75 72 7C 20 7A E2… 0,,21511,1:15.665.541,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,21512,1:15.679.546,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21516,1:15.680.543,2.812 us,,,,,[1 SOF],[Frame: 1889] 0,,21517,1:15.680.546,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 62 E8 93 28 C8 9E 42 FC 8A 63 75 72 7C 20 7A E2… 0,,21521,1:15.681.543,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,21522,1:15.696.549,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 47 0C E3 8B C1 8B EB 8D 1B F5 7E C3 77 42 94… 0,,21526,1:15.697.546,14.004.854 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,21527,1:15.711.551,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21531,1:15.712.548,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,21532,1:15.712.551,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 47 0C E3 8B C1 8B EB 8D 1B F5 7E C3 77 42 94… 0,,21536,1:15.713.548,15.004.895 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,21537,1:15.728.553,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 83 EC 17 C7 F4 D3 28 FB 8D EA 13 18 FC BE 4B C9… 0,,21541,1:15.729.550,14.004.770 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,21542,1:15.743.555,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21546,1:15.744.552,2.833 us,,,,,[1 SOF],[Frame: 1953] 0,,21547,1:15.744.555,50.833 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 83 EC 17 C7 F4 D3 28 FB 8D EA 13 18 FC BE 4B C9… 0,,21551,1:15.745.552,15.004.895 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,21552,1:15.760.558,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E3 45 A9 2A FB 11 B6 59 2B 60 AC B7 9A 05 0B 6B… 0,,21556,1:15.761.554,14.004.750 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,21557,1:15.775.560,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21561,1:15.776.556,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,21562,1:15.776.560,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E3 45 A9 2A FB 11 B6 59 2B 60 AC B7 9A 05 0B 6B… 0,,21566,1:15.777.557,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,21567,1:15.792.562,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B8 DB 28 70 76 41 D7 4F 9C 59 99 7B 75 3E 25 AC… 0,,21571,1:15.793.559,14.004.833 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,21572,1:15.807.564,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21576,1:15.808.561,2.895 us,,,,,[1 SOF],[Frame: 2017] 0,,21577,1:15.808.564,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B8 DB 28 70 76 41 D7 4F 9C 59 99 7B 75 3E 25 AC… 0,,21581,1:15.809.561,15.005.000 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,21582,1:15.824.566,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 18 61 8F D9 89 25 6C 31 42 7E 34 92 B6 EF 24 24… 0,,21586,1:15.825.563,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,21587,1:15.839.568,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21591,1:15.840.565,2.812 us,,,,,[1 SOF],[Frame: 1] 0,,21592,1:15.840.569,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 18 61 8F D9 89 25 6C 31 42 7E 34 92 B6 EF 24 24… 0,,21596,1:15.841.566,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,21597,1:15.856.571,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 53 28 AC FB 39 17 19 45 DD 5B 3D C2 9A D6 86 99… 0,,21601,1:15.857.568,14.004.770 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,21602,1:15.871.573,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21606,1:15.872.570,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,21607,1:15.872.573,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 53 28 AC FB 39 17 19 45 DD 5B 3D C2 9A D6 86 99… 0,,21611,1:15.873.570,15.004.895 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,21612,1:15.888.575,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E4 17 EA 04 90 1F A4 55 E9 AB F5 2D 34 73 79 42… 0,,21616,1:15.889.572,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,21617,1:15.903.577,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21621,1:15.904.574,2.833 us,,,,,[1 SOF],[Frame: 65] 0,,21622,1:15.904.577,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E4 17 EA 04 90 1F A4 55 E9 AB F5 2D 34 73 79 42… 0,,21626,1:15.905.574,15.004.895 ms,,,,,[16 SOF],[Frames: 66 - 81] 0,,21627,1:15.920.580,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E F3 AE 8F A7 67 2D F6 B2 FC 29 D5 8D 3F 97 97… 0,,21631,1:15.921.577,14.004.750 ms,,,,,[15 SOF],[Frames: 82 - 96] 0,,21632,1:15.935.582,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21636,1:15.936.579,2.812 us,,,,,[1 SOF],[Frame: 97] 0,,21637,1:15.936.582,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E F3 AE 8F A7 67 2D F6 B2 FC 29 D5 8D 3F 97 97… 0,,21641,1:15.937.579,15.004.916 ms,,,,,[16 SOF],[Frames: 98 - 113] 0,,21642,1:15.952.584,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 51 58 55 F6 2E 37 4F C6 9B 87 03 97 AC DD BB 40… 0,,21646,1:15.953.581,14.004.750 ms,,,,,[15 SOF],[Frames: 114 - 128] 0,,21647,1:15.967.586,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21651,1:15.968.583,2.812 us,,,,,[1 SOF],[Frame: 129] 0,,21652,1:15.968.586,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 51 58 55 F6 2E 37 4F C6 9B 87 03 97 AC DD BB 40… 0,,21656,1:15.969.583,15.004.916 ms,,,,,[16 SOF],[Frames: 130 - 145] 0,,21657,1:15.984.589,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F4 3A 34 E1 66 90 2A BA 8F B3 B8 CD EA 03 44 42… 0,,21661,1:15.985.585,14.004.770 ms,,,,,[15 SOF],[Frames: 146 - 160] 0,,21662,1:15.999.591,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21666,1:16.000.588,2.812 us,,,,,[1 SOF],[Frame: 161] 0,,21667,1:16.000.591,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F4 3A 34 E1 66 90 2A BA 8F B3 B8 CD EA 03 44 42… 0,,21671,1:16.001.588,15.004.895 ms,,,,,[16 SOF],[Frames: 162 - 177] 0,,21672,1:16.016.593,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DD AA 61 68 B4 EE 54 6A 7C 51 11 99 AB 6A F5 55… 0,,21676,1:16.017.590,14.004.770 ms,,,,,[15 SOF],[Frames: 178 - 192] 0,,21677,1:16.031.595,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21681,1:16.032.592,16.005.041 ms,,,,,[17 SOF],[Frames: 193 - 209] 0,,21682,1:16.048.597,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A B9 ED 0C 75 DC 6B 35 00 B0 BF 38 82 24 09 2D… 0,,21686,1:16.049.594,14.004.770 ms,,,,,[15 SOF],[Frames: 210 - 224] 0,,21687,1:16.063.600,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21691,1:16.064.596,2.833 us,,,,,[1 SOF],[Frame: 225] 0,,21692,1:16.064.600,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A B9 ED 0C 75 DC 6B 35 00 B0 BF 38 82 24 09 2D… 0,,21696,1:16.065.597,15.004.895 ms,,,,,[16 SOF],[Frames: 226 - 241] 0,,21697,1:16.080.602,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 DE EE 0E CF E6 93 70 86 4F E8 6F 74 39 EB 83 75… 0,,21701,1:16.081.599,14.004.750 ms,,,,,[15 SOF],[Frames: 242 - 256] 0,,21702,1:16.095.604,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21706,1:16.096.601,2.812 us,,,,,[1 SOF],[Frame: 257] 0,,21707,1:16.096.604,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 DE EE 0E CF E6 93 70 86 4F E8 6F 74 39 EB 83 75… 0,,21711,1:16.097.601,15.004.916 ms,,,,,[16 SOF],[Frames: 258 - 273] 0,,21712,1:16.112.606,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D9 76 1B 8D 0A C5 DA 9E AC 53 57 FB 64 78 F9 DB… 0,,21716,1:16.113.603,14.004.770 ms,,,,,[15 SOF],[Frames: 274 - 288] 0,,21717,1:16.127.608,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21721,1:16.128.605,2.812 us,,,,,[1 SOF],[Frame: 289] 0,,21722,1:16.128.609,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D9 76 1B 8D 0A C5 DA 9E AC 53 57 FB 64 78 F9 DB… 0,,21726,1:16.129.605,15.004.916 ms,,,,,[16 SOF],[Frames: 290 - 305] 0,,21727,1:16.144.611,50.354 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A6 9C 30 01 30 1C C2 B1 0B 70 12 D9 82 99 B6 B6… 0,,21731,1:16.145.608,14.004.770 ms,,,,,[15 SOF],[Frames: 306 - 320] 0,,21732,1:16.159.613,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21736,1:16.160.610,2.812 us,,,,,[1 SOF],[Frame: 321] 0,,21737,1:16.160.613,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A6 9C 30 01 30 1C C2 B1 0B 70 12 D9 82 99 B6 B6… 0,,21741,1:16.161.610,15.004.895 ms,,,,,[16 SOF],[Frames: 322 - 337] 0,,21742,1:16.176.615,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 A3 00 13 41 FE EC BB 10 DD 44 C2 40 C8 4C 67… 0,,21746,1:16.177.612,14.004.770 ms,,,,,[15 SOF],[Frames: 338 - 352] 0,,21747,1:16.191.617,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21751,1:16.192.614,2.833 us,,,,,[1 SOF],[Frame: 353] 0,,21752,1:16.192.617,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 A3 00 13 41 FE EC BB 10 DD 44 C2 40 C8 4C 67… 0,,21756,1:16.193.614,15.004.895 ms,,,,,[16 SOF],[Frames: 354 - 369] 0,,21757,1:16.208.620,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 91 50 A7 10 C2 25 7F 09 05 97 B8 B8 19 85 0E 97… 0,,21761,1:16.209.617,14.004.750 ms,,,,,[15 SOF],[Frames: 370 - 384] 0,,21762,1:16.223.622,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21766,1:16.224.619,2.833 us,,,,,[1 SOF],[Frame: 385] 0,,21767,1:16.224.622,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 91 50 A7 10 C2 25 7F 09 05 97 B8 B8 19 85 0E 97… 0,,21771,1:16.225.619,15.004.895 ms,,,,,[16 SOF],[Frames: 386 - 401] 0,,21772,1:16.240.624,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B2 7C 67 F8 00 C5 1A AB CD D6 D1 0A EE 7C B3 E3… 0,,21776,1:16.241.621,14.004.750 ms,,,,,[15 SOF],[Frames: 402 - 416] 0,,21777,1:16.255.626,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21781,1:16.256.623,2.812 us,,,,,[1 SOF],[Frame: 417] 0,,21782,1:16.256.626,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B2 7C 67 F8 00 C5 1A AB CD D6 D1 0A EE 7C B3 E3… 0,,21786,1:16.257.623,15.004.916 ms,,,,,[16 SOF],[Frames: 418 - 433] 0,,21787,1:16.272.629,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 B0 1B 3B D7 1B AB 9B 3F 5D DF 76 B5 BD E1 E8 7F… 0,,21791,1:16.273.625,14.004.770 ms,,,,,[15 SOF],[Frames: 434 - 448] 0,,21792,1:16.287.631,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21796,1:16.288.628,2.812 us,,,,,[1 SOF],[Frame: 449] 0,,21797,1:16.288.631,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 B0 1B 3B D7 1B AB 9B 3F 5D DF 76 B5 BD E1 E8 7F… 0,,21801,1:16.289.628,15.004.895 ms,,,,,[16 SOF],[Frames: 450 - 465] 0,,21802,1:16.304.633,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 32 05 5B 89 B3 43 64 2F 95 1B CA A1 84 50 A1… 0,,21806,1:16.305.630,14.004.770 ms,,,,,[15 SOF],[Frames: 466 - 480] 0,,21807,1:16.319.635,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21811,1:16.320.632,2.812 us,,,,,[1 SOF],[Frame: 481] 0,,21812,1:16.320.635,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 32 05 5B 89 B3 43 64 2F 95 1B CA A1 84 50 A1… 0,,21816,1:16.321.632,15.004.895 ms,,,,,[16 SOF],[Frames: 482 - 497] 0,,21817,1:16.336.637,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 38 BF F5 06 1A CC 68 7F 2D 80 93 87 C3 79 59 5E… 0,,21821,1:16.337.634,14.004.770 ms,,,,,[15 SOF],[Frames: 498 - 512] 0,,21822,1:16.351.640,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21826,1:16.352.636,2.833 us,,,,,[1 SOF],[Frame: 513] 0,,21827,1:16.352.640,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 38 BF F5 06 1A CC 68 7F 2D 80 93 87 C3 79 59 5E… 0,,21831,1:16.353.637,15.004.895 ms,,,,,[16 SOF],[Frames: 514 - 529] 0,,21832,1:16.368.642,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 01 4A 11 8E 57 8F 24 D9 64 C1 31 37 F8 1D F2 73… 0,,21836,1:16.369.639,14.004.750 ms,,,,,[15 SOF],[Frames: 530 - 544] 0,,21837,1:16.383.644,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21841,1:16.384.641,2.812 us,,,,,[1 SOF],[Frame: 545] 0,,21842,1:16.384.644,50.479 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 01 4A 11 8E 57 8F 24 D9 64 C1 31 37 F8 1D F2 73… 0,,21846,1:16.385.641,15.004.895 ms,,,,,[16 SOF],[Frames: 546 - 561] 0,,21847,1:16.400.646,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 34 73 70 59 D6 53 2A 68 B0 B4 3F 82 66 D6 F5 72… 0,,21851,1:16.401.643,14.004.750 ms,,,,,[15 SOF],[Frames: 562 - 576] 0,,21852,1:16.415.648,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21856,1:16.416.645,2.812 us,,,,,[1 SOF],[Frame: 577] 0,,21857,1:16.416.649,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 34 73 70 59 D6 53 2A 68 B0 B4 3F 82 66 D6 F5 72… 0,,21861,1:16.417.645,15.004.916 ms,,,,,[16 SOF],[Frames: 578 - 593] 0,,21862,1:16.432.651,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 18 4D F0 26 76 F6 E0 24 AC FB 70 74 2C 2B CF… 0,,21866,1:16.433.648,14.004.770 ms,,,,,[15 SOF],[Frames: 594 - 608] 0,,21867,1:16.447.653,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21871,1:16.448.650,2.812 us,,,,,[1 SOF],[Frame: 609] 0,,21872,1:16.448.653,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 18 4D F0 26 76 F6 E0 24 AC FB 70 74 2C 2B CF… 0,,21876,1:16.449.650,15.004.895 ms,,,,,[16 SOF],[Frames: 610 - 625] 0,,21877,1:16.464.655,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7D 34 62 BA 2F AB 8D 0B BF 7B B0 B4 97 1F CF B1… 0,,21881,1:16.465.652,14.004.770 ms,,,,,[15 SOF],[Frames: 626 - 640] 0,,21882,1:16.479.657,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21886,1:16.480.654,2.812 us,,,,,[1 SOF],[Frame: 641] 0,,21887,1:16.480.657,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7D 34 62 BA 2F AB 8D 0B BF 7B B0 B4 97 1F CF B1… 0,,21891,1:16.481.654,15.004.895 ms,,,,,[16 SOF],[Frames: 642 - 657] 0,,21892,1:16.496.660,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A0 5D EE 79 55 AF 08 74 DA C6 61 2C FB B0 2E 4D… 0,,21896,1:16.497.657,14.004.770 ms,,,,,[15 SOF],[Frames: 658 - 672] 0,,21897,1:16.511.662,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21901,1:16.512.659,2.833 us,,,,,[1 SOF],[Frame: 673] 0,,21902,1:16.512.662,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A0 5D EE 79 55 AF 08 74 DA C6 61 2C FB B0 2E 4D… 0,,21906,1:16.513.659,15.004.895 ms,,,,,[16 SOF],[Frames: 674 - 689] 0,,21907,1:16.528.664,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A3 95 FA 53 4D FC 22 ED 83 8A 14 8F 1C E8 0F 93… 0,,21911,1:16.529.661,14.004.750 ms,,,,,[15 SOF],[Frames: 690 - 704] 0,,21912,1:16.543.666,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21916,1:16.544.663,2.812 us,,,,,[1 SOF],[Frame: 705] 0,,21917,1:16.544.666,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A3 95 FA 53 4D FC 22 ED 83 8A 14 8F 1C E8 0F 93… 0,,21921,1:16.545.663,15.004.916 ms,,,,,[16 SOF],[Frames: 706 - 721] 0,,21922,1:16.560.669,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 74 A3 9B DE 66 EA 58 17 B2 BB AC F5 F8 DD 50 89… 0,,21926,1:16.561.665,14.004.750 ms,,,,,[15 SOF],[Frames: 722 - 736] 0,,21927,1:16.575.671,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21931,1:16.576.668,2.812 us,,,,,[1 SOF],[Frame: 737] 0,,21932,1:16.576.671,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 74 A3 9B DE 66 EA 58 17 B2 BB AC F5 F8 DD 50 89… 0,,21936,1:16.577.668,15.004.916 ms,,,,,[16 SOF],[Frames: 738 - 753] 0,,21937,1:16.592.673,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 61 F0 A2 3E D5 B0 13 D5 51 BC 1C 62 19 AE 19 75… 0,,21941,1:16.593.670,14.004.770 ms,,,,,[15 SOF],[Frames: 754 - 768] 0,,21942,1:16.607.675,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21946,1:16.608.672,2.812 us,,,,,[1 SOF],[Frame: 769] 0,,21947,1:16.608.675,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 61 F0 A2 3E D5 B0 13 D5 51 BC 1C 62 19 AE 19 75… 0,,21951,1:16.609.672,15.004.895 ms,,,,,[16 SOF],[Frames: 770 - 785] 0,,21952,1:16.624.677,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 7E A3 7E 11 5F 8A 2B 95 97 97 35 F3 09 BA F3 CD… 0,,21956,1:16.625.674,14.004.770 ms,,,,,[15 SOF],[Frames: 786 - 800] 0,,21957,1:16.639.680,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21961,1:16.640.676,2.833 us,,,,,[1 SOF],[Frame: 801] 0,,21962,1:16.640.680,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 7E A3 7E 11 5F 8A 2B 95 97 97 35 F3 09 BA F3 CD… 0,,21966,1:16.641.677,15.004.895 ms,,,,,[16 SOF],[Frames: 802 - 817] 0,,21967,1:16.656.682,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2A 85 A8 2E FC BD 67 99 55 5E 4D 20 D9 51 C9 AB… 0,,21971,1:16.657.679,14.004.770 ms,,,,,[15 SOF],[Frames: 818 - 832] 0,,21972,1:16.671.684,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21976,1:16.672.681,16.005.041 ms,,,,,[17 SOF],[Frames: 833 - 849] 0,,21977,1:16.688.686,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E6 79 66 BF CC D2 1D F6 80 17 90 C2 CB C9 50 10… 0,,21981,1:16.689.683,14.004.750 ms,,,,,[15 SOF],[Frames: 850 - 864] 0,,21982,1:16.703.688,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,21986,1:16.704.685,2.812 us,,,,,[1 SOF],[Frame: 865] 0,,21987,1:16.704.689,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E6 79 66 BF CC D2 1D F6 80 17 90 C2 CB C9 50 10… 0,,21991,1:16.705.685,15.004.916 ms,,,,,[16 SOF],[Frames: 866 - 881] 0,,21992,1:16.720.691,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 20 8A F5 C7 9D DD C3 9E 0C 32 1D 36 D2 1D 8E 64… 0,,21996,1:16.721.688,14.004.770 ms,,,,,[15 SOF],[Frames: 882 - 896] 0,,21997,1:16.735.693,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22001,1:16.736.690,2.812 us,,,,,[1 SOF],[Frame: 897] 0,,22002,1:16.736.693,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 20 8A F5 C7 9D DD C3 9E 0C 32 1D 36 D2 1D 8E 64… 0,,22006,1:16.737.690,15.004.895 ms,,,,,[16 SOF],[Frames: 898 - 913] 0,,22007,1:16.752.695,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 91 42 67 39 E2 34 47 2B 97 8B DE F3 09 5B 04 20… 0,,22011,1:16.753.692,14.004.770 ms,,,,,[15 SOF],[Frames: 914 - 928] 0,,22012,1:16.767.697,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22016,1:16.768.694,2.812 us,,,,,[1 SOF],[Frame: 929] 0,,22017,1:16.768.697,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 91 42 67 39 E2 34 47 2B 97 8B DE F3 09 5B 04 20… 0,,22021,1:16.769.694,15.004.895 ms,,,,,[16 SOF],[Frames: 930 - 945] 0,,22022,1:16.784.700,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BC 85 75 3A EE 9C E6 F6 74 5A 97 86 5D 90 68 48… 0,,22026,1:16.785.697,14.004.770 ms,,,,,[15 SOF],[Frames: 946 - 960] 0,,22027,1:16.799.702,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22031,1:16.800.699,2.833 us,,,,,[1 SOF],[Frame: 961] 0,,22032,1:16.800.702,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BC 85 75 3A EE 9C E6 F6 74 5A 97 86 5D 90 68 48… 0,,22036,1:16.801.699,15.004.895 ms,,,,,[16 SOF],[Frames: 962 - 977] 0,,22037,1:16.816.704,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 93 C2 E7 8E A2 64 38 A7 F4 20 C4 D5 25 CE 4D 2E… 0,,22041,1:16.817.701,14.004.750 ms,,,,,[15 SOF],[Frames: 978 - 992] 0,,22042,1:16.831.706,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22046,1:16.832.703,2.833 us,,,,,[1 SOF],[Frame: 993] 0,,22047,1:16.832.706,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 93 C2 E7 8E A2 64 38 A7 F4 20 C4 D5 25 CE 4D 2E… 0,,22051,1:16.833.703,15.004.979 ms,,,,,[16 SOF],[Frames: 994 - 1009] 0,,22052,1:16.848.709,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 13 1B 35 37 BB 4E F4 3D 3D 41 14 55 B4 B2 85 25… 0,,22056,1:16.849.705,14.004.750 ms,,,,,[15 SOF],[Frames: 1010 - 1024] 0,,22057,1:16.863.711,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22061,1:16.864.708,2.812 us,,,,,[1 SOF],[Frame: 1025] 0,,22062,1:16.864.711,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 13 1B 35 37 BB 4E F4 3D 3D 41 14 55 B4 B2 85 25… 0,,22066,1:16.865.708,15.004.916 ms,,,,,[16 SOF],[Frames: 1026 - 1041] 0,,22067,1:16.880.713,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 05 88 70 0E 10 4D 9F 00 42 65 9F DB 73 E6 11 D2… 0,,22071,1:16.881.710,14.004.770 ms,,,,,[15 SOF],[Frames: 1042 - 1056] 0,,22072,1:16.895.715,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22076,1:16.896.712,2.812 us,,,,,[1 SOF],[Frame: 1057] 0,,22077,1:16.896.715,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 05 88 70 0E 10 4D 9F 00 42 65 9F DB 73 E6 11 D2… 0,,22081,1:16.897.712,15.004.895 ms,,,,,[16 SOF],[Frames: 1058 - 1073] 0,,22082,1:16.912.717,50.395 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 73 DA 25 D2 EE ED D1 5D B9 79 68 A8 72 D6 A9 91… 0,,22086,1:16.913.714,14.004.770 ms,,,,,[15 SOF],[Frames: 1074 - 1088] 0,,22087,1:16.927.719,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22091,1:16.928.716,2.812 us,,,,,[1 SOF],[Frame: 1089] 0,,22092,1:16.928.720,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 73 DA 25 D2 EE ED D1 5D B9 79 68 A8 72 D6 A9 91… 0,,22096,1:16.929.717,15.004.895 ms,,,,,[16 SOF],[Frames: 1090 - 1105] 0,,22097,1:16.944.722,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8A D0 4D F6 3D 8D A3 CD 4E 9A 71 49 B3 0E 57 D7… 0,,22101,1:16.945.719,14.004.770 ms,,,,,[15 SOF],[Frames: 1106 - 1120] 0,,22102,1:16.959.724,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22106,1:16.960.721,2.833 us,,,,,[1 SOF],[Frame: 1121] 0,,22107,1:16.960.724,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8A D0 4D F6 3D 8D A3 CD 4E 9A 71 49 B3 0E 57 D7… 0,,22111,1:16.961.721,15.004.895 ms,,,,,[16 SOF],[Frames: 1122 - 1137] 0,,22112,1:16.976.726,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 19 47 62 00 6B DF 34 E8 4D 49 E0 7F 70 91 DB 9E… 0,,22116,1:16.977.723,14.004.750 ms,,,,,[15 SOF],[Frames: 1138 - 1152] 0,,22117,1:16.991.728,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22121,1:16.992.725,2.895 us,,,,,[1 SOF],[Frame: 1153] 0,,22122,1:16.992.729,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 19 47 62 00 6B DF 34 E8 4D 49 E0 7F 70 91 DB 9E… 0,,22126,1:16.993.725,15.004.895 ms,,,,,[16 SOF],[Frames: 1154 - 1169] 0,,22127,1:17.008.731,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 80 E4 9F AC 74 89 5A 33 6B DF DA 2F 5B 20 15 41… 0,,22131,1:17.009.728,14.004.750 ms,,,,,[15 SOF],[Frames: 1170 - 1184] 0,,22132,1:17.023.733,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22136,1:17.024.730,2.812 us,,,,,[1 SOF],[Frame: 1185] 0,,22137,1:17.024.733,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 80 E4 9F AC 74 89 5A 33 6B DF DA 2F 5B 20 15 41… 0,,22141,1:17.025.730,15.004.916 ms,,,,,[16 SOF],[Frames: 1186 - 1201] 0,,22142,1:17.040.735,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 4F 23 A0 B6 BD B3 A6 E2 48 CC E3 D1 D2 D3 83… 0,,22146,1:17.041.732,14.004.770 ms,,,,,[15 SOF],[Frames: 1202 - 1216] 0,,22147,1:17.055.737,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22151,1:17.056.734,2.812 us,,,,,[1 SOF],[Frame: 1217] 0,,22152,1:17.056.737,50.354 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 4F 23 A0 B6 BD B3 A6 E2 48 CC E3 D1 D2 D3 83… 0,,22156,1:17.057.734,15.004.895 ms,,,,,[16 SOF],[Frames: 1218 - 1233] 0,,22157,1:17.072.740,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 42 72 28 5C FC BB D9 43 6E 9F 41 CA 03 88 04 E8… 0,,22161,1:17.073.737,14.004.770 ms,,,,,[15 SOF],[Frames: 1234 - 1248] 0,,22162,1:17.087.742,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22166,1:17.088.739,2.812 us,,,,,[1 SOF],[Frame: 1249] 0,,22167,1:17.088.742,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 42 72 28 5C FC BB D9 43 6E 9F 41 CA 03 88 04 E8… 0,,22171,1:17.089.739,15.004.895 ms,,,,,[16 SOF],[Frames: 1250 - 1265] 0,,22172,1:17.104.744,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 6D 68 80 B2 E5 18 7D D1 08 64 A2 53 3D 77 71 AE… 0,,22176,1:17.105.741,14.004.770 ms,,,,,[15 SOF],[Frames: 1266 - 1280] 0,,22177,1:17.119.746,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22181,1:17.120.743,2.833 us,,,,,[1 SOF],[Frame: 1281] 0,,22182,1:17.120.746,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 6D 68 80 B2 E5 18 7D D1 08 64 A2 53 3D 77 71 AE… 0,,22186,1:17.121.743,15.004.895 ms,,,,,[16 SOF],[Frames: 1282 - 1297] 0,,22187,1:17.136.749,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 55 45 F1 6E 59 23 EA 3E 9D E3 79 53 05 E6 B7 B5… 0,,22191,1:17.137.745,14.004.750 ms,,,,,[15 SOF],[Frames: 1298 - 1312] 0,,22192,1:17.151.751,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22196,1:17.152.747,2.812 us,,,,,[1 SOF],[Frame: 1313] 0,,22197,1:17.152.751,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 55 45 F1 6E 59 23 EA 3E 9D E3 79 53 05 E6 B7 B5… 0,,22201,1:17.153.748,15.004.916 ms,,,,,[16 SOF],[Frames: 1314 - 1329] 0,,22202,1:17.168.753,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 85 93 69 F0 07 98 B2 48 4B 55 EF 94 EB CE FD 7F… 0,,22206,1:17.169.750,14.004.750 ms,,,,,[15 SOF],[Frames: 1330 - 1344] 0,,22207,1:17.183.755,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22211,1:17.184.752,2.812 us,,,,,[1 SOF],[Frame: 1345] 0,,22212,1:17.184.755,50.562 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 85 93 69 F0 07 98 B2 48 4B 55 EF 94 EB CE FD 7F… 0,,22216,1:17.185.752,15.004.916 ms,,,,,[16 SOF],[Frames: 1346 - 1361] 0,,22217,1:17.200.757,50.437 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 D5 52 3A AD 17 5F 96 50 0B D2 02 96 D7 61 2F 77… 0,,22221,1:17.201.754,14.004.770 ms,,,,,[15 SOF],[Frames: 1362 - 1376] 0,,22222,1:17.215.759,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22226,1:17.216.756,2.812 us,,,,,[1 SOF],[Frame: 1377] 0,,22227,1:17.216.760,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 D5 52 3A AD 17 5F 96 50 0B D2 02 96 D7 61 2F 77… 0,,22231,1:17.217.757,15.004.895 ms,,,,,[16 SOF],[Frames: 1378 - 1393] 0,,22232,1:17.232.762,50.750 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 59 BF 75 3F C3 23 21 74 0D BF 3F DA 3C 6C 55 A4… 0,,22236,1:17.233.759,14.004.770 ms,,,,,[15 SOF],[Frames: 1394 - 1408] 0,,22237,1:17.247.764,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22241,1:17.248.761,2.833 us,,,,,[1 SOF],[Frame: 1409] 0,,22242,1:17.248.764,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 59 BF 75 3F C3 23 21 74 0D BF 3F DA 3C 6C 55 A4… 0,,22246,1:17.249.761,15.004.895 ms,,,,,[16 SOF],[Frames: 1410 - 1425] 0,,22247,1:17.264.766,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 EC 66 64 36 91 B1 68 06 4A CF 14 D2 EE D3 71 9C… 0,,22251,1:17.265.763,14.004.770 ms,,,,,[15 SOF],[Frames: 1426 - 1440] 0,,22252,1:17.279.768,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22256,1:17.280.765,16.005.041 ms,,,,,[17 SOF],[Frames: 1441 - 1457] 0,,22257,1:17.296.771,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E0 A6 97 12 B0 75 09 AE C2 57 EC 5C A5 D5 78 6E… 0,,22261,1:17.297.768,14.004.750 ms,,,,,[15 SOF],[Frames: 1458 - 1472] 0,,22262,1:17.311.773,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22266,1:17.312.770,2.812 us,,,,,[1 SOF],[Frame: 1473] 0,,22267,1:17.312.773,50.395 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E0 A6 97 12 B0 75 09 AE C2 57 EC 5C A5 D5 78 6E… 0,,22271,1:17.313.770,15.004.916 ms,,,,,[16 SOF],[Frames: 1474 - 1489] 0,,22272,1:17.328.775,50.604 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 71 87 EF E1 C3 79 05 1B BC 3A 7E 9F 9A B3 52 01… 0,,22276,1:17.329.772,14.004.854 ms,,,,,[15 SOF],[Frames: 1490 - 1504] 0,,22277,1:17.343.777,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22281,1:17.344.774,2.812 us,,,,,[1 SOF],[Frame: 1505] 0,,22282,1:17.344.777,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 71 87 EF E1 C3 79 05 1B BC 3A 7E 9F 9A B3 52 01… 0,,22286,1:17.345.774,15.004.895 ms,,,,,[16 SOF],[Frames: 1506 - 1521] 0,,22287,1:17.360.780,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 3E A7 33 B7 87 45 D0 50 16 1F A6 16 77 E5 CF AA… 0,,22291,1:17.361.776,14.004.770 ms,,,,,[15 SOF],[Frames: 1522 - 1536] 0,,22292,1:17.375.782,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22296,1:17.376.779,2.812 us,,,,,[1 SOF],[Frame: 1537] 0,,22297,1:17.376.782,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 3E A7 33 B7 87 45 D0 50 16 1F A6 16 77 E5 CF AA… 0,,22301,1:17.377.779,15.004.979 ms,,,,,[16 SOF],[Frames: 1538 - 1553] 0,,22302,1:17.392.784,50.833 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 41 1D 11 E1 EF B2 B4 E4 C4 D2 D7 56 B4 83 F8 35… 0,,22306,1:17.393.781,14.004.770 ms,,,,,[15 SOF],[Frames: 1554 - 1568] 0,,22307,1:17.407.786,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22311,1:17.408.783,2.833 us,,,,,[1 SOF],[Frame: 1569] 0,,22312,1:17.408.786,50.770 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 41 1D 11 E1 EF B2 B4 E4 C4 D2 D7 56 B4 83 F8 35… 0,,22316,1:17.409.783,15.004.895 ms,,,,,[16 SOF],[Frames: 1570 - 1585] 0,,22317,1:17.424.788,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 BE BA BD 83 3F 5C A2 7A 72 F1 8A 31 24 8B F8 DF… 0,,22321,1:17.425.785,14.004.750 ms,,,,,[15 SOF],[Frames: 1586 - 1600] 0,,22322,1:17.439.791,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22326,1:17.440.787,2.833 us,,,,,[1 SOF],[Frame: 1601] 0,,22327,1:17.440.791,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 BE BA BD 83 3F 5C A2 7A 72 F1 8A 31 24 8B F8 DF… 0,,22331,1:17.441.788,15.004.895 ms,,,,,[16 SOF],[Frames: 1602 - 1617] 0,,22332,1:17.456.793,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 82 2B 44 73 4D 7C 6D 4F 06 B1 D4 60 C6 71 E4 05… 0,,22336,1:17.457.790,14.004.750 ms,,,,,[15 SOF],[Frames: 1618 - 1632] 0,,22337,1:17.471.795,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22341,1:17.472.792,2.812 us,,,,,[1 SOF],[Frame: 1633] 0,,22342,1:17.472.795,50.333 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 82 2B 44 73 4D 7C 6D 4F 06 B1 D4 60 C6 71 E4 05… 0,,22346,1:17.473.792,15.004.916 ms,,,,,[16 SOF],[Frames: 1634 - 1649] 0,,22347,1:17.488.797,50.770 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 2B 6D F3 E7 F3 47 B2 E6 44 1B 92 40 10 AE 12 84… 0,,22351,1:17.489.794,14.004.770 ms,,,,,[15 SOF],[Frames: 1650 - 1664] 0,,22352,1:17.503.799,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22356,1:17.504.796,2.812 us,,,,,[1 SOF],[Frame: 1665] 0,,22357,1:17.504.800,50.750 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 2B 6D F3 E7 F3 47 B2 E6 44 1B 92 40 10 AE 12 84… 0,,22361,1:17.505.796,15.004.895 ms,,,,,[16 SOF],[Frames: 1666 - 1681] 0,,22362,1:17.520.802,50.479 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AD E9 AB D2 8E AA 62 E7 41 42 89 3A A0 A7 8F 34… 0,,22366,1:17.521.799,14.004.770 ms,,,,,[15 SOF],[Frames: 1682 - 1696] 0,,22367,1:17.535.804,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22371,1:17.536.801,2.812 us,,,,,[1 SOF],[Frame: 1697] 0,,22372,1:17.536.804,50.520 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 AD E9 AB D2 8E AA 62 E7 41 42 89 3A A0 A7 8F 34… 0,,22376,1:17.537.801,15.004.895 ms,,,,,[16 SOF],[Frames: 1698 - 1713] 0,,22377,1:17.552.806,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 00 22 85 5E E6 EC 30 C3 BA 8E C6 DB 17 AD F9 95… 0,,22381,1:17.553.803,14.004.770 ms,,,,,[15 SOF],[Frames: 1714 - 1728] 0,,22382,1:17.567.808,50.979 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22386,1:17.568.805,2.833 us,,,,,[1 SOF],[Frame: 1729] 0,,22387,1:17.568.808,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 00 22 85 5E E6 EC 30 C3 BA 8E C6 DB 17 AD F9 95… 0,,22391,1:17.569.805,15.004.895 ms,,,,,[16 SOF],[Frames: 1730 - 1745] 0,,22392,1:17.584.811,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 24 49 0D BB 8E 8F D0 90 E0 72 81 E4 97 6C C3 DA… 0,,22396,1:17.585.808,14.004.750 ms,,,,,[15 SOF],[Frames: 1746 - 1760] 0,,22397,1:17.599.813,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22401,1:17.600.810,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,22402,1:17.600.813,50.416 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 24 49 0D BB 8E 8F D0 90 E0 72 81 E4 97 6C C3 DA… 0,,22406,1:17.601.810,15.004.895 ms,,,,,[16 SOF],[Frames: 1762 - 1777] 0,,22407,1:17.616.815,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 F3 A2 AC 73 66 1D 33 65 7F A6 6F 16 F9 D4 08 38… 0,,22411,1:17.617.812,14.004.750 ms,,,,,[15 SOF],[Frames: 1778 - 1792] 0,,22412,1:17.631.817,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22416,1:17.632.814,2.812 us,,,,,[1 SOF],[Frame: 1793] 0,,22417,1:17.632.817,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 F3 A2 AC 73 66 1D 33 65 7F A6 6F 16 F9 D4 08 38… 0,,22421,1:17.633.814,15.004.916 ms,,,,,[16 SOF],[Frames: 1794 - 1809] 0,,22422,1:17.648.820,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 89 5E DB FC B4 1B AC 8A E4 79 38 95 B2 05 45 32… 0,,22426,1:17.649.816,14.004.770 ms,,,,,[15 SOF],[Frames: 1810 - 1824] 0,,22427,1:17.663.822,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22431,1:17.664.819,2.895 us,,,,,[1 SOF],[Frame: 1825] 0,,22432,1:17.664.822,50.583 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 89 5E DB FC B4 1B AC 8A E4 79 38 95 B2 05 45 32… 0,,22436,1:17.665.819,15.004.895 ms,,,,,[16 SOF],[Frames: 1826 - 1841] 0,,22437,1:17.680.824,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 A8 E1 F0 F6 D1 E2 F8 1B 03 1F D6 76 43 2E 66 DA… 0,,22441,1:17.681.821,14.004.770 ms,,,,,[15 SOF],[Frames: 1842 - 1856] 0,,22442,1:17.695.826,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22446,1:17.696.823,2.833 us,,,,,[1 SOF],[Frame: 1857] 0,,22447,1:17.696.826,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 A8 E1 F0 F6 D1 E2 F8 1B 03 1F D6 76 43 2E 66 DA… 0,,22451,1:17.697.823,15.004.895 ms,,,,,[16 SOF],[Frames: 1858 - 1873] 0,,22452,1:17.712.828,50.583 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 1D CC C4 A4 BB 48 52 5C 46 FE 52 59 2C 9C 5E BB… 0,,22456,1:17.713.825,14.004.770 ms,,,,,[15 SOF],[Frames: 1874 - 1888] 0,,22457,1:17.727.831,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22461,1:17.728.827,2.833 us,,,,,[1 SOF],[Frame: 1889] 0,,22462,1:17.728.831,50.604 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 1D CC C4 A4 BB 48 52 5C 46 FE 52 59 2C 9C 5E BB… 0,,22466,1:17.729.828,15.004.895 ms,,,,,[16 SOF],[Frames: 1890 - 1905] 0,,22467,1:17.744.833,50.666 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 33 F1 74 FA 9D A3 EF CA 8F B3 59 33 9B 91 BD 67… 0,,22471,1:17.745.830,14.004.833 ms,,,,,[15 SOF],[Frames: 1906 - 1920] 0,,22472,1:17.759.835,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22476,1:17.760.832,2.812 us,,,,,[1 SOF],[Frame: 1921] 0,,22477,1:17.760.835,50.666 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 33 F1 74 FA 9D A3 EF CA 8F B3 59 33 9B 91 BD 67… 0,,22481,1:17.761.832,15.004.916 ms,,,,,[16 SOF],[Frames: 1922 - 1937] 0,,22482,1:17.776.837,50.333 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 E2 29 5A 9E 9B 85 94 8B 05 C0 21 63 49 8B 63 8C… 0,,22486,1:17.777.834,14.004.750 ms,,,,,[15 SOF],[Frames: 1938 - 1952] 0,,22487,1:17.791.839,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22491,1:17.792.836,2.812 us,,,,,[1 SOF],[Frame: 1953] 0,,22492,1:17.792.840,50.312 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 E2 29 5A 9E 9B 85 94 8B 05 C0 21 63 49 8B 63 8C… 0,,22496,1:17.793.836,15.004.916 ms,,,,,[16 SOF],[Frames: 1954 - 1969] 0,,22497,1:17.808.842,50.520 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 13 80 95 DD 59 55 E5 D8 99 AA 17 F5 43 6D 64 4B… 0,,22501,1:17.809.839,14.004.770 ms,,,,,[15 SOF],[Frames: 1970 - 1984] 0,,22502,1:17.823.844,51.000 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22506,1:17.824.841,2.895 us,,,,,[1 SOF],[Frame: 1985] 0,,22507,1:17.824.844,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 13 80 95 DD 59 55 E5 D8 99 AA 17 F5 43 6D 64 4B… 0,,22511,1:17.825.841,15.004.979 ms,,,,,[16 SOF],[Frames: 1986 - 2001] 0,,22512,1:17.840.846,50.562 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 8E 29 42 0B 6C 60 AC E1 98 BA EF 0C 31 B6 0A 32… 0,,22516,1:17.841.843,14.004.854 ms,,,,,[15 SOF],[Frames: 2002 - 2016] 0,,22517,1:17.855.848,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22521,1:17.856.845,2.916 us,,,,,[1 SOF],[Frame: 2017] 0,,22522,1:17.856.849,50.500 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 8E 29 42 0B 6C 60 AC E1 98 BA EF 0C 31 B6 0A 32… 0,,22526,1:17.857.845,15.004.979 ms,,,,,[16 SOF],[Frames: 2018 - 2033] 0,,22527,1:17.872.851,50.416 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 49 D6 29 39 4D 9E B7 BA 86 2C 4B 98 20 57 46 D8… 0,,22531,1:17.873.848,14.004.770 ms,,,,,[15 SOF],[Frames: 2034 - 0] 0,,22532,1:17.887.853,50.895 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22536,1:17.888.850,2.833 us,,,,,[1 SOF],[Frame: 1] 0,,22537,1:17.888.853,50.437 us,64 B,,01,01,OUT txn,05 00 1D 01 00 00 20 00 49 D6 29 39 4D 9E B7 BA 86 2C 4B 98 20 57 46 D8… 0,,22541,1:17.889.850,15.004.895 ms,,,,,[16 SOF],[Frames: 2 - 17] 0,,22542,1:17.904.855,50.500 us,64 B,,01,01,OUT txn,27 00 16 23 00 00 20 00 AD 1B 7C 84 88 E7 FE E7 C4 2B D3 D6 BA 65 DA 94… 0,,22546,1:17.905.852,14.004.750 ms,,,,,[15 SOF],[Frames: 18 - 32] 0,,22547,1:17.919.857,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22551,1:17.920.854,2.812 us,,,,,[1 SOF],[Frame: 33] 0,,22552,1:17.920.857,50.479 us,64 B,,01,01,OUT txn,13 00 16 0F 00 06 0C 00 CA 3D CE FC D4 F7 41 57 01 0D E7 84 BA 65 DA 94… 0,,22556,1:17.921.854,15.004.916 ms,,,,,[16 SOF],[Frames: 34 - 49] 0,,22557,1:17.936.860,50.520 us,64 B,,01,01,OUT txn,05 00 16 01 00 02 0C 00 CA 3D CE FC D4 F7 41 57 01 0D E7 84 BA 65 DA 94… 0,,22561,1:17.937.856,14.004.770 ms,,,,,[15 SOF],[Frames: 50 - 64] 0,,22562,1:17.951.862,50.916 us,64 B,,01,02,IN txn,06 00 16 01 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00… 0,,22566,1:17.952.859,41.008.500 ms,,,,,[42 SOF],[Frames: 65 - 106] 0,,22567,1:17.983.866,4.583 us,,,01,02,[1 IN-NAK], 0,,22568,1:17.994.154,,,,,, / , 0,,22569,1:18.761.750,,,,,, / , 0,,22570,1:18.941.662,,,,,, / , 0,,22571,1:19.007.714,,,,,, / , 0,,22572,1:19.491.928,,,,,, / , 0,,22573,1:19.523.678,,,,,, / , 0,,22574,1:19.524.077,31.007.125 ms,,,,,[32 SOF],[Frames: 1636 - 1667] 0,,22575,1:19.555.084,12.979 us,8 B,,00,00,SETUP txn,80 06 00 01 00 00 40 00 0,,22579,1:19.556.081,2.833 us,,,,,[1 SOF],[Frame: 1668] 0,,22580,1:19.556.084,20.250 us,18 B,,00,00,IN txn,12 01 00 02 00 00 00 40 35 12 21 AB 01 00 01 02 00 01 0,,22584,1:19.557.081,1.002.958 ms,,,,,[2 SOF],[Frames: 1669 - 1670] 0,,22585,1:19.558.085,7.645 us,0 B,,00,00,OUT txn, 0,,22589,1:19.559.081,2.833 us,,,,,[1 SOF],[Frame: 1671] 0,,22590,1:19.559.159,,,,,, / , 0,,22591,1:19.585.387,,,,,, / , 0,,22592,1:19.586.085,31.007.125 ms,,,,,[32 SOF],[Frames: 1698 - 1729] 0,,22593,1:19.617.093,12.979 us,8 B,,00,00,SETUP txn,00 05 01 00 00 00 00 00 0,,22597,1:19.618.090,2.833 us,,,,,[1 SOF],[Frame: 1730] 0,,22598,1:19.618.093,8.250 us,0 B,,00,00,IN txn, 0,,22602,1:19.619.090,29.006.854 ms,,,,,[30 SOF],[Frames: 1731 - 1760] 0,,22603,1:19.648.098,13.000 us,8 B,,01,00,SETUP txn,80 06 00 01 00 00 12 00 0,,22607,1:19.649.094,2.895 us,,,,,[1 SOF],[Frame: 1761] 0,,22608,1:19.649.097,20.229 us,18 B,,01,00,IN txn,12 01 00 02 00 00 00 40 35 12 21 AB 01 00 01 02 00 01 0,,22612,1:19.650.094,2.812 us,,,,,[1 SOF],[Frame: 1762] 0,,22613,1:19.650.097,7.666 us,0 B,,01,00,OUT txn, 0,,22617,1:19.651.094,1.002.958 ms,,,,,[2 SOF],[Frames: 1763 - 1764] 0,,22618,1:19.652.098,13.083 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 FF 00 0,,22622,1:19.653.095,2.812 us,,,,,[1 SOF],[Frame: 1765] 0,,22623,1:19.653.098,35.562 us,41 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01… 0,,22627,1:19.654.095,1.003.041 ms,,,,,[2 SOF],[Frames: 1766 - 1767] 0,,22628,1:19.655.098,7.666 us,0 B,,01,00,OUT txn, 0,,22632,1:19.656.095,1.002.958 ms,,,,,[2 SOF],[Frames: 1768 - 1769] 0,,22633,1:19.657.099,13.083 us,8 B,,01,00,SETUP txn,80 06 00 03 00 00 FF 00 0,,22637,1:19.658.095,2.812 us,,,,,[1 SOF],[Frame: 1770] 0,,22638,1:19.658.098,10.895 us,4 B,,01,00,IN txn,04 03 09 04 0,,22642,1:19.659.095,1.002.958 ms,,,,,[2 SOF],[Frames: 1771 - 1772] 0,,22643,1:19.660.099,7.666 us,0 B,,01,00,OUT txn, 0,,22647,1:19.661.096,1.002.958 ms,,,,,[2 SOF],[Frames: 1773 - 1774] 0,,22648,1:19.662.099,13.083 us,8 B,,01,00,SETUP txn,80 06 02 03 09 04 FF 00 0,,22652,1:19.663.096,2.833 us,,,,,[1 SOF],[Frame: 1775] 0,,22653,1:19.663.099,28.250 us,30 B,,01,00,IN txn,1E 03 53 00 46 00 43 00 33 00 30 00 20 00 4A 00 6F 00 79 00 73 00 74 00… 0,,22657,1:19.664.096,1.002.958 ms,,,,,[2 SOF],[Frames: 1776 - 1777] 0,,22658,1:19.665.099,7.645 us,0 B,,01,00,OUT txn, 0,,22662,1:19.666.096,1.002.958 ms,,,,,[2 SOF],[Frames: 1778 - 1779] 0,,22663,1:19.667.100,13.000 us,8 B,,01,00,SETUP txn,80 06 00 06 00 00 0A 00 0,,22667,1:19.668.097,2.812 us,,,,,[1 SOF],[Frame: 1780] 0,,22668,1:19.668.100,4.562 us,,,01,00,IN txn (STALL), 0,,22671,1:19.669.097,1.556.218.812 s,,,,,[1557 SOF],[Frames: 1781 - 1289] 0,,22672,1:21.225.316,13.000 us,8 B,,01,00,SETUP txn,80 06 00 01 00 00 12 00 0,,22676,1:21.226.313,2.812 us,,,,,[1 SOF],[Frame: 1290] 0,,22677,1:21.226.316,20.250 us,18 B,,01,00,IN txn,12 01 00 02 00 00 00 40 35 12 21 AB 01 00 01 02 00 01 0,,22681,1:21.227.313,2.812 us,,,,,[1 SOF],[Frame: 1291] 0,,22682,1:21.227.316,7.645 us,0 B,,01,00,OUT txn, 0,,22686,1:21.228.313,1.002.958 ms,,,,,[2 SOF],[Frames: 1292 - 1293] 0,,22687,1:21.229.318,13.000 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 09 00 0,,22691,1:21.230.313,2.812 us,,,,,[1 SOF],[Frame: 1294] 0,,22692,1:21.230.317,14.312 us,9 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 0,,22696,1:21.231.314,2.833 us,,,,,[1 SOF],[Frame: 1295] 0,,22697,1:21.231.317,7.666 us,0 B,,01,00,OUT txn, 0,,22701,1:21.232.314,1.002.958 ms,,,,,[2 SOF],[Frames: 1296 - 1297] 0,,22702,1:21.233.317,12.979 us,8 B,,01,00,SETUP txn,80 06 00 02 00 00 29 00 0,,22706,1:21.234.314,2.833 us,,,,,[1 SOF],[Frame: 1298] 0,,22707,1:21.234.317,35.583 us,41 B,,01,00,IN txn,09 02 29 00 01 01 00 C0 F0 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01… 0,,22711,1:21.235.314,2.812 us,,,,,[1 SOF],[Frame: 1299] 0,,22712,1:21.235.317,7.666 us,0 B,,01,00,OUT txn, 0,,22716,1:21.236.314,1.002.958 ms,,,,,[2 SOF],[Frames: 1300 - 1301] 0,,22717,1:21.237.318,13.000 us,8 B,,01,00,SETUP txn,00 09 01 00 00 00 00 00 0,,22721,1:21.238.315,2.895 us,,,,,[1 SOF],[Frame: 1302] 0,,22722,1:21.238.318,8.229 us,0 B,,01,00,IN txn, 0,,22726,1:21.239.315,1.002.958 ms,,,,,[2 SOF],[Frames: 1303 - 1304] 0,,22727,1:21.240.318,13.000 us,8 B,,01,00,SETUP txn,21 0A 00 00 00 00 00 00 0,,22731,1:21.241.315,2.812 us,,,,,[1 SOF],[Frame: 1305] 0,,22732,1:21.241.318,4.583 us,,,01,00,IN txn (STALL), 0,,22735,1:21.242.315,2.003.083 ms,,,,,[3 SOF],[Frames: 1306 - 1308] 0,,22736,1:21.244.319,12.979 us,8 B,,01,00,SETUP txn,81 06 00 22 00 00 A3 00 0,,22740,1:21.245.315,2.812 us,,,,,[1 SOF],[Frame: 1309] 0,,22741,1:21.245.319,51.062 us,64 B,,01,00,IN txn,05 01 09 04 A1 01 A1 02 75 08 95 04 15 00 26 FF 00 35 00 46 FF 00 09 30… 0,,22745,1:21.246.316,2.833 us,,,,,[1 SOF],[Frame: 1310] 0,,22746,1:21.246.319,31.750 us,35 B,,01,00,IN txn,02 06 00 FF 75 01 95 08 25 01 45 01 09 01 81 02 C0 A1 02 75 08 95 08 46… 0,,22750,1:21.247.316,1.002.958 ms,,,,,[2 SOF],[Frames: 1311 - 1312] 0,,22751,1:21.248.321,7.645 us,0 B,,01,00,OUT txn, 0,,22755,1:21.249.316,1.999.280.291 s,,,,,[2000 SOF],[Frames: 1313 - 1264] [Periodic Timeout] 0,,22756,1:21.280.324,1.984.279.979 s,,,01,01,[63 IN-NAK],[Periodic Timeout] 0,,22757,1:23.249.594,1.999.280.291 s,,,,,[2000 SOF],[Frames: 1265 - 1216] [Periodic Timeout] 0,,22758,1:23.296.603,1.984.279.979 s,,,01,01,[63 IN-NAK],[Periodic Timeout] 0,,22759,1:25.249.871,1.999.280.291 s,,,,,[2000 SOF],[Frames: 1217 - 1168] [Periodic Timeout] 0,,22760,1:25.312.883,1.984.279.958 s,,,01,01,[63 IN-NAK],[Periodic Timeout] 0,,22761,1:27.250.149,1.999.280.291 s,,,,,[2000 SOF],[Frames: 1169 - 1120] [Periodic Timeout] 0,,22762,1:27.329.163,1.984.279.979 s,,,01,01,[63 IN-NAK],[Periodic Timeout] 0,,22763,1:29.250.426,1.999.280.291 s,,,,,[2000 SOF],[Frames: 1121 - 1072] [Periodic Timeout] 0,,22764,1:29.345.443,1.984.279.958 s,,,01,01,[63 IN-NAK],[Periodic Timeout] 0,,22765,1:31.250.704,1.798.252.375 s,,,,,[1799 SOF],[Frames: 1073 - 823] 0,,22766,1:31.361.723,1.664.235.541 s,,,01,01,[53 IN-NAK], 0,,22767,1:33.048.954,,,,,,Capture stopped,[Fri 03 Jun 2016 12:01:34 BST] fwupd-1.0.6/plugins/ebitdo/data/update.tdc000066400000000000000000017532571325145456600205200ustar00rootroot00000000000000TPDC?cQW u  .% 1cQW 7  l @`.   `  9!- -`-  `8 @8`@ 8 @@q@@8m]`@ 8q8x8q`\8J qA$@q8q>`68̏8ֵq ' YxAa@vH@H@ `   @@3K@ @F@@`6@@`@` J À@;@ݔCB1@7JEJ J `J@ A-FU@BpB@B i @' `AOBAR `CEa¨R J 8yyaR @@[=G RU )@@ `@# /@ Kc.@PW S$A\AT>T `T\i\B=@BA~`8@B i\b1@AA\XE( 5E\@z{a\ sya"d@x@ !\"@"@BKBBJ >@JBp@U `  Jb@AAJ#`E53@@`;J J 8||E @=D=`=$8&`v` 8CZ`qi8aE@=|=`v!E@谀@g%BEJTJ  a ` B@x@A B@B E?k>`VM@aR @=m=#MFL@{l@ U!@B! B J B" "@B@Ua@ i@x@AAJFE&?aJPEJ@7aJ$ @p=#U`=$WE@@3b% @ @!@@@`@LHAR&J]J J `J @D-GH'`B$ @x@A AR( A@܀@R@aR) @=8= H*@T݀@H@ `@!H+ qT `T\i\, B@BHB@x@AA\- @EVbq \a\K^=#/ |@˘@~!\"0B7BBJ1 B@Bo@a@x@AAJ2`CE!SWaJaJ3 9@ptX`=J! 4@@a)"A5JHJ `J6 B@Bt dR@x@A AR7 .@E/ʀ aR8 ;R7р=l.n@nˀ@M"$;: /@CK )". .E !"!@  As@; = ; >@BN @x@A-As< @EYbZas= ;CZ`=$.@lB@!s ?BAB@BZ@x@AAJ/`EaJB Bm B@B@x@AAJn`CEJaJo 9 f$J#p <@i@!.# _4AqJյJ qr +@B@x@A ARs`CEpgaaRt 9q= cAu@T@ Z ,v B@B@JK[@x@Aw @A;,ha$APax 2k`=#`bVy@@!V |NzJ J  V{ +@ Bq! BS@x@A AR| .@EՀVaR} ; ՠ=ڀ= V(&R&Q~ < 8@׀@6N PT|րT!/UBQ@x@AA\Eclbq\a\ =+=&Q@@ QBBQ B@JB9@x@AAJ`CELmaJQaJ@JX n`=J&QC@ @ d @x@A AS @E}obh@@aS @=E=#@@A~S& C +B B@B@x@AAJ`CE;paJaJ 9W=J#@@$)AJ/J  +@RB@x@A AR`CEqaRbr aR 9R!=R#,"@Y@M@k  B@sB,-@x@A-As @Emrasdmsas \ =do=s#s$ <@n@ {%e @ B<B B@B@x@AAJE)saJTj:{ = =J$@@ @{'%A @J Z +@B@x@A AR`CE,taR @  AR 9  =" <@h@ "$R B J B@JB )@x@AAJ @E[uJJ" ; {^="@\@! =  A SJ  +@ B@x@A AR`CE9vaR Y!R 9j= R@ ~Z0 B@B@B@x@A @AҀP! ; =gwaA /%?$ <@Ϗ@  "6J;J$V B@B5@x@A AR`CEIxaVt!R 9O=R$R7@ K@ J$ 7K  ;G &u@  fC +iJcwkBSS<@x@A%AkETyakAk =€=k&`@ @ s!k @ `Bw B B@JB@x@AAJ`CEa|zaJv@ } #AJ 9Jp`=1@@!~R$ @^@!*ϰ@G :H ! XO +@Bo  @x@ADA .@E2aLk-lE@-b1A YS  A! .@FQ@ " @K@;0>A @@FP$ B@Bp@x@ADAaZ E TaLA( aL21@@=@: =Va&h=" R|@ & V^`{ @6N@ @  @*rA :@@M &) SiCS B@`BBA': `#TS@x@ADA @`E_aL3@$@d?Z!Q R@ B@x@ADRAKuV "B@l@dCk@m D B@x@ADREKaR"KF@@dG$RH BR@x@ADRIKBaR"J@`@dRK#L BR@x@ADRMKKa"RN@DC@dOB#RP BR@x@ADRQKn'RR@ي@dSE$RT B@x@ADRUKۺaR"KV@nҀ@dRWѠ#X B@x@ADRYK"aR"Z@@d[p#R\ BR@x@ADR]K1j'R^@a@d_ #R` BR@x@ADRaKñ'Rb@/@dc d BR@x@ADReKYaR"Kf@@dg0$Rh BR@x@ADRiK@aR"Kj@Y8@dRk7#l BR@x@ADRmKt'Rn@@do[#Rp BR@x@ADRqKhaR"r@ǀ@dsƀ$Rt BR@x@ADRuK]'Rv@@dRw#x BR@x@ADRyKC_QaR"Kz@V@d{#R| BR@x@ADR}KئE'R~@D@d#R BR@x@ADRKn9'R@@dF  BR@x@ADRK6.aR"@o-@d,$R BR@x@ADRK}"aR"K@u@dRpt# BR@x@ADRK.'R@@d#R BR@x@ADRK 'R@/@d$R B/@x@ADRKYTUA"K@K@dR0@ B@x@ADRKaR"K@Z@dƒ#R BR@x@ADRK'R@ڀ@d[#R BR@x@ADRK+'R@"@d!  BR@x@ADRKraR"K@j@di$R BR@x@ADRKCaR"K@@dR# BR@x@ADRK'R@E`@d#R BR@x@ADRKoIa"@@@dF$R B@x@ADRKaR"K@o@dRۇ# B@x@ADRKؕaR"@Ѐ@dqϠ#R BR@x@ADRK. 'R@@d#R BR@x@ADRKg~'R@4_@d^ BR@x@ADRKZraR"K@Ŧ@d1$R BR@x@ADRKfaR"K@Z@dR# BR@x@ADRK>['R@5@d\#R BR@x@ADRKO'R@}@d|$R B@x@ADRKCaR"K@ŀ@dRĠ# B@x@ADRKD8aR"K@ @d#R BR@x@ADRK\,'R@ET@dS#R BR@x@ADRKo 'R@ۛ@dG  BR@x@ADRK aR"K@t@d $RBR@x@ADRK3 aR"K@+@dRq*# BR@x@ADRK/{Z"R@r@d#R BR@x@ADRK'R@0@d$R B@x@ADRKZ aR"K@@dR1# B@x@ADRKQaR"@[I@dH#R BR@x@ADRK'R@@d\#RBR@x@ADRK'R@؀@dנ!(  BR@x` =R !&{(aR"K@ @d$R BR@x@ADR KDpaR"K @g@dR "( BR@x@ADR Kڷ'R@F@d!Q R BR@x@ADRKp'R@@dG$R B@x@ADRKGaR"K@p>@dR="  B@x@ADRK|aR"K@@dr!Q R BR@x@ADRK/p'R@̀@d$R BR@x@ADR!KeaR""@1@d# /$ B M/t@x@ADR%K[eY'R&@\@d'2$R( B@x@ADR)KMaR"K*@[@dR+ǣ#, BR@x@ADR-KA'R.@@d/]#R0 BR@x@ADR1K<6'R2@3@d32$R4 B@x@ADR5K*aR"6@{@dR7z#8 B@x@ADR9KEaR"K:@€@d;#R< BR@x@ADR=K'R>@F @d? $R@ BR@x@ADRAKpZ'RB@Q@dCH D BR@x@ADREKC"KF@q@dGݘ$RH BR@x@ADRIKaR"KJ@@dRKrࠂ#L BR@x@ADRMK01'RN@(@dO#RP BR@x@ADRQKx'RR@1p@dSo$RT B@x@ADRUK[aR"KV@Ʒ@dRW2#X B@x@ADRYKaR"KZ@\`@d[#R\ BR@x@ADR]KOa"R^@F@d_]$R` BR@x@ADRaK'Rb@@dc򍀂$d BK@x@ADReKޝaR"Kf@ր@dgՀ$h B@x@ADRiKE&aR"j@@dRk  @LAl BR@x@ADRmKm'Rn@Ge@dod!J Rp BR@x@ADRqKpzaR"r@ܬ@dsH$Rt B{@x@ADRuKn'Rv@q@dRw" x B@x@ADRyKDcaR"Kz@<@d{s;!Q R| BR@x@ADR}K0W'R~@@d$R BR@x@ADRKK'R@2ˀ@dʀ$ B@x@ADRK\@aR"@@d3$ B@x@ADRKb4aR"K@\Z@dRY  BR@x@ADRK('R@@d^#R BR@x@ADRK'R@@d耂$R BR@x@ADRK9aR"K@1@dR0# BR@x@ADRKFaR"K@x@d#R BR@x@ADRK`"R@G@d$R BR@x@ADRKq'R@@dRH  B@x@ADRKXaR"K@rO@dRN$ B@x@ADRKaR"@@dRs# BR@x@ADRK1'R@ހ@d #R BR@x@ADRK.'R@2&@d%$R BR@x@ADRK\vaR"K@m@dR3# BR@x@ADRKaR"K@]@dɴ#R BR@x@ADRK'R@`@d^$R BR@x@ADRKMa"@D@dRC  B@x@ADRKaR"K@@d#R B@x@ADRKFxaR"@Ӏ@d#R BR@x@ADRK#m'R@H@d#R BR@x@ADRKqka'R@b@dI$R BR@x@ADRKUaR"K@r@dRީ# BR@x@ADRKIaR"K@@dt#R BR@x@ADRK1B>'R@9@d #R BR@x@ADR K@ p,w4 @AC=DEGBHIKGLMOLPQSQTUWVXZ[[\^ _` | x t p l h d ` \ X T P L H D @ < 8 4 0 , ( $     !'                                  | x t p l h d ` \ X T P L H D @ < 8 4 0 , ( $   A @ avm k@Y@ `@JyX F B@aB b {@x@AD>EowaL@@==AC.)`A =^`{ @ V@ @a<.whU@Tp `mi B@B |!@x@ADAESaLAxA'AA =@`= S@@ SK=y !7 `S B@B @x@ADAEˁ kBQA =ҍa"@ɀ@'# }(:J0%Lg%IC%w0s*CZ B@Bt @x@ADAEDaLR'`c =Ϙ`="@ƀ@K=>  B@B !@x@ADAE(aL) a/a =="@X@ 1_C  B@Bu @x@ADAEA觠A[c @ B@B@x@ADAEbaL 7?D =l="@d@ !$1=oc a B@B@x@ADAEZad = %`=!I @n@ ' @ADj$5LgI65:J6 xD! " B@Bx@x@ADA#Eր7c$ ="$_%@^@ ! @=& c @' B@B@x@ADA(EӀ@Y ?a) =y݀="*@Ԁ@ /C+H$, B@By@x@ADA-E/bod. =ߕ`="/@G@ #"2R{yI2 cZA5 `$6 B@B@x@ADA7E}DaL@Yc8 =EN="9@E@A/XC:+; B@Bx@x@ADA<Eaa= =X@!I>@`@ +Q2.8wrm͸ @ 8A? @ B@BA@x@ADAAEoL z=B =aI$_C@ `@E @>ADh E B@B 5$@x@ADAFESL A8!!G = = H@@%A/CI `+J B@B@x@ADAKEpb !L =w`="M@n@&{$5pow 0y:ae6~вN!XANY$+O B@B@x@ADAPED)aL8 AQ =t%`=+$_R@k@ @>AS=A[T B@B@x@ADAUE(&&aL!(!(AV =/="W@X'@ *$҃/tCX Y B@B@x@ADAZE "1A[ =g1a!I\@߀@ +AYHL~x cҼN8kA[]. ^ B@B P@x@ADA_E2aL2(@c` =W<`=$_a@܀@ ! @>Ab c B@B@x@ADAdE=aLA0A8Ce =Ҡ="f@-@#V/2DgAh B@B@x@ADAiER>aB!)Aj =0YI`="k@P@&޺[b g/q0ɷ[E O$R4a& ]Al$m B@B@x@ADAnE JaLR0`co =,VT`="p@M@ '>AqL Ar B@B@x@ADAsEUaL) aaCt =="u@ @&/Cvnw B@B@x@ADAxEYÀbqAy =`a%z@m@%AB޴62\VpB Hqɐ&dY treA{ A| B@B|+@x@ADA}E{aaLrc~ =k`=$_@3]@]@d A B@BA@x@ADAExlaL C =AVx="@y@ &+#V(-`C A/I@GD B@B{@x@ADAE.4maA =:x`=!I@B2@ +,W @ $fxL>lAyO#" ^Ի ma& r1$+ B@B@x@ADAE쀈AA =7a @2/@dA.A[ B@B@x@ADAE}逈 0A =E="@@ /r B@BA@x@ADAEbAA =`=$_@@ &Ɗwtא1'oD:a& j A B@B@x@ADAEn]aLc =`= @@dAg  B@B@x@ADAERZaL j =d="@[@&$/)  B@B:@x@ADAEaD =`="@@&mhX5;ˌhiҖYl[V/a& AY B@B@x@ADAEC΁ c =a"@@dA=  B@B@x@ADAE'ˡ @Y  C =Ԁ="@Ẁ@&/XC  B@B@x@ADAEbA =_`= A@„@ AA!s.&'xzv33Xa& *+A. A B@B@x@ADAE?aL A =Z`= A@@dAA[ B@B@x@ADAE;aL 1A =E= @-=@ /C< B@ B@x@ADAEl a =@a"@@ ?ا{+2B:W U߬xA- cs B@x@ADA @EaLA1 a = ?=,`=+ @@dA Œ!]a B@B@x@ADAEҬ4 Ax!!D =@="@@ /Cn B@B@x@ADAEYhaA"&,A =o`= +@mf@&g] '=7pU 3=*P?a/7#N/a& =Ae$ B@B@x@ADAE aL2@c =l`= @]c@dAb$ B@B@x@ADAEaL A9AC =p'="@@&$/CC+ B@B:@x@ADAE.ف BQA =7"@B׀@%Awm8j.vs:Ԉυx9mBUAր$ B@Bg@x@ADAEaLR)`!A =`="@2Ԁ@dAӀ A B@B@x@ADAE|aL) aac =M="@@ }A/yC B@B}A@x@ADAEJab)qc =P`= A@H@ +th;"w܀:Fq{AI3a& S?AG + B@BA@x@ADAEnaL r1a =M'`= A@E@dAgDA[m@ B@BA@x@ADAER @sd =3 @츀@}妠V~&jwm&H@ U@ gCX$ B@B@x@ADAECs4aL1c>`= @ܵ@d<  B@B`x@9 A @E'p?aLm =b2K`= @)@Ъ1C. + B@DB@x@ADA E J =V/V  @&@d+ $ B@B@x@ADAE @Y+Axc =@="@,@+=ဂ B@B@x@ADAEWb )C =3b`=A @@ :L ;3jRUtiO(ũQD$ B@B:@x@ADAETcaLd =+m`= @@d疀 m B@Bm@x@ADAEQnaL)  c =[="@S@ gm/|C mR"e! B@B@x@ADA"EX oau# = z`= $@l @ +"SѻNV]#_|ŭU*a& A% & B@B+@x$ 9ADA' @EŀmF+( =a )@`@dA*Ac @+ B@DB@x@ADA,E A- = ẁ=".@À@ W/EC/C 0 B@BW@x@ADA1E-~b*A2 =ڄ`= 3@A|@&+? B@B$@x@ADA@E A"1"DA =a B@@ @ h+td^F挼nL[s,[."'FdAC젂@4D B@B sd  @'@x@ADAEEmaL2@dF =`= G@@ @=9~Hf适$I B@AbB@x@ADAJEQaL AAcK =="L@@+ @/LHCM N B@B4@x@ADAOE_aB QDP =f`="+Q@]@& ja`!-lI)QTƘ` ARXS B@B+@x@ADATEBaLR`dU =c`=$_V@Z@ @=W< X B@B@x@ADAYE&aL) a acZ = ="[@V@&A/rC\ ] B@BW@x@ADA^EЁ b:q D_ =^a%`@΀@ ~ ,Lо:6() aSnX>]b[z@Aa- Ab B@B@x@ADAcEaLrdd =U`=$_e@ˀ@dAf g B@BA@x@ADAhEaL :ci =ȏ="j@,@ :/Ckl B@Bw@x@ADAmEAa*tn =CH`= o@?@% 4_H͇pȒqe 'ؒdp-q B@B@x@ADArE Ads =/Ea t@<@dAu;A[v B@B$@x@ADAwE *cx =a"y@~ /fdzm{ B@B@x@ADA|EXLAj} =Z@ ~@l@ +A'>oݩ3VxY:0 9@ DF+د$ B@B+@x@ADAEjaLd =`= @\@dA$ B@BA@x@ADAEgaL c =!sq= @h@ W/CB B@BW@x@ADAE-#a:c =)`="+@A!@!0<&k^0jxq ;F3٣۲ h&a& /A @0 B@B@x@ADAEۀa =&)a @1@ # @>  B@B@x@ADAE{؀) :a =@="@ـ@$/ٌCA[ B@Bc'@x@ADAE*b2}P = 5`=G d@@ AIBQJ;:RzJ_ W&@Z A  B@B$@x@ADAEmL6aLT =@`=$_@ @+ @=$f  B@B@x@ADAEQIAaL 3+A =S="@J@ :&+/XC A B@B@x@ADAEBa A = M`=!I@@&­c`&.i:ʫXa W$+ B@B@x@ADAEB A d =Xa$_@W`@ @>A;A[ B@B@x@ADAE&L!!c = À="@V@&/   B@B@x@ADAEuYbA"1D =]|d`= @s@&:p2A)4^Tĝ?^s,u_W"-a& F+- B@B@x@ADAE.eaL2@d =Uyo`=$_@p@dA$ B@B@x@ADAE*paL AAAc =4= @+,@&/RC+ B@B@x@ADAE怈B#QD =6{a"+@@ v̠-t.ɸӟ>/^H&Ia& اA$ B@B@x@ADAE|aLR`d =*`= @@dA  B@B@x@ADAEЛaL) a#ac =="@@ /.Cl B@B"Y@x@ADAEWWab+qj =!A ^`= +@kU@ {{mԟLP| z"BS(*y "AT  B@B@x@ADAEaLrd =Z`= @\R@dAQA[ B@BA@x@ADAE aL +c =w="@ @ .CB B@B@x@ADAE,ȁ #f+ =Ϊa @@ƀ@ q,gebjQvG51'L|'䫼a& 1AŠ@0`)  ` B@Bq@x@ADAEaLAd = ˵`= @4À@ # @J  A B@B$@x@ADAE{}aL #c =?="@~@#V%o/C B@B@x@ADAE9aA;3M =?`=!I@7@ +T7p@pR3ơW=|0\ a& A6$ B@B+@x@ADAEld =<$_@4@dAe3$ B@BA@x@ADAEP r =="@@&.@C  B@B@x@ADAEשbc = P`=H  @맀@&c' wjVQ"uK깓xRW5A AW+ B@Bc'@x@ADAEAbaLc =`= @ۤ@ @=g ; A B@B@x@ADA E%_aL4c =\!`="@@ *''W dr_H:Ƶ'C]N0EL2@d1 =*aI$_2@[@dA3$4 B@B@x@ADA5E+aL A B@B@x@ADA?E%8aLR`d@ =pB`= A@0h@ ! @JABg AC B@B@x@ADADEz"CaL a$acE =O,="F@#@/|9CGH B@Bt @x@ADAIEށ b qjJ =Na";@܀@$҃5ȋMΣ S./g6v?d @`a& ALۀ +M B@B$@x@ADANElOaLAYirdO =Y`=$_`= @3P@ـ@dAQeؠ@mR B@BA@x@ADASEPZaLE cT =AV =+ AU@@Ġ/nCV W B@Bw@x@ADAXEN[a$IAY = Uf`= Z@L@ +' @Ġ LYC )c:#T,jr#%A[V$+\ B@B+@x@ADA]EAgaLd^ =Rq`= _@I@dA`: a B@B}@x@ADAbE%raL Acc = ="d@U@ /] Ce +f B@BW@x@ADAgE A$ˆH)d̴1X5A@4A B@BM@x@ADAEk;aL2?A =`="@~@ #$>1e} `au-j B@B @x@ADAEO8aL A%AA =B= @9@ @/.C + B@B @x@ADAE BQf+ =a"@@&uEFo/x}JطQL)d/a& gAV+ B@B@x@ADAE@aLR:$ =~`=$_@@ &+ @>J: ` B@B@x@ADAE$aL aac =="@T@&/KC  B@B@x@ADAEdab%q%C = gk \ #%@b@zLg ~MV*xRpgD_lp |A+ + B@BzL@x@ADAE aLr5$ =Sh`=$_@_@ @>AA[ B@B@x@ADAEaL %%A =#=+)@*@ * @A/PC B@B Y@x@ADAEՀ=A = 5!a!I@Ӏ@&('y0~eGP# * xlA- B@B@x@ADAE"aLg/$ = {-,`=$_@Ѐ@dAϠ B@B@x@ADAEϊ-aL =c =="@@ /@Ck B@B@x@ADAEVF.aA5C =M9`="@jD@ ,W$+A-əir}ndBYd;D}&bAC$ B@Bt+@x@ADAE+J$ =IDa"@ZA@dA@ B@B 'M@x@ADAE c =mE"+@~&/C@ +`m0< B@B@x@ADAE+L=C = Pa"@?@&Z{gdFEHЬKii:ut%DK(A  B@BA@x@ADAEoQaLA$$ = ׺[`="@3@dA  B@B@x@ADAEyl\aL c =Jv="@m@&A/YCA B@B@x@ADAE(]a5%C = 5.h`="@&@&l A؄9;$K:3݁=]8ƭJA%  B@B@x@ADAEk%A = +s @#@ ,W @>d"  B@B@x@ADAEO 6&A ==+"A @ހ@ @҃/C   B@B@x@ADA E՘tbp !  @A =`="@햀@ CX5ܝUzAT fB vndR@ AY$+ B@BM@x@ADAE@QaL d = ~`=$_@ٓ@ ! @>9 Œ B@B@x@ADAE$NaL)Ax!!c =@W="@TO@&/~C  B@B@x@ADAE aA">1>D = _`="@@ :#+zG mܡ /$ oW_4ћ.A+ B@B@x@ADA$h`E 2@d! =S a""@@ PA# $ B@DB@x@ADA%E  A6AiA& =Ȁ="+'@)@&/C( +) B@B@x@ADA*EzbBQc+ = 0`=",@x@&-Av Bq;cL)Z;4A- A-. B@Bx B w6@x@ADA/E2aLR6`c0 = {(~`=)1@u@ &+ @JA2t 3 B@B@x@ADA4E/aLaqG5 =`="6@i@A}:Q&lۙjgmRS俕8G>7zL7耂 8 B@B@x@ADA9EaLrd: = `=";@Y@ P<倂 = B@BW@x@ADA>EaL c? =p= )@ԡ@+/zLA@+B B@Bw+@x@ADACE*\a}.DD =b`= E@>Z@&j.="<6%bbf GaGFY$AG B@BM@x@ADAHEaLdI =_`= J@2W@ P1?VA[L B@B}@x@ADAMEyaL .cN =E="O@@ !#VAĠ/MCP+`B@x@ADARÉ WcS = 5a"T@ˀ@ 'AT? CA R<%A#6| z#AUʀ$V B@B@x@ADAWEjaLaX = `="Y@Ȁ@ !$>:Zdǀ [ B@BW@x@ADA\EN]@T a] ==G@Bgb^@~@ /C_ +W` B@B@x@ADAaE=a6IAb =D `="c@;@&ݾm.a/\'d bxV[ !;a& AdU#bXe B@Bg@x@ADAfE? cg =}Aa$_h@8@ # @(&_a,Ai9 j B@@B@x@ADAkE#  6cl =="m@W@&/)Aná$o B@B@x@ADApEb>cq =^#`="r@@ 'AT]S#eCW E9@V~|Kp9:a&  As* t B@B+@x@ADAuEg$aLޗv =R.`=$_w@@ ! @>Ax y B@B@x@ADAzEc/aL A?a{ =m=+"|@)e@ &+ @/ C}d~ B@B@x@ADAE0aIA5 (&;`=!I@@ @ m;ߠθk }q 2!/0= IA@2i7 A B@BM@x@ADAE׀  c =#Fa$_@@ `@>A  B@B@x@ADAEԀ?!!C =ހ="@ր@҃/CnՀ$ B@B`@x@ADAEUGbA"'1'A =R`="@i@ 'g=x"sT1 R]hB!d"  ֧AՍ$ B@B@x@ADA?j`EHSaL2@d =]`="@X@ !$>A  B@DB@x@ADAEE^aL) AA'Ac =lO="+@F@&/ li? B@B@x@ADAE*_aB?Qa =j`="@>i`@ '# *;C"EnB"D;  B@B(@x@ADAELR`d =uaI$_@.t`@ `@>A  B@B@x@ADAExL a?ac =M="@@ (!$A/C B@Bg@x@ADAEqvbbqIA =x`="@p@ 'iuc?T#J *T(a& Ao  B@B@x@ADA=`Ej*aLrd =u`= @m@ ! @>Agl  B@DB@x@ADAEN'aL C ="1=+"+@~(@ /C' B@B(@x@ADAE ?/A =a @@ # @A dn}Wmx?Urˡ-a& \AT$+ B@B@x@ADAE?aLd>`=$_@݀@ # @>A$8  B@B@x@ADAE#aL ?c =="@S@ !A/SpC  B@B@x@ADAESaAj =ZZ`="@Q@ 4Zt~^t& rRc΃y{ ea& )A* B@B@x@ADAE aLd =RW`="@N@ !# a,g A B@@B@x@ADAEaL$c ==$_+@, @&/C +W B@B@x@ADAEĀoCc =0a"@€@&$zN<ܭ<Yff9Bk'4"Aa& CA@0 B@B@x@ADAE|aL(a =+`=$_@@ ' @JA羀  B@B@x@ADAEyaLa =="@{@&/oCmz$ B@BW@x@ADAET5a7M =<`="@l3@ '&lӠz%EvX-'X%1-`a& A2  B@B+@x@ADAE퀈 z% =8$_@X0@ ! @=A/  B@B@x@ADAE 0A =k=+"@@ `@/kC?  B@Bs$@x@ADAE)bA =֬`="@=@ ##!#f9tƬPü'F-FA$+ B@ B(@x@ADAE^aL E B@x@ADAEx[aL !!c =@e="@\@ !/C B@BW@x@ADAEa"1 C = `="@@%t%e 1~⌥ܬ撓(ٹ'ւ bA $ B@BDK@x@ADA Eiπ2@A =a$_ @@ &+ @>Ac  B@B ; @x@ADAEM AAc =&ր=$_@}̀@Gag/NC +A B@B@x@ =A @EԇbB Qa =%`="@腀@&$ڶ-,Ӓ+Jg:&[ec` zT@0 @ J B@DB"Y@x@ADAE>@&aLR.- =|0`=$_@؂@ ' @>A8  B@B@x@ADAE"=1aL a ac =F="!@R>@ !$Ġ/D" # B@B@x@ADA$E bq% =]A;cA[< B@B@x@ADA=E`aL 0r> =(=+"?@@ ! @A/C@iWA B@B@x@ADABETځ A C =ka"D@h؀@&=Et4c?n?֊tM7&K\ E׀$F B@B 6h@x@ADAGElaL0cH =v`="I@WՀ@ &+>JԀ K B@B@x@ADALEwaL6hgM =Q`=$_N@=I@ A-)}Gom\we[h^{UDDOH WP B@B@x@ADAQEaL$R =N`="S@-F@ ! @+=TE U B@B@x@ADAVEwaL? cW =D ="+X@@ $#VǶ/bCYZ B@B@x@ADA[E 8C\ =ša"]@@ #_oЙμ1/ {xrb,a& A^~ _ B@B@x@ADA`EitaL Aa =`=$_b@@ # @=cb d B@BW@x@ADAeEMqaL 9Af ="{=+"g@}r@ ! @Ġ/tCh i B@B@x@ADAjE,a))Ak =3`="l@*@ +P}O&'hJٍ@) X2Lj(wAmS$+n B@BW@x@ADAoE>  dp =|0$_q@'@ ! @>Ar7A[s B@B@x@ADAtE" !)!cu ==+$_v@R@ /Cw x B@Bm@x@ADAyEbA"1Dz =]`="{@@$[zJ|XRq=r 7m>{<a& TA|)} B@B$@x@ADA~EVaL2@d =U`=+$_@@ # @>A A B@B 2^@x@ADAERaL) AAAc =\= @'T@PA/xCS B@B@x@ADAE~aBQj =&`="@ @%AH\zGnY᣶SQl E.a& > @0 B@Bo @x@ADAEƀR`d =$_@ @ `@>A  B@B@x@ADAEÀ aa9G =̀="@Ā@ &+$/fDhA[ B@B4@x@ADAESbb qj =`="@g}@JA4{Ϡ&ʬi} a&  |  B@BJ@x@ADAE7aLrd =&H@Qd_@Wz@$=y  B@B@x@ADAE4aL  c =k>="@5@ /A&>A B@B@x@ADAE( j =a"@<@&Jv,M5JEGPnlea& mf+퀂$+ B@B@x@ADAEaLAd =`=$_@-@ PAꠂA[d B@B@x@ADAEwaL c =@=+)@@ /lW B@B@x@ =A @E`aA c = ?=g'`="@_@&gtkvPY]wsL T VJ~^$ B@B@x@ADAEh(aLa =d2`="@\@ #$JAb[  B@B@x@ADAEL3aL  M = = @|@&g/zC +W B@B@x@ADAEс 9 A =>a"@π@&$!`V}[8m-}x77;TKeCS+ B@BE@x@ADAE=?aLc ={I`=$_@̀@ PA7  B@B@x@ADAE!JaL@Y 9c =="@Q@&$/C  B@BM@x@ADAEBKa9!D =TIV`="@@@ #&lMMQ[Xy}Wˀ_`Aa& cA( + B@B@x@ADAE  =PFa @=@ PA  B@B@x@ADAE  :"C =ba+"+@'~&/C B@B@x@ADAE}L*A = &m'@@ YĪ6>bԥl1`DKrA - B@Bu@x@ADAEknaLA d =x`= @@ @+=$᭠A[ B@B@x@ADAEhyaL !*!c =r="@i@ &+$/Y^Ch B@B@x@ADAES$zaA"1 =+`="@g"@&Ӧ` (Z` sa& BA!$ B@Bm@x@ADAE܀2@d ='a"@Z@>A[ B@B @x@ADAEـ AAc =n=$_A@ڀ@&/\=  B@B@x@ADA  E(bB:Q2IA =`="@<@ A O{χExL @ yD%zc B@DBE@x` =A @EMaLR`d = ?=И`=$_@,@ ! @>A A B@B@x@ADA EvJaL a:ac =KT=" @K@ A/CUC  B@B @x@ADAEab"qG = `="@@ #&lk(-fU/SDGya& ~A}  B@Bv@x@ADAEhrd = $_@@ # @>Aa  B@B@x@ADAEL "c =ŀ=+"@|@ :! @J/RC  B@BJ@x@ADAEvb IA =}`=" @t@ $X4^=U7>xc:a396^+U*A!R$+" B@B@x@ADA#E=/aL d$ ={z`=$_%@q@ ! @>A&6 j@' B@B@x@ADA(E!,aL) c) =5="*@Q-@ /+ , B@B@x@ADA-E Aom. =\a"/@@ +#+A_BFAв9Y?69fa& ?0(1 B@ B+@x@ADA2EaLd3 =P`="4@@ #=$5 !U 6 B@B@x@ADA7EaL c8 =Ʀ="9@&@&g/G?: ; B@B@x@ADA<E}Xax= =5_`=$_>@V@&k\O־"[u^S(/ua& &QIA?U@ B@B@x@ADAAEaLdB =%\`@$_C@S@ &+ @JADR AE B@B@x@ADAFE aL cG =="H@@ &+#V/}CIgJ B@B@x@ADAKERɁ :L =  a"M@fǀ@ #AƭFQii~ӭN˺_$ $ANƀ +O B@B@x@ADAPEaLAQ =`=$_R@VĀ@ # @=ASÀ T B@BA@x@ADAUE~aL ;#AV =u="W@@ ! @҃/nCX=Y B@B@x@ADAZE':a A[ =@)`=!I\@;8@ m25!vJYMaXғ! A]7$+^ B@Bm@x@ADA_E d` ==4$_a@,5@ ! @>b4 c B@B@x@ADAdEv !;!e =B="f@@ /Cgh B@B@x@ADAiE5bA"1cj =@`="k@@ +#$!Nee?@Rik9JLEa& Al}$m B@B+@x@ADA&`EgcAaL2;@co =K`=+$_p@@ # @>Aq`Ar B@DB@x@ADAsEK`LaL; AQ3*t = "X`= u@@ ! @H~{8rPmM\9V=6C CvR$w B@B{  @x@ADAxE<ԁ R`dy =zc"z@@ $ @>{6 W| B@B@x@ADA}E ѡ @Y aac~ = +ڀ="+@PҀ@ !B/nC  B@B@x@ADAEdbb#q+D =Wo`="@@AĠzꬷXoQ`c!jxeD' yA'  B@BA@x@ADA. EEpaLrdDIOz`= @@@VԒ&+ @> & DBW@x@@A EA{aL #cK="@&C@`ڥ/CBc DB@x@ADA @E|D =%a"I+@`@B'#+,$5MP0 zk L AF@2 @ ` !@DB@x@ADAE絁LAdM%aIG@`@d_AW@`@ #>A!  B@B@x@ADAE˲L c = =+"@@ @+A/kCgN B@B@x@ADAERnbAom =u`="@fl@EE$*8?fhT~\:T;kFS L ZAk$ B@BA@x@ADAE&aLd =q`="@Ui@ !>AhA[d B@B@x@ADAE#aL c = l-="@$@h&+/vC<  B@B@x@ADAE'߁ { =a!I+@;݀@&_Vi`cėh~YLa& A܀+ B@BwN[P@x@ADAEaLd =`=$_@+ڀ@ # @=ـ  B@B@x@ADAEuaL c =F="@@KqO!#V/C B@B@x@ADAEOaq om =V`="@N@ +'SW]1ı _Ki--|B#2L@!~#;YAM + B@B+@x@ADAEgaLOm =S`=$_@K@ ! @>A`J  B@BA@x@ADAEKaL ,A = ="@{@ /uC  B@B@x@ADAE $c =a @往@ +# @$+SV+ɰ|-Zd+hC%} L ۖA lQ$+ B@B@x@ADAEA @ B@B}@x@ADAE  i AxAAc =@="@%@|Z/瀂 W B@B@x@ADAE|bB,Q J =$`=%@@p# @A\[co -QApa& t\@0 B@BM@x@ADAEZaLR`d =`=$_@@ # @>A A B@B@x@ADAEWaL a,ac = a="@X@A/ʈf  B@BM@x@ADAEQ abq4D =+`="@e@ +"^+.iipM2_5XE.a& rM  B@Bu$@x@AD>"Eˀrd m6$_@U@ ! @= `iF B@B`x@9 A @EȀc = ?=lҀ="@ɀ@&/3^C@  ! BA@x@ADA E&7bc = B`=% @:@C# @҃P[E̴벀Ž/2&NLV 6A $+ B@B`@x@ADAE/5 A0 B@B@x@ADA1E}aL d2 =$="3@O@#V/IA4 A5 B@B@x@ADA6Eց  c7 =[݈a"8@Ԁ@ 'AK}d" - dmN0r\D41a& f=9& : B@B@x@ADA;EaL< =Nړ`=$_=@р@ ! @>A> ? B@B 'A@x@ADA@EaL F+A =ŕ="B@%@ W&+ @/liCD B@B|@  @'@x@ADAE@/ @{GalcF =,N`=!IG@E@ # @`[qV ɥ^o-@ zF+HD-I B@DBg@x@ADAJEA CK =$K$_L@B@ # @>AMAA[ ` $N B@B@x@ADAOE !!dP = a"Q@~ !/CRfS B@B@x@ADATEQLA" 1CU ='V@e@ +ۢ~*l*=401oJ a& 'AWѵ$X B@B@X+@x@ADAY@/ EpaL2 @f+Z =`=+$_[@X@ ! @>A\AG `@  ] B@DB@x@ADA^EmaL AAd_ ={w="`@n@7/C Ca;b B@B@x@ADAcE&)aB Qcd =/`=%e@:'@&  ly’'!0̅*D}f&$g B@B+@x@ADAhEဈR`ai =,$_j@*$@ # @>Ak# l B@B@x@ADAmEtހ) aadn =A="o@߀@&A/U@rm B@x@ADAr! @Ebb=qas =`="t@@ '$F;t'B|Nb QNrLgF+u{ v B@DBAjA@x@ADA] EfRaLraE`=$_B9@@ @=z!G_ 0& DB@x@ADAq( EJOaL =aT|Y="~zP@ :&+ @/C-C g4 DB@x@ADA? E a=%M`="A@@&$*ox+퐭&FpԿ@ AP$+ B@DBb@x@ADAE;Á Ac =y b@$_K{@@ # @=4@G B@B@x@ADAiq E 6h=%C@mI^a" @y@ !pc õkDWXD'[hDy@ bC& DBd@x@ADAo E4aLAN `="@v@ )A> AG B@DBAbB!:@x@ADAE0!aL d =:="@$2@ !B/C1 B@BF @x@ADAE{쀈Wc =,,a!I+@@ iзƒuDF!"LKMZ$*`~n! jA适$ B@BJ@x@ADAE-aL5a ='7`=$_@@ ! @J怂  B@Bg#@x@ADAEɡ8aL) d =="@@ /OFCeW B@BM@x@ADAEP]9a5c =cD`="@d[@ #$AjEcB)rli^7'W|C2v! nw$Z `XF B@BP@x@ADAEEaL-.IA =`O`=$_@TX@ # @>AW  B@BA@x@ADAEPaL A =g="@@ ! @/}P; B@BS@x@ADAE%΁ p}.c =[a!I@=̀@ +l=;}NN>Ju%fx! F+ˀ$+ B@BA@x@ADAE\aL6  =f`=$_@*ɀ@ @>Ȁ  B@B@x@ADAEtgaL !!d =@="@@ .>C B@B@x@ADAE>haA"61c = Es`="@=@&-[!D% QHr38yYL-' A{<$ B@B@x@ADAEe2@a =B~a"@:@dA^9A[ B@BsB,X@x@ADAEI AAd =="@y@&/TC  B@B@x@ADAEЯbBQc =y`= A@䭀@ @h$Y}Q4be f;/A 'p(raEAPA[ B@Bp@B J@x@ADA@/ E:haLR`c =x`=)A@Ԫ@ @=:4AG B@DB@x@ADAEeaL) aaa =n="@Nf@+/iC  B@B@x@ADAE abqa =R'`="@@&T>]\)d?$*.]ݥJİAm,a& iA%  B@B@x@ADAEف r&a =M$$_@@ @>  B@B@#A@x@ADA@/ EՁ  a =߀="@$׀@&/Cր B@DB@x@ADAEzb}&a =/`=%@@ }p1=lkckQ̼63n A- B@B}@x@ADAEIaLA>U =#`=$_@@dAދ  B@B@x@ADAEFaL c =P=" @G@&/CeA B@Bx!+A@x@ADAVEPaAc `="@d@ +5o}yodHuK6꘧Ng5ֳ'ĸ9m- A`$ B@B+@x@ADAE &D =`" @S`@dA A[ B@B@x@ADA EL d =j="@θ@&/C:W B@B@x@ADAE%sbc =y`= A@9q@&$"+<O0[N113І]ܠN' = 0 `= (@ހ@dA)^ A* B@BA@x@ADA+EI aL J, == -@y@ Wg/EqC. A/ B@BW@x@ADA0ET a?c1 = [`="+2@R@ +dF FDsaUΛFT}L>&̉h  43O$+4 B@B+@x@ADA5E: aLA c6 = xX"`= 7@O@dA83 9 B@B@x@ADA:E #aL?!!a; =="<@R @ /v`=> B@B@x@ADA?EŁ A"1a@ =M.a"A@À@&l:g+ނ(|<O/F+B%@4C B@Bp@x@ADADE~/aL2@'GE =Q9`="F@@dAG H B@B@x@ADAIEz:aL AAAcJ =="K@#|@g/(CL{M B@B@x@ADANEz6;akJBQcO =3=F`=!I:P@4@%-"yܵN)?s, زa& AQ3$R B@B-@x@ADASER`DT =":Q AU@~1@+ @+=V0 +W B@B@x@ADAXE뀈) aadY =="Z@@ A/C[d\ B@B@x@ADA]EORbbqc^ =]`="+_@c@ d ƾ*5o>Z.Aj{[2M" sA`Ϥ a B@B@x@ADAbE_^aLIderf+c =h`=$_`= @3d@W@ @>e 5`B@x@ADAgE\iaLADdh =@jf= i@]@ :/DKj:Ak B@B@x@ADAlE$jacm =u`="+n@8@')Cؑ 1)寋cb(Ja& VCo$+p B@B@x@ADAqEЀcr =$_s@)@dAt u B@B@x@ADAvEs̀ aw =?׀="x@΀@ .>yz B@B@x@ADA{EbAa| =`="}@@&lA^ WvlObaLg,(t`aL$c =H="@|?@/tC$ B@B@x@ADAE oc =a!I@`@&H%$~ovLL&UlVm7AS$ B@Bm@x@ADAE9L*'c ={aI @@+ @+=7  B@B@x@ADAEaLa == @Q@ `A/C + B@B`@x@ADAEjaG =\q`="+@h@ ^)c٪4vy?0;@C9?!78a& Ar(  B@B@x@ADAE#aL zA =Ln`=$_+@e@ @> A B@BA@x@ADAEaL A =)= @#!@ M/r  B@B@x@ADAEyۀ0A =.a"+@ـ@&:ѺL[U#ˀ #O< +BoЕ F+؀$+ B@B@x@ADAEaL A ="`=$_@~ր@dAՀ  B@B@x@ADAEȐaL9o# 8!01A =R`="@cJ@ :fl/RChɾ;8v?;ȷ .I  B@B @x@ADAEaL28@f+ =O`="@VG@dFA[+ B@B}@x@ADAEaLAxAC)A =@i ="@@ 1/49 B@B@x@ADAE$ B8Qc =d@ A@8@Ġ欫tna'ivsk_?g6_9Q M0giS$ B@B@x@ADAEuaLR `C = `= @(@dA[ B@B@x@ADAErr aL) aaA =?|= @s@&/o B@B@x@ADAE-ab qc =4`="+@ ,@  Ġo[cEY9JN∂Y2Ga& py+ + B@Bt @x@ADAEd怈r0 =1$ @(@dA] A B@BW@x@ADAEH  D =="@x@ WA/p  B@B@x@ADAEΞ%b0c =0`="+@✀@ +t~ }\lR(zzfLy!haPN$+ B@B+@x@ADAE9W1aLA(C =w;`= @ә@dA2  B@B@x@ADAETE8 R)`!LW? =vG @@>@dAA2 B B@B@x@ADACE ) aadD = E@L~ W/oCF G B@B@x@ADAHELb)qcI =Ka"+J@@!+z;lfWiHfd8qH!a& tAK# AL B@B-@x@ADAMEmaLr jN =`= O@@ @=P ` zLQ B@B@x@ADAREiaL dS =s="T@"k@+ @A/CUjA[+V B@B@x@ADAWEx%a cX =-,`="AY@#@ A&|x[ |Q<<~t'iMAG"L?a& .OAZ"-A[ B@B@x@ADA\E݀1f+] =!)$_^@} @ @=_ ` B@B@x@ADAaEڀ Jb =="c@ۀ@ A/cCdce B@B{@x@ADAfEMb1cg = e@"+h@a@oJ l|Y`Z?aHpM))@L@ Ai͓ +j B@B@x@g =Ak @ENaL!)Cl =`=$_m@Q@dAnAo B@DB@x@ADApEKaL Aq =tU="r@L@ /ޗs8t B@B@x@ADAuE#a!cv = `=*w@7@ AQXJ7+ =,, 9Ǫ饈wa& Dx@0y B@B@x@ADAzE1t{ = & |@'@ # @JA}A[~ B@B@x@ADAEq) d =6ƀ="@@ +!#V-/C  B@B@x@ADAEw'b1c =~2`="+@ v@ TоoB\Ztj-fmA (*Axu  B@B@x@ADAEc03aLG ={=`=$_+@r@ ! @>\  B@BA@x@ADAEG->aL a = 7=$_@w.@&g/wC A B@B@x@ADAE a =~Ia"+@@ #!00s=774;u6bta& GAM$+ B@B@x@ADAE8JaL*  =uT`=$_@@dA1  B@B@x@ADAEUaL!!c =駀="@L@ A/YkC  B@B@x@ADAEYVa"*1c =S`a`=$_@W@&aיbz{mgkxLZSԀ a& J" A B@Bym@x@ADAE baL2@a =O]l`= @T@dAA[W B@B@x@ADAEmaLAAd =="@!@ /D B@B@x@ADAExʀB2Qz =$xa"@Ȁ@ A8h0fOڏ(jm Ĕ5Aǀ$ B@B@x@ADAEyaLR`c = ΃`="@|ŀ@dAĠA[ B@B@x@ADAEaL) a2ac = = @@ /lCb B@B@x@ADAEM;abqc =A`="@a9@ L rWm\Y܇4\|5A8 A B@B@x@ADAEra => A@Q6@dA5 A B@B@x@ADAEDå)a =ʲ @6@ U.Nu8ڼpCv E e3:A *UC@2 B@@iB$@x@ADAEdaLf+ =`= @'@dA[ B@B@x@ADAEqaaLAxc =@5k="@b@ +:/yC + B@Bom@x@ADAEac =#`= @ @ [ڀ-*Fo66j* |spta& gAw$ B@B}@x@ADAEbՀW:A = a @@ +# @$=[  B@B@x@ADAEFҁ  d =܀="@vӀ@ !#VĠ/ KC  B@B@x@ADAE͍bWc =`="@ዀ@ [=%DL/a&  AM B@B@x@ADAE7FaLf+ =u`="@ш@ !> 1A[ B@B@x@ADAECaL) d =L=$_@KD@ /4!C  B@B@x@ADAE c =Oa"@`@ #!+4X3o&hȻ{ a& D?"  B@BC@x@ADAE L +IA =JaI$_@`@dA   BA@x@ADAEL  =="@!@A/rD B@B@x@ADAEwob c =#vf@"@m@&Զo?Ckh<43bZX o G l- B@B@x@ADA E'aL c =s`= @|j@dAiA[A B@B@x@ADAE$aL !!a =.="A@%@&/ b B@B(@x@ADAEL "1a =a +@`ހ@&$r˹ >{{nY2e@a& =F+݀$ B@BA@x@ADAEaL2#@#IA = '`= @Tۀ@dAڠ  B@B}@x@ADAE(aL AAc =d="!@˖@ /˔C"7# B@B@x@ADA$E"Q)aB#Qc% =W4`="&@6O@ 4N3M 8je `f5r}oA'N$( B@B@x& 9ADA) @E 5aLR+`;D* =T?`="+@%L@ /m$m=$,K - B@DB@x@ADA.Ep@aL) aad/ === 0@@&$/C1 2 B@B@x@ADA3E b+qc4 = Ka"5@ @ r#!ĠJA #DN][7ctbDQ#q A6w 7 B@Bc'@x@ADA8EbzLaLrom9 =V`=$_:@@ ' @>;[ < B@B@x@ADA=EFwWaL d> =="?@vx@ #! @҃/"Y@ A B@B&@x@ADABE2XacC =|9c`="D@0@ + 8#;83{ZEnJI XSa& 9WDEL$+F B@B+@x@ADAGE7 IAH = t6n$_I@-@ ! @>AJ0K B@B@x@ADALE  dM =="AN@K@ W/{CO P B@B@x@ADAQEobcR =Rz`="S@@&bجX5q6AX e ZL>a& xAT!$U B@B@x@ADAVE \{aLA "  db3omW =J`=$_`= @3zLX@@ # @>AY@Z B@B@x@ADA[EXaLd\ =AVb="]@ Z@ !A/C^Y_ B@B@x@ADA`EwaA3ca =`="b@@:tVp'jk{7$jVնc /XAc@2d B@BJ@x@ADAeÈ;jf =a"g@z@ PAh i B@B@x@ADAjEɀ)+Axdk =@Ӏ="+l@ʀ@ /tCma n B@B@x@ADAoELbq ;cp =`="q@d@&,y x8hH)Y=ЈW0X)a& (rЂ s B@B@x@ADAtE=aLu =`=)v@P@ @JAw x B@BA@x@ADAyE:aL Omz =kD= {@;@ 3/D|7A} B@B@x@ADA~E! Ac =a"@5@ P'A^ `ڔ;Klc߸.hznE:Q6=A$ B@B@x@ADAEaL4 c =`=$_@%@ ! @>  B@B@x@ADAEpaL !!a =<="A@@&//C  B@BwJ@x@ADAEfa"41a = m`=$_@ e@ +# @߸0f_ #z1e] qvd$ B@B}@x@ADAEaaL2@a =j`=$_@a@ ' @>ZA[9 B@B@x@ADAEEaL AAa =&="@u@ !/q  B@BA@x@ADAEׁ ABQa =ta"@Հ@&XK}܀\jrR ,LBa& "F+L@0 B@Bm@x@ADAE6aLR<`j = t`="@Ҁ@ &+>A0  B@B@x@ADAEaL) aac =ߖ=$_+@J@ /FC  B@B@x@ADAEHabAڳ  B@B@x@ADAEn*a  Ad =x="A@o@&/fCa B@B@x@ADAEK*+a<$C =06`=$_@_(@&$ӁOƀ$(K\ɫ3+? b 4T  XF B@Bm@x@ADAESNaLxa& v  B@B+@x@ADAEaĀ< C =p)@@ @>AZ  B@B@x@ADAED ; -5A =|"@z@.'#)AD-u >o_pKs3?zK  B@B.@x@ =A @E65}aL A =s`="@w@ $ @>/  B@DB@x@ADAE2aL !-!c =;="@J3@ !#VW/  B@B A  @'@x@ADA%`@ "51a = @=Qa!I@@ AĠ4o' aH'*2nME2 IA $A B@B@x` =A @E aLW2@d = ?=M`=$_@@ ! @>  B@B}@x@ADA EaLA5Ac ==" @@ /;C  B@B@x@ADAEv^aWB=Qj =&e`="@\@$Ġ=^zQ-뜃i.)<禐a& GA[$ B@B@x@ADAEaLR`d = b`="@yY@ #>AX  B@B '@x@ADAEaL) Aa=ac == @@&/NkC` B@B@x@ADAEKρ bq-LW = a" @_̀@ ĠWyK{dOԌx3cCPN7*M!̀ bN " B@B @x@ADA#EaLrd$ =!`=$_A%@Oʀ@ PA&ɀ ' B@B@x@ADA(EaL c) =j="*@ʅ@ &+$/S+5, B@B@x@ADA-E @aD. = F`="/@4>@&Fh~iX}_C% cJƶߊ#F+0= b 1 B@B@x@ADA2Ed3 = C 4@$;@ # @=5: 6 B@B@x@ADA7Eo C8 =P=+$_+9@@&/?C: ` ; B@B @x@ADA<Ebom= =`=">@ @ :'!Q`ABAczUmi,\>2h,t]B?U + ̬@G?u$+@ B@B}@x> 9ADAA @E`iaLdB = ?=`=$_C@@ ! @=DY E B@B #@x@ADAFEDfaL cG = p="H@tg@ &+A/:CI AJ B@B@x@ADAKE!aAF+L = {( "M@@&*VkpnCQYmhzğ,b ANKO B@Bm@x@ADAPE5ځ d4 {%a"R@@ #>AS3 AT B@B@x@ADAUEס @Y cV ==$_+W@I؀@%/ $CX Y B@B@x@ADAZEb-t[ = \ `="\@@ '!҃Awwm qoD_/Z/"Aq A] ` ^ B@B@x@ADA_E K!aLF+` =H+`=$_5@@ ! @=Ab c B@B@x@ADAdEG,aL.e =Q=H bQf@I@ &+A/yCgHh B@B}b@x@ADAiEu-ao(vL+@s&zj =) 8`="k@@ #^ 'j=n:Ds. Go1 eX@ 6hl m B@BA@x@ADAnEເ do = C$_p@yB`@ # @K=q r B@B@x@ADAsEĸLAx!&!ct =@€=+"u@@ M! @/-6hv`w B@BA@x@ADAxEJtDb">1Gy = zO`="z@^r@&Ww ^@'07U.u|`* {q$+| B@B@x@ADA}E,PaL2@d~ =wZ`=$_@Oo@ &+ @>An - B@B@x@ADAE)[aL A>Ac =e3="@*@ /"IA5 B@B@x@ADAE B>Qc = fa"@4@&@S^AX0GS%t0z=S A $ B@B@x@ADAEgaLR`a = q`="@#@ >A߀  B@B@x@ADAEnraL) a>aa =;=)+@@&/xC J B@B@x@ADAEUsab6qj =\~`="@ T@ '!҃y@ZWo2~7-Z+Daca& AuS + B@BXZ@x@ADAE_aLrc =Y`=$_@P@ ! @=Y  B@B@x@ADAEC aL 6c = ="@s @&$/C  B@B@x@ADAEƁ a =͕a"@Ā@&=,xِ4\4EOY-MAJ e# $ B@B@x@ADAE5aLd =rʠ`=$_@@ ,W @>A.  B@B@x@ADAE|aL c ==+'u@I}@ @҃/C  B@B@x@ADAE7a&a =L>`="@5@ +'AIҚ&-8D.x𘦇Ƀ8W)a& 6A- B@B@x@ADAE Ad =H;$_@2@ ! @>AA[ B@B@x@ =A @E &c ==+"@@ &+ @/\C퀂!]a B@DBA@x@ADAEubA6a =)`="@@ #55څD4/qb<\+=dhC!7W [0A$ B@B<@x@ADAE`aLd =!`=+$_@|@ # @=٢ A B@B@x@ADAE]aL6h6c =g="@^@ ! @A/Cc + B@B@x@ADAEJa&c =`="@^@&FMsĪؕD(Nz%*P%>a& "Y  B@ BA@x@ADAEр]P =$_@N@ &+ @>A  B@B@x@ADAE΀ 'a =a؀="@π@&A.\(4A B@BA@x@ADAEb7C =ː`="@3@ #+A2lFox!´ 6^YSa& 0iF+  B@B@x@ADAEBaLJ c =Ǎ`=$_@#@ ' @>A  B@B@x@ADAEn?aLz!!C =;I="@@@ A/EC  B@B@x@ADAE "1c = i@"@ `@ P _xf3OGRQj@ At$+ B@BP@x@ADAE_LA2@C =aI$_@@ ! @>AXA[p@ B@B@x@ADAECaL AA'Ag ==+'u@s@  `@/B>C  B@B@x@ADAEkaABQd vr"`="@i@ +#!A%P j/0:9(0_n AJ B@B+`x@9 A @E4$#aLR'`c =ro-`="@f@ #>A.  B@DB@x@ADA E!.aL6haqF+ =L9`=" @ڀ@  `@9~vnӀCo & ̒=B*2_>pC   B@B@x@ADAE :aLrd =KD`="@׀@ $ @>  B@B@x@ADAEEaL? C =="+@@mՙ/\C+ B@B@x@ADAEtMFa'f+ = TQ`="@K@ MXZ04Y4nI8EIa&  ;AJ  B@B@x@ADAERaLd = Q\`=$_@xH@ ! @> G ! B@BW@x@ADA"E]aL 'c# = =+ $@@Ġ/C%_& B@BW@x@ADA'EI ?F+( =ha")@]@ &֥cdD{:"e"! `*ɻ$++ B@B@x@ADA,EviaLWd- =s`=$_.@N@ PA/A[0 B@B@x@ADA1EstaL?c2 =h}=+ 3@t@ ! @+/m`48$5 B@B@x@ADA6E/uaC?a7 =5`="8@7-@ + *;/ Xò~;]Kh0 FI =Wa& R]F+9,$: B@B@x@ADA;E瀈d< =2a"=@**@ !$>A>) A? B@B}@x@ADA@Em䀈}?GA =>=$_+B@@&/qCC +AD B@B@x@ADAEEi@T/AF =`="G@ @JAa SRKl#0qQdS"@ OAHx I B@B@x@ADAJE^XaLA zA$# =`=$_L@@ ' @>MX N B@B@x@ADAOEBUaL P =_="Q@rV@ !$/rR S B@B; @x@ADATEa(CU =}`="V@@ }YE:xA=kaȳwdrnt߁w. *6a& DWI X B@B@x@ADAYE4Ɂ  AZ =q$_[@ @ ! @>A\- ] B@B@x@ADA^EƁ  !(!c_ =π=+$_`@Hǀ@ /Ca b B@B@x@ADAcEb"1ad =O`="e@@ #!Abq N /lAf-g B@B@x@ADAhE :aLA2@Di =G`=$_j@|@ # @>AkA[l B@B@x@ADAmE6aLAAcn =@="o@8@ !A/SAz쀂 A{ B@B@x@ADA|E§aL) Aa8ac} =="~@@ /QC^ B@B@x@ADAEIcab(q =i`=%@]a@ # @AWBe_RA\6"֩z^a& vA`@0 B@Bc@x@ADAEaLrD =fr$_@M^@ # @>A]  B@B@x@ADAEaL (c =\"="@@҃/xZC3A[ B@Bq B Ƕ@x@ADAEԁ (a = a"@2Ҁ@&1 'A?z"\i5w`@R5! SAр  B@Bm@x@ADAE aLD =`=$_@"π@ &+ @>A΀  B@B #@x@ADAEmaL (c =B=+$_@@ `@/1 A B@BE@x@ADAEDaC =K$`="@C@!A{SHAKEb l  #]ڞ*DsB@4` -& B@Bp+@x@ADAE^AA =H/$_@?@ `@>AW  B@B@x@ADAEB/aL A =0`=+"@r/`@ @A/1C  B@B@x@ADAEɵLA0}P =u;aI"@ݳ@&}ќuޅK$b.WK+C5ʨ0a& .I B@BJ@x@ADAE3nב  B@B@x@ADAELvaL !1!c =V="@M@ /C^3 !k B@B@x@ADAEHwa" 1c =`="@\@ +#ʴ ?X:P%scsa& GiA$+ B@B$@x@ADAEA2@a = $_@M@ # @>A c @ B@B@x@ADAE A Aa =hǀ=+"@Ǿ@ ! @A/-&3 B@BA@x@ADAEybABQz =`="@2w@ A26xuU%yN4 lɜIW3a& ov$ B@Bm@x@ADAE1aLR`c =|`=+$_@!t@ `@>AsA[ B@B@x@ADAEl.aL aac =48="@/@&/&GG B@B@x@ADAE b9qOm =a$_@@ # @J.j[-6mbFPGάUr?As瀂$ B@B{@x@ADAE]aLrA =`= !@@ ' @>AW A B@B@x@ADA¨EAaL) 9c I="@q@&A/C  B@DBA@x@ADAEZa)om =ta`=" @X@ +"M)ŕ}!f8k&j_L Oa& A H  B@B+@x@ADA E3aL#B =p^`=$_ .`@3y @ U@ ! @>A,  B@BA@x@ADAEaL )c =I='u .`@3a @ G@ W&+ @/WC  B@B@x@ADAEˁ c =IFa!I .`@3a @ ɀ@ @AR'#1$Y<"qEqc1c 2$#%7{s &@/W B@B@x@ADAEaLA)D =IF`=$_ .`@3a @ ƀ@ # @>A@ B@B@x@ADA!EaL m" =I="#@@/D$% B@B@x@ADA&Es B@B+@x@ADA?Ea8@ =$&`="A@1@ }#LC HHJh=ieGO!AB C B@Bg@x@ADADEր dE =!1$_ .`@3f+F @ !@ @+>G H B@BW@x@ADAIEl !!cJ =I8݀="K@Ԁ@ }/ L M B@B@x@ADANE2b"*1*GO ==`=$_ .`@3cP @ @&aH9PEWu,JkBA wDQr$+R B@B@x@ADASE]G>aLA2@dT =IH`=$_ .`@3aU @ @ &+ @>VV@W B@B@x@ADAXEADIaL A*AcY =I N="Z@qE@ /C[ \ B@B@x@ADA]E AB:QD^ =Ua"_@T`@-D~ t4,Q9I1|W3a& IA`G ed a B@B W @x@ADAbE2LR`dc = p`aI"d@_`@ #>Ae+ f B@B@x@ADAgELa:ach =="i@F@&~/Cj k B@B@x@ADAlEpabb qcm =Iwl`= An@n@Ġk-N-9-3S= :'4|\'~;a& Aop B@Bs@x@ADAqE)maLrar =Etw`=$_ .`@3iAs @ k@ PAt Au B@B@x@ADAvE%xaL) A aw =I/="x@'@ /L/Cy&z B@BM@x@ADA{Erဈ*om| =a"}@߀@ #$WĠB[v^[/y>}CjZHa& BA~ހ A B@Bg@x@ADAEݙaLc =`= @v܀@ PAۀ  B@BA@x@ADAEaL *c ==" .`@3f+ @ @ ! @/GnC] B@B@x@ADAEGRaj =IX`=!I .`@3a @ [P@ mX< .ѩ{a;p֠α%z*as yIAO$+ B@Bm@x@ADAE aLAd =IU`= @LM@ ! @>LA[ @ `  B@B@x@ADAEaL c =b="@@&$/eC2 B@B@x@ADAEÁ R =ɲa"@0@ #$Aٜʬ\j#?0[hA{7a& [  B@B@x@ADAE{aLgd =ƽ`="@$@ 'K`.C@Td  B@B m4@x@ADAEkxaL c =?="@y@ !A/4 B@B1@x@ADAE3a D =:`=!I .`@3iA @ 2@ #ZB'?P1bjR7na:i/"Ӏs iAr1$ B@B@x@ADAE\쀈A =I7$_ .`@3a @ .@ ! @+=V A B@B@x@ADAE@ @Y)   A = + ="@p@ .iA  B@B@x@ADAEǤbA =w`="@ۢ@&|r*wxw kM*ZQ ofa& GG + B@Bx  @x@ADAE2]aL d =o`=$_ .`@3d @ ˟@ # @>A+  B@B@x@ADAEZaL !!c =Ic= @F[@&/14C  B@B@x@ADAEa"13D =]`="A@@ :!}ApOIQ@x/ QD]A- B@B@x@ADAE΁ 2@d =Dl@$_ .`@3d @ @ PA@ B@B@x@ADAEʁ AAc = {Ԁ=" .`@3a @ ̀@ U&+ @/ Cˀ B@B@x@ADAEqbB#Q#D =I&`="@@ ҃R%CZTbSa& A񃀂  B@B @x@ADAE>aLR`d =`=+ @u@ # @=ՀA[ B@B@x@ADAE;aL i  a#ac =@E="@<@&/C\ B@B@x@ADAEG b+qc ='a% .`@3f+ @ [@%A X?s4`Y|ժoS_EHa`E}A$ B@B+@x@ADAE(aLra =I2`=$_ .`@3a @ K@ PA A B@B@x@ADAE3aL) +a =Ij="@ŭ@&/R.1 B@B:@x@ADAEh4a3a =n?`="@0f@ #$Az); FO>WzB w6VgDe A B@B@x@ADAE @aLa =kJ`= @ c@ PAb  B@BA@x@ADAEkKaL 3a = 3'=" .`@3f+ @ @@ :! @/KC* B@B@x@ADAE؁ ;;MJVa!I!x`@3a ~@ ׀@ ʿB6Riz5aWs Aqր$+ B@B@x@ADAE\WaLc =Ia`= @Ӏ@"Y @> UA[ B@B@x@ADA E@baL ;c = = @p@ W/NC  B@B@x@ADAEIca#a ={Pn`="@G@%(9_i0Y~[5x?66ّ[AF$ B@B}@x@ =A @E1oaLd =sMy`=+$_+@D@dA*A B@DB@x@ADAE #c =za"@E@ /+C  B@B|@x@ADA E r;t! =La +"@@ Ap аC-2<\P˒)%A# $ B@B@x@ADA%EsaL"& = D`= '@@ ! @JA( ) B@B@x@ADA*EoaL) A4a+ = {y=",@q@ /l C-p. B@B@x@ADA/Eq+aa0 =2`="1@)@ #$҃s;(W!a E7% 8 B@B@x@ADA9E !4!$P: = =";@@ !/+ <\ = B@B@x@ADA>EFb"1c? =`=!I@@Z@ c‘CyJ2 ?ud%Aƙ$+B B@Bm@x@ADACETaL24@cD =`=$_E@K@ ! @>F G B@B@x@ADAHEQaL6hAPA[Q B@B@x@ADAREj€ a/CUWV B@B @x@ADAWE}aLbqaX =`=!IY@|@AĠz]lQq#6=o60`AZq{$[ B@B@x@ADA\E[6aLrd] =`=$_^@x@d:_UA[` B@B@x@ADAaE?3aL/cb = =="c@s4@m(/dߡ +c 0<e B@B@x@ADAfEa%9`u%A>$ B@B+@x@ADAEOm =DL @J<@dA;A[ B@B@x@ADAE) = A =]M @~ W/F0 B@BW@x@ADAEL5A =ϸXa"+@/@&뻲dw9*-t3$ A$ ?a& 3D + B@Bm@x@ADAEjYaL A =õc`= @@dA A B@B@x@ADAEjgdaL !!c =>q= @h@ `/C B@B@x@ADAE"ea"1f+ =)p`="A@!@& -|V9xa8 &?.'h +~`Ap $ B@B@x@ADAE[ۀ2@d =&{a @@dATA[A B@B@x@ADAE?ء @Y AAc = ="@oـ@ -&/LC  B@Bw:@x@ADAEœ|bBQG =z`= +@ّ@&S+qX#'&~VA":yHouAE$ B@B@x@ =A @E0LaLR`d =n`= @Ɏ@dA)A `@  iF B@DB@x@ADAEIaLaaC =R="@DJ@ /cC A B@B@x@ADAEaAb5qj =K `= @@ +QwMѽp§AP(aux@a& 7A B@B+@x@ADAE rd =C @`@dAA[ B@B@x@ADAE鹁L) A5c =À="@@&$/vC B@B$@x@ADAEpub=a =|`=H@Q @s@$ g{Y o߱}>cׂچX#DTg;mr + B@Bp@x@ADAE-aLd =y`= @tp@ @}aL) A == @n~@&/SC  B@B@x@ADAE8 a-&a =y?`="+@6@ e&7(=eC@N#{za& AI  B@B@x@ADAE/  d =m<a !@3@dA") # B@B@x@ADA$E ) !!c% =="&@C@ d-/h2C' a ( B@B`@x@ADA)E n@TA"1.F+* = 0G+`= ++@@ +֕ Ui{G46% I[>@=' xA, - B@B+@x@ADA.Eb,aL2@d/ =B6`= 0@@dA1A[c @2 B@B@x@ADA3E^7n@T AAc4 =h="5@`@ W/}TC6_7 B@B@x@ADA8Eo8aBQD9 =!C`= :@@&jnݞ‹SEIL(M@ I&l yA;-< B@B@x@ADA=EҀAR`d> =Nn@ ?@s@dA@ A B@B@x@ADABEπ aaiAC =ـ="U6@Ѐ@ / CEZF B@B@x@ADAGEEObAbqcH =IZ`= I@Y@ +AُMƐRŋ7ps;4')KgV5S WmAJň$K B@B@x@ADALEC[aLrcM =e`= N@I@dAOA[P B@B@x@ADAQE@faL) cR =\J= S@A@ /ACT/U B@BA@x@ADAVE >&IAW =rn@"+X@.q`@&sK63)ӈExM+*nވ>"@ lUAY AZ B@B@x@ADA[EL.c\ =|aI ]@@ &+ @>^~ _ B@B@x@ADA`Eh}aL aa =5="b@@&/yCcd B@B@x@ADAeEl~a.af =s`= +g@k@ +# @.WݭvfKAJ,e8лP2a& ©Ahoj i B@B+@x@ADAjEZ%aLf+k =p`=$_`3l@g@dAmS An B@B@x@ADAoE>"aL `.cp u`="q@ۀ@liҡbga֟P|}"eկYi8Ma& |*CrD$s B@B@x@ADAtE/aLcu =q`= v@؀@dw(A[Wx B@B}@x@ADAyEaL@YAx>>Jz =@㜀="{@G@  +6h/C| +} B@B@x@ADA~ENad =JU`= @L@ W Ġ["F%0sGab$=M;8A$ B@B @x@ADAEaL>?C =BR`= @I@dH mW B@BW@x@ADAEn@T) c' = = @@ /? B@B| o@x@ADAEoa =a"+@@&#0ME%p͢ߥQ&sXψ:ǮD＀  B@B+@x@ADAEwaL a =`= @s@dAӹ  B@B@x@ADAEtaL?!!/F+ =~="@u@ XZ/1C]$ B@BW@x@ADAED0a"1c =6`="@X.@ Aߛ|*{Vą\(Kf>C9v a& A-  B@B@x@ADAE耈 2@c =3 @I+@dA*A[A B@B@x@ADAE AAAc =[=+ @@P/yC/  B@BP@x@ADAEb}Qa =§`="@-@ y-mhL%c 4r@pa& A@0 B@Bq@x@ADAEYaLAR`a = o@ @@ ' @$=C}@A B@B@x@ADAEhV aL a7aIA =,`="@W@$Ġ/tCm B@B}@x@ADAE aAbqc =`="@@&OB՟W=Dl UC[0-a& To$ B@B@x@ADAEYʀr7c =!a"@ @dAW  B@B 5@ADA @E=ǡ @ '7D = р=$_:@mȀ@&/T١ + B@DB@x@ADAEĂ"bd =l-`="@؀@!+$ȨvRz6ÑK` bUgb+a& L;F+D@0%9`  B@B+@x@ADAE.;.aLA'c =8`=)@}@ @>A( A B@B@x@ADAE89aL 'c =A="@B9@A/C  B@BW@x@ADAE a =QDa"@@ #"F jEi?xm(a& *8A  B@B@x@ADAEEaL'a =AO`=$_@@+ @>^ f!@+ B@B@x@ADAEPaLg/t ==+$_@@%$.C  B@B}b@x@ADAEndQap +@sc = +k\`= @b@&Gp 4*J(:lȋ݀ XZa- B@B(@x@ADAE]aL/c =hg`=$_@z_@ @>A^A[ B@B@x@ =A @EhaL?M =#="@@ 4#V҃/D]$ B@DB@x@ADAEDՁ #d =sa!I@\Ӏ@ +A3.^5D3@SUU AҀ$ B@B+@x@ADAEtaL?C =!~`=$_@HЀ@dAπ$ B@BA@x@ADA  EaL 8A =g`= @‹@&/!?. B@DB@x` =A @EFaL"A =L`="+@-D@!+xЂ똳MF'ˡ$]& ` DC@0A B@DB@x@ADA E c  Ia @A@dA }@  B@B@x@ADAEg) !(!,a"@~%/CA[ B@B@x@ADA`DEL"1D ='@@&S<PZV{[W[9 An  B@B@x@ADAEYoaL2(@c `= @@+ @+=gR  `'%` H B@BA@x@ADAE=laL AAj = v=+'u @mm@ /C! $sd" B@B@x@ADA#E'a")A$ =p.`= %@%@&O9SZ{nU s 1cE{A&C$+' B@Bu$@x@ADA(E. AR`c)l+a$_*@"@ @"`C >+' ` , B@B@x@ADA-E݁ aaC. =="/@Bހ@ /T0 1 B@B@x@ADA2EbAbqA3 =H`="4@@ +x-jψԩd1>FP`Ya& f=56 B@B+@x@ADA7EQaLr8&+8 A`="9@@dA:$; B@B@x@ADA<EMaL AA= =W= >@O@&/li?N@ B@B@x@ADAAEn a :B =`="C@@&4x9>1PwExI6˯1AJ!a& 8GD$E B@B@x@ADAFEcG a)AH@r@dAI J B@B@x@ADAKE@Yl CL =Ȁ="M@쿀@& /CNXO B@B@x@ADAPECzbAQ =p@"R@Wx@ A]/U,T[P,Cz@ kASw mT B@B@x@ADAUE2aLcV } `= W@Hu@dAXt Y B@BA@x@ADAZE/ aL A a[ =Z9=+ A\@0@&/C].^ B@B@x@ADA_E D` =a a@,@ 8v0eO'$T1\MZC#MNAb蠂@4-c B@B@x@ADAdEaL Ae "`= f@ @ 0 @Jg|堂 h B@B@x@ADAiEg#aL Aj = +="k@@#V/1(Cl cm B@B@x@ADAnE[$aAco =b/`="p@Z@ P >l#%J 7XJ/AqmY r B@Bm@x@ADAsEX0aLCt _:`="u@V@dAvQ w B@BA@x@ADAxE<;aL  Ay = =$_mz@l@&/{ $s| B@B@x@ADA}É c~ =wFa"@ʀ@&QܖP5[C)zrgsRa& DC B@B@x@ADAE-GaL 9C kQ`=)@ǀ@ @=g'  B@B@x@ADAERaL6h!1d =HD^`="@;@10=nM`q9WU'LF\3M a& 8~C  B@B@x@ADAE 2@c @Ai"@8@ )A @>}7  B@B@x@ADAE A9Ac = = @@ ! @W/RC  B@B@x@ADAEmjbBQa =u`="@@ (zE(twѫHeva& A  B@B}@x@ADAEfvaLR9`G`=$_@q@ ! @>ѨA[j@ B@B@x@ADAEcaL aaa =m="@d@&/7CX B@B@x@ADAEBalbqa =%`="@V@&K^,qſ\Ω\D אW'A  B@B@x@ADAE׀ra "a"@F@ '>A B@B@x@ADAEԀ !F+ =Zހ=)+@Հ@ ! @+A/ C- B@B@x@ADAEbA =Ж`="@,@ 'AYM3{r*NH==xMˏa& A$ B@B@x@ADAEHaLc`=$_@@ ! @>A| A B@B@x@ADAEfEaL) t = ;O="@F@ /3C B@B"Y@x@ADAEad =`="@`@ +#Z^|5G@j.i8ބm*N0B-m A B@B+@x@ADAEXLc aI$_@`@ # @>AQ  B@BA@x@ADAEA&A[ B@B}@x@ADAE'aL91D =0= @A(@P$/AM  B@B@x@ADAEaL) !"!*C =="@ @&/bCW B@By"Y@x@ADAEBā "1d@a"@V€@ #p6M5oJ\RKjLѺ7{ =A A B@B`x@9 A @E|aL2"@c =$`=$_A@F@ ' @>  B@DBA@x@ADA Ey%aL A*Aa =]=+" @z@ ! @/C - B@Bw@x@ADAE5&aBQd =;1`=!I@+3@&p"chF I{)ҝa& eA2$+ B@B@x@ADAE퀈R*`c =8<$_@0@ &+ @>A{/  B@B@x@ADAEf a a IA =6="@@&/C  B@B@x@ADAE=bbqd =H`="@@ #$$96ofhWPyT?l}*A l$! B@B+@x@ADA"EW^IaLr c# =!AS`=$_$@@ ' @>A%P & B@B@x@ADA'E;[TaL t( =e=")@k\@ ! @A/3C* A+ B@B@x@ADA,EUad- =j``=".@@ Ig(;kvDFx9a& >mA/B@0:+0 B@B-@x@ADA1E,ρ c2 =ka$_3@@ ! @>A4& A5 B@B@x@ADA6E̡ @Y 2a7 =Հ="8@@̀@ /AC9 : B@B"Y@x@ADA;Elbd< = Gw`="=@@&h5;: {-cHi8 A> ? B@B@x@ADA@E@xaL2cA =?`=$_B@@ @>AC D B@BA@x@ADAEE@&/CH=I B@B@x@ADAJEldK =%a L@@ 4' @:N%n?|?Ќ_a& AM-N B@B 4@x@AD>OEװaL:cP = `=$_Q@t@ ! @Aac Yb B@BA@x@ADAcEaL =Ad =](= e@@ ! @҃/Cf,Wg B@B@x@ADAhEځ ANi = a"j@+؀@ 'K$p5.Ecȯ(i*0f݅2; [JAk׀$l B@B@x@ADAmEaL7l#n =`= o@Հ@ ! @>Ap{Ԁ q B@B@x@ADArEeaL) !! As =.="t@@ /fCu"Yv B@B#@x@ADAwEJa"1dx =Q`="y@I@ +#~fC5ԧ H5{4# AzlH { B@B+@x@ADA|EWaL2@3C} =!AN`=$_ +@@3~@E@ # @>AP  B@BA@x@ADAE:aL AAc =AV =+"@k@ ! @A/ס  B@B{@x@ADAE BQc =ja"@չ@ -@}!X 6^D3$ƵDA$ B@B@x@ADAE,taLR`c =i`="@Ŷ@>A%  B@B@x@ADAEqaL a#a+F+ =z=$_@@r@ /S4 A B@B@x@ADAE,ab3q#A = B3r #@*@ u'8C|N:ߘƏnlfyѪT66 xD- B@B @x@ADAE rd =?0a+$_@'@ # @=$&A[ B@B@x@ADAEဈ3c == @@ ! @A/C  B@B@x@ADAElbA;c =`="@@ P_w$OhXɆ@p0 v)] {?cA욀$ B@BP@x@ADAEUaLa = &`=$_@p@ ! @>AЗ A B@B@x@ADAER'aL; ;a =3`="A@U @ ` ՙj$ID@ a꺳qH^C  B@BJ@x@ADAEƀW IA =>a"@D @ !>  B@B@x@ADAEÀ? Wc =à='u@Ā@ $ @Ƕ/FrC+ B@Bv@x@ADAE?bc = ˅J`="@*}@&p_VpܯCjFc=`f Nͥ3_v VTA|  B@B@x@ADAE7KaL ~ =‚U`=H@d_@z@ #>zy  B@B}@x@ADAEe4VaL d =5>=$_@5@&/xC B@B@x@ADAE p;  c =aa"@@A)</m`&ufOie$\a& VAo퀂$+ B@B@x@ADAEVbaLW v; =l`=+$_@@ PAOA[d B@B@x@ADAE:maL 8 == @j@  `@ A/0zC  a B@B@x@ADAE`naAc =ygy`="@^@ Ġu flTqzp?jڿa& AA B@B @x@ADAE+zaL $D =id`= @[@ # @=%  B@B@x@ADAEaL) !!d =="@?@/HC  B@B@x@ADAEс "1c =Jؐa"@π@ '&l &B/싋nn8fuusa& ǸA + B@B@x@ADAEaLA ?i2@,D = 5>՛`="@̀@ !>* ˀ  B@B@x@ADAE䆜aLAAd =="a @3@@ &+ @/1C B@B@x@ADAEkBaBQc = I`="@@@ # n!*˫AjĜg'!0o! Rom?  B@B@x@ADAER<`a =Fa+$_@@o=@ # @Q 2@Bq !@<  B@@B@x@2ADA@> @ +@aad 6@  " 9@~A/uV  B@@B@x@ADA@> @@L}  ' 9@T@  -Zu:ztB@ZbK]J4f OC] $+ B@@B @x@ADA @> @kaLArIA 6 >  `=+$_ 9@D@ ! @>A CǶ0z`@B@x@ADA@> @haL/d 6I\r= @i@ &+ @/5/$ B@@B@x@ADA@> @$aAc 6*`="@*"@ +#ADʜ笂D2'V5Qf\C@@ ܲD!$ B@@B@x@ADA@> @܀<G 6 >  '$_ 9@@ # @=z  B@@B@x@ADA!@> @dـ) Ad" 6I-="#@ڀ@&/*C$$% B@@B@x@ADA&@> @b @UMaLA.O / B@@B@x@ADA0@> @9JaL d1 6T= 2@iK@&/C3  4 B@@B@x@ADA5@> @ac6 6 >  q v"7 9@@&, ,>^@LI`;|IA8@ 9 B@@B@x@ADA:@> @+   l a+$_< 9@@ PA=$ > B@@B@x@ADA?@> @aL a@ 6IĀ= A@?@ :! @C/ޗB C B@@B:@x@ADAD@> @vac(>&@ cTG@1f!@+H B@@B@x@ADAI@> @!T/aLA,IAJ 6 5=>z(`=+ K@q@ @>ALp M B@@B@x@ADAN@> @+)aLAO 65="P@-@ /DQ,R B@@B@x@ADAS@> @k瀈A-cT 6 >  4a$_U 9@@&DF"Nt4 @՟5aL CY 6I?`=$_Z@o@ @>[᠂A+\ B@@B@x@ADA]@> @@aL A!!d^ 6="_@靀@&/dC`U c a B@@B@x@ADAb@> @@XAa" 1cc 6 >  ^L`="d 9@TV@ As4Hz?w;5MboO!ꅜ=$3Kdmo1eU+f B@@B@x@ADAg@> @MaL2@ah 6 >  [W`="i 9@DS@ !>AjR k B@@B@x@ADAl@> @ XaL AAdm 6I[= n@@ A/)o*p B@@B@x@ADAq@> @Ɂ BQcr 6ca"s@)ǀ@ +#!,ɓ"DYΣ-mfF[C@ F+tƀ +u B@@B$@x@ADAv@> @daLR`aw 6 >  n`=+$_Ax 9@Ā@ # @>AyyÀ z B@@BA@x@ADA{@> @d~oaL aad| 6I,="}@@ W! @/C~ B@@Bt-&@x@ADA@> @9pabqc 6 {=@{`="@7@&[)zR0, \۠&f0t ɆAj$+ B@@B@x@ADA@> @U Ar55M 6=a+$_@4@ &+ @`.f+N@T B@@B@x@ADA@> @9  d 6=$_@i@&A/?C  B@@BA@x@ADA@> @bA5c 6 >  t`=" 9@Ԩ@ #!$:%PFα+tzs FH ZA@ B@@B3R@x@ADA@> @*caLf+4 5=h`=$_@ĥ@ ' @>A# B@@B@x@ADA@> @`aL F+ 6i="@>a@&/vC : B@@B`@x@ADA@> @a-A 6="`="@@3RĠ^Ft+\ʨ8j A@4 B@@B@x@ADA@> @Ӂ c 6a"@@ &+>A ` B@@B@x@ADA@> @Ѐ) -C 6ڀ="@Ҁ@ ; &+/Cр B@@B$@x@ADA@> @jb a 6/`=!I@~@ # @_֤zKW ^?e>~W@ Aꉀ  B@@B  @x@ADA@> @DaL-d 6`=$_@v@ # @>A҆ ` B@@B@x@ADA@> @AaL  D 6K="@B@ ! @҃/ =CU B@@B[p@x@ADA@> @? =A 6a"@S`@ @pӗ2&x^bjB?-@ BA$+ B@@B@x@ADA@> @LA 6aI+$_@C`@ ! @>AA ` B@@B +&,+@x@ADA@> @L 6taI$_@,l@ '# X1ZxiS*XYpT޺wkRUCk@4 B@@BW@x@ADA@> @&aL D 6q`="@i@ @>xhA B@@B@x@ADA@> @c#aL !!d 6(-="+@$@ $#V>/jC $M !$ B@@Bq:@x@ADA@> @ށ W"1c 6t@K"@܀@ -&?)HKຝrT֢ٓvG)q1Aj B@@B-&@x@ADA@> @TaL2>@a 6`="@ـ@>N  B@@B@x@ADA@> @8aL) AAd 6 ="@h@ -&/ǹC  B@@B@x@ADA@> @OaB>Qc 6pV`=%@M@$AhR|DWG66)hς:fkB'? `̿ B@@B@x@ADA@> @* aL}.`IA 6gS*`=$_@J@ &+ @>A#  B@@B g@W@x@ADA@> @+aL aad 6= @>@P/ѯD G B@@B| @x@ADA@> @ b.qc 6@6a"@@$ĠIDp O P)lƴvgmKsΧ#`@ 5A- B@@B}@x@ADA@> @x7aLrc 6 >  A ] B@@B@x@ADA@> @uBaLa 6I= @w@ ! @Ġ/Cv B@ ,B@x@ADAEi1Caa ="8N`="A@}/@ 'vܿ芹9mHV^}%9"*jykÊۥA.  B@B@x@ADAE逈:>6IA =5Y$_@34 @n,@ ! @>A +  B@B@x@ADA E怈 Ac =AV="@@ /-CT B@B; @x@ADAE?Zb>c =e`="@S@&=CpMZ+! VяXهi?a& "$ B@B@x@ADAEZfaL>a =p`=+$_@C@ # @=  `m} B@B@x@ADAEWqaL) d =aa="@X@&/X;D)A B@B@x@ADA Era>c! =}`=)"@(@g'㶱k !'W|H8o`B?;08FmA# A$ B@Bm@x@ADA%Eˀt& =a$_`3iA'@@ PA(x ) B@B}@x@ADA*EcȀ@Y d+ = +?Ҁ= ,@ɀ@ &+ @+/C- . B@B@x@ADA/E郉bc0 =`="1@@&$Zt-ƢKd7'RVT05M+K^Ha& [[2i$+3 B@B$@x@ADA4ET'M5 =`= 6@~@ # @=A7M 8 B@B@x@ADA9E89aL : =C=$_+;@h:@"YĠ/< $se`#= B@B@x@ADA>E ?c? =ga"A@@@ '!A}J(a 94DeY#/ԀF+A>@4a B B@B@x@ADACE)aL7 DD =`=$_E@@ @=F" G B@B@x@ADAHE aLA!!dI =ֳ="J@A@ &+/"KL B@B@x@ADAMEeakV"71cN =@l`="O@c@ <>,GS~0t!&y0^` FEDP$Q B@B@x@ADARE`2@S = @i`="T@`@>AU_ V B@B m> @x@ADAWEaL) AAAdX = `$="Y@@ /iCZ~[ B@Bu  J@x@ADA\EiրBQc] =a%^@}Ԁ@&'8 >9Mf0S DU<*a& b_Ӏ ` B@B@x@ADAaEԎaLR/`ab =`=$_c@mр@ &+ @JAdЀ e B@BA@x@ADAfEaL aadg == h@茀@%/ iT j B@B@x@ADAkE>Gab/qcl =M`="m@RE@ +#!$iTFn2%V,<Pkc juda2)a& DfF+nD$o B@B+@x@ADApEr7Mq =J$_r@FB@ ' @>AsA t B@B@x@ADAuE dv =U"w@~ W! @҃/x) y B@BW@x@ADAzELc{ =̾ u@"A|@'@ PBi.;˿$ i:@ w  @  B@B@x@ADAEbmaL d =7w="@n@ /p  B@B@x@ADAE(aA'c =/!`="@&@&JǷ m7_VTaJUt?>= x˦6hMDi B@B@x@ADAES 7c =,,a"@#@ #>AM  B@B@x@ADAE7ށ @Y) a = ="@k߀@"YA/Cס + B@B}@x@ADAE-bo$7a =o8`=*@֗@&.Z_-e+|9AQFB{a& ]*B  B@B@x@ADAE)R9aL7/M =jC`=$_@Ɣ@ PA& + B@B@x@ADAE ODaLc =X="@AP@&/0<$ B@B@x@ADAE Ea7c =CP`="@@&N,LC4 N…iJ%oq8ƾa&   B@B@x@ADAE $0D =;[ @@dA  B@B@x@ADAE AAA =ɀ="@@ +*'mA/~ + B@B}@x@ADAEh{\b08 =%g`=!I@|y@&J؟3#%!G)OLs}D4ga& dmJx$+ B@B 4@x@ADAE3haL C =r`= @mv@ PAu  B@̠B@x@ADAE0saL !0!c =:="@1@ /S B@B@x@ADAE> "1a =~a"@R@ P#$+KǘLZ =j( F+ϓB@[Wa& /ZD适$ B@BP@x@ADAEaL2@D =`="@E@dA怂  B@B @x@ =A @EaL) AAc =X="@@ }/?( B@DB@x@ADAE]aB$)* =c`=$_A@'[@&M%Wvs\ƌtw(LPa& iSZ + B@B@x@ADAE}aLR`A =``= A@X@ &+ @"`^=JwW  B@B@x@ADAEaaL aaA =.="@@&/wiS  B@BDK@x@ADAÉ bqf+ =ԭa"@ˀ@ #$AK+_yk=R{dqS#g riSh  B@B@x@ADAESaLrC =Ѹ`=$_+@Ȁ@ ' @>L  B@B@x@ADAE7aL; c =zE`=+"@<@ ! @/Y= B@B@x@ADAE(  a =fB"@9@d!  B@B@x@ADAE @Y D =="@<@  +=  B@B@x@ADAEb c =;`=+$_@@  ǶZ{y,3@C s@{skдG = K@1  B$@x@ADAEgaL8C =`= @@d  B@BW@x@ADAEdaL) A =n="@f@ /oC }eA[ B@B@x@ADA Eh ac ='`= @|@ 3"p) j/_yh Ha& koA W B@B| @x@ADAE؀8C =$ @p@ +# @>A[ B@B@x@ADAEՀ A =߀="@ր@ !#VA/CCR B@B@x@ADAE=v@T8c = `="+@Q@ASꏮŊl~KjK43ͱ,K@  hA  B@Bx@x@ADAEI aL( C =`=$_!@A@ &+ @>" # B@B@x@ADA$EFaL F}A% =\P=$_&@G@ /DC'(( B@B@x@ADA)Ea})c* =#`="++@&@ +#!Ġ-{pV =vE`= ?@m@dA@K A B@B6h@x@ADABE6(FaL AAdC =2="D@f)@ W/wpCEҡ WF B@B@x@ADAGE B QcH =rQa +I@@ yyqE^cLɧ##7iͲa& gJ=K B@B+@x@ADALE'RaLR!`GM =e\`= N@ހ@dAO!A[P B@B$@x@ADAQE ]aL aaAR =ܢ= S@;@&A/)T U B@B@x@ADAVET^ab!qcW =B[i`="+X@R@ +Y_'.JDOd@h "ha& 7F+Y +Z B@B+@x@ADA[E jaLr9!C\ =:Xt`= ]@O@dA^N _ B@B@x@ADA`E uaL Aa == b@ @ WA/4Cc} d B@B@x@ADAeEgŀ9cf = ̀a"+g@{À@%o҃~U0_^v{1^jQ2hOZAh€-i B@B#@x@ADAjE}aL#9Ck =ɋ`= l@l@dAm˿ n B@B@x@ADAoEzaL dp == q@{@&A/CrRs B@Bt @x@ADAtE=6aAcu =<`="+v@Q4@ Ġ_*8 DRb=$P\3rn9Aw3$x B@BC@x@ADAyEDz =9a {@A1@dA|0A[} B@B@x@ADA~E뀈 !8 = S="@@"Yg/C' B@B@x@ADAEbc =`= +@&@&75:Fzb7.zsncā>R2A$ B@B@x@ADAE|_aLc =`= @@dAvA[ B@B@x@ADAE`\aL) a = )f= @]@&/C  B@B@x@ADAEaa =`="+@@&m : z%6پSݏ|_a& Ag  B@B@x@ADAERЁ G = @@dAK  B@BA@x@ADAE6́  a = ׀="@f΀@ /gC  B@B@x@ADAEba =m`="+@І@&$ĥBV%YbfVb bQΘ.<- B@B@x@ADAE'AaL D =e`= @@dA  B@B@x@ =A @E >aL!!c = ?=G= A@;?@ /Y  B@B@x@ADAE A" 1c =:a"+@`@! ƹA#l^o2P9.K"Pf"{mSF+@4WA B@BqJ@x@ADAEL2@ =>w@ @@ @=#@ B@B@x@ADAEaLAAd = ="@@&/C| B@B@x@ADAEgjaBQc =q `=$_ 4@{h@ g"*F"H O: Iw4a%rg@4 B@B@x@ADAE"aLR2`c =n`=$_@ke@ ' @>d  B@B@x@ADAEaL) aaa =z)= @ @ +! @$/}rQA[ B@B@x@ADAE<ہ b2qa =$a"+@Pـ@ b zhҺDW*x ^L疧tn|,)F+؀  B@B@x@ =A @E%aLrf+ =/`=$_@@ր@ ! @>AՀ  B@DB@x@ADAE0aL c = W=$_@@&/C'A B@B@x@ADAEL1a2a =R<`="+@%J@ &#!gʿ&~ٰQCl w(a& AI$+ B@B@x@ADAE|=aLa =OG`=$_@G@dAuF  B@B@x@ADAE`HaL 2a = 8 ="@@ iSA/SC  B@B@x@ADAE漁 2"U =Sa$_@@ ̖85>Q^ L"0{@9HA]|a& yf A B@BJw@x@ADAEQuTaL$c =^`= @귀@dAJA[W B@B@x@ADAE5r_aL2c =|="@es@ W/3y ? B@BA@x@ADAE-`a :D =e4k`= @+@ /c$zDNHtasAC͞F+ A B@DB ?@x` =A @E 6h c = ?=9a"@@ +!#VW#%Eʢ/߱3ehN>'\j C  B@B@x@ADA EVaLW2D =`="A @@ $ @>   B@B@x@ADAESaL W8 = ]="@U@ ! @ՙ/C|T  B@B@x@ADAEfaa =`="@z @Ġ=Re}1C52n%$}NI6Cda& w$  B@B@x@ADAEǀ a =$_@k @ &+ @> A[ B@B@x@ADAE !!a =}΀=" @ŀ@Ġ/>}P!Q " B@B@x@ADA#E;b"1a$ =䆱`="%@O~@ #+^'( N`kp(ɗ1\BE]BF+&}@4' B@B}@x@ADA(E8aLW2@a) =胼`=$_*@C{@ ' @>A+zA[A, B@B}@x@ADA-E5aL AAa. =N?="/@6@/nC0&1 B@BA@x@ADA2E k @sBQa3 =a"4@%@ARaM40ccj5In@ \A5$6 B@B@x@ADA7E{aLR`a8 =`="9@@dA:u렂A[; B@B@x@ADA<E_aL)Axaaa= =@,=$_+>@@ &+ @+A/C? @ B@B@x@ADAAEaabqaB =h`="C@_@ :Ar<SbC[Q*įzkCC'͟3a& M[ADf AE B@B:@x@ADAFEQaLraG =e`=)H@\@ @= IJ AJ B@B@x@ADAKE4aLaL =!=$_M@e@0<Ġ/wCNѡ O B@B-&@x@ADAPEҁ aQ =ga"R@Ѐ@& _:e j <09na&  AS;$T B@B@x@ADAUE&aLaV =cx@$_W@̀@dAX@AY B@B@x@ADAZE aL Aa[ = ґ="A\@:@&/_ C] r^ B@B@x@ADA_ECaa` ==J`= +a@A@&|+R#n6hX'f Ab`4c B@BiS@x@ADAdE ae =9Ga f@>@dAg= Ah B@B@x@ADAiEaj =x@"k@~ /Cl{m B@B@x@ADAnEfLAao =&&'p@z@y҃z*2()ւ~ɭxaq!Aq汀$r B@By@x@ADAsEl'aLat =1`="u@j@dAvʮA[w B@B@x@ADAxEi2aL) Aay =s= z@j@ #/ C{P| B@B  @x@ADA}E;%3aq a~ =+>`="+@S#@  aN9D'xkxj?d W7na& A" A B@B@x@ADAE݀A =(Ia A@? @dA A B@B@x@ADAEڀ a =V="@ۀ@ :/XC% B@Bc'@x@ADAEJbAa =̜U`="@$@ "yX ۍ~R:VU"a& A  B@B@x@ =A @E{NVaL a =``= @@dAtAA B@DB@x@ADAE_KaaL !!a =7U=+ A@L@ /(C  B@B@x@ADAEba"1a = m`= @@ msZ>鮾H6*5ݸAxa& Ae$+ B@Bu@x@ADAEP 2@a = xa @@dAI  B@B@x@ADAE4 AAa =ŀ="@d@ /:C  B@Bt@x@ADAEwybABQa =c~`="@u@$ U!FtsoOag#ܣ^Ş/zA;A[A B@B@x@ADAE%0aLR`a ={`="@r@$=gA[ B@B@x@ADAE -aL) Aaaa =6="P@9.@+ @g/C  B@B@x@ADAE bqa =Ha"@@ ARqkA7*Z#ϯ Ara& ~A怂  B@B7@x@ADAEaLCra =8`=$_@@ @=   B@B@x@ADAEޝaL ) a =="@@ A/3RC~ B@B@x@ADAEeYaa =``="@yW@&$Ǧ@ +_ fsx/"Һ I_"a&  oAV  B@B$@x@ADAEaLa = ]`=$_`3@iT@ &+ @>AS  B@B@x@ADAEaL a ==+)`3a@@& /CCP B@B @x@ADAE:ʁ a =a @NȀ@&Z,sl_Łҫ/@M߹%#k[pAǀ$+ B@B@x@ADAEaLAa =`=$_@>ŀ@ ' @>AĠA[W B@B@x@ADAEaL a =U="@@ !#VJ/C% B@B@x@ADAE;aAa =A`="@$9@g:軓Jx ( у ,ja& A8@0 @  4 B@Bm@x@ADAEza =>a"@6@ PAt5  B@B@x@ADAE^ a =#="+@@ />C + B@B@x@ADAEba =`="@@ #!+ncFAXVŷC͆b pAe`4 B@B@x@ADAEOdaLA =y@)@馀@ @>AI  B@B@x@ADAE3aaL aj="@cb@&/m\C  B@B`x@9 A @Eaa =j#`="@@ VPSS¬{Άа_$` : + B@DB@x@ADA E%Ձ $ a =b $_ @@ ! @>   B@B@x@ADAE ҁ  !!a =ۀ=+'u@9Ӏ@& /   B@Bwg@x@ADAEb"1a =<(`="@@ +#!CJiO;n#a& -+ B@Bu@x@ADAEE)aLA2@a =3`=$_@@ ,W @>A󇠂A[ B@B@x@ADAEB4aLAAa =L="@D@ !/)5IA zC! B@B@x@ADA"EeABQa# = @a"$@y?`@&` a(^,Kib1ca& A%@0A& B@Bm@x@ADA'E϶LR`a( =KaI")@hJ`@ &+>A*A[+ B@BA@x@ADA,EL; aqa- =uWaI".@Nm@ /`C/l 0 B@B@x@ADA1E'XaLra2 =rb`="3@>j@ !>4i 5 B@B@x@ADA6E$caL Wa7 =M.="8@%@ $P59$A[: B@B4@x@ADA;E a< =na"=@#ހ@ #',3 B)B<1\uN^OV>Ns>D>݀ ? B@B@x@ADA@EzoaLaA =y`=$_WB@ۀ@ # @W>Csڀ D B@B@x@ADAEE^zaL aF ="=+"G@@ ! @/CH mI B@Bom@x@ADAJEP{aaK =W`="L@N@ ĠK>M0>y0&_$-jlbVa& #AMd$+N B@B@x@ADAOEO aLAaP =T`=$_Q@K@ &+ @>ARHA[S B@B@x@ADATE3aLaU ==+$_V@c@ /^CW X B@B@x@ADAYE AaZ =jȝa"[@ο@$ĠM@<}?x;pX2$8"Ċ?3a& T}A\9 A] B@B@x@ADA^E$zaL:a_ =fŨ`="`@@ #>Aa! b B@B@x@ADAcEwaLad =Հ= e@8x@PA/QCf g B@BP@x@ADAhE2ak?ai =?9`="j@0@&Y҉:j/fJ )Lpa& -k+l B@B@x@AD>mE An =76$_o@-@ PAp, Aq B@B@x@ADArE瀈) as =="t@ @&A/Duy耂v B@B}@x@ADAwEdb-&ax =`="y@|@ +#&lWA˺Derw?D |Abr|?a& vAz蠀 A{ B@B+@x@ADA|E[aL a} = `= ~@h@ PAȝ `au" iF B@BA@x@AD&+EXaL !!a =b="@Y@ !A/CO B@B@x@ADAE9a"1a =`="@M@&TpE2R!eJsVZKCca& A$+ B@B@x@ADAÈ2@a = a"@A@ &+$+=C B@B}@x@ADAEɀ AAa =TӀ=$_@ʀ@&/5,C$ B@B@x@ADAEbBQa =`="@"@&^\X;}Yyg C&Za& A A B@B@x@ADAEy=aLR`a = z +$_@@ ' @>r B@BA@x@ADAE]:aL aaa =*D="@;@ !$҃/C  B@B@x@ADAE bqa =a"@@ ?'NJytN\ j#{!S[uAd B@Bm@x@ADAENaLra =`=$_@@ ! @>AH  B@B@x@ADAE2aL) a =="@b@ ?/YC  B@B@x@ADAEfaa =im*`="@d@ +#]Tz`+.+z?xÔ naa& $A9 A B@B+@x@ADAE$+aLa =aj5`=$_@a@ # @>A  B@BA@x@ADAE6aL a =%=+"@8@&/д  B@B@x@ADAEׁ a =GAa"@Հ@ 1+"^8Cx%+<ѕa& ռD- B@B1@x@ADAEBaLa =6L`="@Ҁ@ !=р B@B@x@ADAE݌MaL a == @ @&/#Cy B@B@x@ADAEcHNaa =OY`="@wF@M#!1ư׹dlрL,o-EQeˎAE$ B@B@x@ADAEZaLa = Ld`=+$_@gC@ PABA[  B@B@x@ADAEp= a =e"@~ ! @/=CR$ B@Bt@x@ADAE9LAa =p'@M@%QVMNGg ,г̹ANA@4P B@B@x@ADAEqqaL ={`="@=@ &+$>A  B@B@x@ADAEn|aL) a =Lx="@o@ /C#A[ B@B@x@ADAE*}aa =0`="@"(@ +#+A:Cy֖Y*DFdzva& _JA'  B@B+@x@ADAEy  a =-$_@%@ @>r$  B@BA@x@ADAE\߀?!!a =*=+"@@0AG  B@B@x@ADAE2PaL AAAa =Y= @bQ@ WA.uL  W B@B@x@ADA E aBQa =h`="@ @&v|kѬx*9ߍrvYa& *MC8$ B@B@x@ADAE#ā R`a =aa+$_@@ # @>AA[W B@BA@x@ADAE aaa =ʀ= @7€@ ! @Q`BA/4@G B@B@x@ADAE|bAbqa =F`="@z@ AX@3@OxyH_K^ኜ_~Ua& ңA$ B@B@x@ADA!E4aL$ra" =:`=$_#@w@ ! @Q`AB?A$v % B@B@x@ADA&E1aL) Aa' =;="(@ 3@ /$A)x2* B@B@x@ADA+Ec퀈a, =a"-@w@&C6 /zs4Z iyO]fbe׏a& ZA.ꀂ m/ B@Bm@x@ADA0EΥaLa1 = `="2@g@ #>A3瀂A[A4 B@B@x@ADA5EaL a6 =z=)+7@ᣀ@ ! @+/s8M9 B@B@x@ADA:E8^aa; =d`="<@L\@ '$ T&'um"XWY1P!2 5{=[ > B@B@x@ADA?EaLa@ =a{ +$_A@BX AC B@B@x@ADADE aLaE =`="F@%̀@&g eElSF4RcI:f!%rYG̀$H B@Bg@x@ADAIExaLWaJ =`="`3SK@ʀ@ &+ @>Luɠ M B@B@x@ADANE\ aL}aO =5= P@@ W$ @>/JQ +R B@B@x@ADASE?!ao(aT =F,`="U@=@ iS#B:kNJK;5;\OpIAVg$W B@BiS@x@ADAXEM  zAY =C7$_Z@:@ # @= [G \ B@BW@x@ADA]E1 @Y WA!^ = ="_@a@ !/teC` Wa B@Bs@x@ADAbE8bWAc =dC`="d@̮@g(t!p'k遾:KfU8ZyB&a& nAe8 +f B@BW@x@ADAgE"iDaL Ah =`N`=+$_i@@ &+ @>Aj k B@B@x@ADAlEfOaL!!Am = o=$_n@6g@ :/BCo p B@B:@x@ADAqE!Pa"1Ar =>([`="s@@ #!ĠفbvVeb@^Ⱥ!}AHt u B@B@x@ADAvEف 2@Aw =9%fa+$_x@@ # @>AyA[z B@B}@x@ADA{E AAA)A| =="}@ ؀@ ! @ |1iO~x׀  B@B@x@ADAEbgb}!! =! r`="@v@ Nֲ)>!.d hگ$ՃD GYս 'F+⏀- B@BA@x@ADAEJsaLAR`A = }`=+$_@f@ ! @"`C >Aƌ ` B@B@x@ADAEG~aL aaA =zQ=$_@H@ /2 AM B@B@x@ADAE8aAbqA = `="@L@ +#!AIHgj uf M51t8a& {A$ B@B @x@ADAErA =$_@<`@ # @>AA[ B@B@x@ADAEL A = S€="@@ W!A/C" B@B0<@x@ADAE tbA =z`="@!r@ ҸR-Bo5Tk {c3AN\2 f+q$ B@B@x@ADAEw,aLA =w`=+$_@o@ ! @>Aqn  B@B@x@ADAE[)aL) A =/3="@*@&/WlW  B@B@x@ADAE A =a%@@ # @A5wx料 r e-5t<yF+b  B@B@x@ADAEMaLA =`=$_@߀@ ' @>AF  B@BA@x@ADAE1aL A =="@a@ :! @҃/3C  B@B@x@ADAEUaA =g\`="@S@ y.8%~G \Gq  ja& A7- B@B@x@ADAE"aLgA =`Y`=+$_@P@ ! @>AA[ B@B@x@ADAE aLA = ="@6 @ /=C  B@B@x@ADAEƁ AA =Ea%@Ā@&m~حI6,R$fG 91 SU @3A B@B@x@ADAE~aL A =5`=$_@@ # @>A A B@B@x@ADAE{aL A =="@ }@&/Dw| B@B@x@ADAEb7aa =>`="@v5@&?ӗwA9; I sJO9&A4$ B@B@x@ADAE a = ; | "@f2@ PA1  B@B@x@ADAE쀈) !!a =="@@ #&+'+/CL B@BR.@x@ADAE7 b"1F+ = `=!I@K@ # @ n1({Qxq0  A A B@B@x@ADAE`aL2@a =!`=)@?@ # @>A  B@B@x@ADAE]"aL AAa =Vg="@^@%/C"J B@B`@x@ADAE #aBQa =.`="@ @ m al̎֓ؑS[; @Zۑia& rA$+ B@B; @x@ADAEwрR`a = 9a+$_@@ ! @`z.Ap   B@B@x@ADAE[΀ aaa =#؀="@π@&$/=^A  B@B@x@ADAE:bbqIA =E`= + @@& 㘁gEVg @"CXa& A a A B@B@x@ADA ELBFaL$rA =P`=$_@愀@ PAEA[ B@B@x@ADAE0?QaLa =H="@`@@ !#V+/C  B@B@x@ADAE a = c]a"@\`@ +'A^9v_!|۝%:OxS`Ni1A  A7+ B@B@x@ADAE!LD =_gaI"@@ !$>A  B@B@x@ADA EhaL) Aa! =ι=""@5@&/,# $ B@B@x@ADA%EkiaC& =9rt`=$_'@i@ # @qbgj:_?{ya& %o( A) B@B@x@ADA*E#uaLa+ = 4o`=$_,@f@ ' @>-e . B@BA@x@ADA/E aL a0 =*="1@ "@ ! @$/3%o2w!3 B@B@x@ADA4Ea܀D5 = a"6@uڀ@ m ">R H|=Q a& xIA7ـ-8 B@B@x@ADA9E̔aLA: = `=$_;@e׀@ ! @>A<ր = B@B @x@ADA>EaL a? =x=$_@@@&/CALB B@B@x@ADACE6MaaD =S`="AE@JK@& zo&AKGA[L B@B@x@ADAMEaL aN =R ="O@@ !$A/ԁCP!Q B@By + +P 5@ADAR @E aS =ĺa"T@ @ P'Ba71V-'XoG%l]1` qAU$V B@DBP@x@ADAWEvvaL aX = `="Y@@ !>AZp A[ B@B@x@ADA\EZsaL) !!a] =+}="^@t@&/#]C_ ` B@B@x@ADAaE.a"1ab =5`=$_c@,@&~[?lS: ʵ-uz. CN. Ada e B@B@x@ADAfEL 2@ag =2a$_h@)@ `@=giE j B@B@x@ADAkE0  AAal == m@`@ ! @A/I/Cn o B@B@x@ADApEbBQaq = f`="r@ʝ@ 'A)jP!{4'DR ;As6t B@B@x@ADAuE!XaLR`av =^`= w@@ ! @>Ax y B@B@x@ADAzEUaL aaa{ =^="+|@5V@&/C} ~ B@B@x@ADAEabqa =8} "A@@Hu#!\-r(d@>Bʭ?u%xL3 q@ A   B@B@x@ADAEŀa =π="@ ǀ@ !A/`Cvƀ8\ !kW B@Bg@x@ADAEa bAa =`="@u@%M`KyOx=)մa& A~$ B@B@x@ADAE9aLa = #`=+$_@h|@ &+ @>A{  B@B 5@x@ADAE6$aL) Aa =@="@7@ /CK B@B@x@ADAE6 a =/a%@J@ +# @AELnw"r0 A @ XF B@BA@x@ADAE0aLa =:`=$_@:@ # @>A쀂  B@B$@x@AD>E;aL a =Q="@@ !A.9C  B@B@x@ADAE cAo]  B@B@x@ADAEZSaL a =&"=$_@@ ; /sC N B@B@x@ADAEӁ a = ^aG   @р@ P# @{ @ou|.ky^W‚P%bA`$+ B@B@x@ADAEK_aL)A =i`=$_@΀@ # @>AD N B@B@x@ADAE/jaLa =="@_@ !A/MC  B@B} m@x@ADAEDkaAa =!fKv`="@B@ +ac&IOYȮ&þʩ7[ A6 B@B+@x@ADAE  a = ^Ha"@?@ !>A  B@B@x@ADAE @Y A!!a =a"@4~ /qC  B@B@x@ADAEL"1a = 4a%@@ # @A,hy MBQ ZsfČm8s A @2 B@Bo@x@ADAEmaL2@a =3`=$_@@ # @>Aﯠ  B@B@x@ADAEjaLAAa =t="@ l@ +! @/PCuk ` B@B@x@ADAE`&aBQa = -`="+@t$@ +B6+O28܎(,+Mg#  B@B+@x@ADAEހR`a = *$_@d!@ ! @>A  B@B@x@ADAE Aaaa ={="@܀@ W/NK  B@B@x@ADAE5bbqa =ޝ`="+@I@+Ae7&C}Njj֒h TW^a& g+@0+ B@B+@x@ADAEOaLAra = ޚ`=$_@:@dA   B@x@ADAELaL a =HV="@M@ /1 W B@B/@x@ADAE aAa = `="+@@&<nΏ"2.\{={/龜1kx ~J $ B@B@x@ADA Eua = a @@ PAn + B@B 5@x@ADAEY a =*ǀ="@@&$/ A B@B$@x@ADAExba = `= +@v@ # @Wr_Qϔ*F[3t!P2 zD`@2 B@BA@x@ADAEJ1aLa = |`= @s@ ' @>D  B@B@x@ADAE..aL a =7="!@^/@ +!/VC" # B@B[@x@ADA$E a% =a~ "&@@& e,9o+~ 7{I2ηv)@ A'5 ( B@B @x@ADA)E aLa* = ] `=$_W+@@ &+ @>, - B@B@x@ADA.EaL a/ =̨=$_0@4@&*/\C1 2 B@B@x@ADA3EZapt a4 = ;a`= 5@X@&8gA=Ǹ$ 'lC}In6LrF@ rt6-7 B@B@x@ADA8EaLAA9 =3^%`=$_:@U@dA;T < B@B@x@ADA=E&aLa> == ?@ @ A/z:@uA B@Bs  *@x@ADABE`ˀAaC = p1a"+D@tɀ@ '!z~[Z)hpFW4"!f%oEȀ AF B@By@x@ADAGEʃ2aL aH =<`= I@cƀ@dAJŠA[K B@B@x@ADALE=aL A!!aM =z="N@ށ@ /"/IAOJP B@B@x@ADAQE5<>~@T"1aR =BI`=$_S@I:@ "YIP| -.M{}@XmD' peAT9$U B@BJ@x@ADAVE2@aW =?T X@97@dAY6A[Z B@B@x@ADA[E) AAa\ =T="]@@&$/x^_ B@B@x@ADA`E UbBQaa =``="+b@@ uo ~]:֫{P[O< R-YJ.CZKDc Ad B@B"Y@x@ADAeEueaaLR`af =k`= g@@dAhn Ai B@BA@x@ADAjEYblaL aaak =!l= l@c@&/gCm n B@B@x@ADAoEmaqap =$x`="+q@@! iWn6 x#,.Y+^V )-Ar_@1s B@B@x@ADAtEJց rau =!a v@@dAwC x B@B@x@u =Ay @E.Ӂ Eaz =܀="{@bԀ@/!6|ΡA} B@DB@x@ADA~Eba =i`=!I@Ȍ@ A=*a+ƺ_BM KX晌'wA4  B@B@x@ADAEGaLa =a`= @@+ @+=7 + B@B@x@ADAEDaL Aa =3`= @`@ՙT—̀n˅Ql{@5ZM{L68a& T{C @0 B@B@x@ADAELa =2aI"@`@ @>}A[ B@B@x@ADAEشLAxa =@= @@ @K/WCt  B@B@x@ADAE_pba = w`="@sn@ $ĠJI3J(,Ǽ YB(JEp%]{0a& 4Am  B@B@x@ADAE(aLWa =t`=$_@ck@ @=j  B@BW@x@ADAE%aL a =z/=$_@&@PĠ/CJW B@B:@x@ADAE4 a =a"+@H߀@3RĠlȚ~NsxuD_8WI%`u$W#W7ހ$+ B@B`@x@ADAEaLA =`=$_@9܀@dA۠ A B@B@x@ADAEaL a =W="@@vĠ/LD B@B]}@x@ADAE Raa =X`= +@P@gĠG`rTqGw3!}wv a& AO$ B@B}@x@ADAEt aL-& a =U`= @ M@dAmLA[A B@B@x@ADAEXaL !!a =$="@@  Ġ/oC  B@BA@x@ADAE A"1a = "@@ lٶ-?cY4^,!56@ VA_ B@B@x@ADAEI{aL2@a =`="@㽀@dACA[ B@B@x@ADAE-xaL) AAa == @]y@&/C A B@B@x@ADAE3aBQa =i:`="@1@ :.v㿄/=sELҠ + a& 4 bNJ? B@B:@x@ADAE R`a =\7' A@.@dA A B@BA@x@ADAE @Y) aaa =="@3@ 4A/D  B@B@x@ADAE(bbqa =53`="@@&$6=ދV}ÜZQB|X!$-5#C(  B@Btm@x@ADAE\4aLra =1>`= @@dA힠A[ B@B@x@ADAEY?aL a =c="A@[@ /*CtZ B@B@x@ADAE^@aa = K`= @r@ AG{9zGmW:ru lnڑ A- B@B@x@ADAÈa = Va @f@dAA[ B@B}@x@ADAEʀ a =uԀ="@ˀ@ /eI B@B@x@ADA  E4WbAa =b`="@H@ +4wI:zHBk\ʵ*w5jM@ oXZ$ B@DB@x` => @E>caL$a = ?=܉m`="@8@dA B@B@x@ADA E;naL) a =KE= @<@&/^  B@B@x@ADAE a =ya"@@&xiPV):&i<im,̢q7a& IA  B@B@x@ADAEszaLa =`= A@@dAq  B@B@x@ADAEWaL a = ="@@&/yu  B@B@x@ADAEgaa = n`=" @e@&RQ ~G"f=YѐvFߨD!^ " B@Bx@x@ADA#EI aLA$ =k`= %@b@ * @ >J&B ' B@B@x@ADA(E-aL a) =&=+ A*@]@ /AC+ , B@B7@x@ADA-E؁ p-&a. =lߨa /@ր@&A?9mȋ ƒ`Gha& `A07-1 B@B@x@ADA2EaL a3 =\ܳ`=$_ 4@Ӏ@ # @>J5A[6 B@B@x@ADA7EaL!!a8 =җ="9@2@ !#V/: ; B@B#@x@ADA<EIaA"1a= =5P@">@G@&Ons,ρpAzG/gO(@ iA? @ B@Bm@x@ADAAEaL2@aB =1M`="C@D@dDCA[E B@B@x@ADAFE) AAAaG =$_+H@@&/iAIs J B@B@x@ADAKE^ BQaL =  a"M@r@&k ;kź3HJ IAN޷ O B@Bm@x@ADAPEraLR`aQ =`="R@b@dAS´ T B@B@x@ADAUEoaLaaaV =qy="W@p@$Q`%c A/ @GXH `+Y B@B?@x@ADAZE3+abqa[ =1`="\@G)@&i WDZW85lrh¯:+a& J]( ^ B@B@x@ADA_E〈ra` =. a@7&@ Pb% c B@B@x@ADAdE Aae =N=+$_Af@@&/5Jg h B@B@x@ADAiEbaj =."k@@&} QW@ g<9,mLP*XYa& [F+l$+m B@B@x@ADAnEsTaLAao =`= p@@ 0 @= qlA[r B@B@x@ADAsEWQaL at =#[="u@R@ !$҃.1wCv w B@B@x@ADAxE aAay =`="z@ @ +''# az~bW^\;k^ʅ}5< A״{3;XA{^| B@B+@x@ADA}EHŁ a~ =)a"@@ !>A  B@BA@x@ADAE,  a =ˀ="A@\À@&/RtC  B@B@x@ADAE}*ba =c5`="@{@&5cg_w,&]u'ia& ^A3+ B@B@x@ADAE66aLa =[@`=$_@x@ ' @=A  B@B V@x@ADAE3AaL 4) a =<="@54@&/C + B@BW@x@ADAE a =4La"@@ '&lAos#e&IMTqc%=N\[>OHa& "Y  B@B@x@ADAEMaL9A =0W`=$_@@ ! @=耂  B@BA@x@ADAEףXaL a ==+"@@li/s(s B@B@x@ADAE]_Yaa =fd`= @q]@ @Ġ/EDa+s腳\hVK*#4a& _F+\@0W B@B@x@ADAEeaLA a =co`=$_@aZ@ PAYA[ B@B@x@ADAEpaL?!!a =t="@@ !/CLA[ B@B7@x@ADAE2Ё "1a = {a"@F΀@&A Δ!(1D0M b#À  B@Bg@x@ADAE|aL2@a =ӆ`="@6ˀ@ PAʠA[ B@B@x@ADAEaL AAAa =J=$_+@@ /CA B@BW@x@ADAEAaBQa =G`="@?@ &#! A/w%/W-y0 =R7>$ B@BJ@x@ADAErR`a =Da A@ <@ `@>l;  B@B@x@ADAEV) aaa =#a"@~&/ C  B@B@x@ADAEݱLbqa ='@@ +hj22otU6Tqw'6`z k PccMF+] A B@B+@x@ADAEHjaLA  gxra =`= @嬀@ ! @>E  B@BA@x@ADAE,gaLAxa =@p=+'ua @3@\h@&/C  B@B@x@ADAE"aa =AVg)`= @ @ v# @҃gس;WߣEX uXUp7@ d2- B@BA@x@ADAEہ $a =@逃^&$_@@ PA B@B@x@ADAE؁  a =="@1ـ@ W!/d  B@B@x@ADAEba =?`="@@&Ep-~C ѣ4M~~ӂ!l0na& 6F+$ B@BE@x@ADAEKaLAa =0`= @@ &+ @+=덠 C B@BA@x@ADAEHaL$a =R=$_+@ J@ /-CvI B@B@x@ADAE]ao a  `="@u@ +#!A48S- !l<vHBM&Oůy ͽA$ B@B{ XGa`x@9 A @EǼa = $_@e`@ # @>  B@DB@x@ADA ELa =À=" @ߺ@ W!A/;C K + B@BW@x@ADAE2uba = { #@Js@ 7ɆR:<F1/ÜY Ar  B@B @x@ADAE- aL zA { =x`=$_@6p@ ! @>Ao  B@BA@x@ADAE*aL A! = Q4="@+@ /A%k & B@B@x@ADA'EV+aL !!A( ==")@@% /d* + B@BpW@x@ADA,EV,a"1A- =]7`=".@T@ĠrxT75chY' t]n7a& "Y/\-0 B@B@x@ADA1EG8aL2@A2 =ZB`=$_3@Q@ PA4@A[*5 B@B@x@ADA6E+ CaLAA)A7 = = 8@[ @ &+ @+J/(9 : B@B@x@ADA;Eǁ AB!!< =fNa"=@ŀ@ #l0?bsk_XH2? B@B@x@ADA@EOaLR`AA =ZY`= B@€@ # @"`(=$C D B@B@x@ADAEE}ZaL) Aaa BF = 5ц="G@0~@&/AH I B@B@x@ADAJE8[abqAK =3?f`="L@6@ c;]l~3^H.%oa& AM mN B@BtA@x@ADAOE r45#P =/R2 S B@B@x@ADATE퀈!s!U =='uV@@ &+ @+A/[CWqX B@Bu@x@ADAYE\r!cAZ = }`="[@p@ #A',;\}MraV9hc:SvK V\ܦ ] B@B@x@ADA^Ea~aLA_ =`=+$_`@d@ # @=Aa b B@B =Q@x@ADAcE^aL AAd =sh="e@_@ ! @Ġ/DfGg B@B@x@ADAhE1aAi = `="j@E@&WZ$={$J~p*j- m052a& k$+l B@B+@x@ADAmEҀAAn =a+$_o@5@ &+ @>ApA[q B@B@x@ADArEπ As = Iـ=$_t@Ѐ@ />uv B@B@x@ADAwEbAx =`="y@@ +#!'xIX9]E Nӈ0gEuR/MYa& ͤF+z${ B@B@x@ADA|EqCaLA} =`=$_~@ @ # @>Ak A B@B@x@ADAEU@aL A =J="@A@&/;C +W B@B@x@ADAE A =a"@`@ P:`E"!rGxqf$[a& A\@0 B@BP@x@ADAEFL A =aI"@@ !>A@  B@B@x@ADAE*aL  A = ﺀ='u+@Z@ &+ @+/r4C A B@B@x@ADAElaa =^s`="@j@ +#ATd`D+ry0  1  B@B@x@ADAE%aLg a =Yp`=+$_@g@ @=  B@B@x@ADAE"aL !!a = 5+="@0#@ 6h/!   B@B @x@ADAE݁ "1a =;a"@ۀ@ PX`>_G%Wz {KI~+8jF+- B@BP@x@ADAEaLA2@a =/`=+$_@؀@ ! @>AנA[ B@B@x@ADAEՒaLAAa == @@  `@A/$FCq B@B-@x@ADAE\NaABQa = U @"@pL@ +#!A!sE^,^;sY @ xK$ B@BA5@x@ADAE aLR`a =R`=$_@`I@ # @>AHA[ B@B@x@ADAEaL Aaaa = w ="@@%J/P~F B@B*@x@ADAE1 bqa =!a"@E@&|Z7]>Xd&)fΫbN% ݴ 8Jwy`F+A[ B@Bm@x@ADAEw"aLra =,`="@5@ &+>A A B@B@x@ADAEt-aLa =69`='u+@.@A:Mv{_S[Ŝ5?LrO|a& ҧC-  B@BA@x@ADAEq耈a =3Da"@+@ Pj*  B@B}@x@ADAEU a =%= @@.$C  B@B@x@ADAE۠Eba =P`="@@AĠ&H9B`]Vt~ ̿9Va& #[  B@B%o@x@ADAEFYQaLa =[`=+ @ߛ@ P? A B@BW@x@ADAE*V\aL) a =_="@ZW@ [!$/Q#  B@B@x@ADAE]aa =]h`=!I@@%Q5U$KmYJbV^va2I NF+0  B@B:@x@ADAEʁ :a =Ys @ @ PAA[ B@B@x@ADAEƁ a =Ѐ="@/Ȁ@ /{ǀ B@B}@x@ADAEtba =.`="@@ #$+Aŵ}̤3*RnF nAa& 3D@0 B@B@x@ADAE:aLA' =2`=+ @}@ # @>| A B@B@x@ADAE7aL) Aa =A="@9@ @/ŎCp8!&  B@B@x@ADAE[a = a" @o@$mK絊c<>n!R"#a& _A   B@Bx   @'@x@ADA EƫaL a =`=+$_@_@ &+ @>:퀂  B@AbBA@x@ADAEaL !!a =v=$_@ک@PĠ/CF"dg B@B@x@ADAE0da"1a =j`="@Db@ #!Ġ LS]ﱥҫD=\vpk02a& Moma$+ B@B@x@ADAEaL2@a =g`=$_@4_@ PA^  B@B@x@ADA!EaL i AxAAa" =@G#="#@@vĠ/u$% B@B@x@ADA&EՁ BQa' =aG@e]@g (@Ӏ@&Ag%sd7qQq0^!BA ZF+)Ҁ$* B@B+@x@ADA+EpaLR`a, =`= -@ Ѐ@ &+ @+= .iϠA[IN/ B@B@x@ADA0ETaL aaa1 =!="2@@ &+/}vC3A4 B@B}@x@ADA5EEaAbqa6 =L`="7@C@ #A_>سf!"@yPl/s fra& A8[$9 B@B@x@ADA:EE ra; =Ia"<@@@ #>=? > B@B}@x@ADA?E) @Y) a@ =a"A@Y~ }!/SCB zC B@Bg@x@ADADELaE =]a!IF@Ĵ@&MjklW\DlmUdvʛ8qR,TAG0 H B@B@x@ADAIEoaLaJ =X`=$_K@@ &+ @JAL M B@BA@x@ADANEk@TaO =u= P@/m@&/bxCQl R B@B@x@ADASE'aaT =9. `="U@%@ +#!҃\ijZiHw!>ZYa& "AV$W B@B+@x@ADAXE߁ aY =-+$_Z@"@ ' @>A[! \ B@B@x@ADA]E Aa^ =="_@ހ@& /ԄC`p݀ a B@B@x@ADAbEZbac =#`="Ad@n@&f~z2`'!N6z%? Feڕ-f B@B@x@ADAgEP$aLah =.`=$_i@_@ &+ @>jA[Y ` k B@B@x@ADAlEM/aL am =yW="n@N@ &+/sWDoEp B@B@x@ADAqE0 0aAar =;`="s@D@&1xq(rz47W~(_Lk,} yAt$u B@B@x@ADAvEAw = Fa"x@7@ #>Ay z B@B@x@ADA{E~) a| =NȀ="}@@&/r~ B@B|}@x@ADAEzGba =R`=%@x@%J[2q<|(+ >+}Dw@4g@` + B@B@x@ADAEo2SaL a =}]`=$_@ u@ PAit  B@B$@x@ADAES/^aL !!a =9="@0@ &+#VA/QC  B@Bq@x@ADAE "1a =ia"@@ +#'OC'  B@B@x@ADAE)uaL AAa =="+@Y@&/aC  B@BA@x@ADAE[vaBQa =`b`= @Y@ ]|t{կVR.(`8$*  b _YA  !G/-+ B@B@x@ADAEaLAR`a =X_`=$_@V@ ! @> j@ B@B@x@ADAEaLaaa =="@.@ WA/uC B@B@x@ADAÈAbqa =9Әa"@ʀ@ #$Q $Ø ??$Bzڠz W%oA$ B@B+@x@ADAEaLra =-У`="@ǀ@ #>Aƀ  B@B@x@ADAEӁaL) Aa =="@@&/Co f5 B@B@x@ADAEZ=aa = D`=$_@n;@ vp_.O]Y+t6kO˥a& *A:  B@B@x@ADAEa A$_@^8@ @+=7A[c @ B@DB M@x@ADAE a =u="@@&/ܱCD B@BJ@x@ADAE/ba =۴`="@C@& UeS jKXC=gylh+na& A  B@B@x@ADAEfaLa =ױ`=$_@3@dA  B@B@x@ADAE~caL a =Fm= @d@ W* @+$/nC+ B@B@x@ADAEaa =%`="A@@&.[?q? ]sM?g)mh-8gDd S jA$+ B@Bg@x@ADAEo׀*a =" @ @ * @>Ah A B@B@x@ADAESԀ6ha =a"@@ } &rSq~oqYx& yL@?C^$ B@B@x@ADAEDHaLZ: = "@ኀ@ ! @>=@ B@B6h@x@ADAE(EaL a =N="@XF@+ |11C  B@B@x@ADAEaWa =! ``=)@ `@ # @Ġr qKsL˱!q #A/A B@B@x@ADAEL a = WaI$_@`@ P W B@B@x@ADAEL) !!a =ʿ="@-@ !/XC B@B@x@ADAEqb"1a =9x%`="@o@ }8d"ɥѼK\\Ȕ\T5,_a& q A  B@B}@x@ADAE)&aL2@a =,u0`= @l@ ! @+= k  B@BW@x@ADA E&1aL AAa =0=$_+@(@PA/!Co' j B@BP@x@ADAEY BQa =E4xaa? =;`="+@@2@ '!Ġ1`dFi{V-A9 S_f|e^gAY AB B@BA@x@ADACED aD =8 E@/@dAF= AG B@BA@x@ADAHE(  aI =="J@X@+/gK L B@B@x@ADAMEbaN =[`="+O@£@&vj|{ 5̗%8I64 GJP.-Q B@B+@x@ADARE^aLaS =V`= T@@ @+>}UA[AV B@B@x@ADAWEZaL aX =d="Y@-\@ W/CZ[[ B@Bt @x@ADA\Eaa] =4`=%W^@@ PA5ڹ53.yhqDڼG,zeCQsa& ۘA_$` B@BP@x@ADAaE΁ Ab =0a$_c@@dAdA[e B@B@x@ADAfEˀ ag =Հ="h@̀@ /-Ciǹ"aWj B@B}@x@ADAkEYbal = `= m@m@&Ce$߇mZ T5T +Ka& L%Anل$o B@B@x@ADApE?aL aq =`= r@]@dAsA[c @t B@B@x@ADAuE<  B@B@x@ADAE'aLa =="@W@ A/A  B@BA@x@ADAEJaAa =^Q'`="@H@ xiz 5UW"=:Oia& ̫A. B@B@x@ADAE(aLa =VN2`="@E@>A[ B@B@x@ADAE ) Aa = 3 @,@&/:C B@B@x@ADAEa =0>a"@@%&U|kO:&GCJ:Baa& \ m B@Bu@x 9ADA @Es?aLa =+I`="@@dA絀  B@DB@x@ADAEpJaL a =z="@r@ A/qc'mq"f5 B@B@x@ADAEX,Kaa =3V`="@l*@ +A.k373fE),Fβ~a& F+)  B@B+@x@ADAE䀈 a =0a)m@a'@dA&A[c @ B@B@x@ADAE a = p=+ A@@ / CC  B@Bt@x@ADAE-bba =m`="@A@ &ְE+hZ0I񀞣xyha& A$+ B@B@x@ADAEUnaLA =ڠx`= @5@dAA[ B@B@x@ADAE|RyaL a =P\="@S@ /uC+ B@B*@x@ADAEzaa =`="@ @&(еf ۝6 vwZA $ B@B@x@ADAEmƀ a =a"@ @dAgA[ B@B@x@ADAEQÀ) !!a =̀= A@Ā@ W/jC $-a B@BW@x@ADAE~b"1a =`="@|@&3R:awfTDJ(~vx_@a& X  B@B+@x@ADAEB7aL2@a =`= A@y@dA<  B@B@x@ADAE&4aLAAa = =="@V5@&/]D  `BW@x@ADAE BQa =aa"@@ e@^c=a?!4=}VA] )j!v"` 2d-  B@B+@x@ADAE``a =U`= @@dA A[  B@B@x@ADA EaLqaqa =3g`= A @^@A ڹi'ٔ["Je?1D' 6DØ B@B}@x@ADAEaLra =+d`="@[@dZA[ B@B@x@ADAEaL Wa =="@@  +1/Cm B@BW@x@ADAEXрa =a"@lπ@ Ġ0f~ =`= ?@@ ! @`> @f A B@BA@x@ADABEQhaL6haC =!r=+ AD@i@ W/?CE F B@BW@x@ADAGE#a}aH =*)`= I@!@$A*H}u!{ !JW$+K B@B$@x@ADALEB܁ AAM ='4a$_N@@ # @>O;A[P B@B}@x@ADAQE&ف  AaR =="S@Vڀ@ }!#V҃/ICT AU B@BP@x@ADAVE5bAaW =d@`="X@@ 'tI$*[ w*wȈ)AY, +Z B@B@x@ADA[EMAaL} a\ =UK`="]@@ !>A^ _ B@BA@x@ADA`EILaLA!!aa =S="+b@/K@ /ߎCcJd B@B@x@ADAeEMa"1af =6 X`="g@@%$G\=R|ҷ?:3߶ c#& =.Ah$i B@B@x@ADAjE콁 2@ak =* ca$_l@@ # @=DKmb` `au iFn B@B@x@ADAoEк @Y AAAap =Ā="q@@A/Crls B@BP@x@ADAtEWvdbBQau =!A}o`="v@kt@&**ۢqƔXElܟg~ iAws Ax B@B"@x@ADAyE.paLR`az =yz`=$_{@[q@ PA|p } B@BA@x@ADA~E+{aL aaa =5=+ A@,@ &+ @+Ġ/!ECB B@ B@x@ADAE, l + bqa = a!I@@@ P# @@^| !O[1?"֒Psg ?䀂$+ B@B@x@ADAEaLAra = `= @4@ # @>Aဂ  B@B@x@ADAE{aL a =G="@@&$/XrD B@Bg@x@ADAEXaa =^`="@V@&Ibhyz$Yrnd_&vK-a& 3AU$ B@B@x@ =A @ElaLa =[`=$_@S@ &+ @>eRAY B@DB@x@ADAEP aL a == @@ &+ @A/C W B@B@x@ADAEȁ a = ϵ #@ƀ@&Z@kbZ ?[_"àD*YS AW B@B@x@ADAEAaLa =`=$_@À@ # @=;  B@B@x@ADAE%~aLa =="@Y@&/&Cš + B@B@x@ADAE9aCa =h@`="@7@ '+Q&5h=Z1[~1S|a& A0  B@B@x@ADAE a =X=$_@4@ ! @>A  B@BA@x@ADAE a ==+"@/@ &+ @A/ -C  B@B@x@ADAEba =.`="@@ZЕ)%`ő5c79[|FA$ B@B[@x@ADAEbaL$A =-`=$_@@ # @=A夀  B@B@x@ADAE_aL A! =i="@a@ v! @$/Cl`A[m B@BB@x@ADAEVa=! =!A"`="@j@&$ƶ $ƒ]@kSjT` ; A$ B@B@x@ADAEӀ$ 6! bLG@Qd_@Z@ PA  B@BA@x@ADAEЀaQL !!A =rڀ=$_@р@ /CA" B@B@x@ADAE,`"1A =ܒ`="@@@ #!+A=trC=dNK2YCa& A`Ȣ B@B@x@ADAED`2@A = ԏ`=)@0@ # @>A` B@B@x@ADAEzA`) AA&+ =GK="@B@&.U"C B@By m@x@ADAE B"! =+a"@*`@ -&w íL?Xa+=Xߑ`! $A`Ge#*;` XF B@B@x@ADAEkLR ! =6`"@5`@ !>e` B@B@x@ADAEOL aaA =$='u+@@ &+ @#`C /@G  B@B@x@ADAEm7bbqA =tB`="@k@A5} M>q>p'Hi AV` B@Bm@x@ADA, @EA&C`rA =~qM`=+$_@h@ # @=:` B@DB@x` =A @E%#N`` A =,="@U$@&/+C  B@DB@x@ADA Eށ A =[Ya" @܀@ '!_)wx65Z%sק;K[a& nyA +- B@B@x@ADAEZaLA1 Td`=+$_@ـ@ ! @=  B@B@x@ADAEeaL`A =ǝ="@*@ &+ @A/UC B@B@x@ADAEOf`AA ==Vq`="@M@ #ojn ~Ga& ?`Ȣ B@Bm@x@ADAEr`A =)S|`=$_ @J@ # @=!I`" B@B@x@ADA#E}` AoA$ =Lj`="%@j@ !^1r5uA9"=Ϭ@ mD&ֽ`' B@B@x@ADA(Ex`A) = Ó`="*@Z@ $>+`, B@B@x@ADA-Eu`?AxA. =@q="/@v@ ! @^/C0@+1 B@B@x@ADA2E+1aA3 = 7`="4@?/@ R3O8I7x? #qfg-skC %[5.`6 B@B@x@ADA7E逈 A8 =4`+$_9@3,@ ! @>:+`; B@B}@x@ADA<Ez YA= =F=$_>@@ /#D? @ B@B@x@ADAAE`aB = 5`="C@@$'# Z],ib'+Wc6Vf/C+AD$+E B@B$@x@ADAFEkZaL aG =`=+$_H@@ # @>AId J B@B@x@ADAKEOWaL`) !!aL =$a= M@X@ ! @/CN AO B@B@x@ADAPEaA"1aQ =`="R@@ +'i!} dmd4 K;YxzqASV`ȢT B@B3R@x@ADAUE@ˁ 2@aV = ~`$_W@ @ ! @>AX9 AY B@B@x@ADAZE$ȁ aQ AAa[ =р="\@Tɀ@ W /_C] ^ B@BA@x@ADA_EaBQa` =[`="a@@&ʭ+io]7E|hRtc Ab+`Ȣc B@B@x@ADAdE<`R`ae =W`="f@~@ #>Ag`h B@B $M@x@ADAiE8`) aaaj =B='u+k@):@&/&Cl9m B@B@x@ADAnEbqao = 1a"p@@ '!a;u?+$W*[f," 1 ;J? RAq`mr B@B@x@ADAsE`rat = {(bL+$_u@@ ! @=:vaw B@BA@x@ADAxEϩ aL ay =="z@@ &+ @A/Z~C{k| B@B@x@ADA}EUe aa~ = l`="@ic@ Ġ?#c#tۉW8XDwO`( a& +tAb` B@B @x@ADAE`a = h `=$_@Y`@ # @=_  B@B@x@ADAE!` a =t$=$_@@&/XC@ B@B@x@ADAE*ց a = ,a"A@>Ԁ@&? BẢjq@ۦdTeHz= ݞAӀ` B@B@x@ADAE-`a =7`=$_@/р@ PAРA[ B@B@x@ADAEy8` a =I="@@ &+$+$/+C B@B@x@ADAEG9aa = 5MD`="@E@ S#A S`wG۴y~@Ӣ" L ?AD$ B@B@x@ADAEja =JOa"@B@ #$=AdA  B@B@x@ADAENaQ a =P`8"+@~~&/ɊC "#a W B@B@x@ADAEշLa =~['@鵀@ ;`1Ţ a6bq V`<*@a& "U  B@B@x@ADAE@p\aL" = }f`=+$_@ٲ@ @>9  B@BA@x@ADAE$mgaL a =v= @Tn@YA/N  B@B6h@x@ADAE(haa = j/s`="@&@%A"d5 E ~6e8 ͞* B@B :  @'@x@ADAE  a =R,~$_@#@ PA  B@AbB@x@ADAE݁  !!a =="@)߀@ !+/iIAހ B@B @x@ADAEb"1a =,`="@@<$4,U#HYiGFձ\c Zih a& `j@ B@B+@x@ADAEQ`2@a =(`= @@ * @JA㓠A[ B@B #+@x@ADAEN` AAa =X="@O@ /FEj!7CZW B@B@x@ADAEU akHBQa = `="@i@ #+>pucA3hͭ@xEE^kyRa& ,F+$ B@Bm@x@ADAE€R`a =@"@\@ #>  B@B@x@ADAEaQc aaa =sɀ="@@&/ C? B@B@x@ADAE*{`bqa =ׁ`=$_W@>y@ +-68z,m zԔ0\-a& x + B@B+@x@ADAE3aLra =~`=$_@.v@ ! @JAu  B@B mA@x@ADAEx0aL`a =A:=#= @1@ &+#V/k B@BiS@x@ADAE a =`"@@AX 7WݺC5wqlƩUa& yF+适  B@B$@x@ADAEjaLa =`=$_@@ # @=c怂  B@B@x@ADAENaL a>7="@~@%/C A B@B`x@9 A @E\aa =}c`= @Z@ ' @6UHI̓t09#wV; ʞ` uAT@0- B@DB@x@ADA E?`a =``=$_ @W@ @= 8A[ B@B@x@ADAE#`a ==H@A@S@ &+K/(C  B@B@x@ADAÉ Aa =ja"@ˀ@ +b}¨P1?uˣ|@L u/A* B@B@x@ADAE@Ta =R `="@Ȁ@K=  B@B@x@ADAE aLbܤb Aa =Ԍ="@(@BȠ~’/ W! B@B m@x@ADA"E> aa# =0E`=%$@<@ uO)%So6HYWCtH{a& D%; & B@B@x@ADA'E( ='B"$_)@9@ ! @JA*8 + B@B@x@ADA,E a- ==".@@&$/C/iA0 B@B@x@ADA1ET#ba2 = .`="3@h@ #$g XOrq,ӡÔ\cA9NKa& 4A4Ԭ 5 B@B@x@ADA6Eg/aL a7 =9`=$_8@X@ ' @>A9 : B@B@x@ADA;Ed:aL !!a< =sn="=@e@ ! @/qC>?? B@B@x@ADA@E) ;a"1aA =&F`="AB@=@&"_ q?׿ԥFb Al C^͞DKC$+D B@B@x@ADAEE؀A2@aF =#Q$_G@.@ &+ @>HA[I B@B@xG 9ADAJ @ExՀ; AQaK =]a"L@@ W Ƕ:{psM0lPhM,!T|a(DM$N B@DB@x@ADAOEiI^aLR`aP =h`="Q@@ ! @>RbA[S B@B6h@x@ADATEMFiaL aaaU =P="V@}G@ $Ƕ/zW X B@B@x@ADAYEjaWbqaZ =u`=!I[@t`@&uK+{wF4˝&-7r(A˫| \D\T] B@B@x@ADA^E>Lra_ =|aI `@`@ # @>a8 b B@B@x@ADAcE"L) ad =="e@R@&/JpCf g B@B}@x@ADAhErbai =Vy`="j@p@ '$AeLl`7H\V|&~)ngb>Ak) l B@B@x@ADAmE+aLan =Qv`=$_+o@m@ ! @=:p q B@BW@x@ADArE'aL as =1="t@()@ &+ @A/HCu(v B@B@x@ADAwE~〈ax = /a!Iy@@ 1# @~[aӗ^4[[sքf 2/uAz-{ B@B:@x@ADA|E雤aLa} ='`=$_~@ހ@ # @=݀  B@B@x@ADAE͘aL a =="@@ ! @/YCiow B@B>@x@ADAESTaa =[`="+@gR@ !IH:ZOs*mj Kׁa& AQ  B@B`@x@ADAE aLa =W`=$_@WO@dANA[c @ B@B@x@ADAE aL a =n="@ @ /iC> B@B@x@ADAE)Ł q a =a%@AÀ@ }0ċ8 ⪋51֜/`Ra& A€$ B@B@x@ADAE}aLA =`= @-@dAA[ B@B@x@ADAEwzaL) a =D="@{@&/oC B@B@x@ADAE5aa =<`="@4@%Ż,"u5m{l_഍CA~3 + B@B@x@ADAEi*(a =9 @1@dAb0 A B@B 4#@x@ADAEM !!a =)="@}@/oC  B@B @x@ADAEӦbk ƴ@s"1a =@ A@礀@ } `@mJ5Dݡ*N6Be@ \S$+ B@B}@x@ADAE>_aL2@a ={ `= @ء@dA7A[A B@B@x@ADAE"\ aLAxAAa =@e="@R]@ /6D  B@B{ +`@x@ADAEaBQa =Y`= @@ `@ =e~[0']N2/MA($ B@B@x@ADAEЁ R`a =U$a @@dA A[ B@B@x@ADAÉ aaa =ր="@'΀@ /C̀ B@B@x@ADAE~%bAbqa =.0`= @@&<`ۃp*S:~d1$˧-)0a& <A$ B@B@x@ADAE@1aLra =&;`= @@dA₠A[ B@B@x@ADAE= + B@B@x@ADAESa =!AHa"+@gG`@ A;NIi΂Z#*U *d B V A B@B@x@ADAE!aL) a = = @Q@&/5C A B@B@x@ADAE a =Xåa"+@@&$RڡZ-0n"Y .mIa& sA#(  B@B@x@ADA!EuaL a" =P`= #@@dA$ % B@B@x@ADA&EqaL!!a' ={="(@&s@ A/_C)rm* B@B@x@ADA+E}-a"1a, =94`="-@+@ 3AXmc`XTs:[3/?A ~ L %A.* / B@Bc@x@ADA0E倈2@a1 =%1 2@(@dA3'A[ 4 B@B@x@ADA5E AAAa6 ==+ A7@@^ /UD8h 9 B@B@x@ADA:ERbBQa; = `="<@f@ +4TΆDcLeͧ< f|u %D=қ$+> B@B+@x@ADA?EVaLAR`a@ =`= A@Z@dAB C B@B@x@ADADESaL aaaE =m]="F@T@ A/ӖCG=#aH B@BW@x@ADAIE(aAbqaJ =`="K@< @&'hb{Aˌ1smĦv/sa& ?AL $M B@B{+@x@J =AN @EǀraO =a"P@, @dAQ $R B@DBA@x@ADASEvĀ aT =C΀= AU@ŀ@&/ɣCVW B@B@x@ADAXEbaY =h"Z@~@ PADvV^]w4D{oV3\a& A[}}$\ B@Bt@x@ADA]Eg8aLa^ =`=G@f@ A_@{@dA`az a B@B@x@ADAbEK5aL6hac =`= d@@$6h]Oi=Y>Łrְ鞹MCeR `au jf B@B$@x@ADAgE=aLah =z%`= Wi@@dj6A[k B@B@x@ADAlE!&aL am =="n@Q@/@aCo dp B@B@x@ADAqEa'aar =Th2`= s@_@  Ġ2_@kj{U !$4^v*At' u B@B @x@ADAvE3aL/aw =e=`= x@\@dyA[z B@B@x@ADA{E>aLa| = ="}@&@  Ġ/[C~ B@B@x@ADAE}ҀWa =,Ia"@Ѐ@ĠOo$IcŬw^ 9 @dA=  B@B@x@ADAE) !!a = yma"@~A/ZPC< B@B+@x@ADAE'LA"1a =Ϻx'@;@ ;ݷͩɶBVmZ KY5,;<A A B@B[p@x@ADAElyaL2@a =`= @,@dA  B@BA@x@ADAEviaL AAa =:s=+ A@j@ /tCA[ B@Bo@x@ADAE$aBQa =+`= @#@&$6wȋﶺ̨7qn4[ )0@Ra& xA|"$+ B@B@x@ADAEg݀R`a =( @ @ +# @*=?` A B@B}@x@ADAEK aaa =  ="@{ۀ@&$/C A B@B$@x@ADAEѕbl1bqa =`="@哀@ AeۙNF>v]J_Ea& Dt m B@B@x@ADAE/aLa ={`= @r@ &+ @+=Aq  B@B@x@ADAE,aL a =6=+$_+@-@ /7Cg  B@BsA@x@ADAEQ a =a @e@ @A"Q>2R!xZa& d倂$ B@Bq@x@ADAEaLa =`=$_@U@ # @>   B@B@x@ADAEaL`Aa = h="@Ԟ@&$/lj@  B@B:@x@ADAE&Yaa = _8,"@:W@&} J™ ]'! nìcQZy&O F+V- B@Bx@x@ADAEaLA =\`=$_@*T@ PA$S  B@B@x@ADAEuaL Aa =B= @@  `@+g/!C B@B@x@ADAEɁ Aa =a" @Ȁ@ (#!A6onF&jvF;y$cTsyw$ |ǀ$ B@B@x@ADA EfaL a ='`= @ŀ@ # @>A`Ā  B@B@x@ADAEJ(aL`A!!a = ="@~@&/w$ +c  B@B@x@ADAE:)a"1a =A4`="@8@&1IZB`żizϕ X[4բa& F+Q  B@B@x@ADAE; 2@a =y>?a"@5@ &+>5  B@B@x@ADA $`E @AAa! =='u"@O@&/)C# A$ B@DB@x@ADA%E@bBQa& =OK`="'@@!Ab^!g=޴9{bX#1AAa& (& ) B@B@x@ADA*EdLaLR`a+ =NV`=$_,@@ PA- . B@B@x@ADA/E`WaL aaa0 =j="1@%b@&/%dC2aA[3 B@B@x@ADA4E{Xabqa5 =##c`="6@@ '! 1JD]&PEFj60jHa"ha& 7A7@08 B@B@x@ADA9EԀgra: =( na ;@@ @=<A[= B@B@x@: =A> @Eр@ a? =ۀ="@@Ҁ@ &+ @/Af$B B@DB@x@ADACEQo AaD =z`="E@e@ PR2#*=3@*A4S'O*~Lk@ DFъ$G B@BP@x@ADAHEE{aLaI =`=$_J@U@ @=KA[L B@B@x@ADAMEBaL aN =gL="O@C@ }/WCP;WQ B@B}@x@ADARE& aS =a"T@:`@&% RJd=\К OYhR)a& &:AU$V B@Bm@x@ADAWELaX =aI"Y@-`@ &+>AZ [ B@B@x@ADA\EtLa) a] =E=)+^@@&/C_ +` B@B@x@ADAaEna ab =u`="c@m@ 4#!ޡ&rNio*Ȃ~ʏa& bAdl e B@BJ@x@ADAfEf'aLA bag =r`=+$_`= @3h@j@ ' @>Aici j B@BA@x@ADAkEJ$aL@Yal =AV.="m@~%@ `! @g/Cn o B@B@x@ADApE߁ paq =a"r@݀@&D]Z7);͈H\ ma& AsT$+t B@B@x@ADAuE;aLA zAv =y`=+$_w@ڀ@ &+ @>Ax4 y B@B m@x@ADAzEaL A A{ = =$_|@O@&/sC} ~ B@B@x@ADAEPaA =RW`="@N@ m#!J&Daí;'o3>6QO<}9HA%@4- B@Bm@x@ADAE aL A =NT`=$_@K@ ' @>A K  B@B@x@ADAEaL; !1A =7`="@@ -&!K?&|oN`2YJ]G=}Dra& J/ B@BC@x@ADAEyaL2@A =#`="@~@ $>߻  B@B}@x@ADAEvaL AA)A =="@w@"YW/F+$eA B@B$ADA @EP2aB%! =9@L"@d0@ WK#@y&R5J$P59FR@ ./  B@DBA@x@ADAEꀈ}`A =5a+$_@T-@ ! @"`C >,  B@B@x@ADAE aaA =o= @@ W&+ @/+9!;  B@ B@x@ADAE%b}qA =ک`="@9@&2S{%j IM)!e],! A$+ B@B} m F@x$aDA @E[aLrA =ͦ)`=$_@)@ # @=  B@DB@x@ADAEtX*aL A =Eb="@Y@&/A B@B@x@ =A @E+aA = ?=6`="@@ '+ @d * &T5V*"5 Dz@3m+ B@B@x@ADAEèA =A$_@@ @>A^A[ B@B@x@ADAEIɁ  A = Ӏ=+"@3{@yʀ@ &+ @A/C  B@B@x@ADAEЄBbA =AVM`="@䂀@ }w/&Gyg&ߞ F!9Ma& *AP B@Bg@x@ADAE:=NaLA = |X`=+$_@@ @=A4  B@B *@x@ADAE:YaL) A =C=$_@N;@ }/ܔC  B@B@x@ADAE #2 =Rda"@@ : н Hdh- jU{a& T% A B@B:@x@ADAEeaLA =Mo`=+$_@@ ! @>A  B@BA@x@ADAEpaLA == @$@$ @^` /D ` @ XF B@B@x@ADAEzfqaA =/m|`="@d@&}Յs4[b{8V/TEAc$ B@B@x@ADAE}aLA&+ ="j`=$_@~a@ # @Q`AB?A`  B@B@x@ADAEaL A A$%="@@&/Ae# B@B@x@ADAEOׁ a =ޓa"@cՀ@ '&l k,ϙ蠎S -~8Ѕa& hAԀ- B@B@x@ADAEaL a =!ڞ`=G u^@TҀ@ !>AѠ  B@B@x@ADAEaL !!a =j=H@h@!"+@΍@ &+ @/DC:%  B@x@ADAE%HaA"1a =N`="@9F@ #!v%Ȯ@nh\.<FJA% AE$ B@B@x@ =A @EaL2@a =K`="@(C@ #> B  B@DB@x@ADA Es) AAa =7a" @~%/ CA[e B@B$@x@ADAELBQa =a$_+@@& jII7☌z`'-Xa& BAz  B@B@x@ADAEdqaLR`a =`=$_@@  `@>A^  B@B@x@ADAEHnaL aaa =x="@xo@%/C  B@B  }@x@ADA%`DE)abqa =|0`="!@'@&$q;F&,IZoicf>RA"O # B@Bu@x@ADA$E: ra% =w- &@$@ PA'3 ( B@B@x@ADA)E߁  a* =="+@N@ W!'+/nC, - B@BW@x@ADA.Eba/ =Y`=!I0@@&$*4Awduҧa.p q]a& wA1$-2 B@B@x@ADA3ESaLCa4 =M`= 5@@ PA6A[W7 B@B@x@ADA8EOaLa9 =Y=":@#Q@&/SC;P< B@B@x@ADA=Ez aAa> =* @"?@ @&ze{1tOHyI_˘@ r@$A B@B@x@ADABEÀaC =&a"D@@ '$=E F B@B@x@ADAGE A[H =ʀ="I@@&/*rJd +WK B@B@x@ADALEO|baM = `= AN@cz@ m' @$k7MtL>@~p[cpdW%+"\M&~ba& 3/Oy P B@BA@x@ADAQE4!aLaR =+`=$_S@Sw@ ! @=Tv U B@B@x@ADAVE1,aL aW =j;="X@2@&/œIAY9AZ B@B@x@ADA[E$ a\ =7a"]@8@ #4G gKLN 9!lea& ^ꀂ _ B@Bj@x@ADA`E8aL"a =B`=$_b@(@ PAc瀂 d B@B@x@ADAeEsCaL af =C="g@@ ! @+/ hi B@B@x@ADAjE]Daak =dO`=!Il@ \@&(h~-?4*1)Àk=6a& F+my[$+n B@B@x@ADAoEdPaLA ap =aZ`= q@X@ &+ @>Ar]A[s B@B@x@ADAtEH[aL !!au =="v@x@ /Cw x B@B@x@ADAyE΁ A"1az =fa"{@̀@&+_wGh;;,pi' Ť~70a& A|N A} B@B@x@ADA~E9gaL2@a =wq`="@ɀ@ #>2  B@B@x@ADAEraLAAa =퍀="@M@&/C A B@B@x@ADAE?saBQa =TF~`= A@=@&.Tߥ5d(6n~wZ{ĉlSa& y$ B@Bwg@x@ADAE R`a =LC$_@:@ `@JA `auiF B@B@x@ADAE @Y) Aaaa =="@"@ }cV/ 2D B@B}@x@ADAEybbqX =%`="@@ #$$w%t!Vj^lh4ݏ>a& {A ` B@B@x@ADAEhaLra =!`= @}@ # @>Aݪ  B@BA@x@ADAEeaL6ha ='`="@b@$6hFLQƹhh_|>X|ڲUJdk INC`4 B@Bx@x@ADAEـa =$a"@S@ $>$ B@B@x@ADAE a =n=%A@׀@ ! @B/bC9 + B@B@x@ADAE#ba =И`="@7@ &+ =6$5 #dT-otxO@a& 'A$ B@BA@x@ADAEJaLa =`=+$_@+@ ! @>A[+ `AW B@Bq @x@ADAErGaL a =:Q="@H@ /уC B@B@x@ADAEaWa = `=$_@ @ [p# @A*I탭o(EDz +}`Ay@4+ B@B@x@ADAEca =$_@`@ # @>A]  B@B@x@ADAEGL) a = €="@w@ +!A/-C  B@B@x@ADAEsba =~z`="+@q@& (s^@~ PD =%M5U#a& BN@0 B@B@x@ADAE9,aL4A =vw`=$_@n@ &+ @>A2  B@B@x@ADAE)aLa =2=$_@M*@DK/*D  B@B@x@ADAE a =\ T"+@@-ABtoKf-%Zǽ;ab [#$ B@B@x@ADAE aL a =K`=`gd_@߀@dA  B@B@x@ADAEaL A!!a =£="@"@&/DA B@B@x@ADAExUa"1a =%\"`= +@S@ m' @Ġ t CX;Mg!#$aR\0Dza& BAR- B@B@x@ADAE #aL2@a =!Y-`=)@|P@dAOA[ B@B@x@ADAE .aL AAa =="@ @ /Cc B@B@x@ADAENƁ ABQa =9a$_@bĀ@ +j?&% \;Pd2xu}a& ʟAÀ$ B@B+@x@ADA&  E~:aLR`a =D`= @R@dAA B@DB@x` =A @E{EaL) aaa =i= @|@ /!\ " B@B@x@ADA#EG]taL'  a$ =@g="%@w^@ -&!#V$/ \C& A' B@B@x@ADA(Euaa) =~`=!I*@@&qI)e{.@lM50K tYYpa& Jw+M$+, B@B@x@ADA-E8с Aa. =za$_/@@ &+ @>01A[1 B@B 4M@x@ADA2E΁ a3 =׀="4@Lπ@ /DD5 6 B@B@x@ADA7EbAa8 =S`= 9@@ P# @$P>U Tz*ODJzka& :#; B@B@x@ADA<E BaLa= =K`=$_>@@dA?A[@ B@B@x@ADAAE>aL AaB =H="C@!@@&/TDD? +WE B@B@x@ADAFExuaG =0a"+H@`@&$>;<n7e08#|VKNa& Z)AIJ B@B-@x@ADAKEⲁLAL = aI M@|@dAN O B@B@x@ADAPEƯaL aQ = ="R@@0<>.CSbT B@B@x@ADAUEMkaAaV =q`= +W@ai@ @ A{On첧tldd_u0F^a&Խa& lAXh +Y B@B$@x@ADAZE#aL a[ =n`= \@Rf@dA]eA[A^ B@B@x@ADA_E aL !!a` =`*="a@!@/r@Cb8 c B@Bo mDK@x@ADAdE"܁ lzL"1ae =a!If@6ڀ@ +s]b(qht&r3 gـ$+h B@B+@x@ADAiEaLA2@aj =`= k@&׀@+ @+=6hl֠A[Am B@B@x@ADAnEqaL AAao =A="p@@ /$q Ar B@BW@x@ADAsELaABQat =S`="u@ K@&=-p`^BN5\->1b]iR a& \vwJ +w B@Bm@x@t =Ax @EbaLR`ay =P@L"z@G@>{[ | B@DB@x@y =A} @EFaL aaa~ = ?= = @v@&/7IA  B@B@x@ADAEͽ bqa =} a"@Ề@&|{4'@b|zc^7a& xM B@B@x@ADAE7v aLra =u`=$_@Ѹ@dA1  B@B@x@ADAEsaL@Y a =|="@Ot@&/V + B@B@x@ADAE.aa =J5$`="@,@&lWtoeEZwE,@f֙u)HpBa& F+"  B@B@x@ADAE a =2/ @)@dAA[+ B@BA@x@ADAE @Y a ==+"+@!@&//C䀂 B@B@x@ADAEw0ba =(;`="@@ +c!x 2w{8"nR1)'! `A$+ B@B+@x@ADAEW} A B@B@x@ADAEaLaaa =ɒ= @ @ \- @A/cC B@Bt @x@ADAEwDaAbqa = +K`="@B@ +#KA/T74vK`BOb A$ B@B+@x@ADAEra =Ha`6h@{?@ #>> A B@B@x@ADAE) Aa'a"@~ !/)a B@B`x@9 A @ELLa ='@`@gĠkW@'Z!9fqVY._V([7` F+̲ A B@DBt@x@ADA EmaLa = `=" @O@ &+>A   B@B@x@ADAEjaL a =_t=$_@k@ /Y3C6A[ B@B:@x@ADAE!&aa =,`="+@5$@ #!1P]g Қ^Xt5y&0a"Zva& A#  B@Bq@x@ =A @Eހa =)@L$_@%!@ # @>A  B@DB@x@ADAEp a =8="@܀@ ! @$/^C  ! B@B@x@ADA"Eba# = `="$@ @ ^M8oOK e΋Ӝ nA%v$+& B@B@x@ADA'EaOaLa( =`=$_)@@ ! @>A*^A[+ B@B@x@ADA,EELaL a- =V=$_.@uM@ /C/ 0 B@B@x@ADA1EaAa2 =x&`="3@@ +#!kẸ@PLB{2;I`6a& A4L5 B@B+@x@ADA6E6 A7 = t 1a$_8@@ # @>A9/ : B@B@x@ADA;E  a< =ƀ="=@J@ DK!A/> A? B@B@x@ADA@Ex2b-&aA =Q=`="B@v@&H6-XĘCgoWe 5xv*t#É?C%D B@B@x@ADAEE 1>aL aF =M|H`="G@s@ &+>AH AI B@B~@x@ADAJE-IaL !!aK =7=$_+L@/@ /kM.A[N B@B@x@ADAOEv逈A"1aP ='Ta"Q@@&  J6uׁ98^>~[vV]eDra& IAR怂 S B@B@x@ADATEUaLA2@aU =_`=$_V@z@ @JAW。 X B@BA@x@ADAYEŞ`aL AAaZ == [@@҃/xC\a] B@B @x@ADA^EKZaaBQa_ =al`="`@_X@ m'!%c# )~?AtK&̼걏ܬAaW$+b B@B-&@x@ADAcEmaLR`ad =!]w`=$_e@OU@ ! @=`fT  `iq g B@B@x@ADAhExaL aaai =k="j@@ A/4Ck6l B@B@x@ADAmE!ˁ Abqan =уa"o@5ɀ@%JZ\Nx|"mia:GQU7Ohaa& hApȀ Aq B@B @x@ADArEaLras =Ύ`=$_t@%ƀ@ # @>uŠ v B@B@x@ADAwEoaL ax =C="y@@ !$A/#DCz ${ B@B@x@ADA|E;aa} =B`="~@ :@&  `Hz5oHX0}ܿAv9$ B@B+@x@ADAE`Aa = ?a"@6@ PAZ A B@B H@x@ADAED 4) a ==$_+@t@ /*C  B@B@x@ADAEˬba = x`="@ߪ@ #!+F?([Q;0P0 #JQ:-9(Z׭ (AK A B@B$@x@ADAE6eaLa =s`=+)@ϧ@ # @>A/  B@BA@x@ADAEbaL a =k="@Jc@ :! @A/.C  B@B@x@ADAEaa = U$`="@@ ms5G#i@(oN=ߕd A - B@B@x@ADAE ց a =H!$_@@ ! @> B@B@x@ADAEҁ f a =܀="@#Ԁ@&$/CӀ  B@BA@x@ADAEuba = "`="@@&An-;u3_ K*<]ZfJʆ sFA$ B@B+@x@ADAEFaLA = `=$_@z@ ' @>Aو  B@B@x@ADAECaL a =M="@D@ !A/jC` B@Bli@x@ADAEK a = a"@_`@ 'Mf'NI-O_b%gr7 {A$ B@B@x@ADAEL a =@"@R`@ !>A  B@B@x@ADAEL?!!a =f="+@͵@&/C9 + B@B@x@ADAE pb"1a = v`="@4n@!s#i@&!İxCnJhSv>7Am  B@BO@x@ADAE(aL2@a = s`=+$_@$k@ `@>Aj  B@BA@x@ADAEn%aL AAAa =3/="@&@ 0AY  B@B@x@ADAED3aL6haqa =X?`="@O@ } GWU'{bnEOGlCJ$ B@Bg@x@AD>E5 @aLra =wUJ`="+@L@ ! @>2  B@B@x@ADAEKaL a ==%@I@Ƕ/C + B@B@x@ADAE a = PVa"@@$Ġ6on',C `RjhhN1p'7]6ڊS IRA  B@B$@x@ADAE {WaLa = Ha`="@@ )A>  B@B}@x@ADAEwbaL) a =="@y@ !$+/~Cx+ B@B@x@ADAEu3caa =!:n`=!I+(@1@ ' @S)8ZKqTzay f c=A0  B@BsW@x@ADAE뀈a =7y$_@y.@ ! @=`-  B@B@x@ADAE耈a ==" @@ /C c$ B@B:@x@ =A @EJzbCa =`="@b@ AvMg^=.? d[` XAΡ  B@DBA@x@ADAE\aLa =`=$_@R@ # @>A  B@B@x@ADAEYaL@Yk Aa =ic='u@Z@ W! @/tC9  B@B@x@ADAEapga =`="A@7@& f# iu) }&ua& A#A$+ B@B@x@ADA!ÈA zA" =$_#@$@ PA$ W% B@B@x@ADA&Enʀ  A' = :Ԁ="(@ˀ@ /C) * B@B@x@ADA+EbkA, =`="-@ @A dv 4{}ɋ 8Js F,A7A.uA[-/ B@B:@x- 9ADA0 @E_>aL A1 =`=+ 2@@ # @=3XA4 B@DBM@x@ADA5EC;aL !!A6 =E="7@s<@A/H~8 9 B@B@x@ADA:E "1A; =va!I<@@& ƹjYݝ9/޽ jgmUjC#=J> B@B@x@ADA?E4̒@T2@A@ =r`=$_A@@ PAB. C B@B@x@ADADEaL) AAAE =ᵀ=H g F@H@&/TGG H B@B@x@ADAIEgaB'?!J =Kn`="K(@e`@ #$ v`DtA=MVܻNU'nAQqߛWo=Z2 5@GL( M B@B @x@ADANE a }`AO =Gk`= P@b@ PAQ R B@B@x@ADASEaL aaAT =&="+U(@@ ! @/CV!]enW B@B@x@ADAXEt؀bqAY =!a!IZ@ր@&{ÒBI%Q;2pݔAB3Lc a& ʭA[Հ-\ B@B@x@ADA]EߐaLrA^ =W _@yӀ@ &+ @>`Ҡ c @a B@B@x@ADAbEÍaL Ac == d@@&/oC!FGp B@B@x@ADAqE Ar =ha"s@~ !A.kCt4u B@B @x@ADAvELAw =)a!Ix@3@&$} uШN:>.-yʃ2a& Ay@0]`8` XFz B@B@x@ADA{Er*aL*!/m| =4`=$_}@#@ &+ @>A~ `6h B@B@x@ADAEmo5aL) A =2y="@p@ /GC  B@B@x@ADAE*6aA =1A`="@)@ 4#$A}8cLe,hs$%{-e*[Ma& #2At( ` B@B 4@x@ADAE_〈A =.L$_@%@ @>AX  B@BA@x@ADAEC  A =="@s@9~/5  B@B@x@ADAEɛMbA =vX`=$_@ݙ@&kܤ}æs0^xGFDmBrAI B@B@x@ADAE4TYaL@)A =qc`=$_@Ζ@ `@>A-  B@B@x@ADAEQdaL OA =Z= @HR@&/"9C  B@B@x@ADAE ealA =Gp`="@ @!A5"Lĥ/Q|BKWkFA @4 B@B@x@ADAE ŀJ a =K{a+ @@ ,W @>AA[ B@B@x@ADAE !!a =ˀ="@À@A/4C€ B@B@x@ADAEt}|bA"1a =!`=!I@{@ +' @@F=d.G!$' } |t* a& -Az$ B@BA@x@ADAE5aL2@F+ =`=$_@xx@ @= wA[ B@B@x@ADAE2t) AAAa =<="@3@ W /^C^ B@BA@x@ADAEI BQa =c"@]@ vm`ZHj*#^R"ڋ֥VԂ a& 9"A뀂  B@B@x@ADAEaLR`a =`="@M@>A耂 A B@B@x@ADAEaL aaa =d`="@Ǥ@&m.C3 B@BUD@x@ADAE_aLbqa =e`=)@2]@ +pNÓ/:OHMlcٲ&bHA\  B@BA@x@ADAEaLra =b`=$_@&Z@dAYA[A B@B@x@ADAEmaL a =5="@@ WA/xC  B@B`@x@ADAEρ a =a @΀@&H0%E79 ~O!2t)=e(As̀$+ B@BIXUG@x@ADAE^aLa =`= @ʀ@dAW GA B@B$@x@ADAEBaL a =="@r@ /1C  B@B@x@ADAE@aAa =G`= @>@ PA)??/Rz̀,Se&1#(PAI B@B@x@ADAE3 R =qD @;@ 4 @J-A[ B@B@x@ADAE @Y a =="@G@&/|C +W B@B@x@ADAEba =J`="@@ dzXCĘS\:60SK}⫀77a) B@B@x@ADAEjaLa =FT+$_@@dA `  B@B@x@ADAEfaL; a =$)`= @ @;qN Ӝ4I.њaߑҾbO33a& ԸD   B@B@x@ADA Eڀ!G =&a @w@dA[-Ġ B@BW@x@ADAE a =="@؀@/"C^  B@BF@x@ADAEH bl}a =+`= @\@&[r- 3 B"z0/&I< b l^A Ȑ$A B@B$@x@ADAEK,aL a =6`= @L@dA[ B@B@x@ADA EH7aL !!a! =cR=""@I@  Ġ/rC#3$ B@B@x@ADA%E8aW"1a& = C`= '@1@ A2ɼd&~rBR&:ya& 7nA( +) B@B@x@ADA*E2@a+ =N ,@"M`@dA- A. B@B@x@ADA/ElL AAa0 =9À="1@@ 2.BC23 B@B@x@ADA4EtObBQa5 ={Z`="+6@s@ sw;!>&ߍT6na& )A7sr$8 B@B@x@5 =A9 @E]-[aLR`a: =xe`= ;@o@dA<W = B@DB@x@ADA>EA*faL) aaa? = 4="@@q+@&/CA AB B@B@x@ADACE bqaD =uqa AE@@ b9^ u2`=H@ r@\6@&*ױ?+'EYz+n!@ =NAs5$t B@Bm@x@ADAuEav =;a w@L3@+ @+`.Ax2 y B@B J@x@ADAzE퀈) a{ =b="|@@&/bA}2~ B@B@x@ADA߄Eba ɯ`="@1@ +a͌Т "HnNx`|H7<Xd A B@DB+@x@ADAEaaL" =Ŭ`="@!@dA ] B@B@x@ADAEk^aL a =4h= A@_@&/d B@B@x@ADAEaa = `="@@7gX 2c9),ꄐ̇' /30Qa& Or  B@B}  @x@ADAE]Ҁ a =)W@@dAV  B@B@x@ADAEAρ  !!a =ـ="@qЀ@ /YUD  B@B; @x@ADAENJb"1a =w`="@ۈ@ A^@ 1&~m@(^5Cca& JG$+ B@B@x@ADAE2CaL2@a =p @ @̅@dA+  B@B@x@ADAE@ aLAAa =I= A@FA@ /$UA[ B@B@x@ADAE@taL a =  ~="@pu@&/C  B@Bx@x@ADAE/aw6a =6`="@-@ #+gŽtj]{2421)f-a& /AK B@B@x@ADAE1 A =o3a"@*@ '>A+ ]^B$@x@ADAE ^) a =="+@E@ ! @+A/ZC  B@B@x@ADAEbAa =P`="@@ md,M? , Z,a& A  m B@B@x@ADA EYaL a =D`=$_ @@ ! @>A  B@BA@x@ADAEUaL !!a = {_=$_@W@ / CV B@BA@x@ADAEqa"1a =`="@@&J3ϻhtxCe^cG\Nj2z\A- B@B@x@ADAEɀ2@a =$_@u @ # @>A  B@B@x@ADAEƀ6hAQa = !@Z@ ! @ xeǍ ֟sE*yW՘`ۦ%+t )_C"@3m# B@Bu@x@ADA$E:aLWR`a% =`="&@K}@ P'| ( B@B@x@ADA)E7aL aaa* =^A="++@8@ !P/sC,1+- B@B@x@ADA.E Wbqa/ =a"0@0@AĠ_:ya& 9NA1$2 B@Bx@x@ADA3EaLra4 =`="5@#@ &+$+=:6퀂 7 B@B}@x@ADA8EjaLa9 = ;=$_ +@@3:@@ /; +< B@B@x@ADA=Ecaa> =AVj@"?@b@ #!Ġ >aR Ű[1>;T#mޖ7aU '3D@qa A B@B@x@ADABE\aLWaC =g `=$_D@^@ # @>EU F B@BA@x@ADAGE? aLbH AaH =#="I@p@ Jw! @/CJܡ K B@B@x@ADALEԁ aM =va"N@Ҁ@ +j`r5 ՙy r*h7=+XǨJg?OF$P B@B+@x@ADAQE1aLaR =n"`=$_S@π@ ! @>AT* U B@*B@x@ADAVE#aL aW =Ⓚ="AX@E@ W/j?Y Z B@B@x@ADA[EE$aa\ =TL/`="]@C@ M#+Ag8Z6;t1#fGO{ PF+^-_ B@B+@x@ADA`E #aa =DI:$_b@@@ # @>Ac? d B@B@x@ADAeEaf = ;a+"g@~ ! @A/cChAi B@B@x@ADAjEqLAak =-F'l@@\FᇣQmwRMad\ L lm񳀂$n B@B@x@ADAoEnGaL8p =Q`=+$_q@t@ ! @>Arհ s B@B}@x@ADAtEkRaL Aau =u=$_v@l@&/ w[ +x B@B@x@ADAyEF'Saaz =-^`="{@Z%@ m#!A8>$y0h`6G@u8G$5:f+|$+} B@BY@x@ADA~E߀ a =*i$_@J"@ ' @>A!  B@B@x@ADAE܀ !!a =i="A@݀@&/DlW0 B@B@x@ADAEjb"1a =Ǟu`="@/@ P+̈́jh˥3 $Mo1+:#a& J + B@B}@x@ADAEPvaL2@a =Û`=$_@@ ! @>A  B@B@x@ADAEjMaL AAa =3W="@N@v/AC B@B@x@ADAEaBQa =`="@@ +#A{^a4߹@Dge(G~+] pAp$+ B@B@x@ADAE[AR`a = $_@@ PAT  B@B@x@ADAE?  aaa =Ȁ=+"@o@ ! @+/  B@B@x@ADAEybAbqa =v`="@w@ %.4f֞+ށU}?NsMDF B@B@x@ADAE02aLra =r}`=+ @t@ ! @>A)A[ B@BM@x@ADAE/aL a =8=$_@D0@ /<;C  B@B@x@ADAE a =Ha"@@ #!҃ IyUĴAQAT}"a& A B@Btm@x@ADAEaLa =C`=$_@@ # @>䀂  B@B@x@ADAEaL) a =="@@ !A/5C B@BJ@x@ADAEp[aa =(b`="@Y@%*}k#볉krPX$AX  B@B@x@ADAEaLa =_`=$_@tV@ &+ @>AU  B@B@x@ADAEaL a ==+$_@@ :/bC[ B@B:@x@ADAEÉ a =a"@Yʀ@ #!A:%<DM2kPo4ova& Aɀ$+ B@B@x@ADAEaLa =`="@Qǀ@ #>Aƀ  B@B@x@ADAEaL a =\="@Ă@ ! @A/IC0 B@BW@x@ADAE=aa =C@"@.;@ NoGpKpJ2pWa H#CA:$ B@B@x@ADAEA =@ a+$_@8@ ! @>A~7A[ B@BA@x@ADAEi a =1="@@ /C B@B@x@ADAEb-&a =`=%@@ +# @AwyY:6a'l^Q$IMDa& ,zAt$ B@B@x@ADAEZfaL a =$`=$_@@ # @>AT A B@B@x@ADAE>c%aL) !!a =m="@nd@'.VC  B@B@x@ADA+  E&a"1a =u%1`="@@&K}uP#6ywt @ UAE  B@DB@x` =A @E0ׁ 2@a =m"<$_`k3C@@ &+ @>A)  B@DBA@x@ADA Eԡ @Y AAa =݀=" @DՀ@ &+/AyC   B@B{@x@ADAE=bBQa =KH`=!I@@&Nk9 ;`Fhe䚍I a& A$ B@B@x@ADAEHIaLR`a =BS`=$_@@ # @>A  B@B@x@ADAEDTaL aaa =N= @F@&N.@"CEA B@B@x@ADAEoUabqa = ``=" @_`@&gz_,m%-_eNAq5L:З)A!-m" B@Byg@x@ADA#EڸLra$ =kaI+$_%@sj`@ PA& ȸ' B@B@x@ADA(EL a) =="*@@ &+$+J/aC+ZA, B@B@x@ADA-EEqlbAa. =ww`=!I/@Yo@ ?# @҃-!hQL-\/ 8"_$a& QA0n$1 B@B*@x@ADA2E)xaLa3 =t`= 4@Il@ # @>A5k 6 B@B@x@ADA7E&aL) a8 =d0="9@'@ -&!/0}C:/; B@BP@x@ADA<E a= =a">@.@ Ԛ,}Hvyt:3Mo};fEa& A?߀ +@ B@B+@x@ADAAEaLaB =`="C@݀@ !>D~܀ E B@B@x@ADAFEhaL @saG =Y`=$_H@Q@ Ƕxx;g*ؾ@#00 dV# flCIoP J B@ BpW@x@ADAKEZ aL^L =V`="M@M@ @JNS O B@B}@x@ADAPE>aLޗaQ == R@r @[p @Ga/@CSޡ T B@B@x@ADAUEÁ aV =yʽa"W@@AĠA)JM0ݖHb´ .AQGa& (CXD$AY B@BA@x@ADAZE/|aL"[ =m`=+$_\@Ⱦ@ P](A[&` ^ B@B@x@ADA_EyaLAxa` =@む="a@Cz@ !/Cb c B@Bm@x@ADAdE4aWae =R;`=!If@2@JĠ2ߏAmGe3-kD ڗAgh B@BJ@x@ADAiE  aj =B8 k@/@ `@>l.A[d@m B@B@x@ADAnE逈A!!ao =="p@@vՙ/,Cqꀂ$r B@B(@x@ADAsEob"1at =`="u@@ #$Ġ iF)2!H&%4m71z[KjY^:  Av@3+w B@B@x@ADAxE]aL 2@ay =`=+ z@s@ ' @>{ӟ A| B@B@x@ADA}EZaL) AAAa~ =d="@[@ !/CY+ B@B 4@x@ADAEDaBQa =:u!IA@X@ V-ǯl#tTSqzERa& %A  B@B@x@ADAE΀R`a =a$_@H@ ! @>A  B@BA@x@ADAE aaa =cՀ= @̀@PA/ӘC/  B@B@x@ADAEbbqa =`="@-@!A4kgQM.vyqȒb\m<8iNa& VA@0A B@ BA@x@ADAE?aLra =Ŋ&`=$_@!@ ' @>A!U B@B@x@ADAEh<'aL a =,F="@=@ W! @Ġ/C  B@B@x@ADAE a =2a"A@@&A*Ħi6:Af8s6kAn + B@B$@x@ADAEY3aLa ==`=$_@@ PAR  B@B@x@ADAE=>aL a =="@m@ /3C  B@B@x@ADAEh?aa =toJ`="@f@ }#+AM²|We1M09a& AD B@B}@x@ADAE.!KaLa =llU`="@c@dA(  B@B@x@ADAEVaLVa ='="@F@&/UC + B@B@x@ADAEف Ca =Jaa$_@׀@  :o^s3>}'Į=}"[A  B@B@x@ADAEbaLa =Il`= A@Ԁ@dA W B@B@x@ADAEmaLa == @@"Y/hwC  B@B@x@ADAEnJnaa =.Qy`="@H@ #18ڿTQV#5 G'Q/|:AG$ B@BM@x@ADAEzaL$ zA =N`= @rE@dAD  B@B@x@ADAE  i Ax%A =   @@PĠ/̒CY  B@B@x@ADAEC A =a"A@W@%(J/頂 `+0 B@B@x@ADA1EaL AA2 =="3@쥀@ 3/94X5 B@B@x@ADA6EC`aA7 =f`= +8@W^@ XdqqBꎁi\-.R#2NT #]9]A[ : B@B+@x@ADA;EaLA< =c(`=$_=@K[@ @>>ZA[? B@Bx@x@ADA@E)aL) AA =Z= B@@ /CC-D B@B@x@ADAEEс ;7$F =4a"+G@,π@ ` ]um63w!jլ!o4ūiuEv#AH΀ I B@BE@x@AD>JE5aL AK =?`=$_L@̀@  @>AM|ˀ N B@BA@x@ADAOEg@aL  AP = /= Q@@ @/CR f5S B@B@x@ADATEAAaaU =HL`="V@@@&gm0g]?:=YNxAA' &0Y];a& nAWm?$+X B@B@x@ADAYEXA CZ =EWa$_[@<@dA\Q ] B@B@x@ADA^E< 6h!1a_ =kca"`@ְ@+C铭Çc8:&&hYAiՃ"Cl+B9WCaB@4d b B@Bq6h@x@ADAcE-kdaL2@ad =n`="e@ǭ@#V+/{Ck l B@Bm@x@ADAmE#paWBQ!8& =H*{`="o@!@AĠ+om؈i^qpElC%.K_a&  'Apq B@B@x@ADArE܁ R`as =@'a"t@@>u v B@B}@x@ADAwE؀) aaax = ='uAy@ڀ@ / Czـ{ B@B@x@ADA|Embbqa} =`="~@@  Ġl8Ox!dr D.wmm%

Kv> x0U! *F+s$ B@B:@x@ADAE.aLa =y`=$_@q@ &+>{p  B@B@x@ADAEf+aL a =.5="@,@ /C B@B@x@ADAE Aa =a"@@ m#+.KW?G1$sra& Jwm䀂$ B@B@x@ADAEWaLF+ =`="@@ #>AQ  B@B@x@ADAE;aL) a =="+@k@ ! @QC /4P  B@B:@x@ADAEWaa =v^`="@U@  (3Yej(Şnba& AB m B@B|@x@ADAE,aLD =j[`=$_@R@ ! @=&  B@B@x@ADAE aLa =="@@@%/C  B@BH@x@ADAEȁ a = ? #@ƀ@+A)1 hmʩF6 N]A  B@B@x@ADAEaL a =`=$_@À@ '>A€  B@B@x 9ADA @E}aL A!!a ==+"@@&$/vC~Am B@DBo@x@ADAEl9a"1a =!@`= @7@&A9Rt3-_7lEg7-ja& A6@0 B@ B<@x@ADAEA b2@a = =*a @t4@ PA3  B@B6h@x@ADAEAxAAa =@="@@ &++ |1CWA B@BW@x@ADAEB+bABQa =! 6`="@V@ #AWs@UU<]" aHF($iȼ 7§$ B@B@x@ADAEb7aLR`a =A`="@E@ #$>AA[+ B@BA@x@ADAE_BaL aaa =Ui="fi @3@`@ @Ġ/[D,@A B@BW@x@ADAECabqa = !N`="@+@ t9F`YWCRSB6) %A@2 B@B@x@ADAEӀra =Y$_@@ ! @>{  B@B@x@ADAEeЀ a =*ڀ="-@р@ &+/^ C  B@Bq@x@ADAEZba =e`="@@ P#AjcO#:PXWS5xdAl + B@BA@x@ADAEWDfaLa =!Ap`=$_ @@ @>A P  B@BA@x@ADA E;AqaL a =K="@kB@ `/[C  B@B~@x@ADAE a =v}a"@|`@ mU}_5أꬶͷoZ A%A[ B@B@x@ADAELa =什=+'u@@@&/M  B@B(@x@ADA!Emba" =Ct`="#@k@&A]z1qրJwFd6-K:SF D$ A% B@B @x@ADA&E&aLa' =?q`="(-@h@ '>A)gA[* B@B@x@ADA+-`DE"aLa, =,= -@$@ ! @+/7C.#C/ B@BW@x@ADA0Elހa1 =a"2@܀@&$FCd B/wh`5x[pEmA3ۀ$4 B@B@x@ADA5E֖aL"6 = `=$_7@pـ@ PA8؀ A9 B@B @x@ADA:EaL) a; =="<@ꔀ@&/AC=V> B@B@x@ADA?EAOaa@ =U`="A@UM@3RJ κtta0^iR{vbϴ3IQs ABL AC B@B @x@ADADEaL aE =R`= F@EJ@ ' @= GI H B@B@x@ADAIEaL !!aJ =\=+)+K@@&/CL,M B@B@xK 9ADAN @E "1aO = ?=a"P@*@&V?Ze΋UIf>r9< AQ@2WR B@B@x@ADASExaL2@aT =`="U@@ PAVz W B@B@x@ADAXEeuaL AAaY =1= Z@v@&.@C[\ B@B@x@ADA]E0aBQa^ =7`="_@.@&^|- 'V]uo AMA`k$a B@kBq@x@ADAbEV R`ac =4a+)d@+@ PAeOA[+f B@BA@x@ADAgE:  aaah == i@j@ ! @/3Cj k B@B@x@ADAlEbAbqam =n @"n@՟@&\ GQzPQ\tI&@ 6AoAp B@B@x@ADAqE+Z aLrar =i`= s@Ŝ@ PAt% u B@B@x@ADAvEWaL) aw =`=H@gD_+x@?X@&/|Cy z B@B@x@ADA{Eaa| =>!`="}@@+҃ȗV#1^=qZw"Hvx|@ 0Oa& 3A~  B@B 4@x@ADAEˁ a =,a"@ @ '$=  B@B@x@ADAEǀ; a =8"@@ @A/ŖC뀀  B@B@x@ADAE;9aLa =C`="@o~@ P}  B@BW@x@ADAE8DaL a =~B="@9@=VA[z B@B@x@ADAE@ a = Oa"@T@ &+!Ƕճ}>ՠQ+|c(hrW D@2 B@B@x@ADAEPaLWa = Z`="@D@$=  B@B@x@ADAE[aL a =S="@@ &+/C+W B@B@x@ADAEe\ao a =kg`=!I+@.c@ e-=6ߤuK|2x<5YykAb$ B@B @x@ADAEhaLA = hr`=$_@`@ @> z_  B@BW@x@ADAEdsaL) a =5$="@@A/GC B@B"Y@x@ADAEՁ ka = {~a"@Ӏ@%>HTXo!n͊lo)u7 %Ak  B@B$@x@ADAEUaL a =ى`="@Ѐ@ &+>AO  B@B@x@ADAE9aL !!a =="@i@ :A/ӪC  B@B@x@ADAEFa"1a = qM`= A@D@ # @̤(d:8 VBKm{NҖRbW A@  B@B@x@ADAE+ `2@a = lJa$_A@A@ # @>A$  B@B}@x@ADAE  AAa ="@?~ W! @A/C  B@B|   @' 5@ADA @@LlABQa =I'@@ <[E0W2_T:Dג.f` Ade B@DB|@x@ADAEpaLAR`a = 5>`=+$_@@ ! @>A  B@B@x@ADAElaLaaa =v=+$_@n@ /Vam B@B@x@ADAEk(aAbqa =/`= @&@%r{Agt.gf[W$ p(D%  B@B@x@ADAEra =,$_@o#@ # @>A" + B@B@x@ADAE݀F Aa =="@ހ@&/CY$ B@B}@x@ADAE@ba = `="@T@&[T#sw%7t ѧYtj[ "#A$ B@Bx@x@ADAEQaLa =  +$_@D@ PA`  B@B@x@ADAEN`) a =_X="@O@&/C*A B@B@x@ADAE aa =`="A@)@&*Vr٠eu }$f=Ձ H-a& BA. A B@B@x@ADAE€a =  a @@ PAy  B@BA@x@ADAEd a =,ɀ= W @@ W! @҃/nC   B@Bt@x@ADA Ezla = { `="@x@&IL+g56h&%DXB1G:^Oc Aj$+ B@B@x@ADAEU3 aL$a =~`= @u@ PAN  B@B@x@ADAE90aL a =:=$_@i1@ W/tC A B@B@x@ADAE a =p"a"A@@&5² |á z[ݦa& \?$ B@B@x@ADA E*#aLA! =h-`= "@@ # @= ## ` $ B@B@x@ADA%E.aLa& =ת="'@>@ !$A/ ʈ( A) B@BuA@x@ADA*E\/aa+ =Ac:`=",@Z@ gJY4kJZv&KV;Mya& OF+-. B@B@x@ADA/E;aL a0 ==`E`="1@W@ !K=2V 3 B@B@x@ADA4EFaL) A!!a5 =="6@@&/lcC78 B@B@x@ADA9Ej̀"1a: =Qa%;@~ˀ@ # @+¶fcf?9}@< q@D+ha& CA<ʀ += B@B@x@ADA>EՅRaL2@a? =\`=$_@@rȀ@ @>AAǠ i7 AB B@B@x@ADACE]aL AAaD =="E@郀@ A/FTG B@B@x@ADAHE?>^aBQaI =Di`=$_J@S<@&|i/0RS۝Mí߾a& DK; L B@B@x@ADAMER`aN =At$_O@C9@dAP8 AQ B@B@x@ADARE aaaS =Z="T@@&/@CU* V B@B@x@ADAWEubbqaX =ŵ`="+Y@(@&~O(Hϴ,w< p= Ga& AZ$+[ B@B@x@ADA\EgaLra] =`= ^@@dA_x ` B@B@x@ADAaEcdaL ab =0n="c@e@ A/Cd e B@By@x@ADAfEaAag =&`="h@@ iW v+[U7 rNN}[J/A@y~a& Crijj B@B@x@ADAkET؁ al =#a"m@@dAnN o B@B@x@ADApE8ա @Yk aq = ߀="r@hր@%g/rs t B@BW@x@ADAuEbav =l`= w@ӎ@&$*y]ySnj7Q0DM h|8F+x? +y B@Bt+@x@ADAzE)IaLa{ =g`= A|@Ë@dA}#A[~ B@B@x@ADAE FaLa =O= @=G@&$/1C  B@B@x@ADAEaa =<`="+@`@! ARk2u(ArkNp`$b A  B@ Bp@x@ADAELA&rEa =@aI @`@ @=  B@B@x@ADAE㶁L Aa = ="a @3@@+ @g/^C@+ B@B@x@ADAEirba =AVy`="+@}p@ v.⩗h7>`s%MR׹ͯroAo-+ B@B@x@ADAE*aLA =v`=$_@nm@ @=l  B@B@x@ADAE'aLqa =`="@W@18k6chv4 VCM#YcC$ B@B@x@ADAEaL a = "@Bހ@dݠ@+ B@B@x@ADAEaL !!a =a="@@  +/)+ B@B@x@ADAETaW"1a =Z `=)+@(R@+ @+ĠG;v;fxgE9m-ZDQ A B@BA@x@ADAE~ aLW2@a =W`='u@O@ @=xNA[-]  B@B@x@ADAEb aL) AAa ='="@ @%/V4C  B@B@x@ADAEā BQa =$a"+@€@ aĠR_X0So~~+pa& uAi  B@BA@x@ADAET}%aL}`a =/`=$_@@ @>M  B@B Y@x@ADAE8z0aL aaa == @h{@ A/YC  B@B -&@x@ADAE51abqa =o<<`="+@3@gĠGqw&.%geNϏ}Ra& A>@0 B@B}@x@ADAE) ra =f9Ga$_@0@dA"  B@B@x@ADAE @Y a =="@=@ /GC  B@Bw@x@ADAEHba =@S`= @@Ġ_Ng٪;‰*Rv (BXȢZ;a& .^  B@B@x@ADAE^TaLa = @^`= @@dA  B@B`@x@ADAE[_aLa =e="@]@ /؊C~\ B@B@x@ADAEi`aa =k`= @}@ +SIqc$]3M}bI 5 Ea& 2A$ B@BA@x@ADAEπa =v @m@dAA[ B@B 5@ADA @È) Aa =ր="@̀@ W/CS B@DB@x@ADAE>wba =`="+@R@ mH-CjzQqHV v\ua& dZA + B@B@x@ADAE@aLa =拍`= @B@dA A/  B@x@ADAE=aL8a =]G= @>@ /vC-  B@B@x@ADAE a =a"@'@ b\u&lyS L6N@ "* $ B@B @x@ADA E~aL" =`= @@dAwA[A B@B!B5B@x@ADAEbaL ޗa =*="A@@g/z A B@Bs $@x@ADAEiaa =p`= +@g@ T.0c+!Km1Jwb Σ$a& Dh$ B@B@x@ADAES"aL a =m`= @d@dALA[ B@B@x@ADAE7aL@Y !!a =)="!@k @ WA/ C"# B@BA@x@ADA$EڀA"1a% =va"&@؀@& .}Pv' o<<|co'>$( B@B@x@ADA)E(aL2@a* =f`="+@Հ@ &+$g>," - B@B@x@ADA.E aL) AAa/ =ᙀ= 0@<@& /1 2 B@B@x@ADA3EKaBQa4 =;R`="5@I@W!(_6P݊OҾ㾃2vE젾x6@4-7 B@B@x@ADA8EaLA )R`a9 =O`=$_`= @3v:@F@ ' @>;E < B@B@x@ADA=EaLaaa> =AV ="?@@/~@} A B@Bq@x@ADABEhbqaC =a"D@|@ 'sSiC:-VhAJж K B@B@x@ADALEqaL+AxaM =@{=+"N@r@&$/OS3';P B@B@x@ADAQE=-aaR =3`= S@Q+@ @A],E'[\"U cLj!lQOmT*A[a@U B@B+@x@ADAVE倈AaW =0a$_X@E(@ PAY'A[Z B@B@x@ADA[E  a\ =P="]@@A/6h^(_ B@BW@x@ADA`EbAaa =&`="b@'@ '.UqwGgžb9t.2<TVc$d B@B@x@ADAeE}V'aLaf =1`="g@@ !$+=hv i B@BA@x@ADAjEaS2aL$ak =.]="+l@T@ &+ @/Vm$n B@B@x@ADAoE3ao)  +ap =>`="q@ @ 1#wʂ~#mlc^1 Yg\׏@ rl $s B@B@x@ADAtERǀau =!AIa$_v@ @ # @=wP Ax B@B@x@ADAyE6ā az = ΀="{@jŀ@ !/`LW|֡ +} B@B@x@ADA~EJba =uU`="@}@ ]rs`pZ鱙WΐU [WhMB>A  B@B(@x@ADAE(8VaLA =e``=$_@z@ ! @>A!  B@BA@x@ADAE 5aaLAx@! =@>=+$_@<6@&/lD  B@B@x@ADAE lAA =;la"@@!҃rZYˀTی ^s܄DgA>a& @0C B@Bm@x@ADAEmaL A =:w`="@@ '>Aꀂ B@B@x@ADAExaL !!A =="@@ ! @A/}A[ B@B@x@ADAEgaya"1A =h`="@{_@&/YsMxUЮ Nm@k{>ޔ&p– a& s^$ B@B@x@ADAEaL2@A =e`=+$_@k\@ PA[A[ B@B@x@ADAEaL AA)A = =$_@@ /R: B@B@x@ADAE=ҁ $B%! =؛a"@QЀ@&䈣H&suaZV|/~aU Jπ`4 B@B@x@ADAEaLR`A =զ`= @À@ # @"`C >À  B@B@x@ADAEaL) aaA =\="@@ !$/;A' B@B@x@ADAECabqA =I`="@&A@ 'e }@ebrΌ))%fa& xA@  B@B@x@ADAE}rA =F$_@>@ @>v=  B@BA@x@ADAE`+0 8A = a+"@@ /3Cg  B@B@x@ADAERlaLA =`="@ﮀ@ @>K  B@B}@x@ADAE6iaLAxA =@s= @fj@ +^l&0 s|zݐ>B,X4G  B@BW@x@ADAE$aA =h+`="@"@gՙLcGփ"& DFsrLas[a& /D<$A B@Bg@x@ADAE'݁ WA =e(a+$_ @3@@ # @> A[- B@B@x@ADAE ځ A = = @;ۀ@ ! @W/٩C  B@B@x@ADAEbWA =F`="@@ AĠJy-ޅ'wt]ڸ=wє/>a& + B@B{@x@ADAEMaLA =:@$_@@ ! @>A  B@B@x@ADAEJaL) AA = T=H gj@L@ /݆D|K B@B@x@ADAEgaA = `="@{@ #+ QA [92ȶيA-S` M~a& %/A + B@B@x@ADAEѾ A = a"@k@ #>AA[A B@B@x@ADAE  A =ŀ="+@开@ :! @+A/CQ B@B@x@ADA0  EAu⠂Ad B@DB@x@ADAE`KaL AAa = 1="@@ ! @Ġ/0C  B@B@x@ADAEXLaABQa =_W`=" @V@&Ncbju Ҥ Dk4g: Ip!f A" B@B@x@ADA#EQXaLR`a$ =\b`=$_%@S@ `@>A&J ' B@B@x@ADA(E5caLaaa) =="*@e@&/U+ , B@Bli@x@ADA-Ecabqa. =hn`="/@ǀ@ #+A].{a߾~Hk f'," a& F+0<1 B@B@x@ADA2E&oaLra3 =dy`="4@Ā@ '$>A5 A6 B@B@x@ADA7E zaL) Aa8 = ӈ="9@:@ !A/SC: ; B@BH@x@ADA<E:{aa= =>A`=!I>@8@ q_dWL c̅tmia& m? A@ B@B@x@ADAAE aB ==>a$_C@5@ ! @>AD4 E B@B@x@ADAFE aG = = H@@ /mI| J B@B@x@ADAKEfbaL =`="M@z@7'ps@4>6?z W|%њ1Aa& _gN樀-+O B@B7@x@ADAPEcaLaQ =`=$_R@j@ # @>ASʥ T B@B@x@ADAUE`aL aV =j= W@a@4҃/CIAXQY B@B@x@ADAZE;aa[ ="`="A\@O@&AnhQv133Pݒ`8&IA]$^ B@B+@x@ADA_EԀ(a` =$_a@@@ PAb c B@B@x@ADAdEр ae =Sۀ="f@Ҁ@ &+$Q l@C /d"@Gg&h B@B@x@ADAiEbaj =œ`="k@%@& "!mISYt. \y;Aـ  B@B@x@ADAEߔaLaaa =="@@ /lKC{ B@B@x@ADAEfPaAbqa =W*`="@zN@ +UyQŝPDRZ>va&  AM$ B@B@x@ADAE+aLra =T5`="@iK@dAJ  B@B@x@ADAE6aL) Aa =="@@&/CP B@B 5@ADA @E; a = ?=Aa A@O@&$fS;COx[5\ @ ?g A  B@B@x@ADAEyBaLa =L`=)@?@dAA[ B@B@x@ADAEvMaL a =Z= @w@ A/_C% B@B@x@ADAE2Naa =8Y`="+@$0@ A(yyBʖDQÖ~:Xo쏻!A/  B@B"Y@x@ADAE{ꀈa =5d @-@dAt,  B@B@x@ADAE_ a =/="@@ /=C  B@B@x@ADAEeba =p`="+@@ w OKi̅Pt=IG줟}a& aAe$+ B@B@x@ADAEP[qaLAa ={`= @Ꝁ@dAI  B@B@x@ADAE4X|aL6ha =o`="@@ A~",ptV M % h!9(o@:Fa& 5C:  B@B@x@ADAE%́ 6| =ga"@@dA[W B@B`@x@ADAE Ɂ ? a =Ҁ="@9ʀ@  + /WC  B@B@x@ADAE@TWa =E`= @@AĠhC{<[2bl_.?HĦ>:5A B@B@x@ADAECz:A[ B@B@x 9ADA @Ee"1a = a"+@y@!PKvdPSjw8,gMw$9*` A  B@DB?@x@ADAEЭaL2@a1  `= @i@ @= W B@BW`x@9 A @EaL AAa =x="$@䫀@+ @A/1PA B@DB@x@ADA E:faBQa =l`="+ @Nd@ )m l?1m4l*`L*ftya& $qD c$+ B@B@x@ADAEaLR`a =i`=$_@?a@ @=`A[ B@B@x@ADAEaL aaa =U%="@@/]C%W B@Bw @x@ADAEׁ bqa =a%@#Հ@ CH{n:Z;۬ }a` f=a& `AԀ$ B@BJ@x@ADAEzaLra =`= @Ҁ@dA sѠ ! B@B@x@ADA"E^aL a# =2="$@@ /C% & B@BC@x@ADA'EGaa( =N`= )@E@%o҃G/PZ;CeTy7`*9e=:TkSeA*e+ B@BC@x@ADA,EOaLa- =K@ .@B@dA/I@0 B@B@x@ADA1E3 ) a2 =  3@c~vA/C4 5 B@BtA@x@ADA6ELa7 =wa"+8@ζ@&/[k2p/{ 25ψa& {9: : B@B@x@ADA;E%qaLa< =b`="=@@dA> ? B@B@x@ADA@En aLaA =w="B@8o@ A/DC D B@B@x@ADAEE)!aaF =@0,`= +G@'@&>4D/y-e>0r;OP(;Ip$H/PAH I B@B@x@ADAJE aK = 7-7a AL@$@dAM# AN B@B@x@ADAOE AaP =="Q@@&/|CRz߀ S B@B@x@ADATEd8bpliaU =%C`= V@|@ +Ͳ{:5T2.F@a& "xAW藀-X B@B+@x@ADAYERDaLAZ =N`= [@l@dA\ȔA[] B@B@x@ADA^EOOaL a_ =Y="`@P@ A/TCaOb B@B7@x@ADAcE: PaAad =[`="e@N @&Pé`Ut857v#\Af$g B@B@x@ADAhEÀ ai =fa"j@>@dAk$l B@BA@x@ADAmE !!an =Mʀ= o@@ +/SCp$A[+Aq B@Bg@x@ADArE|gb"1as =Âr`="t@#z@& Ēqbf6r24~o1֞Yxg:Auy+v B@B|@x@ADAwEy4saL2@ax =}`= Ay@w@ * @g>zsv { B@B@xy 9ADA| @E]1~aL AAa} =.;="~@2@& />C  B@DB`@x@ADAE BQa =a"@@&AvzQ};7V6?Tq13*M"]NAd + B@B@x@ADAEOaLR`a =`=$_@@ ' @>H  B@BA@x@ADAE3aL aaa ==+ A@c@&A.VC  B@B@x@ADAE]aqa =nd`= @[@ +' @gFQa*yy2yGza& ֚A9- B@B+@x@ADAE$aLra =ba`=$_@X@ ! @= A[W B@B@x@ADAEaL@Y a =="@<@ W&+g/ C B@BW@x@ADAE΁ a =Bոa"@̀@&@Gcz9؀D5GG"57R'A A B@B@x@ADAEaLa =7`="@ɀ@ #>AȠ  B@B@x@ADAE݃aL a ==$_+@ @ ! @+/Cy B@B@x@ADAEd?aa =F`="@x=@&$%2 r]ox Qk0Na& eA<$ B@B@x@ADAEa = Ca$_`3r@h:@ PA9  B@B@x@ADAE) a ={="@@& //ICN B@B>@x@ADAE9ba =`="@M@ #+uñ cir ^gP,,a& s A + B@B@x@ADAEhaLAa =`= @=@ ' @=  B@BA@x@ADAEeaL a =Qo=+"+@f@ ! @J/!C$ B@B@x@ADAE!aa ='`="@"@ vI<C#A1,"f'kmta& L*$ B@Bv@x@ADAEyـA) =$ x-"@@ !>r  B@B P @'@x@ADAE] a =1= @׀@ H/*  B@AbB@x@ADAE ba =`="@@XZbl(ck _@ݏ4O p8`F+c$ B@cB Jw@x@ADAENJaLA a =!`=+$_@猀@ # @=AG  B@BA@x@ADAE2G"aL) !!a =Q= @bH@ ! @A/LC % !kW B@B @x@ADAE#aA"1a =q .`="@@ +'a10[v19h(xD!OY-a& ?A9 B@B@x@ADAE# 2@a =a9$_@8`@ ! @>A A B@B@x@ADAEL) AAa =="@7@ /cC  B@B@x@ADAEs:bBQa =:zE`="@q@ m#5)C5Oaeeq2ث0OPF+a& :d + B@Bm@x@ADAE+FaLR`a =6wP`=+$_2@n@ # @>Am  B@B@x@ADAE(QaLaaa =2="@ *@ @A/dx)!& B@BJ@x@ADAEc䀈bqa = \a" @w@ CbF[ì Ǔ@= va& WG ဂ  B@B@x@ADA EΜ]aLra = g`=+$_@g߀@ @>Aހ  B@B W,X@x@ADAEhaL Aa =v=$_@⚀@v @/IAN!6  B@B@x@ADAE8Uiaa =[t`="@LS@2iQ+*ŷ:b3%ga& AR@0oc@m B@B@x@ADAE uaLAa = X`=+$_@A.qA[/ B@B@x@ADA0E\{aL a1 = ="2@|@ &+/~3 4 B@B@x@ADA5E6aa6 = =`="7@4@ #AkP[F${nϊ}n#coLF+8c9 B@B"Y@x@ADA:EM A9*gxa; =:a"<@1@>=K > B@B@x@ADA?E1 @Y Axa@ =@ ="a @3 4A@a@ /CB C B@B@x@ADADEbaE =AVm`="F@̥@ {~p gTdpͦ޶(AG8 H B@B@x@ADAIE#`aLJ =``=H@SQK@@ !>AL M B@BA@x@ADANE]aL+@saO =@f= P@7^@%/Q NR B@B@x@ADASEa.aT =F`="U@@&P\>DHj;c_Jka& jhDV-W B@BP@x@ADAXEЁ  aY =5$_Z@@ ' @>A[\ B@B@x@ADA]E !!a^ =׀="_@ π@&/DC`x΀ a B@B@x@ADAbEbb$"1ac =`="Ad@v@ +'&lE'دh'kpQ6AJ^7v,)a& ~&Aeↀ$f B@B 4@x@ADAgEAaL2@ah = `=$_i@g@ ! @= jƃ k B@B@x@ADAlE>aL AAam =H="n@?@ &+/ CoM+p B@B@x@ADAqE8 BQar =@"s@L`@ +#LsfH8J4i ݾ@~x]^aOAt$u B@B@x@ADAvELR`aw = aI"x@?@ #>Ay z B@B g@x@ADA{E aL) aaa| =V="}@@&/ 6C~" B@B@x} 9ADA @E k abqa =q`=$_@!i@ C^oƈxH%g<ݳd?"L` sAh + B@DB@x@ADAEx#aLra =n#`=$_@f@ ! @JAqe  B@B$@x@ADAE[ $aL a =,*="@!@ W&+#VA/C  B@B@x@ADAEہ a =/a"@ـ@&  lBjU飅NH]=a& mQAb  B@B"Y@x@ADAEM0aLa =:`=$_@ր@ # @=F  B@B@x@ADAE1;aL a ==$_@a@ `! @J/}C  B@Bt @x@ADAELA񷀂 A B@B@x@ADAErjaL@Y) Aa =|="@t@ W!A/FC{s +W B@B@x@ADAEb.kaa = 5v`=!I@v,@&JHj1`7h vt#(|a& `A+  B@B 4@x@ADAE怈A = 2$_@f)@ &+ @>(  B@B@x@ADAE〈 a =u="@@ /CLA[ B@B@x@ADAE7ba = 쥍`="@K@ #$*+k Gv*.0{÷#QAD$ + B@B@x@ADAEWaL a =ߢ`=$_@;@ @>A  B@B@x@ADAETaLA5!!a =Z^="@U@&$/| &  B@B@x@ADAE alXZ"1a =`="A@ @&N@t{~T| 5J{o~簔Ss*GF+ $+ B@B@x@ADAEwȀ@a =$_@ @ @>Ap  B@B@x@ADAE[ŀ AAAa =/π="@ƀ@ A/C W B@B@x@ADAE‱bABQa =`="@~@ PAwޯh)Hv.<&[:fAa + B@B\@x@ADAEL9aLR`a =`=+$_@{@dAEA[W B@B :%o@x@ADAE06aLaaa =@="@`7@&/LJC  B@B@x@ADAE bqa = ta @@&{"͘{4=%i95VsԗA7 B@B@x@ADAE!aL-ra =c`= @@dA3   B@B@x@ADAEaL) Aa =ް="@5@&/"C  B@B@x@ADAEbaa =Ai`=" @`@&δ6LtGWc oZ2`^Bja& Y  A B@B@x@ADA EaLAa = 4f`= @]@dA\ A B@B@x@ADAEaL a =!= @ @&/ w B@B@x@ADAEaӀa =@ @uр@ P@1IBjN! N@ DF+Ѐ- B@BP@x@ADAE̋aLa = `= @f΀@dA͠A[ B@B@x@ADA EaLda! =J`= "@NB@ :ڇv%qu4*h}8 oJ ̋KqC#A$$ B@B@x@ADA%Ea& =G%a '@>?@d(>A[) B@B@x@ADA*E:a+ =Y&a",@~  + /-% . B@B@x@ADA/E Lo:a0 =1a 1@$@ &l| d`ٱgi?6)8YC- a& D2$3 B@Bm@x@ADA4Evm2aL zA5 =<`= 6@@d7p 8 B@B@x@ADA9EZj=aL) WA!: =#t= ;@k@Ġ.-C< = B@B@x@ADA>E%>aWA? =,I`="+@@#@A[O ypqIu!Ad%31`AAa +B B@B@x@ADACEKށ A AD =)Ta E@ @dAFE G B@B@x@ADAHE/ۡ @Y !!AI =="J@_܀@&A/MK L B@BW@x@ADAMEUb"1AN =!o``= +O@ʔ@&AbG҇-u}DE.< DP6 Q B@B@x@ADARE!OaaL2@AS =^k`= T@@dAU V B@B@x@ADAWELlaL AA)AX =U="Y@5M@A/ CZ [ B@Bw g@xY 9ADA\ @EmaBQA] =<x`= ^@@ Ԃ)rs%dcs5_IPY$A_ -` B@DB @x@ADAaE AR`Ab =8 a c@@dAdA[e B@B}@x@ADAfEڼaaAg =ƀ="h@ @ /r$Civj B@Bu@x@ADAkEaxbAbqAl =`= m@uv@ V}9fCWeH.&=. `}D Anu$o B@B+@x@ADApE0aLrAq = |`= r@es@dAsr$t B@BA@x@ADAuE-aL AAv =7= w@.@ W/LCxKy B@BW@x@ADAzE6aA{ =`="+|@J@&$߂zY٥8 ֭7FO4A}怂$~ B@B@x@ADAEaLAA =`= @:@dA。  B@B@x@ADAEaL) A =M="@@&$/C  B@B+@x@ADAE ZaA = ``="@X@ A f:Qa="bifjĕy6 AW m B@B@x@ADAEvaLA =]`= @U@dAoTA[ B@BA@x@ADAEZaL A =#=G@ A@@ A/]C  B@B@x@ADAEʁ A = a @Ȁ@ @2`C {Λv"8@+PE萜 + `@2N B@B @x@ADAEKaLA = `= @ŀ@ @;ہD A B@B@x@ADAE/") A =="@_@+ @$/C]  B@Bp@x@ADAE;aA =]B`="@9@lYk 2!$}k74ڍB4<\+[a& {A5@0 B@B@x@ADAE  A = ^?a$_@6@ @=  B@B@x@ADAE @Y AZA =="@4@ WA/WC  B@BA@x@ADAEba = ; #@@ P 5sH1gjvAq1h aί A  B@B@x@ADAEdaL a =3`=$_@@+ @>A呂  B@B@x@ADAEaaL) !!a =k="@ c@&/XCub B@B@x@ADAE`a"1a = $`="@t@ XDTSj¬I %:7bC A A B@B|@x@ADAEՀ2@a = !'$_@c@ ' @>A  B@BA@x@ADAEҀ [AAa ={܀=+ A@Ӏ@ ! @/ `K  B@B@x@ADAE5(bBQa =3`="@I@&e`L*7䗂jpa& :o$ B@B}@x@ADAEF4J&A      R`A3  ݑ> H =`G `= @3@9@ $`6@*@ `@Q @C K`z.@G@T `@  iF B@B B @'@x@AD>EC?aLADaaa =@@[XM= @D@ `@ | e`L*7䗂jp?A  `XA B@B  @x@ADAE l#Cbqa = Ka"@J`@ #!K'#!ж$fj~&EDJCl&Փ~6A@4 B@B@x@ADAEuLra =VaIG @U`@ #$=n  B@B@x@ADAEYLAxa =@.="+@@ ! @Ġ/C  B@B@x@ADAEoWbka =vb`="@m@ +S(x#5NYg WeX #A` B@B@x@ADAEJ(caLa =sm`=$_@j@ ! @>AD  B@B 'A@x@ADAE.%naL) a =/="@^&@&/ՎC 4  B@x@ADAE a =eya"@ހ@%A>RQ1KDQŝYgnI-IA5  B@Bx @x@ADAEzaLa =a`="@ۀ@ '>A   B@B !@x@ADA EaLOm =П=)+ @3@ ! @OmA/@G !k B@B@x@ADAEQaa =7X`="@O@ ' ꒐x|eT j#lmPa& %A  B@Bu @x@ADAE aLa =2U`=$_@L@ ! @K=K  B@B@x@ADAEaL Aa =="@ @ /Cu B@Bt@x@ADAE_€F+ =ɨa"!@s@ #!҃V¥tgʯ|9E췍tA'ü g@ᇶ( B@B@x@ADA)EwaL a* =="+@x@ ! @҃/C,J- B@B@x@ADA.E53aAa/ =9`="0@I1@&XxIgTL5 (? T`j4.A10 2 B@Bx+@x@ADA3E뀈 a4 =6$_5@9.@ &+ @>A6-A[7 B@B@x@ADA8E耈 !!a9 =O=":@@%A/hC;< B@B@x@ADA=E b"1a> =`="?@@ #+Ay eRERYjdůRa& A@$A B@B|@x@ADABEt\aL2@aC =`=+$_D@ @ ' @>AEn AF B@B$@x@ADAGEXYaL) AAaH =-c="I@Z@&A/CJ K B@BA@x@ADALEaBQaM =`="N@@ >hńIvi] ; kQ浞eAO_ AP B@B@x@ADAQEJ́ R`aR =a+$_S@@ ! @>ATC U B@BA@x@ADAVE.ʁ  aaaW =Ԁ= X@^ˀ@ &+ @/CY AZ B@B@x@ADA[Ebbqa\ =d "]@ȃ@ #AlBŷC8%c2u.]ˊa0@ iA^4-_ B@B@x@ADA`E>aLraa =\`=$_b@@ # @Qz:=$cd B@B@x@ADAeE;aL 4Axaf =@D="g@3<@ !/Ah !owi B@B@x@ADAjE ak =>a"l@@%0#xB^9mݍ./V_a& Frm $n B@B@x@ADAoEaLap =2(`=$_q@@ &+ @>ArA[c @s B@B@x@ADAtEث)aLau ==+$_v@@ /Dwtx B@B@x@ADAyE_g*aaz =n5`="{@se@ +#!X:hg; (+hPRdk? &entba& A|d$} B@B+@x@ADA~E6aLa = k@`="@fb@ #>Aa  B@B@x@ADAEAaL) Aa =z&="@@ W! @A/QCI+ B@B@x@ADAE4؁ a =La"@Hր@&<֤Y\' 4Z{x IN a& (/AՀ  B@B@x@ADAEMaLa =W`=$_@8Ӏ@ &+ @>AҀ  B@B$@x@ADAEXaL a =KX`="@@ /C B@B@x@ =A @E IYaLa =Od`="@G@&$T4ҧŮx9R= ,7` ~nAF  B@DB@x@ADAEteaLA =Lo`=$_@ D@ # @>AmC  B@B@x@ADAEX a =(p)@~ ! @/BC  B@B@x@ADAE޹La ={a!I@@ +' @%>Bi7Kv1^l3^$+ B@BA@x@ADAEIr|aL a =`=$_@㴀@ ! @=$BA[ B@B@x@ADAE-oaL) !!a =x=+"@]p@&/   B@B@x@ADAE*aA"1a =l1`="@(@ P#!҃_FP]-?1Ժ;a& F+4 B@BA@x@ADAE 2@a =\.a"@%@ '>A  B@B@x@ADAE  AAa =="@2@ W! @A/FC W B@B@x@ADAEbBQa =5`="@@ v'TRgRM\{3'BJB$6A  B@Bs @x@ADAESaLAR`a =1`=$_@@ ! @>A핵`  B@B@x@ADAEP` aaa =Z="@R@ W/VCsQ B@B@x@ADAE^ abqa = `="@r @+Ala盱vT\6LINN1)h .A + B@Bp@x@ADAEĀra =$_@b@ # @>A  B@BA@x@ADAE a =qˀ="@€@%/}I  B@B@x@ADAE3}ba =٦@$_@G{@ ' @>EOxc**3KO_xXo@ aDz$+ B@B@x@ADAE5aLa =܀`=$_@8x@ ! @=w  B@B@x@ADAE2aL a =V<="@3@ &+/CA B@B@x@ADAE a =a"@@ #-H&ǩ.v1N+cy%M1A` + B@ByA@x@AD>Es`a =`=G@3R@@ #>Al蠂  B@B *@x@ADAEWaL a =#="@@ !/YC $ B@B$@x@ADA5  E^aa =e@K!I@\@&[aԲ~1U|bUH࠷sǻ@ цA^ B@DB@x` =A @EH aLa =b`=$_@Y@ &+ @JAB  B@DB@x@ADA E,aL) a ==" @\@&/'C   B@B@x@ADAEρ o7a =ca"@̀@ #$2`bQ>/vܙD8>ˏia& jA7 A B@Bt .@x@ADAE aLA =[*`=$_@ʀ@ ' @>A  B@B@x@ADAE+aL a =ʎ="@2@ ! @/!FC A B@B@x@ADAE@,aAa =9G7`=!I @>@ 3iԆ9,-.2ВԢ*\-= sA!" B@Bx@x@ADA#E  a$ =0DBa$_%@;@ ! @>&: ' B@B@x@ADA(E !!a) =="*@@ /C_C+s , B@Bw@x@ADA-E]Cb"1a. = N`= /@q@&AqM>'.94ot?VFC"0y@a& B0ݮ+1 B@B@x@ADA2EiOaL2@a3 =Y`=$_4@a@ # @>A5A[G6 B@B@x@ADA7EfZaL AAa8 =tp=H@4 9@g@ ! @A/!tC:H; B@BA@x@ADA<E3"[aABQa= =(f`=!I>@G @ ' @`Yߪ7f"BNKB_Ex")a& d?$@ B@B{+@x@ADAAEڀR`aB =%q$_C@7@ ! @=DA[E B@B@x@ADAFE׀) aaaG =V="H@؀@ /?dIJ B@B@x@ADAKErbbqaL =}`="M@@&4%N' 6Fh7EJPi&gzF+N O B@Bv@x@ADAPErK~aLraQ =`=+$_R@ @dASl T B@B@x@ADAUEVHaL@Y) aV =+R="W@I@&%o/VCX$Y B@B}@x@ADAZEaa[ = `=)\@@ ' @$jX8!8=5z^ua& "oA]] ^ B@B@x@ADA_EHaLa` =`= a@`@dAbA Ƕc B@B@x@ADAdE,L WXae =c{aI"f@r@ A)b PFo ǜc)\k@Cg2$h B@B}@x@ADAiE-aLaj =[x`= k@o@ ! @>lA[m B@B@x@ADAnE*aLAxao =@3="p@1+@  +/7lCq r B@B@x@ADAsEakat =8`= u@@JĠH71Ik|0G ;AbGx[n,a& ccAv w B@B@x@ADAxEaLay =0`=$_+z@@d{߀ | B@B@x@ADA}E֚aLa~ == @@&/OCr B@B@x@ADAE]Vaa =]`="+@qT@ '!Ġ>W#LvHɁc* $ƸCa+ga& ~AS$ B@B@x@ADAEaLA =Z`= @aQ@dAP  B@B@x@ADAE aL) Aa =w="@ @&/]RCG B@B@x@ADAE2ǁ a =a$_@Fŀ@ -`j0aJbɮUg2o@a&  ZAĀ A B@B@x 9ADA @EaL a =`= @:€@dAA B@DB`@x@ADAE|aL !!a =Q="@}@ /vCa B@BP@x@ADAE8a"1a =>  @6@ F`@^\ݺ TW ,^0_D 2ɾҦ E qA5$+ B@B}@x@ADAEr2@a =; @ 3@dAk2 A B@B@x@ADAEV AAa =="@@ /C Ø B@B}@x@ADAEܨbBQa =!`="@@&>gn'?־+ HVa& [A\$ B@B 5@ADA @EGa"aLR`a =,`= @ᣀ@dA@ `a/ ir B@DB@x@ADAE+^-aL) aaa = g= @[_@  `@$>.C  B@Bt@x@ADAE.aAbqa =n 9`="@@%Agsw1o){H~^z}'&tذ"`2 B@B@x@ADAEҁ ra =ZDa @@dA ` B@B@x@ADAEϡ @Y a = 5؀="@0Ѐ@ /M`  B@B@x@ADAEEba =3P`="@@ +B/.Ұ\t=1-0:AQa& F+  B@B+@x@ADAEBQaLa =/[`="@@dA넠A[ B@B@x@ADAE?\aLa =I= A@A@ /?/Cq@ B@B@x@ADAE\a = ha"@pg`@ gejP`v-6?N1ZF5Uj a& A  B@B@x@ADAEdzLa =raI A@`@dA  B@B@x@ADAEsaL Aa = w= @۱@ }/n:CG B@B@x@ADAE1ltaa =r`="@Ej@&Aa8 FVʺ-i\9bHQP [pi$+ B@B@x@ADAE$aL`a =o`= @:g@dAf  B@B@x@ADAE!aL a = M+= @"@ /~D B@B@x@ADAE݁ Aa =a"@ۀ@ mA1)8qo/7?/a&  Aڀ$ B@B@x@ADAEqaLA ~6`= @ ؀@dAjנ  B@B`x@9 A @EUaL a =&="@@ /.'C  B@DB@x@ADA EMa-&a =T`=" @K@ U -0' e&7Z y,ra& WA ` B@B+@x@ADAEFaL a = Q`="@H@ # :=C@ A B@B x@x@ADAE*aL) !!a = ` = A@Z@&A/C  B@B@x@ADAE A"1a =ja"@ż@ J*0Z;zHKʰ& [tJa& \A1  B@B @x@ADAEwaL2@a =Y`=$_ 4@@ &+ @>  ! B@BA@x@ADA"EtaL AAa# = 5}= $@0u@ ?&+ @g/C% & B@B +4@x@ADA'E/aBQa( =66`=")@-@ +#=䬥d Ar83kA*-+ B@B+@x@ADA,E R`a- =.3$_.@*@ # @=A/)A[06@-B@x@ADA1E䀈aaa2 =="A3@@ W!/C4q倂5 B@B@x@ADA6E[bbqa7 =`="8@o@&$[[Kb;hŸQ !(r*!sQdlA 9۝ A: B@@iB$@x@ADA;EXaL$ra< =`=$_=@`@ &+ @>A>A[? B@B@x@ADA@EU* AaA =s_="B@V@ /DCFD B@B@x@ADAEE1aaF = `="G@E@&$OAVd,?´vaGM[+AAH$I B@B$@x@ADAJEɀaK =a"L@4 @ #>AM N B@B@x@ADAOEƀ) aP =PЀ=)+Q@ǀ@&$/_CRS B@B@x@ADATEbaU =#`="V@@&!XחY.*'mPb8a& AW AX B@Bm@x@ADAYEq:$aLaZ =.`=$_[@ }@ PA\j| ] B@B@x@ADA^ET7/aL a_ =)A="`@8@&/5,Ca b B@B@x@ADAcE ad =:a"e@@ #&lW$m K3jVn_TSCqAf[ g B@B@x@ADAhEF;aLai =E`= j@@ PAk? l B@B@x@ADAmE*FaL@Yk an ==+"+o@^@ ! @/Cpʨ q B@B@x@ADArEcGaas =ajR`="t@a@&$xZ;r&V]C61:ݲB3a& vu0-Pv B@B@x@ADAwESaLA m =Yg]`= y@^@ &+ @>zA[{ B@B@x@ADA|E^aL6ha} =6i`=+$_~@Ҁ@$Ƕ%BTQ[1 W/R~)2‹UDLD$ B@B@x@ADAEjaL a =2t`="@π@ &+>΀  B@B}@x@ADAEԉuaL>!!a == @@+/Ct  B@B@x@ADAE[EvaW"1a = L`="@oC@&;2„( 1h3.xT-xza& hAB  B@BM@x@ADAE2@a =I$_+@_@@ P?  B@B@x@ADAE WAAa =va"@~&/CE"diK B@B@x@ADAE0LBQa6 ܼ'@D@A.廒=Zy}b6ɑ4ۥ\ nA  B@BC@x@ADAEnaLR`a =ع`= @4@ PA  B@BW@x@ADAEkaL aaa =Hu="@l@ -&&+)A/~ B@B@x@ADAE'abqa =-`="@%@&@ȶ.IsjV d~Rx91a& $$+ B@B@x@ADAEp߀ra =* @"@ # @=m!A[g@ᇶ B@B $`@x@ADAET܀ a ==+$_@݀@&/'G  B@B}@x@ADAEۗbAa =`="@@ '!AD©Ue*s"wa& ;}AZ  B@B@x@ADAEEPaLa =`=+$_@ޒ@ ! @=>  B@BA@x@ADAE)MaLa =V="@YN@ &+A/QC + B@B`@x@ADAEaa =d`=!I@@ # @V3.At]ll1A0 B@B<@x@ADAE a =X $_@@ # @>A A B@B@x@ADAE $a =ǀ="@2@ !/C + B@BC@x@ADAEybo ƴ̟a =5`="@w@&M3h-;"` AJ6لA  B@B@x@ADAE1aLa =1}@$_@t@ &+ @>As ` 6h B@BA@x@ADAE.aL}a =8=$_@0@&//Ct/  B@Bt @x@ADAEZꀈa = a"A@r@&v>Qu?3^2΢oa& JA瀂$ B@B@x@ADAEŢaL$ zA =`=$_@^@ ' @>A䀂  B@B@x@ADAEaLAx@! =@q= @٠@&/>fCEW B@B@x@ADAE/[a$&! =a%`="@CY@ '!Q.Q%eI |lQ[Lna& AX$ B@B@x@ADAE&aL A =^0`=+$_@3V@ ! @=UA[ B@B@x@ADAE~1aL !!A =R="7@@ &+/ C B@B  @x@ADAÉ "1A =A iƀ A B@B@x@ADA ESHaL) AA' = ="@@&/wC  B@B@x@ADAEA>  B@B@x@ADAE( @Y5 aaA =="@X@/>C  B@B@x@ADA!E`bbqA" =!dk`=$_#@ë@&@~Inu?/i6mKljh4iT[p\A$/ % B@B|@x@ADA&EflaLrA' =[v`=$_(@@ PA) * B@B@x@ADA+EbwaL A, =l= -@.d@ ! @/xpC.cA/ B@B@x@ADA0ExaA1 ==%`="2@@ m'AF`3Ev`sikSKP"a& A3-4 B@B@x@ADA5Eց A6 =-"a+ 7@@ ! @>A8A[9 B@B@x@ADA:EӀ A; =݀="<@Հ@ /eC=oԀ a> B@B@x@ADA?EZbkgA@ =`=$_A@n@ +# @ak|K[0~ADM%â? dBڌ$C B@B+@x@ADADEGaL FE =`=$_F@^@ @>G$H B@B@x@ADAIEDaL AJ =yN="K@E@ W/(LDM B@B:@x@ADANE/aAO =`="P@C`@&ujG.ӧ8ujaˏ_}0a& +F+Q$R B@B@x@ADASELAT =aI"U@3`@dAV AW B@B@xU 9ADAX @E}L@h5 AY =M="Z@@&/ݰC[A\ B@DB@x@ADA]EqbA^ =w`=)_@o@ AZN#AEvC A`n a B@B@x@ADAbEo)aL!)Ac =t`=)d@l@dAehkA[f B@BA@x@ADAgES&aL A_-Ah =0="i@'@ #V$/>X:j k B@B@x@ADAlE am =a!In@߀@ @ƃ'Us zqNRa& qAoY@0p B@B@x@ADAqEDaL Cr =`= s@܀@ @=t=u B@B@x@ADAvE(aL !!aw =저="x@X@+ @/D]Cy z B@B@x@ADA{ERa"1a| =_Y`="+}@P@ AJ5'KyB@Hg_wa& A~.$ B@B+@x@ADAE aL2@a =WV $_@M@ @=  B@B@x@ADAEaLAAa ==$_@- @ /M)CA B@B@x@ADAEÀBQa =4a"+@@ aAL؜^]Ap 10;Veaa& FA$ B@B@x@ADAE{aLR`a =,`=$_@@dA轀  B@B@x@ADAExaL) Aaaa =="@z@&/* ny B@B@x@ADAEY4abqa = ;'`= +@m2@  nQUF+3b 6/괌/a& D1  B@B@x@ADAE쀈ra =82@ @a/@ @+=A. m B@B7@x@ADAE逈; Om =>a"7@B@g̥ͥ~/7ZP:a9l/C  B@Bg@x@ADAE]?aLa =֨I`="@2@d  B@BW@x@ADAE}ZJaL a =Qd= +@[@ +ՙ/,~ B@B@x@ADAEKaa =V`="@@ Ġr4eߡOdZU^צZHWf`4<@ *D$A B@B@x@ADAEn΀a =@逃aa"@@dg  B@B@x@ADAERˀ a =Հ= @̀@ /Jw  B@B@x@ADAEنbbWa =m`="@턀@ Ġȭwɷ DvdDS+^5)a& xDY B@B @x@ADAEC?naLa =x`= A@݁@dA}b  B@BA@x@ADAEaL !!a ='= @@PA/2Cn"f5 B@B@x@ADAEXـ"1a =a"@l׀@ +<8 4Ew8u=QjXT"a& Aր$+ B@Bt@x@ADAEÑaL2@a =ݾ`=$_`3@]Ԁ@dAӀ  B@B@x@ADAEaL AAa =p= @׏@ W/Rt C B@B@x@ADAE-JaBQa =P`="@AH@&A>|uf5}g  B@B@x@ADAEQpaL) a =z= A@q@ W/]~ + B@B@x@ADAE+aa =2`="+@)@ +#!'# u;ŊM _, 5/6NrX  B@B+@x@ADA EC a! =/ $_"@&@ # @>#< $ B@B@x@ADA%E& @Y a& = +="'@W@&/x( ) B@BW@x@ADA*Eba+ =U`=",@@ \TX*㈍3jsQ̗z7%ӭja&  J-- . B@B@x@ADA/EUaLa0 =`=$_1@@ @>A2 3 B@B@x@ADA4EQaL a5 =[=+'u6@,S@ W&+ @$/C7R8 B@BA@x@ADA9E aa: =3)`=!I;@ @&A de^^ (lԁ2PgJkL!a& r<-= B@B+@x@ADA>E)aLa? =+4`=$_@@@ # @=`A `@  B B@B@x@? =AC @E€ aD =̀="E@Ā@ !#V/xVDFmÀG B@DBW@x@ADAHEX~5bAaI =@`="J@l|@ +A{RBs=p9b na& AK{$L B@B+@x@ADAME6AaL#AN =K`="O@[y@ !>APx Q B@B@x@ADARE3LaL aS =!o==$_+T@4@  @ /[CUB +V B@B@x@ADAWE- aX =Wa"Y@A@&0) Am3jsUA|NWa& bAZ쀂+[ B@Bug@x@ADA\EXaL a] =b`=$_^@1@ ' @=A_适 ` B@B@x@ADAaE{caL !!ab =D="c@@&/Cde B@B@x@ADAfE`dak U@s"1ag =fo`="h@^@&-)3 䗷psDcUuQ63@ dbAi] +j B@B@x@ADAN6EmpaL2@al cz`=$_m@[@ PAnfZ o B@DB@x@AD>pEQ{aLAxAAaq =@%=+)r@@&-/NCs t B@B@x@ADAuEЁ BQav =׆a"w@΀@ #!uԁw)esS۟΀{b?a& 7xW$+y B@BJw@x@ADAzEBaL-R`a{ =ԑ`= |@ˀ@ PA};A[~ B@B@x@ADAE&aLaaa ==+"@V@ ! @/  B@B@x@ADAEAabqa =aH`="@?@ ; ~q*1AYz|oK'?F+, A B@B}+@x@ADAE ra = UEa"@<@ !$> B@B@x@ADAE a =$_`3@+~ /VC B@B|@x@ADAELa =2'@@ #!W#}{M]HN,~ml]H\a& bA$ B@B<@x@ADAEjaLa =*`="@@ #>欀  B@B@x@ADAEgaL) a =q="@i@&/Clh B@B@x@ADAEW#aa =!A *`="@k!@ +W]o^> o, 7~3 YA e#XF B@B+@x@ADAEۀa =&$_@[@ ! @+=$  B@BA@x@ADAE a =w=+'u@ـ@ &+ @/SuCB  B@B@x@ADAE,ba =ٚ`="@@@ #Az:Je[KGxt/pz?،$"Hռa& ȅA$ B@BP@x@ADAELaLa = ؗ`=+$_@4@ # @=  B@B W@x@ADAE{IaL kfa = `="@@ @W%[qאx+RQ&P3WCb Qwbt! MC@2 B@B @x@ADAElA =r"@@ $ @QC >e`  B@B@x@ADAEP Axa =@Ā="@@ @/ W B@B@x@ADAEuba = |`="@s@ "Y&+ `HHy#݈3#^+ l}C]W@2 B@Bo + m@x@ADAEA.aL a =y`=$_@p@ ! @>;  B@B@x@ADAE%+aL) !!a =4="@U,@ &+/QC  B@Bq@x@ADAE "1a =\*a"@@ #aFIٮ8<D Pe&A, A B@BJ@x@ADAE+aL2@a = T5`="@@ m#>A  B@B@x@ADAE6aLAAa =ʥ="@*@A/C B@B@x@ADAEW7aBQa =.^B`=$_@U@ 'I9&hG]gzc7,pJ}(+M+՘sa& A  B@B@x@ADAECaLR`a =)[M`=$_@R@ ! @JAQ  B@B@x@ADAE NaL Aaaa == @@Ġ/Cl  B@B@x@ADAEVȀ}qa =!A Ya"@jƀ@ +#!҃Joaڵ͍ dŀ$+ B@B+@x@ADAEZaLAra =d`=+$_@ZÀ@ PA A[m9  B@x@ADAE}eaL/a =y="@~@ !/DE$ B@B@x@ADAE,9faAa =?q`=!I@@7@ +w쵙" ?NNL@>`lsiqa& #A 6$ B@B@x@ADA Ea = <| @04@ ! @+=:3  B@B@x@ADAEz Aa =C="@@ W/SC( B@B@x@ADAE}ba =`="@@&GjyH>0ob A$ B@B@x@ADAEkbaLa =`=+$_+@@ `@>e A B@B@x@ADAEO_aLbH a =i="!@`@ !'/BC" # B@B@x@ADA$Eaa% =!`=!I&@@ ' @/ёőG-hΟa^_"'V ( B@B@x@ADA)EAӁ a* =a +@@ ! @=A,: - B@B}@x@ADA.E%Ё  a/ =ـ="0@Uр@ / D1 2 B@B@x@ADA3Eba4 =g`="5@@҃F%öyt8E32//=1wa& z6+-7 B@B@x@ADA8EDaLA9 =S`=$_:@@ # @>A;< B@B@x@ADA=E@aL a> =J= ?@*B@ C! @A//D@AA B@B"Y@x? 9ADAB @EaC = ?=)a"AD@`@ 'fJMe| "GD N iAE@2F B@B@x@ADAGE봁L aH = {)aI$_I@`@ g! @>AJ K B@B@x@ADALEϱL !!aM =="N@@ /)OkP B@B@x@ADAQEVmb"1aR =t`="+S@jk@&$z"`BDC=(F;I Ea& LDTj$U B@BP@x@ADAVE%aL2@aW = p`=$_X@Zh@ @>AYg Z B@B@x@ADA[E"aL) AAa\ =m,="]@#@&$/`C^@_ B@B$@x@ADA`E+ށ BQaa =a +b@?܀@ ' @Am)VPZu'ض=SEy=tx7O }ہcۀ d B@B@x@ADAeEaLR`af =@$_g@/ـ@dAhؠ@i B@B @x@ADAjEy aL aaak =F="l@@ A/Dmn B@B@xl 9ADAo @EO abqap = 5=U`="+q@M@ +Qz"$k:_ $ArL s B@DBt @x@ADAtEkaLrau = R `= v@J@dAwdI x B@B@x@ADAyEO!aL az = = {@@ W//| } B@B@x@ADA~Eտ a =,a"+@齀@&&W%ȃlO1+ ~]+DU$+ B@B@x@ADAE@x-aLa =~7`= @ں@c9 A B@B@x@ADAE$u8aLa =~= @Tv@ /<~  B@B@x@ADAE09aAa = W7D`="+@.@ +A+5#sZ)K8ش&F؊S VO+ B@B+@x@ADAE a =S4Oa @+@dAA[ B@B@x@ADAE  Aa =="@)@ W/G怂 B@B@x@ADAEPba = -[`= +@@&]>5Tr SN8l1.Vg[$"A$ B@B@x@ADAEY\aL%oa = {,f`= @@dA蛠 B@B@x@ADAEVgaL) a =`= @W@&/Cj B@B@x@ADAEUhaa =s`="+@i@ A#&M8lFJ+ R + j*DA  B@B@x@ADAEʀ" = ~ @Y @dA  B@BA@x@ADAE a =lр="@Ȁ@ A/C@  B@B@x@ADAE*bpHa = ډ`="@B@&ƨ[ԑvtLϋI_}v A$+ B@B@x@ADAE;aL a =҆`= @/~@dA}  B@B@x@ADAEy8aL !!a =AB="A@9@&/wCA B@Bs:@x@ADAE $"1a =a @@&|˽Bj!XJ>׆97(vL2 a& A + B@Bm@x@ADAEjaL2@a =`= @@dAcA[ B@B@x@ADAENaL AAa =="@~@ A/C - B@B@x@ADAEdaBQa =k`="@b@ +Gk=~u4"^U"Ʋ֑uBKrY{a& vU B@B@x@ADAE?aLR`a =}h`="@_@dA9  B@B@x@ADAE#aLqaqa =Z`="@Ӏ@i]&7aFT -= ^a&  D*  B@B@x@ADAEaLWra =R`="@Ѐ@d W B@B@x@ADAEaL? a =ɔ="@)@  + |1C B@BO@x@ADAEFaa =! /M`="@D@&?}v{1] g:} ^AC  B@B@x@ADAEa ='J W@A@d@A[ B@B@x@ADAE a =a+ m@~&Ġ/JCj  B@BO@x@ADA:  ETLa = a"@h@A-^VY"$:#O+um3ԯZ@ _cAԴ$+ B@DB+@x` =A @Eo@Wa = `= @X@dAA B@DB@x@ADA El aL a =sv=" @m@ A/OC ?A B@B@x@ADAE*( aAa =.`="@>&@ Ġa9C$w_nxW& a& A%$ B@B @x@ADAEa =+"a"@-#@ #$=(" A B@B@x@ADAEx݀6ha =Q= A@ހ@%/9li +A B@B@x@ADAE#ba =.`=" @@ $ĠS81(;k`3_(ȯg xWxD! " B@B@x@ADA#EiQ/aLA$ =9`=$_%@@ ! @>C&c ' B@B@x@ADA(EMN:aL Aa) =X="*@}O@ :&+$/7C+ A, B@Bu@x@ADA-E ;aa. =F`="/@@ #+)B۠cl= Mdht}?0T 1 B@B@x@ADA2E?  a3 =| Q$_4@@ # @=A58 6 B@B C@x@ADA7E# A!!a8 =Ȁ=+"9@W@&$/?:á ; B@B{ @x@ADA<EzRb"1a= =Z]`=">@x@&$ոgw?7raO mu; DiIa& Zr?)-+@ B@By@x@ADAAE3^aL2@aB =V~h`=$_C@u@ &+ @>AD A[E B@B}@x@ADAFE/iaL AAAaG =9="H@(1@%/rI0J B@BW@x@ADAKE~뀈BQaL =*ta"M@@ #&lia\G%/paE#a& ; N耂 +O B@B}@x@ADAPEuaLR`aQ ='`="R@@ PAS堂A[T B@B +'XZ@x@ADAUE͠aL aaaV =="+W@@ ! @K/:XiY B@B@x@ADAZET\abqa[ =c`="\@hZ@ qK^Ӥ&$jʑ&U#hFa& A5]Y$^ B@BJ@x@ADA_EaLra` =!``=)a@\W@ ! @>AbV `ݟ/c B@B@x@ADAdEaL) ae =!o="f@@ W/Gag>h B@BW@x@ADAiE)́ aj =ӣa"k@=ˀ@ +#+AQ% L6J5CJҙe]$:,((Tlʀ Am B@B+@x@ADAnEaLao =Ю`=$_p@-Ȁ@ # @>qǀ r B@BA@x@ADAsEwaL at =A=+"u@@ ! @ /Cv w B@B@x@ADAxE=aay =D`="z@<@&$v55?IAb8  B@B@x@ADAEM$a =!=$_@@&$/9C  B@B@x@ADAEӮbCa =`="@묀@&A yJ0ڦ\kj!mid$XGe"a& zLW-0 @ B@B+@x@ADAE>gaLa =`=+$_@۩@ ' @=;A[a@၊ B@B@x@ADAE"daLa = m= @Ve@ ! @A/(zL¡$ B@B@x@ADAEao#a =U&`="@@ `'lIp8©a l3]{v]a& Mд-@0 B@Bm@x@ADAE؁ $ zA =Q#$_@@ ! @>A  B@B@x@ADAEԁ  A! =ހ="@'ր@ /jCՠ  B@Bq g@x@ADAE~b4! =*@"@@ m#z6PrEpA\&ͨ#Gf@ AǶ B@B+@x@ADAEHaL A =& `=+$_@@ @>A⊀  B@B@x@ADAEE aL !!A =O=G@b@F@&A/P9Ch B@B @x@ADAESa"1A =`="@g`@ LD{D]/G8tjoS%V VWa& Lm  B@B@x@ADAEL2@A =!$aI+$_@[#`@ ! @>A  B@B@x@ADAEL AA' =j='u@ҷ@ A/m> B@B@x@ADAE(r%b"! =x0`="@Aaݠ  B@B@x@ADAELSaL A =!="@|@ /  B@B@x@ADAESTaA =Z_`="@Q@ #7YOL Ik%xg ga& F+S B@B@x@ADAE= `aLA =Wj`="@N@ #>7  B@B8@x@ADAE! kaL) A =="@Q @ !A/C  B@B@x@ADAEā A =Uva!I@€@  #D_D/NZf=jb{z;Ψ(a zYA( A B@B@x@ADAE}waLA =Pȁ`=$_@@ ! @JA  B@BA@x@ADAEyaLqA =9<`= @3@&li&!?׭0/xmt'a& C2  B@Bli@x@ADAE퀈A;%9"@0@ &+ @>/  B@B`x@9 A @E A =="@@ $#Vli/Ch  B@DB@x@ADA ERbA =`=" @f`@&.(GղW`MI R%a& %A ңCA B@B@x@ADAE^a W-5A =`=$_@W@ # @=A[ B@B@x@ADAE[aL  A =ue="@\`~ !. C= B@B@x@ADAE(a Wa =`="@<@ '# ,Vx% EPD VwèľCK 3H{oA$ B@B$@x@ADAEπ a =a"@+@ PA  A! B@B}@x@ADA"Ev̀) !!a# =Bր="$@̀@ :/RCC%̀& B@B@x@ADA'Eb"1a( =`=%)@@&uk̀-NSv<,L<Va& PXA*} + B@B@x@ADA,Eg@aL2@a- =`=).@@J @JA/aA[A0 B@B@x@ADA1EK=aL AAIA2 =G="3@{>@&/tC4 5 B@BC@x@ADA6E BQa7 =a"8@@ dAEWfxC#J׿.ݲ2+

6 A? B@B@x@ADA@E!aL aaDA == B@Q@ `@E.CC D B@B@x@ADAEEi@TbqaF =Tp:Q G@g@ :2>$}jtk[[тxw gH'-I B@B:@x@ADAJE"aLAraK =Pm`="AL@d@dAM N B@B@x@ADAOEaLaP =(="Q@& @ /8RS B@B@x@ADATE}ڀAaU =)a"V@؀@ }@|5b߻ 'u֮ W׀ AX B@Bg@x@ADAYEaLaZ =%`="[@Հ@dA\ԠA[] B@B 1@x@ADA^Eˏ&aL Aa_ = `="`@@ W/?agb B@BA@x@ADAcERK'aad =R2`= Ae@fI@%o$oUL9d'ZDeTMWIJfH$g B@B%o@x@ADAhE3aLai =N=`= j@VF@dAkEA[l B@B@x@ADAmE>aL) an = u = o@@&/Cp<q B@B@x@ADArE' as =Ia"+t@;@ -&A 201$#e>l9eAu Av B@BR.@x@ADAwEtJaLax =ϿT`= y@+@dAz { B@B@x@ADA|EvqUaL a} =F{= ~@r@ A/PIC B@B@x@ADAE,Val  Ua =3a`="+@+@!Ahh KäbʆfRXEp0:W@ PA|*@1 B@B[@x@ADAEg倈" =0la @(@dA`'A[ B@B@x@ADAEK @sa =@="@{@$/C  B@B+@x@ADAEѝmba =x`=!I:@囀@ mAfW'ÛSYpa,W{da& 8AQ$ B@BP@x@ADAEJ  B@B@x@ADAEÁ ) AAa =̀="@%ŀ@&/CĀ B@B@x@ADAE|bBQa =1`="+@}@&^0B3Z@a`J a& g|  B@B@x@ADAE7aLR`a =$`=$_@z@dAy  B@B@x@ADAE4aL aaa = >="@5@ A/gf B@B@x@ADAEQ bqa = a"@e@ #O=<>*g&gA+Sa& F+퀂  B@B@x@ADAEaLra =`= @V@dAꠂ A B@B@x@ADAEaL a = t=+ W@Ц@g-&/C< B@B@x@ADAE&aaa =g`= @:_@ m^4Kv<f5u_g (]!(a& EA^$+ B@B@x@ADAEaLa =d`= @.\@dA[A[ B@B@x@ADAEuaL a =A ="@@ A/iC B@B@x@ADAEс Aa =a"@Ѐ@ P~1q`Vx? m j(ta% q(|π$ B@Ba@x@ADAEfaLa =`="@̀@dA_̀$ B@BA@x@ADAEJaL a =!A= @z@&/uD  B@Bg@x@ADAEBaa =I@"@@@ v'A!<>7pzKMNh@ ]Q B@B+@x@ADAE; a =yFa @=@dA5  B@B@x@ADAE @Y a =a"@O~&A/  B@BW@x@ADAELa =N'@@&l:H`y, y,JtjSx^a& #nF+& @J  B@Bp W c'@x@ADAElaL A#1 ='`= <@@ ,W @>  B@BA@x@ADAEh(aL a =r=+"@%j@ @҃/BCi!&Ţ B@B@x@ADAE{$)aa =(+4`=!I @"@ PAddDSwy-2P2a& iA !- B@B@x@ADA E܀ a =#(?$_@@ ! @>  B@B@x@ADAE !!a =="@ڀ@ }&+#V/iAf  B@Bg@x@ADAEP@b"1a =K`="@d@Aӂr "aD}4؉bQÊ>В@.Y B@BA@x@ADAEMLaL2@a =V`=$_@3H@T@ # @= A[ B@B@x@ADA!EJWaLqAQa" =AV c`="#@:@ !ZZr5YGp%kF6f B[ć!a& IA$$% B@ B@x@ADA&ER`a' = na"(@*@ P) * B@B@x@ADA+Et aaa, =Aŀ="-@@ !B//C.+/ B@B@x@ADA0Evobbqa1 =}z`="2@u@ War(ľ{f'V{a-Ra& dA3{t 4 B@BA@x@ADA5Ef/{aLWra6 =z`="7@q@ !M8_ 9 B@B@x@ADA:EI,aL a; =6=$_A<@y-@ /7HC= > B@Bm@x@ADA?E a@ =a"A@@ +#!QC A'ڑBfwz+eR0N03 + x@GBP C B@BA@x@ADADE;aLaE =x`=+$_F@@ # @>G4 H B@BW@x@ADAIEaL aJ =릀="K@O@ W! @ՙ/fTCL M B@B@x@ADANEXaaO =M_`="P@V@   DU22Wf{$  ֐^xa& '`Q%@0mR B@B@x@ADASEaLaT =N\`=+$_U@S@ @>V A[W B@B@x@ADAXE aLaY ==$_Z@$@ /`[\ B@B@x@ADA]E{ɀAa^ ='a"_@ǀ@$Ats}!9QLdfA]ޟ4Af ްȣa& OF+`ƀ$a B@B@x@ADAbEaLac =#`=$_d@Ā@ @>AeàA[f B@B g1@x@ADAgE~aL Aah =="i@@&/Cjek B@B@x@ADAlEP:aq am = A`="n@h8@ĠMJ@h'&z;R?va& Ao7$p B@B@x@ADAqEAr ==a"s@W5@ *>At4 Au B@B@x@ADAvE) aw =s= Ax@@.0Cy:z B@B@x@ADA{E%bAa| =ұ`="}@9@ +#!K˛IWc>W>B)e A~  B@BA@x@ADAEcaL a =ͮ`=+$_A@)@ ,W @>A  B@BA@x@ADAEt`aL !!a =A^A[ B@B@x@ADAEIс  AAa =ۀ="@yҀ@ / C  B@B@x@ADAEόbBQa =`="@㊀@ #+AQ07e@߱)ު0 p5 L AAO A B@B@x@ADAE:EaLCR`a =x)`=$_@ԇ@ # @>A3  A B@B@x@ADAEB*aLaaa =K="@NC@ !A/\mC  B@B@x@ADAE bqa =M6a"@5`@ +iKsicӮ=BcKP`e"a& q3R%@0 B@B+@x@ADAELra =AaI"@@`@ !>A  B@B@x@ADAEL@Y Aa ==$_+@'@ /9~ B@B@x@ADAEznBba ='uM`="@l@&nLU\QF#qLb#V ymBa& F+k  B@Bm@x@ADAE&NaLAa ="rX`=$_@~i@ @JAh  B@B@x@ADAE#YaL a =-="@$@&/OCd B@B@x@ADAEO߁ a =da"@c݀@&SyrQj.Gٝ>'k Ѵ.a& om܀  B@B@x@ADAEeaLa =o`=$_@Sڀ@ PAـ  B@B@x@ADAEpaL a =j= A@Ε@& /u: B@B @x@ADAE$Pqaa =V|`= @8N@&x f*9.w>ooyAa& aM$+ B@BA@x@ADAE}aLa =S`= @)K@ ,W @JAJA[Y B@B@x@ADAEsaL a =7="@@#V/g B@B@x@ADAE Aa =Ǔa"@@ +'$ΨX#\A>F'd$X$+P/]A[ B@B6h@x@ADAEHvaL a =="@xw@ &+/ʳC W B@B@x@ADAE1aa =|8`=!IW@/@ m# @+{ك@c` 1uvAa& /AO+ B@BA@x@ADAE9  a =w5$_@,@ # @>3 A B@B@x@ADAE @Y) !!a =="@M@ W!/ٜC=  B@B@x@ADAEb"1a =P`="@@ הiǃ~8L6d4شv]܅5Ba& !A$ + B@B@x@ADAE[aL2@a =L`=$_ @@ ! @>A   B@B@x@ADA EWaL AAa =a=$_@#Y@ /l CX B@B@x@ADAEyaBQa =.`="A@@ #!лTdjϢ$|駪vVA  B@B@x@ADAEȀ aaa =Ҁ="@ɀ@B҃/d B@BM@x@ADA ENbbqa! =`=""@b@!=_ C=n8 ͞JzF+#΁@4$ B@B@x@ADA%EnI/D?HS@ w`A2$3 B@B[p@x@ADA4E aLa5 =`=$_6@(@dA7A[8 B@B@x@ADA9EraL6ha: =l `=";@ d@ WnIJjg3 Եdy[IGд^C<yc = B@Bt  B@x@ADA>Ed!aLWa? =i+`= @@`@ +$ @JA] B B@B@x@ADACEG,aL? aD =%= +E@x@+0/CF G B@B@x@ADAHEց aI =7a+ J@Ԁ@ ' X]U~tz)x a& xAKN L B@B @x@ADAME98aL aN =zB`=$_O@р@dP6 Q B@B@x@ADARECaL i AxaS =@="T@M@&Ġ/CU V B@B@x@ADAWEGDaaX =\NO`= Y@E@&h(_[![pC8:Joa& =BZ#-[ B@B@x@ADA\EPaL"] =PKZ`= ^@B@dA_A[` B@B}@x@ADAaE ab =[a"c@"~ *#VĠ/˴Dde B@B@x@ADAfEyL-&ag =)fa!Ih@@ Qgbm4} ڊ c](ϝ1Ai$j B@B@x@ADAkEpgaL al =!q`= m@}@dAnݲA[o B@B@x@ADApEmraL) A!!aq =w= r@n@ /ǬCsct B@B@x@ADAuEN)sa"1av =/~`="+w@b'@&X,V-K8)I62ibm1Ya& Ax& y B@B@x@ADAzEဈ2@a{ =,a |@R$@dA}# ~ B@B@x@ADAEހ AAa =i="@߀@ /3C8 B@BH@x@ADAE#bBQa =ܠ`= +@7@ ACݘ`O2~g0[A  B@B@x@ADAERaL$R`a =ϝ`= @+@dA A B@B@x@ADAErOaL aaa =FY="@P@&/wC B@B@x@ADAE abqa =`= @ @ >2 FR"(*\2M|Y8ia& x$+ B@Bu X@x@ADAEcÀra =a @@dA\!FGA B@B$@x@ADAEG  a =ʀ="@w@҃/  B@B@x@ADAE{ba =`= @y@ >=e<4 61½1 ;>a& F+M A B@B @x@ADAE84aLa =v`= @v@dA1  B@B@x@ADAE1aLa =:= @L2@ /\C  B@B@x@ADAE a =Oa"+@@&q>UX=,>9hhRy3a& A# B@B@x@ADAE aLa =K`= @@dA  B@B@x@ADAEaL) Aa =="@!@&/k B@BA@x@ADAEx]aa =0d`="@[@&˘(o \y#4ʺDZ A B@B@x@ADAEaLa = a`= @|X@dAW * B@BA@x@ADAEaL6ha = =+ A@@>/~Cg  B@B@x@ADAEM΁ a = @ @à@&(ťSңɸb">s @3Zo's@ Aˀ$ B@B@x@ADAE aLA =`= @Qɀ@dAȀ  B@B@x@ADAEaL Aa =l= @̄@ /C8A B@B@x@ =A @E"?aa =E"`="@6=@&$ؕ7z!VF^CN}SYd"soA<$ B@DB$@x@ADAE$ a =B-a @&:@ 4 @>C9 A B@B@x@ADAEq@Y !!a =>= @@ /$ B@B@x@ADAE.bA"1a =9`="@ @ #!vQԭE~cJY-n[a& 9Dx$ B@Bm@x@ADAEbh:aL2@a =D`=$_ 4@@ # @>C\ A B@B@x@ADAEFeEaL) AAa = o="@vf@&/ύC A B@B@x@ADAE FaBQa =}'Q`="@@&y%q-/DP~}]&Ênͨzh@ iAM m(B@x@ADAE7ف R`a =@逃y$\a"@@ &+>A1  B@B[p@x@ADAE֡ @YAaaa =߀='u+@K׀@&/   B@B@x@ADA E]bbqa =Kh`=" @@!A0VёuYw3ӳQ{q&( m #ja& "  B@B(@x@ADA@@E JiaL-ra Ns`=$_@@ PA  B@DB@x@ADAEFtaL Aa =P="@!H@ ! @$/}GA[ B@B(@x@ADAEwuaa =4 `="@@&?/d7BQPds9/*A%5a& #IA`- B@B@x@ADAE⺁ Aa = ` !@{`@ PA" # B@B@x@ADA$EƷL a% ==$_&@@&/ըC'b( B@B@x@ADA)EMsbAa* =z`="+@`q@ #!+K҃Lr'Qv\gԶF3a& A,p A- B@B3R@x@ADA.E+aLa/ = v`= 0@Qn@ ' @>1m 2 B@B@x@ADA3E(aL@Y) a4 =o2="5@)@ !A/m6;$7 B@B@x@ADA8E"  a9 =a":@:@& 'މ2Y/sRr;w>a#f!ް0];D;ဂ$< B@B@x@ADA=EaLa> =`="?@)߀@ &+>@ހ AA B@B$@x@ADABEpaLaC ===$_AD@@&/nCE +F B@B@x@ADAGETaaH =[`="I@S@ #!A)fx;|Q*({h&}c\$Ua& AJ{R K B@B@x@ADALEb aL zAM =X`=+$_N@O@ ' @>AO[ P B@BA@x@ADAQEF aL A,CAR = ="S@v @ ! @ /YCT U B@B@x@ADAVEŁ AW =|a"X@À@ ʠ!MpOl}F-K?Nja& AYLZ B@B@x@ADA[E7~aL A\ = t`=$_]@@ ! @>A^0 _ B@B@x@ADA`E{aL; !1Aa =R=`="b@4@  ਻X'P?TQt$U_!9Y?͞c!$Ad B@B@x@ADAeE 2@Af =J:@"g@1@ ! @>h@ȰoĠi B@B@x@ADAjE  AA)Ak =='ul@ @ $ @K; /QF+m쀂n B@B@x@ADAoEwbB!!p = + `="q@@JĠ4zBnvd0L]^y Iu NAr$s B@B@x@ADAtE_ aLR`Au =#`="v@~@ #>wۡ x B@B}@x@ADAyE\aL) aaAz =f`="{@]@ !/C|af5} B@B@x@ADA~ELaLbqA =$`=!I+@`@Ġ-9DAi4@r֤89FA  B@B6h@x@ADAEЀrA =/$_@P@ PA  B@B@x@ADAÈ A =c׀="@΀@A/pjC6 B@Bv@x@ADAE!0bA =ُ;`="@5@ #$)`C B{>"I.g65Rrv + g  B@BC@x@ADAEAA  B@B@x@ADAEp>GaL A>DHG`="+>@?G`@ 1! @Ġ/5>  B@B@x@ADAEGa A> S`="A@ R`@ 'g+%hQJEvV5TUe -Dv@2j@ B@B @x@ADAEaLA =]aI$_@@ @>ZA[ B@B@x@ADAEE^aL A =="@u@&A'.ۿC  B@BA@x@ADAEj_aAA =xqj`="@h@&CQbCv@>֐fNr|a& K A B@B@x@ADAE6#kaLA = tnu`="@e@ '>A/ B@B@x@ADAE vaLA =)="@J!@&/  B@B@x@ADAEہ A =Na*`3@ـ@& ]c׷:i bz/ҁ:3. 7F+! B@B@x@ADAE aL@8 =Iߌ`=$_@ր@ * @JA A B@B@x@ADAEaL) A A =="@@&/6C B@B@x@ADAEvLaa =&S`="@J@ P#$$6VVՓ3=Zn[*R 'AI A B@BP@x@ADAEaL C =P`=$_@zG@ PAF  B@BA@x@ADAEaL !!a = ="@@"Y҃/: Ca B@B@x@ADAEK "1C =İa @_@3RĠ-m5 G,V4V.ӛ_4g;0 A˺$ B@B@x@ADAEuaL2@a =`= @P@ &+ @+=g  B@B@x@ADAEraL AAa =v|= @s@  `@/^C6 B@B@x@ADAE .a$BQa = 4`="@4,@ #!+hBNx5ݨz̧yP \A+$ B@B@x@ADAE怈R`a = 1a+$_@()@ # @>( B@B @x@ADAEo〈 aaa =7="@@ !/ pC  B@B@x@ADAEbAbqa =`=!I@ @&&p7Mfu V a& VqAv$ B@B@x@ADAE`WaLra = `=$_@@& @>AZ B@B@x@ADA?  EDTaL) a = ^= @tU@&/]C  B@DB@x` =A @Eaa = ?=w`="+@ @&S]Jg_!)g_KDN =# lAK  B@B@x@ADA E5ȁ a =s@$_ @ @dA /  B@B@x@ADAEš @Y a =΀="@Iƀ@&/q@C  B@B@x@ADAEbR = U`= +@~@ `@҃F f՟$HAMmsSg,݅ A  B@B@x@ADAE 9aLa = L`= @{@dA  B@B@x@ADAE5aL a =?=" @7@ /sC!6" B@B@x@ADA#Eua$ =*%a %@@&瑘dzK ـ9Ӷ"V)|: S)A&-' B@B-&@x@ADA(E&aLAa) = 0`= *@y@dA+렂 , B@B$@x@ADA-EĦ1aL a. =="/@@ /C0`1 B@B@x@ADA2EKb2aAa3 = h=`= 4@_`@&x+мGݡ"g؈78e y ΃A5_ +6 B@B$@x@ADA7E>aLJ8? eH`= 9@O]@ :* @=:\ A; B@B@x@ADA@@&/8C?5@ B@B@x@ADAAE Ӂ aB = Ta"+C@4р@&[5fΝ.{Lv8:"O;D4 UADЀ@1oE B@B@x@ADAFEUaL aG = _`=G d_H@$΀@dAÌ ` @ iFJ B@B@x@ADAKEn`aL) !!aL =6="M@@&/CN O B@B@x@ADAPECaa"1aQ =Jl`= +R@ B@ ' @҃Қ$E;֊d-6$MX*SuA AT B@B@x@ADAUE`2@aV = Gwa)W@>@dAXY dY B@BA@x@ADAZED @Y AAa[ = xa"\@t~ /QD] ^ B@B#@x@ADA_EʴLBQa` ={a$_a@޲@&Jh.g!5?X & 'cRFK|N@ jAbJc B@Bt @x@ADAdE5maLR`ae =r`= f@ί@dAg. h B@B@x@ADAiEjaL aaaj =s= k@Ik@&J/j(l m B@BJ@x@ADAnE%a$bqao =P,`="+p@#@&5zDlK W(`OПga& Dq$r B@B@x@ADAsE ށ rat =H) u@ @dAv w B@B@x@ADAxEځ 6hay =a"z@@ AWkS6) nsB^sfz#y2Q̋$C{@.C!]` W| B@B#@x@ADA}ENaLa~ =`= @y@dِ  B@B@x@ADAEKaL a =U="@L@ m/ҢC_A[c @ B@B@x@ADAEJaWa = `="@^@&@rlsqLJ¾!ԹS'ܻIa& A@0 B@B@x@ADAEa = a"@R@ #$C >: ` B@B6h@x@ADAE a =]ƀ= W@Ƚ@&/>8A4A[ B@B@x@ADAExba =~`="@3v@ Ae>3vs^e[ -͑  Na& +|Au A B@B@x@ADAE0aLa ={`=$_`3%o@#s@ @>r  B@BW@x@ADAEn-aL a =27= @.@+ @A/PC  B@B@x@ADAE a =a"@@k5-T~=ORJehTT0ȷ#aU Ct怂$+ B@B}  T@x@ADAE_aLAA =@$_@@ PAXA[ B@B@x@ADAECaLbH a ==$_@s@9~/sC GāB6h@x@ADA @EYaAa =``="@W@7Ġ/*lSVY1g-MV#oNk` eF+I A B@DB@x@ADAE4aL6h a =r]`= @T@ * @>A-A[ B@B@x@ADAEaL!!a =="@H@&/C  B@B@x@ADAEʁ "1a =K'a"@Ȁ@gĠmv&v4GF UקU8SԊA B@B}@x@ADAE (aL2@a =G2`="@ŀ@ PA  B@B$@x@ADAE3aL) AAAa == A@@A/"C!]f5 B@B@x@ADAEt;4aBQa =$B?`="@9@ '!ĠcÄz($-\͊BIJP_ ia& A8  B@B@x@ADAER`a =?J)W@x6@ ! @=`5  B@BA@x@ADAE aaa =="@@ }&+/V_  B@B@x@ADAEIKbbqa =V`="@]@ +#(nDr"(ٌ M2 a&  nDɩ$ B@B+@x@ADAEdWaLra =a`=$_@M@ # @>  B@B@x@ADAEabaL a =ak="A@b@ W!/BC4A B@B@x@ADAEca$a =#n`="@2@ 6a۠>Fg*ȶ}#/rv$źa& fA@0j@ B@B@x@ADAEՀa = y$_@#@ @>AA[ B@B@x@ADAEmҀ a =1܀=+$_@Ӏ@ /uJC  B@B@x@ADAEzbAa@@`="@@ PX+`GbܷXÛQmR"#^p iAt@2 B@B`x@9 A @E^FaLa =`=+$_@@ @>AX  B@DB@x@ADA EBCaL) a = M= @rD@ @҃/1iA   B@B@x@ADAE a =ya"@`@ m3O}v5v{` (hq;x\a& IF+I  B@Bw@x@ADAE3La =qaI$_@`@ ! @>A-  B@B$@x@ADAELa =轀="@G@ }A.C  B@B}@x@ADAEobo  +@a =bv`="@m@ &#+ |?9rǣ3 V2A " `"YXF! B@B@x@ADA"E (aLA# =Fs`=$_$@j@ # @>A% & B@B@x@ADA'E$aLAxa( =@.=+")@&@ ! @A/C*%+ B@BGa@x@ADA,Esa- =a".@ހ@ :ARxf+mK̄T@Ra& 6h/ݠ@00 B@Bp@x@ADA1EޘaLA a2 =`=$_3@xۀ@ @Q`B?A4ڠ `5 B@B@x@ADA6E•aL !!a7 ==+$_8@@ /B6h9^: B@B@x@ADA;EIQa"1a< =W`="=@]O@ Wuw4T*ƦUfv;`a& #>N A? B@Bu@x@ADA@E aL2@aA =T`="B@LL@>ACK D B@B@x@ADAEEaL AAaF =`= G@@ /#H3I B@Bt@x@ADAJE BQaK = a"L@2@&B+ ȖO=h&ahV H*CM$N B@B@x@ADAOEzaLR`aP =j8$_Q@"@ &+ @JAR AS B@B@x@ADA+x`ElwaL) aaaU =9="V@x@ /CWX B@DBy@x@ADAYE2abqaZ =9`="[@1@ #&l %zm!@@B؊3r!MJz}x5a& SA\s0 A] B@B|@x@ADA^E^뀈ra_ =6$_`@-@ # @>AaW b B@BA@x@ADAcEB 8 ad =="e@v@&/Cf g B@B@x@ADAhEȣbai =y)`=$_j@ܡ@ +Ϊ=)FfeO!g2EGΨv)$kH$+l@aBx@x@ADAm@ B 3\*aLan =p4`=$_o@̞@ ! @>p, q B@DB@x@ADArEY5aL as =b= t@GZ@ W&+ @$/-Du v B@B@x@ADAwE6alax =NA`="y@@&|<ĺf9x#צ;oa& kAz${ B@B@x@ADA|É a} =FLa+$_~@@ # @=A[ B@B@x@ADAEɁ a =Ӏ="@ˀ@ !/"CʀA B@B@x@ADAEsMbka =#X`=!I@@ +' @|Ɩh d.Kꍌkư3Fa& A󂀂$ B@B@x@ADAE=YaLa =c`=$_`3*@w@ ! @=  B@B@x@ADAE:daL) Aa =D="@;@&$|-.C]A B@B:@x 9ADA @EH a =oa"@\@ #r6\ %xݻ0_,wg + B@DB@x@ADAEpaLA =z`="@L@ '>A  B@B@x@ADAE{aL a =m`="@3f+@1e`@Aՙob}O큍SzVbu<l,h[ɠtEDd  B@BA@x@ADAEa  a =AVj`="@%b@ $ @Ja  B@B g@x@ADAElaLAx!!a =@8&= @@/C B@B@x@ADAEׁ "1a =ޞa"@ր@*ĠnYЌa!G<_YkUa& XArՀ$A B@B-&@x@ADAE]aL(@a =۩`=+$_@Ҁ@ PVA[ B@B@x@ADAEAaL AAa =="@q@ &+$+Ġ/C  B@B-&@x@ADAEHaWBQa =uO`=!I@F@ W# @T+ A B@B@x@ADAE ) aaa ="@F~ /;C B@Bt 9~@x@ADAELbqa = Ua"+@@ 6hFҥFI5 D$3 }$ B@B+@x@ADAEraLra =E`="@@dA  B@B@x@ADAEnaL) a =x="@p@ }b/|Do B@B@x@ADAEr*aa =1`= +@(@ +^Z`惗O젤Ҩ1ʢa& A' A B@B+@x@ADAE Aa =.a)@v%@dA$  B@BA@x@ADAE a =="@@ W/LC]  B@BsA@x@ADAEGba =`= @[@ @W| ˡѝphԽb 5Z'N]Xka& Aǘ$ B@B@x@ADAESaLa = @K@ @=  B@B ,XE@x@ADAEPaL a =ZZ="+@Q@+ @/LdDZzڋC>vD zLDK $ B@B`@x@ADAEĀAa =$__ @%@ @=?  B@B@x@ADAEk a =<ˀ="@€@ A.DK B@B@x@ADAE| bAa =+`="+ @{@ gCd}UR(5pQXa& F+ rz$ B@B@x@ADA E\5,aLC[ =6`=$_@w@dAV  B@BA@x@ADAE@27aL) a =  <="@p3@ }/[  B@Bg@x@ADAE o a =Ba"@@ {xs3|F~GZB(@Da& DK + B@B+@x@ADAE1CaL a =sM`="@@dA+A[/ B@B@x@ADA!ENaL!!a" =⬀= +#@E@&/$ % B@B@x@ADA&E^OaA"1a' =YeZ`="(@\@ d0KF-n\gc6SCa& RD) * B@B P@x@ADA+E[aL2@a, =Dbe`= -@Y@dA."O` / B@B@x@ADA0Ef AAAa1 = {= 2@@&/l~C3 4 B@B@x@ADA5EqπBQa6 =1qa"7@̀@ 6hG$RL*X1g&U_ B@B@x@ADA?E}aL aaa@ == A@@ /`CB\C B@B@x@ADADEG@~aAbqaE =F`="F@Z>@ q“= t̩cDި{C {F AG= +H B@By@x@ADAIEraJ =Ca K@K;@dAL:A[M B@B@x@ADANE aO =f="P@@&$/!CQ1R B@B?@x@ADASEbaT =Է`="U@0@ CbLݴ]™", 4_ysN^5V$W B@B@x@ADAXEiaLaY =Ĵ`="Z@ @dA[ \ B@B$@x@ADA]EjfaL) a^ = ;p= A_@g@&/ `a B@B@x@ADAbE!aac =(`="d@ @&A֊8;pN\# *R$D~?Ca& {MF+eq Af B@B@x@ADAgE\ڀah =% Ai@@dAjU k B@BA@x@ADAlE@ׁ  am =  ="n@p؀@&-/aCo p B@B@x@ADAqEƒbar =r`="s@ڐ@&JQt#yeubxo7槾({f` AtFu B@Bg@x@ADAvE1KaLaw =n`=`} x@ʍ@ 0$Jy* z B@B@x@ADA{EHaL@YL a| =Q="A}@II@ }!)-/j:C~  B@B@x@ADAEa$a =L `=!I}@@&AT.FR]IPe[H\l"o[n$ B@B@x@ADAE " =Da$_@`@ `@>JA[+ B@B@x@ADAE긁L a =€="@@ /ioD B@BA@x@ADAEqtbAa =){`="@r@&E⇩b} J=^Ka& NAq$ B@B@x@ADAE,aL a =x "@to@ #$>Jn  B@B@x@ADAE) aL!!a =3= @*@&%o/2bC_ + B@B@x@ADAEF "1a =a"@Z@& vJIF 6!F OmA   B@B{$@x@ADAEaL@a = `=$_A@J@ PA߀  B@B@x@ADAE!aL AAAa =e="@ě@&$/C0A B@B@x@ADAEV"aBQa =\-`="@/T@&bAQ|l[>OTb]*5a& .S  B@Bm@x@ADAE.aLR`a =Y8`= @Q@ PAP  B@B@x@ADAEj 9aL6haqa =D`=+ A@ŀ@ @1vSpRr޺&ZKS o%]Ѱa& DpĠ@0 B@B-@x@ADAE[EaLra =O`= @@ PXA[ B@B AC@x@ADAE?|PaL a =="A@o}@ g! @Ga/`C  a B@B@x@ADAE7Qaa =z>\`="@5@AĠ꽡 ⪳YXSVN[ͿB wlAE  B@BA@x@ADAE0 Wa =n;ga"@2@ P)A[c @ B@B@x@ADAE a ==$_@D@ /  B@B}@x@ADAEhba =Ps`="@@ #!+^5S쎗}[2Tsi+Va& &D B@B@x@ADAEataLa =C~`= A@@ # @>:  B@BA@x@ADAE]aLa =g="@_@&/6C^ + B@B@x@ADAEpaCa =$ `="@@A(n`=!'[ia&*2D4XUD  B@B@x@ADAEрa =$_@x@ &+ @>:  B@BA@x@ADAE΀a =؀="@π@ &+/D_  B@B@x@ADAEEba =`=!I@]@ # @ĠhN2 ݮdb^,ݽ>\bT L uAɇ$ B@B@x@ADAEBaL z 9 퍭`=$_@I@ # @>A  B@B@x@ADAE?aL A 9 \I="@@@ @/CB0m B@B@x@ADAE A =a"@.`@&vJj̈=gd^|7_6h]A$ B@BDK@x@ADAELA A =aI+$_ @@ &+ @K=1 ~A[ B@B@x@ADA EiaL !!A =1="@@ &+/UqC B@B@x@ADAEka"1A =r`=!I@j@ +# @A#36R+{Y6Q*Qko3%8a& Api$ B@BY@x@ADAEZ$aL2@A = o`=$_@f@ # @>AT  B@B@x@ADAE>!aL) AA( = +="@n"@ !A/vF  B@B@x@ADA E܁ B"!! =ua""@ڀ@&s\WxJF#q|lIBOK}P#E $ B@B@x@ADA%E/aLR`A& =m`="'@׀@ &+>A() ) B@B@x@ADA*EaLaaA+ =ۛ=",@C@&A/ }- A. B@BA@x@ADA/EMabqA0 =ST@%1@K@ +# @%`C KA*PJ:A7G 8 B@B@x@ADA9E aL AA: = =";@@ ! @҃/YcC<= B@B@x@ADA>EoA? =a"@@@ Ad5NJaM@ #ַG2 jAAﻀ-+B B@BA@x@ADACEvaLAD ="`=$_E@s@ ! @>AFӸ G B@B@x@ADAHEs#aL AI =}=$_J@t@ W/VCKZL B@B@x@ADAMED/$aAN =5/`="AO@X-@ +#!AëҟnT2C!KkRa& v[AP, AQ B@B@x@ADARE瀈AAS =2:$_T@I*@ # @=$U) AV B@B@x@ADAWE䀈 AX =d="Y@@ !A.wCZ/[ B@B@x@ADA\E;bA] =¦F`="^@.@ k T&gS]<1aӬM2M7a& iS_@0` B@B@x@ADAaEXGaLAb =Q`=+$_c@@dAd~ e B@B@x@ADAfEhURaL) Ag =,_="h@V@ /WiSiA[j B@B@x@ADAkESaAl =^`=%m@@ 1%9- 4e`yxz(pDF+no o B@B@x@ADApEZɀ Aq =i r@ @ +# @JAsSA[t B@B@x@ADAuE=Ɓ   Av =Ѐ="w@nǀ@&/hCx #ay B@B@x@ADAzEājba{ =xu`="+|@@ $,Sϟ*:4w7\Iwa&  A}D ~ B@B@x@ADAE/:vaL a =l`=$_+@|@ ! @>(  B@B@x@ADAE7aL !!a =@= @C8@ &+ @/C  B@B@x@ADAE "1a =Fa"+@@&A`Lt jʿ]r ˇ=ˇ;ia& *\A- B@B+@x@ADAEaL2@a =B`=$_@@dA쀂  B@B@x@ADAE觘aLAAa ==$_@@ / B@B@x@ADAEocaABQa ='j`="+@a@ P a+$v(4B/ .>ó0$g{c~a& `$ B@B Lc'@x@ADAEaLR`a =g`= @s^@dA] lM@W B@B@x@ADAEaL Aaaa ="="@@ }/ Y W B@B@x@ADAEDԁ bqa =ڻa +@XҀ@ mк>xEt_.-kuJpa |5IAр B@B+@x@ADAEaLra =`= @Lπ@dAΠA[ B@B[p@x@ADAEaL a =[= @Š@&A/C. B@B@x@ADAEEaa =K`="+@-C@&X(HIef|.m6Ŏ=/a& oB  B@Bm@x@ADAEa =H @@@dA}? A B@BA@x@ADAEh W$ =8 @~&/ D  B@B@x@ADAELa =aG@ @@& WOGpNc"oHSa={An$+ B@B@x@ADAEYnaLAa =`=+ @@dAR  B@B@x@ADAE=kaL@Y a = u="@ml@& /Z A B@B@x@ADAE&aa =|-@ +@$@ m `@  qe\Fs Ao1B_0WyJgx@ DC + B@Bm@x@ADAE.߁ a =p* a @!@dA'!A[ B@B@x@ADAE܀; a =R @@ g8/vR&>[O2ԷL`d7?XC@4 B@B@x@ADAEPaL(J =A$`="@@d  B@B}@x@ADAEL%aL a =V= @N@ +/uCM B@B@x@ADAEn&aa = 1`="@@ĠSX'oHxj&`["0p޵"6 ѲA  B@Bu@x@ADAEW a = ލ/ǒc s<; < B@B@x@ADA=E a> =@@$_?@7@ ! @=@6 A B@BA@x@ADABE aC = =bD@@Ġ/BE F B@B@x@ADAGEmbaH =`="I@@&BGJQpV F4 b~J$ma& F+J-+K B@B@x@ADALEeaLaM =`=$_N@u@ `@>AOѧ P B@B}@x@ADAQEbaL aR =l='uS@c@&/aTXU B@B@x@ADAVEBaaW =$`="X@V@ `'!AFE+Q@¼8;Oea& TDY$Z B@BJ@x@ADA[Eր"\ =!a ]@F@ ! @=A^A[z_ B@BA@x@ADA`EӀ aa =b݀="b@Ԁ@ &+ @A/Cc-d B@B@x@ADAeEbaf =ȕ`="g@,@&Nq!5'ٚU=Fi{Dފ~a&  Ah$i B@BJ@x@ADAjEGaL ak =`=$_l@@ # @=m| n B@B@x@ADAoEfDaL) !!ap = 3N="q@E@&/Q%Crs B@B@x@ADAtE "1au =@"v@`@ '+A'^?w@kt{]V\}Ss@ 1Awm mx B@B@x@ADAyEWL2@az =aI"{@`@ !>A|Q } B@B@x@ADA~E;L AAa =="+@k@ &+ @+҃/C  B@Bu@x@ADAEpbBQa =sw`="@n@ +#ֺ+"FC @_Puç)͞B  B@B@x@ADAE-)aLR`a =jt&`=+$_@k@ # @=A&  B@B@x@ADAE&'aL aaa =/="@A'@ W! @Ġ/sD  B@B@x@ADAE bqa =S2a"@߀@ ?^ ?_ҬRב?@F 66A- B@Bv@x@ADAE3aLAra =@=`=+$_@܀@ ! @>A۠A[  B@B@x@ADAE>aLa = ="@@ /li B@B@x@ADAEmR?aAa =YJ`=%@P@ +# @ҏ:fF䖿ѰP9vO֬GDa& 5O  B@B+@x@ADAE KaLa =VU`=$_@qM@ # @>ALA[ B@B@x@ADAEVaL Aa =="@@ W!A/W B@B@x@ADAEBÁ a =aa"@V@*Ġ\ ~3f>N;ck#_W }IA$ B@B@x@ADAE{baLa =l`="@E@ &+>A A B@B@x@ADAExmaL) a =b=$_+@y@&/OQC, B@BM@x@ADAE4naa =:y`="@+2@ +#!hQ8Ƶ[/<&ZtR{Մ2+E`FA1 A B@BA@x@ADAE쀈a =7a+$_@/@ ' @>A{.  B@BA@x@ADAEf a =2="@@ W! @҃/ jC  B@B@x@ADAE줅bo2U@sa =`="@@&lp20}^BcPܘqޠ1K.Z[i,Ap$ B@B@x@ADAEW]aLA = `=$_@3@@ &+ @>AP  B@B@x@ADAE;ZaLADa =@d=$_@k[@&/EC A B@B@x@ADAEala =r`="A@@&Y;L^ұyr;fa& UAA$ B@B@x@ADAE,΁  a =j$_@@ ' @>A%A[- B@B@x@ADAEˁ !!a =Ԁ="@@̀@ !$A/C A B@B@x@ADAEb"1a = C`="@@&T,-ƝeRԮ6_N$s AC B@B@x@ADAE?aL2@a =`=+$_@@ PA  B@BDK@x@ADAE;aL6hAQa =!`=$_@@ ՙ mW!%O;Ƌ={>a& kC  B@B@x@ADAE֯aLR`a = `= @p@ ! @+=}  B@B@x@ADAnEaL? Waaa =="+@ꭀ@ $#VUD/SGCV+ B@DB@x` =A @EAhabqa =n`="@Uf@ Ġ:YKR\ع{Լ^Q-%d.cGfv` ߽Ae  B@DB @x@ADA E aLra =k`=$_+ @Ec@ # @= b  B@BW@x@ADAEaL@Y a =\'=$_@@W/)C0  B@B@x@ADAEف a =@ @*׀@ĠY&Z'[HVt*~(rI@ lր$+ B@B@x@ADAEaLAa =`=$_@Ԁ@4 @>AzӀ  B@B@x@ADAEeaL a =1=  @@ &+ @/;D!A" B@B@x@ADA#EIaAa$ =P`="+%@G@ ,W{'fo(Da""bstY+?J&k +' B@B@x@ADA(EVaLa) =M(`=$_*@D@dA+OA[, B@B@x@ADA-E:  a. = )a"/@j@ /v0 1 B@B@x@ADA2E a3 =r4a$_4@ո@ADFCb9S>o8Cַ ? FF+5A6 B@B@x@ADA7E+s5aLa8 =i?`= 9@ŵ@dA:%A[; B@B@x@ADA<Ep@aL) a= =y= >@?q@&/+C? @ B@B@x@ADAAE+AaaB =F2L`="+C@)@ A_%9`4 EƘm3@a& 8AD +E B@B@x@ADAFE AG =>/W H@&@dAI% AJ B@BA@x@ADAKE aL =="M@@ :A/ΟCNဂ O B@B|C@x@ADAPEkXbaQ =c`="+R@@&5;"9w9ˮ_0a& >AS뙀$T B@B@x@ADAUETdaL aV =n`= W@p@dAXϖA[AY B@B@x@ADAZEQoaL !!a[ =[=G@6h\@R@ W/ȚC]VA^ B@B@x@ADA_E@ pal-L "1a` ={`= a@T @&Ū%nGC+'vTH֨hy  B@B@x@ADAEc؀ !!a =-= A@ـ@&/dC  B@B@x@ADAE+bA"1a = {6`="@@ +#!'# 12uaeT᧜mIԱ(qAj$ B@B+@x@ADAEUL7aL2@a =A`=$_n @3@@ ,W @> N  B@B 5@ADA @E9IBaL AAa =AV= S="@iJ@ W! @ /` + B@BW@x@ADAECalABQa =t N`="@@%gM![Q˓b8 Sra& OD?- B@B@x@ADAE* R`a =hYa$_@X`@ @>A#A[u B@B@x@ADAELaaa =À=$_@>@ :/)cC  B@B@x@ADAEuZbAbqa =I|e`="@s@ +A㞦Nrt^ ~uI Tu1y>a& ,A B@B)@x@ADAE-faLra ==yp`=$_@p@ # @>AoA[ B@B@x@ADAE*qaL AaE4="@,@ !$A/C+ ` @ XF B@BA`x@9 A @Ej怈a =|a"@~@&J#*DIY&]pyru'|l]:S ` A。+ B@DB+@x@ADA EԞ}aLa =`=" @q@ &+>A  A B@B6h@x@ADAEaL a ==$_+@蜀@&/?CT B@B@x@ADAE?Waa =]`="@SU@ #!+MCHTc`-ٜta& 'AT + B@B@x@ADAEaLa =Z`=+$_@CR@ ' @>AQ  B@BA@x@ADAE aL; a =Ϋ`="@(ƀ@&/ C ŀ$! B@B@x@ADA"EaLa# = ˶`="$@À@ $ @>%x€$& B@B@x@ADA'Ec}aL6ha( =8="+)@~@mW5* ++ B@B@x@ADA,E8aa- =?`=".@6@ &+$:J/HHł}C+{͒ #_hb$c -/i$0 B@B@x@ADA1ET WA2 =<$_3@3@ ! @=; 4MA[5 B@BN[B@x@ADA6E8  Wa7 ==b#8@h@ &+/o"Y9 $s`: B@Bu   @'@x@ADA;EbWa< =k`="=@ӧ@gĠf0G'0]P b/lcmL$aUnf zIA>?? B@AbB@x@ADA@E)baL aA =g`=+$_B@¤@ # @>AC# WD B@B}@x@ADAEE _aL!!aF =h="G@A`@&/yVCH +I B@B@x@ADAJEa"1aK =M!`=%L@@ P' @nsZi玟>mAO_1.m/Ϸژ b AM  N B@B@x@ADAOEҁ 2@aP =<$_Q@@ ! @=AR S B@B@x@ADATEπ AAAaU =ـ="V@р@ &+A/gCW~ЀAX B@BA@x@ADAYEibBQaZ =! @"[@}@ #oĠ>G[}|4=:|!s| ]$q ~A\鈀 ] B@B@x@ADA^EC aLR`a_ =`=$_`@m@ # @>Aaͅ b B@B@x@ADAcE@aL aaad =J="e@A@ ! @҃/CfTg B@B@x@ADAhE> bqai =!a"Aj@R `@ nQ#u_ESrH`U?Kq Ak$+l B@B@x@ADAmELran =+aI$_o@G@ ! @>ApA[p@` q B@B@x@ADArE,aL as =Y="t@@PĠ/u)v B@BP@x@ADAwEm-aAax =s8`="y@(k@ +#+App![5̿uc}VOA  3Dzj${ B@@iBr@x@ADA|E~%9aLCa} =pC`="~@h@ '>AwgA[d@ B@B6h@x@ADAEb"DaL a = >,="@#@ !/C  B@B@x@ADAE݁ a =Oa!I@ۀ@ 4 ҦQoW#/ ,hfAi B@B<@x@ADAESPaLa =Z`=$_@؀@ ! @JAM A B@B@x@ADAE7[aL$a =="@k@&A/Cס + B@B+@x@ADAEN\aCa =nUg`="@L@&rO+c8,BX5Me_0xd%a& CB  B@ B@x@ADAE)haLAa =jRr`=$_@I@ ' @>A&  B@B@x@ADAE saL~ Aa = = @A@ ! @/C  B@B@x@ADAE pa =@~a!I@@ ' @ghe%Yx[ms2-4ՈHɎoǧ8dA A B@B"@x@ADAEwaL$ zA = ;É`=$_@@ -&! @=  B@B@x@ADAEtaL A! =~="@v@ .BC~uA[ B@B@x@ADAEh0a$A =7`=$_@|.@&A^cbq]]BnK!^a& m-$ B@B@x@ADAE耈 A =4a$_@l+@ +# @>A*A[ B@B@x@ADAE倈 !!A =="@@ !#VA/#t S B@BA@x@ADAE>b"1A =`=!I@R@&'pҠGQ߆ TXO Z9\;a& Y$ B@B@x@ADAEYaL2@A =椸`=$_@B@ PAA[ B@B@x@ADAEVaL) AA)A =Y`= @W@%$/( B@Bx$@x@ADAEaB%! =`="+@'@ m#! v`2;-*ɽoV0XrSU^r + *@G m B@B+@x@ADAE}ʀR`A =a @ @dAw A B@B@x@ADAEaǀ aaA =*р="@Ȁ@&A/C  B@BW@x@ADAEbbqA =`=$_@@ 1y mLT|ǒ^|ifW8@ CAh  B@B@x@ADAES;aLrA =@逃`= @}@dALA[A B@B@x@ADAE78aL A =B="@g9@ W/oC  a B@BW@x@ADAE A =ra @@ yHmQ{#~ST* a& TA=- B@B @x@ADAE(aLAA =j`= @@dA!A[c @A B@B@x@ADAE aLA =ܲ="@<@ /C  B@B @x@ADAEd@TAA =?k `="F@b@&styՅDNJ9MYxNWy  A  B@B@x@ADAE aLA =;h`="@_@dA^  B@BA@x@ADAEaL$0 =#= @@ W/4 C } B@BW@x@ADA EhՀA ="a"@|Ӏ@ &A;q$Nw-/煩}^b77 AҀ$ B@B+@x@ADAEҍ#aLA =-`= A@lЀ@dAπ  B@B@x@ADAE.aL) A =="@拀@&A/CR B@B@x@ADAE=F/aA =L:`="@QD@ +fl $?oN&ۓuʴG:luSAMaASAC A B@B+@x@ADA!E!'" =IE #@BA@dA$@A[% B@B :*@x@ADA&E  A' =XFa+ A(@~&/eC)( * B@B@x@ADA+ELa, =ǽQa"-@&@ +#Jw,[Kw^R/ LlIa& HA.$/ B@B@x@ADA0E}oRaL a1 =\`= 2@@dA3v A4 B@B@x@ADA5Eal]aL6h!1D6 =.i`= :7@%@g  :'kOH\ƭd^QCI# q7a& :nC8g$A9 B@Bg@x@ADA:ER W2@a; =+ta+ <@"@ $ @A= =KA[> B@B@x@ADA?E6݁  AAa@ == A@fހ@ ! @/BCB  aC B@B@x@ADADEubBQaE =e`="F@і@ xhNm!"]Qw}w+ cC|AG=@4a@H B@Bp Jz3R@x@ADAIE'QaLR`aJ =`= +K@@ ! @> L! M B@B@x@ADANE NaL) aaGO =W="P@;O@ /CQ R B@B@x@ADASE abqaT =R`="U@@DS#+"t)Ա~G6ݭ4e ɠM*a& '\AV +W B@B@x@ADAXE raY =: a"Z@@>A[ \ B@B@x@ADA]Eྀa^ = Ȁ="_@@ #/pC`|a B@B@x@ADAbEgzbac =`="d@{x@  ;z0$! <D@dEkf3xa& hgew f B@B@x@ADAgE2aLah =~`=$_i@ku@ ! @JAjt k B@B@x@ADAlE/aL Aam =~9= n@0@/goRp B@B@x@ADAqE< ar =a"s@P@%Afȩ TM'iD/ #A^@qT:;E|a& 6F+t耂$+u B@Bm@x@ADAvEaLAaw =`=$_x@@@ ' @>Ay堂A[Oz B@B@x@ADA{EaL a| = X= }@@ :! @Ġ/~' B@B@x@ADAE\aa =b`="@%Z@&-1]Ùf-H*`̮2VDY` A B@B@x@ADAE|`a =_`=$_@W@ PAuVA[ B@B@x@ADAE`aL a = (="@@ W/C  B@BA@x@ADAÉ a =a"@ʀ@ +#+>N17LD`71{a& Wlig B@B@x@ADAEQaLU =@"@ǀ@ #$=K A B@B 8@x@ =A @E5aL) a =="+@e@ ! @A/dD  B@DB@x@ADAE=aa =mD `="@;@ rGd5#<}W%6{A< A B@B@x@ADAE'  a =dAa+$_@8@ ! @>  B@BA@x@ADAE @Y !!a = +=$_@;@ /C  B@B@x@ADAEb"1a =I$`="@@ H#!a(w/T"p~xjwoua& }P$ B@BE@x@ADAEf%aL2@a =9/`=$_@@ # @>A  B@B@x@ADAEc0aL AAa = m="@e@ H!A.a}|dA B@B@x@ADAEf1aBQa =&<`="@z@ mLgt^TG+>` *0| rq 0\ua- B@Bm@x@ADAE׀; R`a =#G$_@k@ ! @>AA[ B@B@x@ADAEԀ aaa =}ހ=+$_@Հ@ /gQA B@B@x@ADAEAu  B@B @x@ADAE_L) a =0="@@Ġ/MC  B@B} `@x@ADAEqwba =x`="@o@ #8*tr,̗IԸ$a& RRAf A B@B@x@ADAEQ*aLa =u`=$_@l@ PAJ  B@BA@x@ADAE5'aL a = 1="@e(@&/~C  B@B@x@ADAE a =da @@ -XSeHgXH0>OT c[gA;@4W B@B@x@ADAE&aLa =c`= @݀@ @JAB9 Gab|B@x@ADAE aL a =Ρ= @:@ &+ @A/hKC  B@B@x@ADAESaa =EZ`=" @Q@&AfbqW}"4_I@SxkA $ B@B@x@ADA E aL" =9W`= ! @d_ +@N`@ #>M  B@B@x@ADAEa a =I="@ @ !/C{ N B@BA@x@ADAEfĀa =a !:!I +@z€@ AҰš1^)c^lLC hA$ B@B*@x@ADAE|aL a =I`=  $_ +@j@ ! @>ʾ  B@B@x@ADA EyaL) A!!a! =I=""@z@ :/$C#P$ B@B[p@x@ADA%E;5a"1a& =;`="'@O3@ #$7 QQ/ۺ\cA-/ . B@B@x, 9ADA/ @Eꀈ AAa0 =IU="1@@ !/MC2%3 B@DB@x@ADA4EbBQa5 =`=  !I6 +@$@ [Exm 0ƈqezvEP2Il  ?A7 8 B@B@x@ADA9E{^aLAR`a: =I@H@ $_;@@ ! @>A<t = B@B ::;@x@ADA>E_[aL aaa? =+e=  @ +@\@ W/A B B@BW@x@ADACEabqaD =I`= E@@ m# @ANKչr?J8@;N0¹oFe$+G B@B P@x@ADAHEPρ raI =a J +@@dAKI L B@B@x@ADAME4́ aN =Iր="O@d̀@ / GP Q B@B@x@ADAREbAaS =p&`= !:T +@υ@&׫qlڻ~] :/3soF3sAU;V B@B@x@ADAWE%@'aLaX =Ic1`=  )AY +@@dAZ$[ B@B@x@ADA\E =2aL; a] =IH=`="^@@&g/_C_$` B@B$@x@ADAaE>aLab =8H`= c +@@dd e B@B@x@ADAfEޭIaLag =IpU`= +h +@yg@&3k;%V0_DU&k'R@6 if mj B@B@x@ADAkE!VaLmal =I m``= +m@id@d+nc zo B@B+@x@ADApEaaL maq =(= >-r +@@&+/`sPt B@B@x@ADAuE:ځ t av =Ila w@R؀@&^C߆ NYO#~Ea& 9Gx׀ Ay B@B:@x@ADAzEmaLޗ{ =w`= |@>Հ@d}Ԁ ~ B@B@x@ADAExaL a =U= @@&/uC% B@B$@x@ADAEKyaa =Q`= + +@#I@ buϻ/_ݥ7L|  H$ B@B+@x@ADAEzaL a =IN`=  +@F@dAsE  B@B@x@ADAE^aL !!a =I; =  +@@&>/O A B@B>@x@ADAE廁 "1a =I›a"+@@ +!je^Afz5 @5'a& Ve B@B+@x@ADAEOtaL2@a =`=   +@鶀@dAI  B@B@x@ADAE3qaL) AAa =Iz="@cr@ W/-  B@B@x@ADAE,aBQa =f3`="@*@ ?-+vt.l^`('d۠H aJ:  B@ B#@x@ADAE$ R`a =0a  +@'@dA  B@B4@x@ADAE aaa =I= W +@8@&&/C  B@B@x@ADAEbbqa =I?`="@@ +fkd?8!\[vj$Oyӝ]bYa& =-A  B@ B+@x@ADAEUaLra =7`= @@dA󗀂  B@B@x@ADAERaLa =\= @T@ WA/C~S  B@B@x@ADAEdaa =`="@x @&Cwqq=JOԃM6A - B@B@x@ADAEƀa = a }' +@h @ &+ @IC a> 4 ` B@B@x@ADAEÀ a =Ì= ! +@Ā@ /AO B@B@x@ADAE:bAa =I`="@M}@&AdBȐ6( :Vy quVԫDA| + B@B@x@ADAE7aLa =^ "$_ +@>z@ # @>vy  B@B@x@ADAE4aL@YL a =IT>="@5@ !$0v^'.\|`۪V3NuA퀂$ B@B@x@ADAEyaLa =`= S'$_ +@@ ! @>Asꀂ  B@B$@x@ADAE]aL) a =I*=  " +@@&/1CN B@B@x@ADAE`aa =Ig(`="@^@ `#!v82?.%g@AH  B@BA@x@ADAE24aL a = ="@c@ ! @A/bCϡ  B@ϠB|Z2@x@ADAEс a =i?a"@π@ +eu3hdۜFX_%b(/9π$B+@x@ADAa7E$@aL a =aJ`= A +@̀@ !>A  B@B@x@ADAEKaL !!a =IՐ="f dm$_@8@ W/'D  ]` @ ) B@B@x@ADA EBLa$"1a =CIW`=" @@@&A5N}?BWB):tt0`n[9At,Da& ]A- B@B|+@x@ADAE 2@a =7Fb$_@=@ # @`.A<@T B@B@x@ADAEAAa =ca &+  +@ ~ ! @A/5Cy B@BW@x@ADAEdLABQa =In'@x@ ''΅ܐq1g/ljep{A IA䰀$ B@@iB@x@ADAEkoaLR`a =y`=+$_!@k@ ! @>A"ǭ # B@B&@x@ADA$EhzaL Aaaa% =r="&@i@ `.eC'N ( B@B@x@ADA)E9${abqa* =*`="+@M"@ #!҃4I{01M)Rcyru 2;kADXA,!A- B@B(@x@ADA.E܀ra/ ='$_0@=@ # @>A1 A2 B@B$@x@ADA3Eـ a4 =T= gA5 +@ڀ@ !A/tC6#7 B@B@x@ADA8Eba9 =I`= : +@"@ ܛ?dӷp(J 4#]Kۣ A; +< B@Bm@x@ADA=EyMaLa> =I`=  $_? +@@ ! @>A@r A B@B@ 5@ADAB @E]JaL aC =I)T="D@K@ /OE F B@DB@x@ADAGEaZ:H = `="I@@&! )L[[^B +b%8/h#_R *4DJc$+K B@B@x@ADALEN aM = a  +$_N +@@ # @>AOGP B@B@x@ADAQE2  aR =IĀ=  )S +@b@&/CT U B@B@x@ADAVEvbaW =Ii}`= X +@t@&HVÁY_U@ot!Zjy%os ̳AY8$Z B@B@x@ADA[E#/aL a\ =Iez`=G@,W$_]@q@ `@>A^ `:iF_ B@BA@x@ADA`E,aLaa =5=  b +@7-@ `@/:Cc +`d B@B@x@ADAeE af =ICa g@@&$1ꋃ4:I?\D5A`8&ha& Ahi B@B@x@ADAjEaLJk =6`= l@@ # @=mဂ n B@B@x@ADAoEܜaL )Acap =_`= =Q q +@{V@$ՙ|Ts׷/3]&Џ"Ts舔Þ 8(rU s B@B@x@ADAtEaLW au =I \@"v@gS@ PwR x B@B@x@ADAyE aL?Ax!!az =@}= { +@@ !&l/(|M} B@B@x@ADA~E8Ɂ "1a =Ia!I@Lǀ@&MF3w2sّ̍̎YJtrƀ  B@B@x@ADAEaL2@a =`= i}&+'u + -<Ā@ PÀ  B@BW@x@ADAE~aL AAa =IW= !:  +@@}/͞#N B@B@x@ADAE :aBQa =I@*`=  +@!8@%oAWE'Kr 4]'CTY *7b LW7$+ B@BE@x@ADAExWR`a =I=5a+ @5@ ' @=Wq4A[ B@B@x@ADAE\ aaa =$= &+ +@@ ! @Ġ/C  B@BtY(`@x@ADAE6bAbqa =IA`=!I@@ +' @7pA}«Pf+%/9 dS^&(a& Bc B@B+@x@ADAEMcBaLra =L`=$_@祀@ ! @=FA[ `po   B@B@x@ADAE1`MaL a =i=  +@aa@&/sD  B@B@x@ADAENaa =Id"Y`=  +@@ 1#%ɱދwD gJVƨrQ'+ 9E8 B@B+@x@ADAE"ԁ a =I`da"@@ '>A  B@B@x@ADAEѡ @Y) a = +ڀ= =Q +@6Ҁ@A/E  B@Bf=@x@ADAEeba =IFp`=!I@@*U0A?$'GDuhz>̝a& F+  B@B*@x@ADAEDqaLa =9{`=  $_ +@@ 6h&+ @JA񆠂  B@B}@x@ADAEA|aL a =IK=  +@ C@ :&+#V/FCxB B@B@x@ADAEba =Ia  +@v`@ #V9 %$em_<Ip4# A- B@B@x@ADAE͵La =I aI  $_ +@f`@ @<  B@B@x@ADAEL6ha =I=  " +@峀@ /{CQ  B@B@x@ADAE7nb$a =It`="A@Kl@&A ,'G!Sf)%La& Ak$ B@BA@x@ADAE&aLA =q`=$_@ 6]n}b}c A܀$ B@B@x@ADAEwaL a =I`= @ڀ@dAqـ  B@B@x@ADAE[aLQ!!a =(= = +@@&/C +A B@B@x@ADAEOa"1a =IV`= @M@ {Eb~)MhSsBC a& Ab  B@B@x@ADAELaL2@a =S`= @J@dAFA[ ` B@B@x@ADAI  E0aL AAAa == @`@&/i3C  B@DB@x` =A @E BQa = ?=oab#Q+@˾@&yZ#31fTBZjLa* uA57  B@B@x@ADA E"yaLR`a =_`= @@dA   B@B@x@ADAEvaL aaa == @6w@ ` `@/Ga  B@B@x@ADAE1abqa =48`="@/@ Aҳw[\/An(zF+ @4d B@BP@x@ADAE ra = 95  @,@dA+  B@B@x@ADAzE怈a ="A @ @ /VC!w瀂" B@DB@x@ADA#Eb bAa$ =`="%@u@&A 9H' 2? EҘ \&ៀ ' B@B  !@x@ADA(EZaL$a) = `=G * *@e@ @=+Ŝ ,I , B@x@ADA-EW aL Aa. =a=H@! A/@X@&$/0L1 B@B6h@x@ADA2E7!aa3 = ,`="4@K@&,yVm;%aj]]qL&,fas IF+5$6 B@B@x@ADA7Eˀa8 =7a"9@;@dA: A[; B@B@x@ADA<EȀ$a= =ZҀ= >@ɀ@&/C?% +@ B@B@x@ADAAE 8bmaB =C`="C@$@&ag~bv}t[%hPa& AD E B@B@x@ADAFEwXE Y B@B@x@ADAZE0faL A![ =="A\@`@ }/"A] ^ B@Bs@x@ADA_Eega$=!` =clr`= +a@c@&Hk))7+=c[T_-Ld 5Ab6dW+c B@B@x@ADAdE!saL Ae =ci}`=$_Af@`@ # @K<Jg h B@B@x@e =Ai @E~aL!!Aj =$="k@5@ !#V/îCl cm B@DB@x@ADAnEց "1Ao =D݉a"p@Ԁ@ P'?J0OHlV~<2,a& Aq r B@ BPq 5@ADAs @ aL2@At = 9=4ڔ`="u@р@ !>AvР w B@B cNA$X@x@ADAxEڋaL AAA'y ==" @@30z@ @ :/*C{vG| B@B@x@ADA}EaGaB%!~ =AV N`="@uE@! v`lWĠ, I w2Ipl,N!T%X2 @GD  B@Bo  @x@ADAER`A =K$_@eB@ # @>AA A B@B$@x@ADAE) aaA =ta"@~ !A/CK  B@Bq@x@ADAE6LbqA =澸'@J@&$Onq[`sFUI_PJrgt۾@a& O+  B@B@x@ADAEpaLr &+ =޻`=$_@:@ PA  B@BA@x@ADAEmaL; A =/`="@'@ /1&$ B@B@x@ADAEvဈ(# =,a"@$@ !#VJo#$ B@B@x@ADAEZ A =&='u@߀@ :$ @B5 W B@B@x@ADAE@TA = 0`="@@W}nIp-3Ҍ(g$N"cDL74  B@B@x@ADAE @Yy A =ɀ="@4@ W/z5C  B@By@x@ADAE{ bA =;`="@y@&>;*UZum*.9î J  B@B@x@ADAE3aL A =3!`=+$_@v@ # @>Au  B@B@x@ADAE0"aLWvA =:='u@ 2@ ! @A/;vu1 B@B`@x@ADAE`쀈a = -a"@t@ +'AP|EVDQg8XyjB#"j F+适  B@B@x@ADAEˤ.aL a =  8`=+$_@h@ ! @>A怂  B@B}@x@ADAE9aL A!!a ={="@ߢ@ /3J=K B@B@x@ADAE5]:a"1a =cE`="@I[@&WsN:e5Ya3,o<@-a& EAZ$+ B@B@x@ADAEFaLA2@a = `P`=+$_@9X@ # @>AW Y B@B@x@ADAEQaL@YAAa =P="@@ !$A/iabqaJ@Et`="@<@ #$s׷\mRC֫~q454 ` B@B+`x@9 A @EJ ra = ?=Ba"@9@>AD  B@B + @x@ADA E. 4) a ==" @^@&A/gD  A B@B@x@ =A @Eba =j`=$_@ɭ@ _AOWeD|_/d\]:jj b 3A5`4 B@DB @x@ADAE haLa = ]`=$_@@ ! @+=A  B@BA@x@ADAEeaL a =n= @4f@UD/C  B@B@x@ADAE aa = ?'`="@@&n#^+iބJ|Wչ= uA  ! B@B@x@ADA"E؁ a# =2$$_$@@ ,W @>A% & B@B@x@ADA'E a( =߀=")@ ׀@&/1YC*uր A+ B@B@x@ADA,E_b$a- = `="A.@s@ '&l 6]o`$? B@B-@x@ADA@E AA =`"B@8`@dAC D B@B@x@ADAEEL) aF =W="G@@ C/CHI B@B@x@ADAJE sbaK =y`=%L@q@ gU.R}cm/!AMp N B@B  C@x@ADAOEt+aL aP =v`=)Q@n@dARnmA[S B@B@x@ADATEX(aL !!aU =92= V@)@ /CW X B@B@x@ADAYE "1aZ =@"+[@@ ּ[sIώvU ʞv(Mu/cpS@ 9A\_ ] B@B :@x@ADA^EJaL2@a_ = `= `@ހ@dAaC b B@B !(@x@ADAcE. aL AAad == e@^@ /Cf Ag B@B`@x@ADAhET aBQai =e[`="+j@R@ PH'^²%I_3Jhaߋn3 %a& k4-l B@BP@x@ADAmE aLR`an =]X#`= o@O@dAp q B@B@x@ADArE $aLaaas == t@3 @ 6h/Du !jv B@Bs@x@ADAwEŁ bqax =:/a"+y@À@&:8Lb,ԡ&8y%+a& :Az { B@B@x@ADA|E}0aLra} =6:`= ~@@dAA[c @ B@B@x@ADAEz;aLa =="@|@ / Ct{ B@B@x@ADAE_6,J?u.Ҁ,ȷXa& A3$ B@B@x@ADAEa =:R @c1@dA0A[ B@B@x@ADAE뀈) a =="@@ /|"CI+ B@B@x@ADAE4Sba =^`="+@H@ P1T9[qlǬq6u@}( =a& [oA  B@Bu@x@ADAE__aLa =ܪi`= @8@dA A B@B@x@ADAE\jaL a =Kf="@]@&/CC B@B@x@ADAE kaa =v`="@@ ?yPC~k{&|S,M ĝ(A  B@B@x@ADAEtЀa = @@dAmA[A B@B@x@ADAEX̀6ha = W@@A9Egw?<~BCW+a& `c'^$ B@B:@x@ADAEIAaLWA =`="@⃀@dBA[ B@B@x@ADAE->aL a =H="+@]?@  +`/c'  B@B  @x@ADAE a =ga"@`@JĠW:PXH8qmŷ;:! <5G4 B@B{@x@ADAEL a =\aI"@@ #'J A[W B@B@x@ADAEaL !!a =Ӹ= @2@vĠ/C  B@B`@x@ADAEja"1a =5q`="@h@Ġnm~*z ՕVQt!aW4ԃa& kA  B@BJ@x@ADAE"@T2@a =1n`=$_@e@ 4 @>d  B@B@x@ADAEaL) AAa =)="@!@ }&+$/Cs  B@B@x@ADAE^ۀBQa = a"@rـ@;*Ȫ++cml=5  A؀  B@B(@x@ADAEɓaLR`a =`=$_@bր@ # @=Հ  B@BA@x@ADAEaL aaa =q=+"@ݑ@ @A/ CIA[ B@BO@x@ADAE3Labqa =R`=!I@GJ@ ' @A ʭ*6~c=b`0|}AI$+ B@BC@x@ADAEaLra =O`=$_@;G@ ! @AB  B@B@x@ADAE, @Y a =="@\@&/C  B@B@x@ADAE&ba =c1`="@ǜ@ 6h#xn 3+8gjvQT4fmca& , A3 m B@BJ@x@ADAEW2aLa =[<`="@@ '$>A  B@B@x@ADA!ET=aLa" =]="+#@1U@ `! @A/&C$  % B@B@x@ADA&E>aq a' =AI`="(@ @&`ymM^1h>CP1Ka& aA) * B@BA@x@ADA+Eǁ A%m = 0Ta+$_-@ @ &+ @>A. / B@B@x@ADA0E Aa1 =΀=$_2@ƀ@%/(MC3sŀ 4 B@B@x@ADA5E]Uba6 =``="7@q~@!҃`m(FBh6j9E縍ua& 6A8}@0+9 B@B@x@ADA:E8aaLA a; =k`=+$_<@a{@ ' @>A=zA[> B@B@x@ADA?E5laL !!a@ =p?="A@6@A/"CBHC B@B@x@ADADE3 "1aE =wa!IF@F@&Aݸ߉0P)-4ħ&(.HL\ Ia& GAV_$W B@B @x@ADAXEraLR`aY =e`="Z@ ]@ #$=[l\ A\ B@B@x@ADA]EVaL) aaa^ =!="_@@& /kC` a B@B@x@ADAbEҁ bqac =٦a%d@Ѐ@ +' @^>\=#B__t0p` kVCYBa& Ae] `J XFf B@B+@x@ADAgEHaLrah =ֱ`=$_i@̀@ ! @=jA k B@BA@x@ADAlE+aL@Y am =="n@`@>A/Co̡ p B@Bg@x@ADAqECaar =_J`="s@A@ +#!҃ڞSNdKF z@/5jӾ, pzAt2$u B@B@x@ADAvE aw =ZG$_x@>@ PAy z B@B@x@ADA{E  a| ="}@1~ W! @/VC~ A B@BA@x@ADAEL$a =4a"A@@&/b<}1x2 Vmr][:lA B@B@x@ADAElaLA ba =0`= @@ &+ @>A뮠A[ B@B@x@ADAEiaLa =s="@k@ /M@CrjA B@B@x@ADAE]%aAa = ,`="@q#@ +#+Ag e>){@JqUH9a& "$ B@B@x@ADAE݀a =)a"@d @ #>A[ B@B@x@ADAEڀ Aa = s="@ۀ@&/bG B@B@x@ADAE2ba =ߜ@$_g @3@F@&**?x-;'-*SW3{(kY}';5}F+$ B@B@x@ADAENaLA =AVڙ`=$_@6@ `@JA A B@B$@x@ADAEKaL) a = IU="@L@&/GQC B@BA@x@ADAEaa = `="@@ #$҃H>}ZeZq?F8)a& *MC  B@B@x@ADAEr a = ' @ @ PAk  B@B@x@ADAEV !!a =ƀ="@@ !/{gC  B@B@x@ADAEw(b"1a =~3`=!I@u@ vzB>u)Ą"(vɨea& IA\$+ B@B@x@ADAEG04aL2@a ={>`= @r@ #! @+=@  B@B@x@ADAE+-?aL AAa = 7= @[.@%J/C  B@B9~@x@ADAE BQa =fJa"@@&g%toi[JdnIʗꊃ>$aa& ~A1$ B@B%o@x@ADAEKaL$R`a =ZU`=+$_+@@dAA[ B@B@x@ADAEVaLaaa = 5̧="@0@&/URC  B@B@x@ADAEYWak:@sbqa =?`b`= +@W@ ' @aa6T$j؟OcfcZ 2@ bjA B@B 9~@x@ADAEcaLra =/]m`= @T@dAS  B@B@x@ADAEnaL) CAxa =@="+@@ W/FCq B@BW@x@ADAE\ʀa =ya"+@pȀ@ M׋ZDg~4ȝjQ*~~&.{F!` Aǀ  B@B>@x@ADAEƂz`Aa =΄`= @`ŀ@dAĀ  B@B@x@ADAEaL a = ="@ڀ@&A5/h0CF B@B@x@ADAE1;aa =A`= +@E9@ +8]Jք·0T38fZ` LA8  B@B+@x@ADAEa =>a @66@dAL5  A B@B@x@ADAE a = T=b @@ WA/C  B@BW@x@ADAEba =`= @@& qfO"lbƚ3_6-ڛa& ;F; $+ B@B@x@ADA EqdaLAa =`= @@dAnA[A B@B@x@ADAEUaaL A =%k="@b@ /F{ A B@B@x@ADAEaAa =#`= @@ A/N߳%YN]ƍqCq}vVD[ + B@B@x 9ADA @EFՁ  =  @@dA?  B@DBA@x@ADA E*ҡ ) a! = +ۀ=""@ZӀ@ /# $ B@B@x@ADA%Eb.a& =e`="+'@ɋ@ P2wD] ]ƷT|a& D(5) B@B@x@ADA*EFaL a+ =Y`= ,@@dA- . B@B@x@ADA/EBaL) !!a0 =L="1@/D@&A//C2C3 B@BA@x@ADA4EA"1a5 =6a"6@`@ +H엱gsGgtFz;?1A< fA7 A8 B@B@x@ADA9EL2@a: =2aI ;@`@ ! @P=< = B@B =QV@x@ADA>EԳL AAa? ==+ W@@@ A/CAq B B@B@x@ADACE[obBQaD = v  E@om@&Mz8yH=;Y(sn^@ ytFl$G B@Bm@x@ADAHE'aLR`aI =s`=$_J@_j@ # @>Ki L B@B@x@ADAME$aL aaaN =v.= O@%@&/z:PF"dnQ B@B@x@ADARE0 $bqaS =a"T@Dހ@&a/c|'&| E 3Ia& F+U݀-V B@B@x@ADAWEaLraX = (`=$_Y@4ۀ@ PAZڠ [ B@B@x@ADA\E)aL a] =L= ^@@ &+ @+*/C_` B@B@x@ADAaEQ*aAab =W5`="c@O@ ># -11u`Qj0Sa& AdN$e B@Bm@x@ADAfEp 6aLag =T@`= h@ L@ # @=iiKA[g@ᇶj B@B@x@ADAkETAaL al =$="m@@&/jCn o B@B@x@ADApE aq =La"r@￀@& }y /fJspYa& :As[t B@B@x@ADAuEEzMaLav =W`="w@޼@ &+>x? y B@B$@x@ADAzE)wXaL a{ =='u|@Yx@&/C} +~ B@B@x@ADAE2Yaa =e9d`="@0@ #!A Oa ]vZ:.Ī 6A0  B@B@x@ADAE a =X6o$_@-@ PA  B@BA@x@ADAE @Y a =="@3@&/3C耂  B@B@x@ADAEpba =2{`="@@ ٢ ŨC4y(H}Voc/0(62j5O L ^A- B@B%o@x@ADAE[|aL =-`= @@ ! @+=靀  B@B@x@ADAEXaL a =b="A@Z@&%o/CpY B@Bt P@x@ADAEZaa = `="@n@ #A#;p$XGf aI &/Y`|B LxTOiA$ B@B+@x@ADAÈ a =$_A@_@ PAA[ B@B@x@ADAEɀA!!a =yӀ=+"@ʀ@ ! @+$/PECI$ B@B@x@ADAE0b"1a =`="@D@ hgVXZ>6oMZp<{a& =)A$ B@B@x@ADAE=aL2@a = ܈`=+ @7@ ! @>A  B@Bc@x@ADAE~:aL) AAAa =KD=$_@;@&/C'f5W B@B@x@ADAE BQa =a"@@&$ aO%i  B@B$@x@ADAESaL aaa =$="@@ !$ |1'_C  B@B@x@ADAEfabqa =! m`="@d@&6'z.q5۴(, BZ  B@Bm@x@ADAEEaLra =j`=$_@a@ PAB  B@B@x@ADAE)aL a =%=+$_@Y@&/^lD  B@ B 5@ADA @ ׁ a =da"@Հ@ +#!+.^ )e#M`UAD|&=_ A/-+ B@DBP@x@ADAEaLAa =X`= @Ҁ@ ' @>A lM W B@B@x@ADAEaLa =ϖ=+"@.@ ! @A/C B@B}W@x@ADAEHaAa =5O@"@F@&APesU<M0Q«`@ VmA  B@B@x@ADAE aLa =-L`="@C@ &+=BA[ B@B@x@ADAEda =$_@r@  Ƕj Fll{qFٶɥ!Iԋ A kC޶$ B@@iB@x@ADAEq aL(a =*`="@b@ !>³  B@B@x@ADAEn+aL[pa =ux="+@o@mǶ/CH +M  B@x@ADAE/*,ao )@ra =07`="@G(@AĠୗ7"wGJ ^kzZ@ Q '  B@B|A@x@ADAE } zA =-B$_+@3%@ P $  B@B@x@ADA E~ Ax@! =@N=" @@Ġ/   B@B@x@ADAECbWA =N`= A@@Ġ3YX,Aml](et>5*a& vqF+$ B@B@x@ADAEoSOaL8%A =Y`= @ @ -&PAhA[W B@B@x@ADAESPZaL !!A =Z= @Q@ W&+ @/]C  B@B@x@ADAE [a"1A =f`="!@ @&Aj+Xf,ιTAfҼ:L5q\$  UA"Y$# B@B@x@ADA$EDā 2@A% =qa+ &@@dA'= ( B@B@x@ADA)E( AA)A* =ʀ="+@X€@ /yC, - B@BA@x@ADA.E|rbAB%!/ =W}`=%W0@z@ @ v`C A{Y+pôOt[G2 fĒ + 1/@2+2 B@B@x@ADA3E5~aLR`A4 =`= 5@w@ PA6 7 B@B@x@ADA8E1aL) AaaA9 =;=":@-3@ /L C];2A[< B@Bq@x@ADA=E퀈bqA> =4a"?@@ # n=t/ :kdս,; a& {A@ A B@B@x@ADABEaLr C =,`="D@@$+>:E瀂 F B@B@x@ADAGEҢaL AH =="I@@ /iWCJnK B@B@x@ADALEY^aAM =e`=$_`3N@m\@ Hi`1dυH'.?7ϯ; p ',AO[ P B@BH@x@ADAQEaLAR =b`=$_S@aY@ @>TX U B@B6h@x@ADAVEaL AW =|="X@@ H/CYDZ B@BH@x@ADA[E.ρ A\ =a ]@B̀@ PKǷɔLh|a& _A^̀$+_ B@BP@x@ADA`EaLAa =`=H d_b@2ʀ@dAcɠ d B@B@x@ADAeE}aL Af =E=H@ g@@ /Chi B@Bt@x@ADAjE@aEg,Wk =F`="+l@>@ "DTD;!Vvh{#el G}mD@ S. A B@B@x@ADAEځ  a =V% @@dAA[ B@B@x@ADAEց !!a =="@,؀@ /xY׀ B@B@x@ADAEb"1a =,!`="+@@ \\Ma,s+5Ny)J`.ygga& R.  B@BP@x@ADAEJ"aL2@a =+,`= @@ # @$>猀  B@B@x@ADAEG-aL AAAa =Q= @I@ W! @J/R.nH"f5 B@B@x@ADAEX.aBQa = 9`="@l@   QtGq}DEKO@͠>iZa& J@0a@ B@B@x@ADAEûR`a =!Da$_@]C`@dA  B@B@x@ADAEL aaM =l€=$_@׹@ /CC B@B@x@ADAE.tEbAbqa =zP`="@Br@ ) ⫹ʬ4a^oR Aq$ B@B@x@ADAE,QaLra =w[`= @2o@ @=CnA[  B@B@x@ADAE|)\aL a =M3="@*@&$/  B@B:@x@ADAE a =ga"@@&lAݶW!Ӽ|cD%]uep:q`Jҕx⠂@4 B@B+@x@ADAEmhaLa =r`="@ @ &+>g߀  B@B6h@x@ADAEQsaL) a =="A@@ A/~  B@B@x@ADAEUtaJ =\`="@S@& 7Sv,TrD"ft%IAX  B@B @x@ADAECaLga =Y`=$_@P@ @+>A<  B@BA@x@ADAE' aL a = = @W @& / C  B@B@x@ADAEƁ a =]͖a"@Ā@  aA#0].Rj@RȐ#i7׭=?tA-- B@Bx@x@ADAEaLF+ =Uʡ`=$_@@ ! @= B@B@x@ADAE{aL a =Ņ="A@,}@&$/XC| B@B$@x@ADAE7a$a =7>`= +@5@ m# @%oWe~FM"J$ǨvL3]OݻZ A$ B@Bm@x@ADAE A pD =+;a$_@2@ ,W @>A1A[m B@B@x@ADAE쀈 a =="@@ !/WCm퀂 B@B@x@ADAN  EXbAa =`="@l@%$ɴ‹t"F= +13k0o;jU~~~$Aإ$ B@DB@x` =A @E`aL a =`="@[@ &+>A  B@DB@x@ADA E]aL ". `_@!1a =!`=$_+ @A@ C ǶuI'܆D/"Ζ'H3ְ T`_C  A B@B6h@x@ADAEр2@a ="@1@ ! @J  B@B@x@ADAE{΀?AxAAa =@H؀="+@π@m}/Jw B@B<@x@ADAEbBQa =`="@@ Ġ挆Y}'Ȩōѧm2Wj6zja& V}  B@B@x@ADAEmBaLR`a =`=$_ @@ P!f " B@BW@x@ADA#EQ?  aaa$ =I="%@@@ !'+/}& ' B@Bs@x@ADA(E bqa) = a"*@ `@&fn[u\U+4,9R;?x4a& YIA+W$+, B@B@x@ADA-EBLAra. =aI /@@ PA0;A[1 B@B@x@ADA2E&aLa3 = ﹀=+$_+4@V@ /'uC5 6 B@B"Y@x@ADA7EkaAa8 =er#`="9@i@ #!+AרVQܞ$i" p9`iߔa& A:, ; B@Bk@x@ADA<E$$aLa= = Uo.`=">@f@ #$>? @ B@B@x@ADAAE /aLaB =*="C@+"@ !A/[CD!E B@B@x@ADAFE܀aG =*:a!I+H@ڀ@ ,jVA] twpDx` AI@1J B@B6h@x@ADAKE;`aL =E`=$_M@׀@ ! @>:Nր AO B@B@x@ADAPEБFaL) aQ =="R@@ /EaSlA[T B@B@x@ADAUEWMGaaV =!ATR`="W@kK@ #$҃|FgLf\i4̡25NYdXJ Y B@B@x@ADAZESaLa[ =P]`=$_\@[H@ @>A]G ^ B@BA@x@ADA_E^aL a` =i ="a@@ /dbB c B@B@x@ADAdE, ae =ia f@@@ *T8 ξ9QY 7IAg$h B@B@x@ADAiEvjaLAj = t`=$_k@4@ ! @>Al m B@B6h@x@ADAnE{suaL ao =K}= p@t@/w/q(dr B@B@x@ADAsE/va$at =5`="u@-@&<|#.BڄJGCIP1 a?a& SDv,-w B@B@x@ADAxEl瀈 ay =2a+$_z@*@ ' @K= {e)A[c @| B@BA@x@ADA}EP䀈 !!a~ = ="@@ !$Ġ/-C  B@B@x@ADAEןbA"1a = `=!I@띀@ P' @Pt1(d- F={EA+v kAW B@B@x@ADAEAXaL2@a =`=$_@ۚ@ W! @=:$ B@B@x@ADAE%UaL AAa =^="@UV@&/ޗ  B@B@x@ADAEaBQa =\`="@@& 2ʟȁƅܺ3ghN2{b:J^a& @^D, B@B@x@ADAEɁ R`a = Ta"@ @dA A B@B$@x@ADAEš @Y aaa =π="@*ǀ@&/rCƀ B@B@x@ADAEbbqa =2`=)@@ `@$}vep!9)cuƱk.Q + B@B@x@ADAE9aLra =)`=)@|@dA{A[ B@BA@x@ADAE6aL a =@= @8@ /l7 B@B@x@ADAEVlda =!A a"@j@ mr+Db6ei~y>(; W vF+$+ B@B@x@ADAEaLa =`= @Z@ # @+>쀂  B@B@x@ADAEaL a =u= @ը@&$/LZCA B@B@x@ADAE+caa =i`="A@?a@&AOG]gp 5z,՜eA` + B@B+@x@ADAEaLa =f $_A@0^@dA]  B@B@x@ADAEzaL a =G"= @@ &+ @+$/IC B@B@x@ADAEԁ a = a"+@Ҁ@ A9̇krl?% ^;c iJa& &Aр$ B@B@x@ADAEkaLa =`= @π@dAe΀  B@B@x@ADAEOaL) a =="@@&/( C  B@B@x@ADAEDaoa =K%`=%@B@ @+m TRRkOrLt<2$^mZA[A B@Bp@x@ADAE@ A = H0 @?@ @=:  B@B @x@ADAE$ a =1"@T~ m @A/m W B@B@x@ADAELAa = WXRcPgSI +\ВON}%%<t Ք A B@B@x@ADAEOlaLR`a = v`= @Z@ @JA + B@B@x@ADAELwaL aaa =pV="@M@&/ @ B@B@x@ADAE+xabqa = `="@?@&RZ9Y[]9|$jž CF+$ B@B@x@ADAEra = a"@.@ *>  ! B@B$@x@ADA"Eya# =Jǀ= A$@@&/foC% +& B@B@x@ADA'Eyba( = 5`=")@w@ #!$]{HV:ԗon cF|~ bA*v + B@B * 5@ADA, @Ek1aLa- = ?=|`=$_.@t@ ,W @K=/ds `:  iF0 B@BA@x. 9ADA1 @EO.aL; a2 =`="3@@ ! @ g陴8id:q}ݰV ` f#C4U DB@x@ADA6 @E@aLa7 = ?=}`="8@@ $ @>99 : B@B@x@ADA;E$aL Wa< =="=@T@ !B/C> W? B@B@x@ADA@EZaaA =[a`=!IB@X@AĠQ]IvztG;~Nahͻ0HMAC*$AD B@B@x@ADAEEaLWaF =S^`=$_G@U@ &+ @K=HA[$I B@B@x@ADAJEaLaK =="L@)@ /hCMN B@BW@x@ADAOEˀWaP = 8a"Q@ɀ@ S#$Ġ_S#Ot A&$9O1^"/ L  LAR$S B@B3R@x@ADATEaLAU = {(`="V@ƀ@ #=Wŀ X B@B@x@ADAYE΀aL AaZ =="+[@@ 6h! @A/`C\j +W] B@B@x@ADA^EU@&DnxZ3@W&AHDa& Ap +q B@B@x@ADArEeaL2@as =Ұ`=$_t@.@ ' @>Au v B@B@x@ADAwEybaL AAax =El=+)y@c@ ! @/ Cz{ B@B@x@ADA|EaBQa} =$'`="~@@ 'N| V.EM)T&ZA 8A$+ B@@iB @x@ADAEjրR`a =!2a"@@ !>Ac  B@B6h@x@ADAEN aaa =݀="@~Ԁ@ /fC A B@Bt   @'@x@ADAEԎ3bbqa =}>`="@茀@!+l; \fZ+ zbt` 5T@1-]  B@AbBA5@x@ADAE?G?aLra =I`=+$_@؉@ # @>A8A[ B@BA@x@ADAE#DJaL) a =M="@SE@ @A/lD  B@B @x@ADAE a =ZVa"@U`@ 'I]gbG6I)D6= 5a& DA* B@B@x@ADAEVa a =Ra`=$_@``@ ! @>A  B@B@x@ADAEL) a =ž=g'gb@(@&/C B@B@x@ADAEpbba =3wm`="@n@&1)h(5Jr>)A"?Hmda& Am  B@B@x@ADAE(naLa ='tx`="@k@ PAj  B@B@x@ADAE%yaL a =/="@&@ !A/ 2CiA B@B0<@x@ADAET a =a!I+@h߀@&ex_΁HKq'E)V-@ժgAހ  B@Bm@x@ADAEaLra =`=)@\܀@ PAۀ  B@B@x@ADAEaL a =!k= @ӗ@&/C? B@B@x@ADAE)Raa =X`="@=P@&ӾO-j }Z M7Xl6y٠Ya& -1O$+ B@B@x@ADAE aLA =U`=+ @-M@ ' @=LA[ B@B@x@ADAExaL a =@="@@ !$҃/1 B@B@x@ADAE o-&a = ɳa!I@@&=>l9EN0wۦ՜c) F+ `L XF B@B 4@x@ADAEi{aL a =ƾ`=$_@@ PAbA[ B@B@x@ADAEMxaL !!a =="@}y@&/}C "#a B@B@x@ADAE3a"1a =:`="@1@%J}~py@E3W[x|b2](/a& QCT B@BP@x@ADAE>aL2@a =|7`="@.@ '$=A8 A B@B@x@ADAE" @Yc AAa =="@R@A/#  B@B@x@ADAEbBQa =b`= A@@ ' @Hۤ\&!Պ%Y]~%#+ D.) + B@B@x@ADAE]aL$R`a =U`=$_A@@ -&! @=  B@B@x@ADAEYaL Aaaa =c="P@([@ &+ @/4Z B@B@x@ADAE~abqa =*`="@@ m##L'M>՞))\@Z; v  F+$ B@Bm@x@ADAÈra =&@$_ @@dA   B@B@x@ADA E a =Ԁ="@ˀ@&$/Ci  B@B@x@ADAESbla =`="A@g@ PGMX"Tq \k^9wW5e?#a& _AӃ+ B@Bg@x@ADAE>aLA &F  ba =`= @X@dA  B@B@x@ADAE;aLAxa =@nE= @<@&/kx> B@B@x@ADA!E) Aa" =(a"+#@=@&$9rQYnFBgYtE4 O>? D$$% B@B$@x@ADA&E)aLa' =3`= (@-@dA) * B@B@x@ADA+Ew4aL) a, =C="-@@&/C.$/ B@B@x@ADA0Eg5aa1 =n@`= +2@f@&;Y gG&7[`R>la& pA3~e 4 B@B@x@ADA5Eh AaLa6 =kK`= 7@c@dA8bbA[C9 B@B@x@ADA:ELLaL6ha; ='= <@@&/X\C=$> B@B@x@ADA?E؁ a@ =Wa"+A@ր@&1zl_7mgtFRW¢x)4`+0 v7BS C B@B 4@x@ADADE>XaLAE ={b`= F@Ӏ@dAG7 H B@B@x@ADAIE"caLqaJ =PPo`= K@G@ @$'# F`8|O-;`jcNG8Ve L( +M B@B@x@ADANEpaL aO =Mz`= P@D@dQ R B@B@x@ADASE @Y W!!aT ={a"U@+@P/V W B@ B@x@ADAXE} "1aY = .a!I +@@3+Z@@AĠ+2}o%A[p B@B@x@ADAqEWaqar =բa"s@<@&b:,kE(i9!lߝca& kCt u B@Bu 4@x@ADAvETaLraw =ԟ`="x@0@dy Wz B@B@x@ADA{EvQaL? a| =?[="}@R@  +Ƕ/C~'d B@B@x@ADAE aa =`="@ @AǶK_P2c2hIWu`m'A}  B@B@x@ADAEhŀa ='u@@ * @W>a  B@BW@x@ADAEL a =̀=+ m@|À@&Ga/gC  B@BGa@x@ADAE}ba =`="@{@&3N(zr?y)c4oW7D> I+Oa& $AR$+ B@B@x@ADAE=6aLWa =`=$_@x@ ' @>6A[g@ᇶ B@B@x@ADAE!3aLa =<="@U4@ !$A/C + B@B@x@ADAE a =\a"@@ 'AZcSc&qyor#821+`6#A,$ B@B@x@ADAEaL 4a =T]"@@ !>A B@BA@x@ADAEaLa =˭="+@*@ g/P$ B@BJ@x@ADAE}_aa =.f`="@]@ `#!+qLE&| x(<Oqa& (D$ B@Bm@x@ADAEaLAJ A =%c`=$_@Z@ # @>AY A B@B@x@ADAEaL) A! =="@@&/CgA B@B@x@ADAERЁ 1! =*a"@f΀@ 2/e;GG"^p=7/"ɯa& 9À  B@BA@x@ADAE+aL A =5`=$_@Vˀ@ ! @>Aʀ  B@BA@x@ADAE6aL !!A =m=+'u@ц@ W&+ @/4C= B@Bw:@x@ADAE'A7a"1A =GB`="@;?@ +#AaGjm0NOaa& >$ B@B@x@ADAE2@A =DMa"@+<@ #>A;  B@B@x@ADAEv AA' =>N"@~ W! @ /   B@B@x@ADAEL$B!! =Y'@@&A`3aVL(߭@ks{a& QxF+|$ B@BA@x@ADAEgjZaLR3c! =d`=+$_@@ &+ @"`C >A` ` B@B@x@ADAEKgeaL a' ! =q=$_@{h@ /TA A B@B@x@ADAE"faAb1! =~)q`="@ @ +#!g quWw7)[n":oa& iAR B@Bs@x@ADAE<ہ rA =z&|$_@@ # @>A6 A B@B@x@ADAE ء @YN A = +="@Pـ@ W! @/iA  B@B@x@ADAE}bA = S`="@@';6!◻uW9t"<5 miA'  B@B@x@ADAELaLA =O`=+$_@@ &+ @>AK B@x@ADAEHaLAAR=" ~@%J@'.iAI B@B@x@ADAE|aA =I1 `=% @@ P# @ .`lWA 뮢"hqCK:F}Dn"D€2 ` S  B@BP@x@ADA E缀A =(a$_@`@ ' @ .`A>A S  B@B@x@ADAE˹L AA = À="@@& /s4Ag B@B@x@ADAEQubA =|`="@es@%>9BJ0qF^A So  B@B@x@ADA E*aL A! =t4= "@+@&9~/G#<$ B@B9~@x@ADA%E& A& =a"A'@:@ #! .`cAϹqH?F*:2+h#ÆO@+ ( S。$) B@B@x@ADA*EaL@4+ =`=$_,@+@ PA-ࠂA[. B@B@x@ADA/EuaL  A0 ==="1@@ !/@C]2W3 B@B@x@ADA4EVaa5 =]`="6@U@ +GDe Kg[cɕN#'^F.ot0<TMA7|T$8 B@B+@x@ADA9EfaL a: =Z`=";@R@ !$ .`E>A< S`Q = B@B(@x@ADA>EJ aL) !!a? = ="@@z @ W/aAA "#f5B B@B@x@ADACEǁ "1aD =~a%E@ŀ@ +# @ .`cAཥYe 1}ihHN.VNDSpQC[2 i@GF SQ G B@B+@x@ADAHEK S5 L B@B$@x@ADAME} aLAAaN =膀="O@O~@ !A/EAP Q B@B$@x@ADARE8 aBQaS =V?`="T@6@  KĠԈmܕ&s͚g}۰WO$Na& AU&6 V B@Bxg@x@ADAWER`aX =N< $_Y@3@ ! @ .`D>AZ S [ B@B@x@ADA\E  Aaaa] =="^@%@&J/0A_` B@B@x@ADAaE{!bbqOmb =(,`=%c@@ +# @ .`cĠ?BTa*jUȗ1dWGHn2 Mh@Gd S-e B@BA@x@ADAfEa-aL-rag =$7`=$_h@@ -&' @ .`A>Ai S UGߣ j B@B@x@ADAkE^8aL-&al = D`="m@e@ }!0<m̜nص].F5fY{= VSAn o B@BA@x@ADApEҀaq =Oa"r@T@dsA[oc@mt B@B@x@ADAuEπ av =kـ="w@Ѐ@/Cx;y B@B@x@ADAzE&PbWa{ =ߑ[`=$_+|@:@ 䑢l#O*Bt2)(vT0Wzha& )A}$~ B@B@x@ADAEC\aLa =Ύf`='u@*@d  B@B@x@ADAEt@gaL) a =IJ= @A@ Ġ/C B@B@x@ADAE a =sa"+@r`@ -c>AJ4jXqVwT#kA{ + B@B|@x@ =A @EfLa =}aI @@dA_ A B@DBA@x@ADAEJ~aL a == @z@ / 6C  B@B@x@ADAElaa =s`="+@j@&T9&M)"~B>m҈q1P B@B@x@AD>E;%aLR =xp`= @g@dA4 A B@B@x@ADAE"aL a =+="@O#@&/!2  B@B@x@ADAE݁ a =Va +@ۀ@ mAnlѿ:e0^qI]1Ys6^7a& A%$ B@B6h@x@ADAEaL a =R`= @؀@dA A[ B@B`@x@ADAEaL!!a =="@$@  cV .`$X/@G S NG B@B@x@ADAE{NaA"1a =+U`="@L@:9st*1.7-ĕb,7g0Gƨa& t K$ B@B@x@ADAEaL2@a =#R`="@I@'O&+$ .`C>: SH@g B@B@x@ADAEaL AAAa = = @@&/pt e + B@B@x@ADAEP BQa =a"@d@! .`cĠ#AaTd089M7\Z9g2  Sм@/ B@BR.@x@ADAEwaLR`a =`=$_$@T@dA  B@B@x@ADAEtaL aaa =c~=H@Qb@u@$/-:  B@B@x@ADAE%0abqa =6`="@9.@&Murmu4E$na& 1D-  B@Bm@x@ADAE耈ra =3 @*+@+ @ .`f+=UD S*@g B@B@x@ADAEt a =E=+$_@@&/!A  B@B@x@ADAEba =`="@@ ,W! .`cA,-B ?76r2 @G Sz$+ B@B@x@ADAEeY@Ta = `=$_@@ @ .`A> S^  B@B@x@ADAEIV aL a =`="@yW@ /YA  B@B 4@x@ADAE aa =`="@@ ! .`C-mCA '(1 @G SO$ B@Bg@x@ADAE:ʁ a =x"a$_@ @ &+ @ .`a=A S3@gA B@B@x@ADAEǁ a =Ѐ="@NȀ@ /MA R  B@x@ADAE#ba =].`="@@& y Up37]bԸ?G.=A% zA% B@B@x@ADAE;/aLa =M9`=$_@}@ # @"`D>A  A B@B@x@ADA E7:aL) Aa =A=" @#9@& /A8 B@B@x@ADAEza =*Ea"@@%AC q5bS5`[# a& t m B@B@x@ADAEFaLޗ ="P`="@~@ PA퀂  B@B@x@ADAEȨQaL a == A@@&/Tz:d B@B@x@ADAEOdRaa =k]`="!@cb@ #!gn'7;4z- %ub?[F+"a # B@B@x@ADA$E^aL a% =!gh`=+)A&@W_@ PA'^ ( B@B@x@ADA)EiaL !!a* =n#="+@@&$/?/C,:A- B@B$@x@ADA.E$Ձ "1a/ =ta"0@8Ӏ@&h%i!^~öVk[#XmnLa& 4A1Ҁ$+2 B@B@x@ADA3EuaLA2@a4 =`=+ 5@(Ѐ@ &+ @+=6ϠA[7 B@B@x@ADA8EsaL AAa9 =@= :@@ &+ @g/†C;< B@B@x@ADA=EEaABQa> = L`="?@D@&033PΘi8yk?+?JA@yC AA B@B@x@ADABEdR`aC =I$_D@@@ # @=E] F B@B@x@ADAGEH  aaaH =a"I@x~&/CJ K B@B@x@ADALE϶LbqaM ='N@㴀@% c>Јѱc$aC0@(?ib |AOO+P B@B@x@AD>QE9oaLraR ={`=+$_S@ֱ@ @>AT3 U B@B6h@x@ADAVElaLbH) aW =u=)X@Mm@ &+ @A/+PCY Z B@B@x@ADA[E'aa\ =M.`="]@%@EK=3ae J.ɳEa& A^$ A_ B@BJ@x@ADA`E aa =L+a$_b@"@ # @=Ac d B@BA@x@ADAeEܡ @Yaf =="g@#ހ@ 4! @%o/ Chݠ i B@B@x@ADAjEybak =!`="l@@ 0(|D!|* =CA9pam$n B@B@x@ADAoEPaLap =`=$_q@}@ @>Arݒ s B@B@x@ADAtEMaL Aau =W="v@N@&/gwdA[x B@B@x@ADAyEN a$az =`="A{@b@&f UE OxzbZ[ >q9SF+|- aA} B@B@x@ADA~Ea = $_@S@ ' @>A a ၊ B@B@x@ADAENa =؀ "@tA[ B@B@x@ADAEr/ aL a =>9="@0@ :!B/C + B@B@x@ADAE Wa =a!I@ @ Njm٘yxGS8JQca& fGy耂+ B@B@x@ADAEcaL a =#`=$_@@ ! @>]  B@B@x@ADAEG$aL !!a = ="@w@ /0JC A B@B @x@ADAE[%a"1a = {b0`="@Y@ #$AofU̗ɃVSA&A3[mR# 5AN  B@B@x@ADAE91aL2@a =v_;`=$_@V@ # @>A2  B@BA@x@ADAE6߭t,D#- B@B@x@ADAEHaLR`a =KR`=$_@3@ǀ@ @>AA[ B@B@x@ADAESaL aaa =AV= @"@ /C B@B@x@ADAEx=Tabqa =)D_`="@;@&bx 0W#Kt>ʗ/); yA:$ B@B6h@x@ADAEra =%Aja+$_@8@dA7  B@B`@x@ADAE/a = ="@@ /Cg$ B@B@x@ADAENkba =v`= +@b@ 1@U"7i?=caW.a& DKΫ$ B@B@x@ADAEfwaLa =`= @R@dAA[ B@B@x@ADAEcaL) Aa =mm= @d@ /^DK8A B@BP@x@ADAE#aa =%`="+@7@!WĠlԘUw1MeQ}ەdșa& "F+  B@Bg@x@ADAE׀a ="a @'@dA  B@B@x@ADAEqԀ a =6ހ="@Հ@/JC ՠA[ B@Bq$@x@ADAEba =`=!IW@ @&$Nm>+Q ݃"s@pUOa& x  B@B@x@ADAEcHaLa =`= @@+ @+= \A[ B@B@x@ADAEGEaL a =  O="@wF@ A/  A B@Bo@x@ADAEaa =`= @`@ $Z珺'Asm|Q-t6Q2a& ʛF+M$+ B@B@x@ADAS  E8LAA! =vaI$_+@`@ @>1A B@DB@x` =A @ELa =쿀="@L@ /A A B@B@x@ADAE&aL!!a =0= @!(@ /NR.' B@B@x@ADAEx "1a =$a"@@ #!|C J@l944 ?5 2^Ia& }F+߀$ B@B@x@ADAEaL2@a = `=G@gd_A @|݀@>A!܀ " B@B@x@ADA#EƗaL) AAa$ =="%@@ /JQC&b' B@B@x@ADA(EMSaBQa) =Y@"*@aQ@ K$*hoS_!lj -,&"EdBw@ q +P A, B@B@x@ADA-E aLR`a. =V`=$_/@PN@ ! @+=0M 1 B@BA@x@ADA2EaL aaa3 =h=+'u4@ @&/D58 6 B@Bw@x@ADA7E"ā bqa8 =a 9@6€@ m# @ ̓|~Nؼ_kRLa& 7:$; B@B@x@ADA<E|aLra= =%`=$_>@*@ ' @>A? @ B@B@x@ADAAEqy&aL i AxaB =@E="C@z@0<J/>D AE B@B-&@x@ADAFE4'a$aG =;2`="H@ 3@ m񡙪—U"ԬTBg*:]KF+Iw2@4+J B@Bm@x@ADAKEb퀈aL =8=a$_M@/@ @>AN[A[O B@BA@x@ADAPEF  aQ =  = R@v@ &+ @/ gCS T B@B@x@ADAUEͥ>bAaV =}I`="W@ᣀ@ ZH&"C[NjXb"M2AXMY B@B@x@ADAZE7^JaLa[ =uT`=$_\@Ѡ@ @Q`AB?A]0 ` ^ B@B@x@ADA_EaL a` =d="a@K\@&J/Ab c B@BJ@x@ADAdEVaae =Ra`="f@@&Z(_O_2q'v3Op42d` Ag"h B@B@x@ADAiE ρ 6haj =l`"k@@ &+>Al Am B@B6h@x@ADAnEˡ @Y ao =Հ=)+p@ ̀@&/Cq̀r B@B@x@ADAsEwmbat =  x`="u@@!O {ta"ڧ$rɗn> 3Av w B@B@x@ADAxE?yaLޗy = `=+$_z@{@ ,W @>{ہ | B@BA@x@ADA}EA  B@B@x@ADAEaL !!a =t="@ˮ@ -&/vC7 B@B-&@x@ADAE!ia$"1a =o`="@5g@ #)6q )6^I˄G.[a& Af$ B@B@x@ADAE!aL2@a =l`=$_@&d@ # @>AcA[ B@B@x@ADAEpaL AAa =<(=+"@@ ! @A/kC  B@B@x@ADAEف BQa =a"@ ؀@%A~o~M >#֙_|"I?a;p Aw׀$ B@Ba@x@ADAEaaLR`a =`="@Ԁ@ &+>A[  B@B @x@ADAEEaLqaqa =Q`=$_@H@ # 'y&%`\?>jt)a& "CL  B@B{W@x@ADAE6aLra = tN`="@E@ ! @+=0  B@B@x@ADAEaL? a = ="+@J@Ƕ/  B@B@x@ADAE a =Ua"@@ #$ĠWM#` CK9܎$͵Zja& cCD!  B@B@x@ADAE taLa =I`=$_@@ P  B@BW@x@ADAEpaL a =z="@ r@ ! @/oCq B@B@x@AD>Ev,aa = '3=!I@*@ĠO* ]$oޔ’Cí5 "C)- B@B@x@ADAE䀈Aa =0 @{'@ &+ @>A&A[ B@B@x@ADAEဈ a =="@@&/4Ca B@BA@x@ADAEKba =`="@_@&癖8D|& Fʂ~o(^&9a& ʯA˚ A B@B6h@x@ADAEUaLa ='`=+$_+@S@ ' @>A[ B@B m @'@x@ADAER(aL6ha =f\="@S@/AZ  B@B@x@ADAED4WaL@Y !!aT>="@x5@ !/UC$ B@B`x@9 A @E "1a =tba!I@@ ' @Au D !A62WܽiM]3)` lAK  B@DB @x@ADA E6caL2@a =sm`=$_ @@ 4 @=A /A[Ƕ B@B@x@ADAEnaL AAa =ޮ="@J@ /-@C  B@B6h@x@ADAE`oaBQa = Qgz`=$_@^@ b(ȞBcur| z]77;?Dt A $+ B@B@x@ADAE {aLR`a = Id`=$_@[@ +# @>A  B@B@x@ADAEaLaaa =="@@ !#V҃/[;C ! B@B:@x@ADA"EvрAbqa# ="ؑa!I$@π@ G ~wBHv^Wm0Mf*9%a& A%΀$& B@Bޗ@x@ADA'EaLra( = "՜`=G 1)@~̀@ !>A*ˀ$+ B@B@x@ADA,EĆaL Aa- == .@@&$/tC/`0 B@B$@x@ADA1EKBaa2 =  I`="+3@_@@ #!+(K%re%; A4?$5 B@B @x@ADA6EAa7 =Ea$_+8@O=@dA9< : B@B@x@ADA;E) a< =ua"=@~ A/XC>5? B@B@x@ADA@E LaA =͹a$_B@4@ +E*Y+` k r|0Fnj \YAC` mD B@B+@x@ADAEEk`aF = ȶ`= G@$@dAH I B@BA@x@ADAJEohaLgaK =;r="L@i@ W/uCM N B@BW@x@ADAOE#aaP =*`= Q@ "@ m(pvAOY{u>%#I٬Sda& ARy!$S B@B@x@ADATE`܀(aU = ' V@@dAW] X B@B@xV 9ADAY @EDف aZ =="[@xڀ@ }/BC\ ] B@DB@x@ADA^Eʔb#a_ =~`="`@⒀@&aى%l1B~4$$^ da*gt n?AaN$b B@B@x@ADAcE5MaLAd =s`= e@Ϗ@dAf. g B@B@x@ADAhEJaL A!i =S= j@IK@ /Ck pl B@B@x@ADAmEaAn = X  #o@@<S(9E[=šֆ^?La/c Ap q B@B<@x@ADArE  As =H a t@@dAu v B@B@x@ADAwE  !!Ax =Ā="y@@%/Cz +{ B@B@x@ADA|Euvb"1A} =)}`="~@t@ vU-4syBx*9ۓ7٪ga& &As B@B@x@ADAE.aL2@A =!z)`="@|q@ !$=p  B@B6h@x@ADAE+*aL AA)A =5= A@,@%/ C_A B@B@x@ADAEJ B"! =5a"@^@ #! v`C A󮏧g-)Ս?<Z9@0P + H@G䀂 + B@B@x@ADAE6aL$R`A =@`=$_@N@ ,W @>ဂ  B@B@x@ADAEAaL aaA =m="@ɝ@ W! @/kdC5 B@B@x@ADAEX3"  bqA =^M`="@3V@ mQXU.7Oƛݻ@d`*/MJ&f AU$+ B@Bm@x@ADAENaLrA =[X`=$_@#S@ ! @>AR  B@B@x@ADAEn YaL A =;=bq@d_@@&$/LC  B@B@x@ADAEȁ A =da"@ǀ@&:4f*DB^/S/RxRa& tƀ$ B@B@x@ADAE_eaLA =o`=$_@À@ ' @>AXA[ B@B@x@ADAEC~paL A ==+)@s@ ! @A/ d B@B@x@ADAE9qaA =v@|`="@7@ 'ݪahTj|QjUY,wn2\a& F+J B@B@x@ADAE4 A =r=a"@4@ !>A.  B@B$@x@ADAE qA =T"@@ : uk58$ -7t"e)ȵ9a& EB  B@B@x@ADAE caLA =G`="@@ !>  B@B@x@ADAE_aL? A =i="+@a@ :$#V>/vF+`!]iK B@B} @x@ADAEtaA =$"`="@@AĠpOot9u3Nva& a  B@BA@x@ADAEӀ A =$_+@x@ # @=:  B@BW@x@ADAE  A =ڀ=+$_@р@ ! @W/g_  B@B@x@ADAEIba =`="@]@&v ڞSWdxe_R6և8 A  B@B@x@ADA!E !@Ta" =JS+`=)#@J@ ! @+=A$ % B@BDK@x@ADA&E,aL Aa' == (@@$/]C)* B@B@x@ADA+Esa, =(7@"-@@ P#!A;?]vGZG a

@ KA=.$> B@B+@x@ADA?E逈a@ =4Z  A@M,@ ! @+=AB+@C B@B@x@ADADE怈 aE =`="F@@ W/AgCG3H B@Bu + M@x@ADAIE[baJ = ֨f`="K@2@A8h-yY^؜`dpM }AL$M B@B@x@ADANEZgaL"O =ƥq`="P@"@ #>Q R B@B@x@ADASElWraL) aT =@a="U@X@ !'+A/CVW B@B@x@ADAXEs aY = 0~`=!IAZ@@ ' @JW$d17sqp3b,9v A[s \ B@B@x@ADA]E^ˀ a^ =@$__@ @ -&! @=A`W Aa B@BA@x@ADAbEBȡ @Y !!Xc =҉a"d@rɀ@ #/Ce f B@B@x@ADAgEȃaL"1Ah =u`=$_i@܁@ # @A4spYS*h?fr%OR .,"0a& ajHk B@B@x@ADAlE3<@T2@am =p`=$_n@~@dAo, Ap B@B@x@ADAqE9aL AAar =B="s@G:@ / gt u B@B@x@ADAvE $BQaw =F@"+x@@ M&v$pt,+ϐ6HU>ͼ@ F+y -z B@B@x@ADA{EaL$R`a| =`= }@@dA~  B@B 0`@x@ADAE쩸aLaaa == @@ /DK B@B@x@ADAEse@TAbqa ='l`="+@c@&-}4b/ {ϱp?wJD,@ Db$ B@B@x@ADAEaLra =i`= @w`@ @>_  B@B@x@ADAEaL Aa =$="@@&/e(C] +Edau XF#^ B@B} +$@x@ADAEHց a =@"@\Ԁ@&$]yUta,.MhWR~T@ VӀ+ B@B@x@ADAEaLa =!`="@Pр@dAР  B@B #A@x@ADAEaL a =g= A@ƌ@&/;D2 B@B@x@ADAEG a =M`="@1E@&/SM"탊,>ոGc9AD + B@B 4@x@ADAEa =J)@!B@dAA  B@B@x@ADAEl a =@ @~ / C  B@B@x@ADAELa = #@@ +tfXP_*gCY9A49U #Ar$+ B@B+@x@ADAE]p aLa =`=+ @@ ! @>V  B@B@x@ADAEAmaL a =w="A@qn@ :/zC A B@B@x@ADAE(aa =t/"`= +@&@&a>հQbu 4XQۊho4a& AG$ B@B@x@ADAE2 /A =,-a$_A@#@ # @>+A[ B@B@x@ADAEށ a =="@F߀@ }!#V/C  B@B}@x@ADAE.ba =U9`="@@ 'g~~_+5 BFrLU x1a& A B@B@x@ADAER:aL a =ED`="@@ !>A  B@B$@x@ADAENEaL)7!!a = X="+@P@ S/CO B@B@x@ADAEr F "1a =&Q`="@@ #!+*.gU^M QɫuȞ~)ne ,C m B@B@x@ADAE€g2@a =\a$_@v@ # @>A  B@B@x@ADAE; AQa = ha"@[y@ W!>yfPEepg}^J KICx  B@B@x@ADAE3iaLR`a =~s`="@Kv@ $ @>u  B@B@x@ADAE0taL aaa =^:="@1t`~ ! @W/eC2 B@Bs @x@ADAEta bqa =`="@0@& ǝÞ 26dAL mv*Uka& n`A适$A B@B@x@ADAEaLra =`=$_@ @ &+ @>V栂 O B@B@x@ADAEkaL a = 3=+$_@@ /LC B@B@x@ADAE\aWa =c`=" @[@`Bg94G+ [ p DjAyx/a& } qZ A B@B.@x@ADA E\aLa =``="@W@ #>AUA[ B@B@x@ADAE@aL a =  = @p@ ! @+KA/'}  B@B@x@ADAÉ a =tԮa"@ˀ@ 'u:tZ]hH_Q2$^F+G@4 B@B+@x@ADAE1aLa = oѹ`=$_@Ȁ@ ! @>A+  B@B@x@ADA EaL) a! =ތ=""@E@&A/C# $ B@ BP@x@ADA%E>aa& =LE`="'@<@ +#玢d8 %M.YĔނ[_:! }1( ) B@B+@x@ADA*E a+ =DBa",@9@ '>A- . B@B@x@ADA/E @Y a0 = {="+1@@ C! @+A/123 B@B@x@ADA4Eqbua5 =*`="6@@ 57N==AU%HI쳼a& ϿF+7 8 B@B:@x@ADA9EgaL A:V `=+$_;@y@ ! @>A<թ = B@B}@x@ADA>EdaL a? = n=$_@@e@&/9CA\B B@B@x@ADACEF a$aD =&`="E@Z@&ApMBes҂ ^r'g|AF$+G B@B@x@ADAHE؀ aI =#G@Qd_J@J@ '>AK L B@B@x@ADAMEՀ !!aN =a߀="O@ր@ !$+A/CP1րNQ B@BP 5@ADAR @Eb"1aS =ȗ `=!IT@0@&s%]yhr֩t|/Hp|g` AU$V B@DBP@x@ADAWEI aL2@aX =Ĕ`=$_Y@ @ `@>AZA[d[ B@B@x@ADA\EjFaL AAa] = 7P="^@G@&/C_` B@B@x@ADAaEaBQab =$`="c@@ #M=NqIWkyd@J,wAdq#`$e B@B%o@x@ADAfE[ R`ag =/`"h@.`@ '$>AiU j B@B@x@ADAkE?L) aaal =="m@o@&$/Cn o B@B$@x@ADApEr0bbqaq =wy;`= r@p@ +Gbk4MIp۞MЛ|x?9AsFA[t B@B@x@ADAuE1+Ax*A[y B@BA@x@ADAzE(GaL@Y a{ =1= |@I)@&/nC} ~ B@B@x@ADAE a =SRa"@@A䟬tZ3k/[ AIIz?S~7`7|A$ B@B@x@ADAESaLa =C]`=$_@ހ@dA݀  B@B@x@ADAE^aL a == @@ * @+/C !k B@B@x@ADAEpT_a$a =[j`="A@R@ AqO#HӃ}"[UyPuA%/Q@4a@ B@B@x@ADAE kaLAa =Xu`= @uO@dAN  B@B@x@ADAE vaL a =="@ @ /LD[ B@Bc'@x@ADAEFŁ Aa =ˁa"@ZÀ@ Br(\CnAm3䗐@ X&a& ߨA€$ B@Bg@x@ADAE}aLa =Ȍ`="@I@$=DK  B@B@x@ADAEzaL a =d="@{@ }/)C0 +A B@B@x@ADAE6aa =<`=*W@/4@&mh}dS=wq|−(dƄ5ta& OA3+ B@BJ@x@ADAE8[A =9$_@1@dA0A[ B@B@x@ADAEi뀈 a =.="@@+#V+/cCA[ B@BW@x@ADAEba =`="+@@ UEnY#>yS淵ZG^荢fB3DK<US͞a& AE$+ B@B@x@ADAE0Ё 2@a =ma$_@@dA)  B@B@x@ADAE͡ @Y AAa =ր="@D΀@ /OC  B@B{%o@x@ADAEbBQa =G`= +@@&AR:_P a/wWCE%~C UQ8& ykA$ B@BA@x@ADAEAaL$R`a =`= @@dA  B@B@x@ADAE=aLaaa =G="@?@ /GC>W B@Bt@x@ADAEpbqa =,a"@`@ PYu?#!t ? ~Հ  B@B@x@ADA Ei1aL a =1= @@ ! @Ƕ/zE B@B@x@ADAEK2aa =R=`=!I@J@gĠqy:~RKFހCa& GoI$A B@BV@x@ADAEZ>aLa =OH`=$_@F@ &+ @K=:WA[d B@B@x@ADAE>IaL a = ="@n@ / C #a B@B@x@ADAEż Wa =tTa"!@غ@ #$Ġ>3EPwϪ]j{4V=k 5#nA"D # B@B@x@ADA$E/uUaLW"% =m_`="&@ȷ@ #>A'( c @( B@B@x@ADA)Er`aLa* ={="++@Cs@ ! @A/BC, - B@B@x@ADA.E-aa-&a/ = ^4l`="0@+@ AﲴV5[|Lr &-12 B@B@x@ADA3E  a4 =B1wa$_5@(@ ! @Q`B?A6' 7 B@B@x@ADA8E ) A!!a9 ==":@@ /"Y;。< B@B@x@ADA=EoxbA"1a> =`="?@@ +#+A?\zr1$߭O2+QYLa& C]@ +A B@B+@x@ADABEVaL2@aC =`="D@s@ #>AEӘ F B@B@x@ADAGESaL AAaH =]="+I@T@҃/^CJYAK B@B@x@ADALEDaBQaM =`="N@X @ +DsM|mO`qhsk]ypa& {O P B@BJ@x@ADAQEǀR`aR =a+$_S@L @ @JAT U B@B}@x@ADAVE aaaW =W΀= X@ŀ@g @/Y/A[mZ B@B@x@ADA[Eb$bqa\ =ֆ`="]@-~@ +mGD@~c+AkNa& rF+^}$+_ B@B@x@ADA`E8aLraa =ƒ`=+$_b@{@ PAc}z d B@B@x@ADAeEh5aL af =A?=$_g@6@ ! @ /^ChAi B@B}@x@ADAjE Aak =a"l@@ ҎbAB:4N> a& dmo$n B@Bx@x@ADAoEYaLap =`= q@@ ! @>rRA[s B@B@x@ADAtE=aL au = ="v@m@ />dw #aAx B@B6h@x@ADAyEaaaz =ph`="{@_@ #+"^0úF,dQpHrɈa& <|D} B@BJ@x@ADA~E.aLa =e`="@\@ #>( A B@Bu@x@ADAEaL) a = ="@B@ `!/HIA  B@Bv@x@ADAEҁ a =Fa!I@Ѐ@ $I Аrl"X$w=h*a& }A + B@B@x@ADAEaLa =A@$_@̀@ ! @JÀ  B@BA@x@ADAEaL@Yh5 a == @@ /C  B@B@x@ADAEnCaa =J`="@A@ #!'# sf3eo8^,dkK>Y%A@$ B@B@x@ADAEA =G$_@r>@ # @>A=  B@B@x@ADAE Aa ="@~ ! @/CY  B@B@x@ADAECL$a ='a"A@W@&^y8E2[' g txC5a&  %Añm B@B@x@ADAEl(aL a = 2`=$_@H@ &+ @> ȸ B@B@x@ADAEi3aLA!!a =fs="@j@ `/ C2$ B@B1@x@ADAE%4aA"1a =+?`="@-#@ +#+AvC.fڑ#2A}  B@B@x@ADAEgڀ) uAAa =3="@ۀ@ !A/r nA B@B@x@ADAEKbBQa =V`=!I@@*ĤHR\FRY,^tKUSh4E/F+n  B@B+@x@ADAEXNWaLR`a =a`=$_@@ }&+ @JARA[c @ B@B@x@ADAES ` B@B@x@ADA EaL@Y) Aa =b=  @@&/ 1 +A B@B@x@ADAEʁ a =a"+@0Ȁ@ #!I)9M,K WFحN֙tZрyda& dC]ǀ  B@B@x@ADAEaLA zA =`=$_@ŀ@dA|Ā  B@B@x@ADAEfaL A! = /="@@ A/+C B@Bu@x@ADAE:a$A =A`=" @9@ +|+ֺeڔA¤w|(uu A!m8 " B@B+@x@ADA#EX+A$ => %@5@dA&Q ' B@B@x@ADA(E< @Y !!A) ==+'u+*@l@ }  =AW #xC+ , B@B@x@ADA-E«b"1A. =s`="/@֩@1A0B$+1 B@B@x@ADA2E-daLA2@A3 =k@ 4@Ʀ@dA5&@Ȥ6 B@B@x@ADA7EaaL NAj`=8=`=G%  A B99=$`=`3{ `9@8:80V# 8H`8;88 7`8<8j q=8m68q>88>?8t,`8ֵq ' d2@ =@U`=\ F`rKA@@@S`6@@`@AÀ@|@{BJcJ J `J@  -FC B@Bo B  @' @x@A ARDEIa$ J 8DE =@@[i=: `!RRUF@@ `@# P@ K@(@5!+JF GT `T\i\H B@BA~`@ \@x@AA\IEXa\ 5E\@a\JX@\`=3K@@ d!\""@BLBBBJM B@JBo@١ `  J@x@AAJNEπEUO=Tހ=``yP8#a` 8Q88 R =! 3,O`v!S@M@@{%BTJJ  a U B@B@x@R =BV @EacMW =@ր= =#MX@#@ #M$`! !@BYBJZ B@B@a@ @x@AAJ[EmÀ> < :H \ =@paJ$W! ]@@@S~@- @ HAR^JJ J `J-GH_ B@BpE$ H@x@A AR`E5Ya =@Y=!R"\R'Hb@u@ 2$ @HcTՠ+ T\i\d B@BC\%@x@AA\eExbqHAJcf =@z=#g@y@~!\""@BhBXB0+BJi B@Bp J@x@f =AJj @EB4aJaJk =@p==J! l@@@S "ARmJqJ n B@Bt d@x@A ,oEPaR aRp =@P=lq@@ "#: @, K )".  C !+L "c  rAsrk s B@B  @x@A-AstEfasZasu = `%$`=$v@#@!s#@BwB"Bx B@B@x@AAJyE݀aJz =JJ$J! {@@J "dAR|JJ$ } B@RB@x@A AR~ETa aR =RQW= '@-V@@Sb"$)`]K  xANFUF B@NB `@x@AANExaNaN =@̀="@.@ V!N B̀ B B@B@x@AAJEJaJ =JE`=J#@PD@ "BJCJ  B@RB@x@A ARE aR =R2R#a@~H' ;KSF!M305-Joyst3ck0`.` B@hBL @x@A"AhE*)1 =hcwh#h'@v@ pB<B B@JBN@x@AAJE&1a Jb =J="@@ *, _4AJ]JA# B@RB@x@A ARE4aR aR =Rc= RA@ ~R B B@BDJK @x@AAcasA! Q =5c  1&]@}3@,WJ2J NV B@NBV@x@A ARE퀈V  aR = = V!R]2W@@6WT\T\ : B@BB%E@x@AA\EGdbq N  a\ =@ =\&Q@w@~QB BQ B@BQ@x@AAJEdeaJQ  aJ =JM#f`=,n"J#@!@!, AJ$J  B@RB@x@A AREۀ aR =Rހ=RL@݀@@S" @` WuKw܀K¦ B@SB!@x@A ASEagbh SaS =@&=S#@@~:!S @ IBB B@BJ@x@AAJERhaJx =J3i`=J#@@!C"8)AJ J  B@RBI@x@A AREɀ b =RЀ=R#@3VI@2ˀ@ " @3Ikʀk0 B@sBJS@x@A-AsE|jb sas =A?A=s#s$@@~!s @ BB B@B@x@AAJEAkaJaJ =J^=J$@@ @{'%AJ5J Z B@RB@x@A ARElaRVaR =@ր=R#@Q@ @ B B B@B 5@x@AAJEsmaJaJ =J1n`=J#J"@M0@! BJ/J  B@RB@x@A AREꀈ ;aR =R= Rb\Rp@@@~; ZB B@B B@x@AA+obw 1: 8a = )$ q`= @@ "BVJJ  B@NB@x@A ARE RA@aR =@=R$V@ـ@' @Q }@'K u&5F 0 1 2 5u%F;e 9Beu %E ) ^a@G[ 1! B@B 4@x@ADAEErbj a ==f@@ 6(!{& !]A] a!! Ame *m B@mB :m@x@A'AmEOsaml =mc t`=m"@ @ u" @ B;B B@JB@x@AAJEƀQ> !.=-`@<Li@k-|axTk,,? L8=5D k u7`=u - A#@@ @ @ @`@(_' @# `@ @   )   !@   / @8Bitd  @B5!! P@8@@ A ` " `g XG@  a>ABAE"}% @HZ`i `n@8!`$`M a@I@;@c1`M }Р"I@s`@ @E$ 1 @5i&A]fwupd-1.0.6/plugins/ebitdo/ebitdo.quirk000066400000000000000000000014011325145456600201240ustar00rootroot00000000000000[FuEbitdoDevice] # bootloader USB\VID_0483&PID_5750=bootloader USB\VID_2DC8&PID_5750=bootloader # FC30 USB\VID_1235&PID_AB11=none USB\VID_2DC8&PID_AB11=none # NES30 USB\VID_1235&PID_AB12=none USB\VID_2DC8&PID_AB12=none # SFC30 USB\VID_1235&PID_AB21=none USB\VID_2DC8&PID_AB21=none # SNES30 USB\VID_1235&PID_AB20=none USB\VID_2DC8&PID_AB20=none # FC30PRO USB\VID_1002&PID_9000=none USB\VID_2DC8&PID_9000=none # NES30PRO USB\VID_2002&PID_9000=none USB\VID_2DC8&PID_9001=none # FC30_ARCADE USB\VID_8000&PID_1002=none USB\VID_2DC8&PID_1002=none # SF30 PRO/SN30 PRO ## Nintendo Switch mode (Start + Y) USB\VID_057E&PID_2009=none ## Dinput mode (Start + B) USB\VID_2DC8&PID_6000=none USB\VID_2DC8&PID_6001=none ## Xinput mode (Start + X) USB\VID_045E&PID_028E=none fwupd-1.0.6/plugins/ebitdo/fu-ebitdo-common.c000066400000000000000000000073641325145456600211270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-ebitdo-common.h" const gchar * fu_ebitdo_pkt_type_to_string (FuEbitdoPktType cmd) { if (cmd == FU_EBITDO_PKT_TYPE_USER_CMD) return "user-cmd"; if (cmd == FU_EBITDO_PKT_TYPE_USER_DATA) return "user-data"; if (cmd == FU_EBITDO_PKT_TYPE_MID_CMD) return "mid-cmd"; return NULL; } const gchar * fu_ebitdo_pkt_cmd_to_string (FuEbitdoPktCmd cmd) { if (cmd == FU_EBITDO_PKT_CMD_FW_UPDATE_DATA) return "fw-update-data"; if (cmd == FU_EBITDO_PKT_CMD_FW_UPDATE_HEADER) return "fw-update-header"; if (cmd == FU_EBITDO_PKT_CMD_FW_UPDATE_OK) return "fw-update-ok"; if (cmd == FU_EBITDO_PKT_CMD_FW_UPDATE_ERROR) return "fw-update-error"; if (cmd == FU_EBITDO_PKT_CMD_FW_GET_VERSION) return "fw-get-version"; if (cmd == FU_EBITDO_PKT_CMD_FW_SET_VERSION) return "fw-set-version"; if (cmd == FU_EBITDO_PKT_CMD_FW_SET_ENCODE_ID) return "fw-set-encode-id"; if (cmd == FU_EBITDO_PKT_CMD_ACK) return "ack"; if (cmd == FU_EBITDO_PKT_CMD_NAK) return "nak"; if (cmd == FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA) return "update-firmware-data"; if (cmd == FU_EBITDO_PKT_CMD_TRANSFER_ABORT) return "transfer-abort"; if (cmd == FU_EBITDO_PKT_CMD_VERIFICATION_ID) return "verification-id"; if (cmd == FU_EBITDO_PKT_CMD_GET_VERIFICATION_ID) return "get-verification-id"; if (cmd == FU_EBITDO_PKT_CMD_VERIFY_ERROR) return "verify-error"; if (cmd == FU_EBITDO_PKT_CMD_VERIFY_OK) return "verify-ok"; if (cmd == FU_EBITDO_PKT_CMD_TRANSFER_TIMEOUT) return "transfer-timeout"; if (cmd == FU_EBITDO_PKT_CMD_GET_VERSION) return "get-version"; if (cmd == FU_EBITDO_PKT_CMD_GET_VERSION_RESPONSE) return "get-version-response"; return NULL; } void fu_ebitdo_dump_raw (const gchar *title, const guint8 *data, gsize len) { g_print ("%s:", title); for (gsize i = strlen (title); i < 16; i++) g_print (" "); for (gsize i = 0; i < len; i++) { g_print ("%02x ", data[i]); if (i > 0 && i % 32 == 0) g_print ("\n"); } g_print ("\n"); } void fu_ebitdo_dump_pkt (FuEbitdoPkt *hdr) { g_print ("PktLength: 0x%02x\n", hdr->pkt_len); g_print ("PktType: 0x%02x [%s]\n", hdr->type, fu_ebitdo_pkt_type_to_string (hdr->type)); g_print ("CmdSubtype: 0x%02x [%s]\n", hdr->subtype, fu_ebitdo_pkt_cmd_to_string (hdr->subtype)); g_print ("CmdLen: 0x%04x\n", GUINT16_FROM_LE (hdr->cmd_len)); g_print ("Cmd: 0x%02x [%s]\n", hdr->cmd, fu_ebitdo_pkt_cmd_to_string (hdr->cmd)); g_print ("Payload Len: 0x%04x\n", GUINT16_FROM_LE (hdr->payload_len)); } void fu_ebitdo_dump_firmware_header (FuEbitdoFirmwareHeader *hdr) { g_print ("Version: %.2f\n", (gdouble) GUINT32_FROM_LE (hdr->version) / 100.f); g_print ("Destination Address: %x\n", GUINT32_FROM_LE (hdr->destination_addr)); g_print ("Destination Length: %" G_GUINT32_FORMAT "\n", GUINT32_FROM_LE (hdr->destination_len)); } fwupd-1.0.6/plugins/ebitdo/fu-ebitdo-common.h000066400000000000000000000070741325145456600211320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_EBITDO_COMMON_H #define __FU_EBITDO_COMMON_H #include G_BEGIN_DECLS /* little endian */ typedef struct __attribute__((packed)) { guint32 version; guint32 destination_addr; guint32 destination_len; guint32 reserved[4]; } FuEbitdoFirmwareHeader; /* little endian */ typedef struct __attribute__((packed)) { guint8 pkt_len; guint8 type; /* FuEbitdoPktType */ guint8 subtype; /* FuEbitdoPktCmd */ guint16 cmd_len; guint8 cmd; /* FuEbitdoPktCmd */ guint16 payload_len; /* optional */ } FuEbitdoPkt; #define FU_EBITDO_USB_TIMEOUT 5000 /* ms */ #define FU_EBITDO_USB_BOOTLOADER_EP_IN 0x82 #define FU_EBITDO_USB_BOOTLOADER_EP_OUT 0x01 #define FU_EBITDO_USB_RUNTIME_EP_IN 0x81 #define FU_EBITDO_USB_RUNTIME_EP_OUT 0x02 #define FU_EBITDO_USB_EP_SIZE 64 /* bytes */ typedef enum { FU_EBITDO_PKT_TYPE_USER_CMD = 0x00, FU_EBITDO_PKT_TYPE_USER_DATA = 0x01, FU_EBITDO_PKT_TYPE_MID_CMD = 0x02, FU_EBITDO_PKT_TYPE_LAST } FuEbitdoPktType; /* commands */ typedef enum { FU_EBITDO_PKT_CMD_FW_UPDATE_DATA = 0x00, /* update firmware data */ FU_EBITDO_PKT_CMD_FW_UPDATE_HEADER = 0x01, /* update firmware header */ FU_EBITDO_PKT_CMD_FW_UPDATE_OK = 0x02, /* mark update as successful */ FU_EBITDO_PKT_CMD_FW_UPDATE_ERROR = 0x03, /* update firmware error */ FU_EBITDO_PKT_CMD_FW_GET_VERSION = 0x04, /* get cur firmware vision */ FU_EBITDO_PKT_CMD_FW_SET_VERSION = 0x05, /* set firmware version */ FU_EBITDO_PKT_CMD_FW_SET_ENCODE_ID = 0x06, /* set app firmware encode ID */ FU_EBITDO_PKT_CMD_ACK = 0x14, /* acknowledge */ FU_EBITDO_PKT_CMD_NAK = 0x15, /* negative acknowledge */ FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA = 0x16, /* update firmware data */ FU_EBITDO_PKT_CMD_TRANSFER_ABORT = 0x18, /* aborts transfer */ FU_EBITDO_PKT_CMD_VERIFICATION_ID = 0x19, /* verification id (only BT?) */ FU_EBITDO_PKT_CMD_GET_VERIFICATION_ID = 0x1a, /* verification id (only BT) */ FU_EBITDO_PKT_CMD_VERIFY_ERROR = 0x1b, /* verification error */ FU_EBITDO_PKT_CMD_VERIFY_OK = 0x1c, /* verification successful */ FU_EBITDO_PKT_CMD_TRANSFER_TIMEOUT = 0x1d, /* send or receive data timeout */ FU_EBITDO_PKT_CMD_GET_VERSION = 0x21, /* get fw ver, joystick mode */ FU_EBITDO_PKT_CMD_GET_VERSION_RESPONSE = 0x22, /* get fw version response */ FU_EBITDO_PKT_CMD_FW_LAST } FuEbitdoPktCmd; const gchar *fu_ebitdo_pkt_cmd_to_string (FuEbitdoPktCmd cmd); const gchar *fu_ebitdo_pkt_type_to_string (FuEbitdoPktType type); void fu_ebitdo_dump_firmware_header (FuEbitdoFirmwareHeader *hdr); void fu_ebitdo_dump_pkt (FuEbitdoPkt *hdr); void fu_ebitdo_dump_raw (const gchar *title, const guint8 *data, gsize len); #endif /* __FU_EBITDO_COMMON_H */ fwupd-1.0.6/plugins/ebitdo/fu-ebitdo-device.c000066400000000000000000000422511325145456600210700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "fu-ebitdo-common.h" #include "fu-ebitdo-device.h" typedef struct { gboolean is_bootloader; guint32 serial[9]; } FuEbitdoDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FuEbitdoDevice, fu_ebitdo_device, FU_TYPE_USB_DEVICE) #define GET_PRIVATE(o) (fu_ebitdo_device_get_instance_private (o)) gboolean fu_ebitdo_device_is_bootloader (FuEbitdoDevice *self) { FuEbitdoDevicePrivate *priv = GET_PRIVATE (self); return priv->is_bootloader; } static gboolean fu_ebitdo_device_send (FuEbitdoDevice *device, FuEbitdoPktType type, FuEbitdoPktCmd subtype, FuEbitdoPktCmd cmd, const guint8 *in, gsize in_len, GError **error) { FuEbitdoDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); guint8 packet[FU_EBITDO_USB_EP_SIZE] = {0}; gsize actual_length; guint8 ep_out = FU_EBITDO_USB_RUNTIME_EP_OUT; g_autoptr(GError) error_local = NULL; FuEbitdoPkt *hdr = (FuEbitdoPkt *) packet; /* different */ if (priv->is_bootloader) ep_out = FU_EBITDO_USB_BOOTLOADER_EP_OUT; /* check size */ if (in_len > 64 - 8) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "input buffer too large"); return FALSE; } /* packet[0] is the total length of the packet */ hdr->type = type; hdr->subtype = subtype; /* do we have a payload */ if (in_len > 0) { hdr->cmd_len = GUINT16_TO_LE (in_len + 3); hdr->cmd = cmd; hdr->payload_len = GUINT16_TO_LE (in_len); memcpy (packet + 0x08, in, in_len); hdr->pkt_len = (guint8) (in_len + 7); } else { hdr->cmd_len = GUINT16_TO_LE (in_len + 1); hdr->cmd = cmd; hdr->pkt_len = 5; } /* debug */ if (g_getenv ("FWUPD_EBITDO_VERBOSE") != NULL) { fu_ebitdo_dump_raw ("->DEVICE", packet, (gsize) hdr->pkt_len + 1); fu_ebitdo_dump_pkt (hdr); } /* get data from device */ if (!g_usb_device_interrupt_transfer (usb_device, ep_out, packet, FU_EBITDO_USB_EP_SIZE, &actual_length, FU_EBITDO_USB_TIMEOUT, NULL, /* cancellable */ &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to send to device on ep 0x%02x: %s", (guint) FU_EBITDO_USB_BOOTLOADER_EP_OUT, error_local->message); return FALSE; } return TRUE; } static gboolean fu_ebitdo_device_receive (FuEbitdoDevice *device, guint8 *out, gsize out_len, GError **error) { FuEbitdoDevicePrivate *priv = GET_PRIVATE (device); GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); guint8 packet[FU_EBITDO_USB_EP_SIZE] = {0}; gsize actual_length; guint8 ep_in = FU_EBITDO_USB_RUNTIME_EP_IN; g_autoptr(GError) error_local = NULL; FuEbitdoPkt *hdr = (FuEbitdoPkt *) packet; /* different */ if (priv->is_bootloader) ep_in = FU_EBITDO_USB_BOOTLOADER_EP_IN; /* get data from device */ if (!g_usb_device_interrupt_transfer (usb_device, ep_in, packet, FU_EBITDO_USB_EP_SIZE, &actual_length, FU_EBITDO_USB_TIMEOUT, NULL, /* cancellable */ &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to retrieve from device on ep 0x%02x: %s", (guint) FU_EBITDO_USB_BOOTLOADER_EP_IN, error_local->message); return FALSE; } /* debug */ if (g_getenv ("FWUPD_EBITDO_VERBOSE") != NULL) { fu_ebitdo_dump_raw ("<-DEVICE", packet, actual_length); fu_ebitdo_dump_pkt (hdr); } /* get-version (booloader) */ if (hdr->type == FU_EBITDO_PKT_TYPE_USER_CMD && hdr->subtype == FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA && hdr->cmd == FU_EBITDO_PKT_CMD_FW_GET_VERSION) { if (out != NULL) { if (hdr->payload_len != out_len) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "outbuf size wrong, expected %" G_GSIZE_FORMAT " got %u", out_len, hdr->payload_len); return FALSE; } memcpy (out, packet + sizeof(FuEbitdoPkt), hdr->payload_len); } return TRUE; } /* get-version (firmware) -- not a packet, just raw data! */ if (hdr->pkt_len == FU_EBITDO_PKT_CMD_GET_VERSION_RESPONSE) { if (out != NULL) { if (out_len != 4) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "outbuf size wrong, expected 4 got %" G_GSIZE_FORMAT, out_len); return FALSE; } memcpy (out, packet + 1, 4); } return TRUE; } /* verification-id response */ if (hdr->type == FU_EBITDO_PKT_TYPE_USER_CMD && hdr->subtype == FU_EBITDO_PKT_CMD_VERIFICATION_ID) { if (out != NULL) { if (hdr->cmd_len != out_len) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "outbuf size wrong, expected %" G_GSIZE_FORMAT " got %i", out_len, hdr->cmd_len); return FALSE; } memcpy (out, packet + sizeof(FuEbitdoPkt) - 3, hdr->cmd_len); } return TRUE; } /* update-firmware-data */ if (hdr->type == FU_EBITDO_PKT_TYPE_USER_CMD && hdr->subtype == FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA && hdr->payload_len == 0x00) { if (hdr->cmd != FU_EBITDO_PKT_CMD_ACK) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "write failed, got %s", fu_ebitdo_pkt_cmd_to_string (hdr->cmd)); return FALSE; } return TRUE; } /* unhandled */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "unexpected device response"); return FALSE; } static void fu_ebitdo_device_set_version (FuEbitdoDevice *device, guint32 version) { g_autofree gchar *tmp = NULL; tmp = g_strdup_printf ("%.2f", version / 100.f); fu_device_set_version (FU_DEVICE (device), tmp); } static gboolean fu_ebitdo_device_validate (FuEbitdoDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (device)); guint8 idx; g_autofree gchar *ven = NULL; const gchar *whitelist[] = { "8Bitdo", "SFC30", NULL }; /* this is a new, always valid, VID */ if (g_usb_device_get_vid (usb_device) == 0x2dc8) return TRUE; /* SF30/SN30 Pro when started with "START + Y" * Emulates a "Nintendo Switch Pro Controller" * "Real" Nintendo Switch controllers don't work over USB */ if (g_usb_device_get_vid (usb_device) == 0x057e && g_usb_device_get_pid (usb_device) == 0x2009) return TRUE; /* verify the vendor prefix against a whitelist */ idx = g_usb_device_get_manufacturer_index (usb_device); ven = g_usb_device_get_string_descriptor (usb_device, idx, error); if (ven == NULL) { g_prefix_error (error, "could not check vendor descriptor: "); return FALSE; } for (guint i = 0; whitelist[i] != NULL; i++) { if (g_str_has_prefix (ven, whitelist[i])) return TRUE; } g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "vendor '%s' did not match whitelist, " "probably not a 8Bitdo device…", ven); return FALSE; } static gboolean fu_ebitdo_device_open (FuUsbDevice *device, GError **error) { FuEbitdoDevice *self = FU_EBITDO_DEVICE (device); FuEbitdoDevicePrivate *priv = GET_PRIVATE (self); GUsbDevice *usb_device = fu_usb_device_get_dev (device); gdouble tmp; guint32 version_tmp = 0; guint32 serial_tmp[9] = {0}; /* open, then ensure this is actually 8Bitdo hardware */ if (!fu_ebitdo_device_validate (self, error)) return FALSE; if (!g_usb_device_claim_interface (usb_device, 0, /* 0 = idx? */ G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { return FALSE; } /* in firmware mode */ if (!priv->is_bootloader) { if (!fu_ebitdo_device_send (self, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_GET_VERSION, 0, NULL, 0, /* in */ error)) { return FALSE; } if (!fu_ebitdo_device_receive (self, (guint8 *) &version_tmp, sizeof(version_tmp), error)) { return FALSE; } tmp = (gdouble) GUINT32_FROM_LE (version_tmp); fu_ebitdo_device_set_version (self, tmp); return TRUE; } /* get version */ if (!fu_ebitdo_device_send (self, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA, FU_EBITDO_PKT_CMD_FW_GET_VERSION, NULL, 0, /* in */ error)) { return FALSE; } if (!fu_ebitdo_device_receive (self, (guint8 *) &version_tmp, sizeof(version_tmp), error)) { return FALSE; } tmp = (gdouble) GUINT32_FROM_LE (version_tmp); fu_ebitdo_device_set_version (self, tmp); /* get verification ID */ if (!fu_ebitdo_device_send (self, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_GET_VERIFICATION_ID, 0x00, /* cmd */ NULL, 0, error)) { return FALSE; } if (!fu_ebitdo_device_receive (self, (guint8 *) &serial_tmp, sizeof(serial_tmp), error)) { return FALSE; } for (guint i = 0; i < 9; i++) priv->serial[i] = GUINT32_FROM_LE (serial_tmp[i]); /* success */ return TRUE; } const guint32 * fu_ebitdo_device_get_serial (FuEbitdoDevice *device) { FuEbitdoDevicePrivate *priv = GET_PRIVATE (device); return priv->serial; } gboolean fu_ebitdo_device_write_firmware (FuEbitdoDevice *device, GBytes *fw, GError **error) { FuEbitdoDevicePrivate *priv = GET_PRIVATE (device); FuEbitdoFirmwareHeader *hdr; const guint8 *payload_data; const guint chunk_sz = 32; guint32 payload_len; guint32 serial_new[3]; g_autoptr(GError) error_local = NULL; const guint32 app_key_index[16] = { 0x186976e5, 0xcac67acd, 0x38f27fee, 0x0a4948f1, 0xb75b7753, 0x1f8ffa5c, 0xbff8cf43, 0xc4936167, 0x92bd03f0, 0x5573c6ed, 0x57d8845b, 0x827197ac, 0xb91901c9, 0x3917edfe, 0xbcd6344f, 0xcf9e23b5 }; /* corrupt */ if (g_bytes_get_size (fw) < sizeof (FuEbitdoFirmwareHeader)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware too small for header"); return FALSE; } /* print details about the firmware */ hdr = (FuEbitdoFirmwareHeader *) g_bytes_get_data (fw, NULL); fu_ebitdo_dump_firmware_header (hdr); /* check the file size */ payload_len = (guint32) (g_bytes_get_size (fw) - sizeof (FuEbitdoFirmwareHeader)); if (payload_len != GUINT32_FROM_LE (hdr->destination_len)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "file size incorrect, expected 0x%04x got 0x%04x", (guint) GUINT32_FROM_LE (hdr->destination_len), (guint) payload_len); return FALSE; } /* check if this is firmware */ for (guint i = 0; i < 4; i++) { if (hdr->reserved[i] != 0x0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "data invalid, reserved[%u] = 0x%04x", i, hdr->reserved[i]); return FALSE; } } /* set up the firmware header */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_DEVICE_WRITE); if (!fu_ebitdo_device_send (device, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA, FU_EBITDO_PKT_CMD_FW_UPDATE_HEADER, (const guint8 *) hdr, sizeof(FuEbitdoFirmwareHeader), &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to set up firmware header: %s", error_local->message); return FALSE; } if (!fu_ebitdo_device_receive (device, NULL, 0, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to get ACK for fw update header: %s", error_local->message); return FALSE; } /* flash the firmware in 32 byte blocks */ payload_data = g_bytes_get_data (fw, NULL); payload_data += sizeof(FuEbitdoFirmwareHeader); for (guint32 offset = 0; offset < payload_len; offset += chunk_sz) { if (g_getenv ("FWUPD_EBITDO_VERBOSE") != NULL) { g_debug ("writing %u bytes to 0x%04x of 0x%04x", chunk_sz, offset, payload_len); } fu_device_set_progress_full (FU_DEVICE (device), offset, payload_len); if (!fu_ebitdo_device_send (device, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA, FU_EBITDO_PKT_CMD_FW_UPDATE_DATA, payload_data + offset, chunk_sz, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to write firmware @0x%04x: %s", offset, error_local->message); return FALSE; } if (!fu_ebitdo_device_receive (device, NULL, 0, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to get ACK for write firmware @0x%04x: %s", offset, error_local->message); return FALSE; } } /* mark as complete */ fu_device_set_progress_full (FU_DEVICE (device), payload_len, payload_len); /* set the "encode id" which is likely a checksum, bluetooth pairing * or maybe just security-through-obscurity -- also note: * SET_ENCODE_ID enforces no read for success?! */ serial_new[0] = priv->serial[0] ^ app_key_index[priv->serial[0] & 0x0f]; serial_new[1] = priv->serial[1] ^ app_key_index[priv->serial[1] & 0x0f]; serial_new[2] = priv->serial[2] ^ app_key_index[priv->serial[2] & 0x0f]; if (!fu_ebitdo_device_send (device, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA, FU_EBITDO_PKT_CMD_FW_SET_ENCODE_ID, (guint8 *) serial_new, sizeof(serial_new), &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to set encoding ID: %s", error_local->message); return FALSE; } /* mark flash as successful */ if (!fu_ebitdo_device_send (device, FU_EBITDO_PKT_TYPE_USER_CMD, FU_EBITDO_PKT_CMD_UPDATE_FIRMWARE_DATA, FU_EBITDO_PKT_CMD_FW_UPDATE_OK, NULL, 0, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to mark firmware as successful: %s", error_local->message); return FALSE; } if (!fu_ebitdo_device_receive (device, NULL, 0, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to get ACK for mark firmware as successful: %s", error_local->message); return FALSE; } /* success! */ fu_device_set_status (FU_DEVICE (device), FWUPD_STATUS_IDLE); return TRUE; } static gboolean fu_ebitdo_device_probe (FuUsbDevice *device, GError **error) { FuEbitdoDevice *self = FU_EBITDO_DEVICE (device); FuEbitdoDevicePrivate *priv = GET_PRIVATE (self); const gchar *quirk_str; /* devices have to be whitelisted */ quirk_str = fu_device_get_plugin_hints (FU_DEVICE (device)); if (quirk_str == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported with this device"); return FALSE; } priv->is_bootloader = g_strcmp0 (quirk_str, "bootloader") == 0; /* allowed, but requires manual bootloader step */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_remove_delay (FU_DEVICE (device), FU_DEVICE_REMOVE_DELAY_USER_REPLUG); /* set name and vendor */ fu_device_set_summary (FU_DEVICE (device), "A redesigned classic game controller"); fu_device_set_vendor (FU_DEVICE (device), "8Bitdo"); /* add a hardcoded icon name */ fu_device_add_icon (FU_DEVICE (device), "input-gaming"); /* only the bootloader can do the update */ if (!priv->is_bootloader) { fu_device_add_guid (FU_DEVICE (device), "USB\\VID_0483&PID_5750"); fu_device_add_guid (FU_DEVICE (device), "USB\\VID_2DC8&PID_5750"); fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); } else { fu_device_remove_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); } /* success */ return TRUE; } static void fu_ebitdo_device_init (FuEbitdoDevice *device) { } static void fu_ebitdo_device_class_init (FuEbitdoDeviceClass *klass) { FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); klass_usb_device->open = fu_ebitdo_device_open; klass_usb_device->probe = fu_ebitdo_device_probe; } /** * fu_ebitdo_device_new: * * Creates a new #FuEbitdoDevice. * * Returns: (transfer full): a #FuEbitdoDevice, or %NULL if not a game pad * * Since: 0.1.0 **/ FuEbitdoDevice * fu_ebitdo_device_new (GUsbDevice *usb_device) { FuEbitdoDevice *device; device = g_object_new (FU_TYPE_EBITDO_DEVICE, "usb-device", usb_device, NULL); return FU_EBITDO_DEVICE (device); } fwupd-1.0.6/plugins/ebitdo/fu-ebitdo-device.h000066400000000000000000000032661325145456600211000ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_EBITDO_DEVICE_H #define __FU_EBITDO_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_EBITDO_DEVICE (fu_ebitdo_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuEbitdoDevice, fu_ebitdo_device, FU, EBITDO_DEVICE, FuUsbDevice) struct _FuEbitdoDeviceClass { FuUsbDeviceClass parent_class; }; FuEbitdoDevice *fu_ebitdo_device_new (GUsbDevice *usb_device); /* getters */ gboolean fu_ebitdo_device_is_bootloader (FuEbitdoDevice *device); const guint32 *fu_ebitdo_device_get_serial (FuEbitdoDevice *device); /* object methods */ gboolean fu_ebitdo_device_write_firmware (FuEbitdoDevice *device, GBytes *fw, GError **error); G_END_DECLS #endif /* __FU_EBITDO_DEVICE_H */ fwupd-1.0.6/plugins/ebitdo/fu-ebitdo-tool.c000066400000000000000000000112011325145456600205750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-ebitdo-common.h" #include "fu-ebitdo-device.h" static void fu_ebitdo_tool_progress_cb (FuDevice *device, GParamSpec *pspec, gpointer user_data) { g_print ("Written %u%%\n", fu_device_get_progress (device)); } int main (int argc, char **argv) { gsize len; g_autofree guint8 *data = NULL; g_autoptr(FuEbitdoDevice) dev = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuQuirks) quirks = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(GError) error = NULL; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GUsbContext) usb_ctx = NULL; g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); /* require filename */ if (argc != 2) { g_print ("USAGE: %s \n", argv[0]); return 1; } /* use quirks */ quirks = fu_quirks_new (); if (!fu_quirks_load (quirks, &error)) { g_print ("Failed to load quirks: %s\n", error->message); return 1; } /* get the device */ usb_ctx = g_usb_context_new (&error); if (usb_ctx == NULL) { g_print ("Failed to open USB devices: %s\n", error->message); return 1; } g_usb_context_enumerate (usb_ctx); devices = g_usb_context_get_devices (usb_ctx); for (guint i = 0; i < devices->len; i++) { GUsbDevice *usb_device = g_ptr_array_index (devices, i); g_autoptr(FuEbitdoDevice) dev_tmp = fu_ebitdo_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (dev_tmp), quirks); if (fu_usb_device_probe (FU_USB_DEVICE (dev_tmp), NULL)) { dev = g_steal_pointer (&dev_tmp); break; } } /* nothing supported */ if (dev == NULL) { g_print ("No supported device plugged in!\n"); return 1; } /* open device */ locker = fu_device_locker_new (dev, &error); if (locker == NULL) { g_print ("Failed to open USB device: %s\n", error->message); return 1; } g_print ("Device Firmware Ver: %s\n", fu_device_get_version (FU_DEVICE (dev))); g_print ("Device Verification ID:\n"); for (guint i = 0; i < 9; i++) g_print ("\t%u = 0x%08x\n", i, fu_ebitdo_device_get_serial(dev)[i]); /* not in bootloader mode, so print what to do */ if (fu_device_has_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER)) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (dev)); g_print ("1. Disconnect the controller\n"); switch (g_usb_device_get_pid (usb_device)) { case 0xab11: /* FC30 */ case 0xab12: /* NES30 */ case 0xab21: /* SFC30 */ case 0xab20: /* SNES30 */ g_print ("2. Hold down L+R+START for 3 seconds until " "both LED lights flashing.\n"); break; case 0x9000: /* FC30PRO */ case 0x9001: /* NES30PRO */ g_print ("2. Hold down RETURN+POWER for 3 seconds until " "both LED lights flashing.\n"); break; case 0x1002: /* FC30-ARCADE */ g_print ("2. Hold down L1+R1+HOME for 3 seconds until " "both blue LED and green LED blink.\n"); break; case 0x2009: /* SF30/SN30 pro: switch mode */ case 0x6000: /* SF30 pro: Dinput mode */ case 0x6001: /* SN30 pro: Dinput mode */ case 0x028e: /* SF30/SN30 pro: Xinput mode */ g_print ("2. Press and hold L1+R1+START for 3 seconds " "until the LED on top blinks red.\n"); break; default: g_print ("2. Do what it says in the manual.\n"); break; } g_print ("3. Connect controller\n"); return 1; } /* load firmware file */ if (!g_file_get_contents (argv[1], (gchar **) &data, &len, &error)) { g_print ("Failed to load file: %s\n", error->message); return 1; } /* update with data blob */ fw = g_bytes_new (data, len); g_signal_connect (dev, "notify::progress", G_CALLBACK (fu_ebitdo_tool_progress_cb), NULL); if (!fu_ebitdo_device_write_firmware (dev, fw, &error)) { g_print ("Failed to write firmware: %s\n", error->message); return 1; } /* success */ g_print ("Now turn off the controller with the power button.\n"); return 0; } fwupd-1.0.6/plugins/ebitdo/fu-plugin-ebitdo.c000066400000000000000000000064171325145456600211330ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-ebitdo-device.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuEbitdoDevice) device = NULL; /* open the device */ device = fu_ebitdo_device_new (usb_device); fu_device_set_quirks (FU_DEVICE (device), fu_plugin_get_quirks (plugin)); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* success */ fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (dev)); FuEbitdoDevice *ebitdo_dev = FU_EBITDO_DEVICE (dev); g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(GUsbDevice) usb_device2 = NULL; /* get version */ if (!fu_ebitdo_device_is_bootloader (ebitdo_dev)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "invalid 8Bitdo device type detected"); return FALSE; } /* write the firmware */ locker = fu_device_locker_new (ebitdo_dev, error); if (locker == NULL) return FALSE; if (!fu_ebitdo_device_write_firmware (ebitdo_dev, blob_fw, error)) return FALSE; /* when doing a soft-reboot the device does not re-enumerate properly * so manually reboot the GUsbDevice */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); if (!g_usb_device_reset (usb_device, error)) { g_prefix_error (error, "failed to force-reset device: "); return FALSE; } g_clear_object (&locker); usb_device2 = g_usb_context_wait_for_replug (fu_plugin_get_usb_context (plugin), usb_device, 10000, error); if (usb_device2 == NULL) { g_prefix_error (error, "device did not come back: "); return FALSE; } fu_usb_device_set_dev (FU_USB_DEVICE (ebitdo_dev), usb_device2); /* success */ return TRUE; } gboolean fu_plugin_update_reload (FuPlugin *plugin, FuDevice *dev, GError **error) { FuEbitdoDevice *ebitdo_dev = FU_EBITDO_DEVICE (dev); g_autoptr(FuDeviceLocker) locker = NULL; /* get the new version number */ locker = fu_device_locker_new (ebitdo_dev, error); if (locker == NULL) { g_prefix_error (error, "failed to re-open device: "); return FALSE; } /* success */ return TRUE; } fwupd-1.0.6/plugins/ebitdo/meson.build000066400000000000000000000016121325145456600177470ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginEbitdo"'] install_data(['ebitdo.quirk'], install_dir: join_paths(datadir, 'fwupd', 'quirks.d') ) shared_module('fu_plugin_ebitdo', sources : [ 'fu-plugin-ebitdo.c', 'fu-ebitdo-common.c', 'fu-ebitdo-device.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], ) executable( 'fu-ebitdo-tool', sources : [ 'fu-ebitdo-tool.c', 'fu-ebitdo-common.c', 'fu-ebitdo-device.c', ], include_directories : [ include_directories('../..'), include_directories('../../libfwupd'), include_directories('../../src'), ], dependencies : [ plugin_deps, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs, ) fwupd-1.0.6/plugins/meson.build000066400000000000000000000011371325145456600165030ustar00rootroot00000000000000subdir('dfu') subdir('ebitdo') subdir('steelseries') subdir('nitrokey') subdir('test') subdir('udev') subdir('unifying') subdir('upower') # depends on dfu subdir('csr') if get_option('plugin_altos') subdir('altos') endif if get_option('plugin_amt') subdir('amt') endif if get_option('plugin_thunderbolt') and udev.found() subdir('thunderbolt') subdir('thunderbolt-power') endif if get_option('plugin_colorhug') subdir('colorhug') endif if get_option('plugin_dell') subdir('dell') endif if get_option('plugin_synaptics') subdir('synapticsmst') endif if get_option('plugin_uefi') subdir('uefi') endif fwupd-1.0.6/plugins/nitrokey/000077500000000000000000000000001325145456600162035ustar00rootroot00000000000000fwupd-1.0.6/plugins/nitrokey/README.md000066400000000000000000000005731325145456600174670ustar00rootroot00000000000000Nitrokey Support ================ Introduction ------------ This plugin is used to get the correct version number on Nitrokey storage devices. These devices have updatable firmware but so far no updates are available from the vendor. The device is switched to a DFU bootloader only when the secret firmware pin is entered into the nitrokey-app tool. This cannot be automated. fwupd-1.0.6/plugins/nitrokey/fu-nitrokey-common.c000066400000000000000000000032371325145456600221160ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-nitrokey-common.h" static guint32 fu_nitrokey_perform_crc32_mutate (guint32 crc, guint32 data) { crc = crc ^ data; for (guint i = 0; i < 32; i++) { if (crc & 0x80000000) { /* polynomial used in STM32 */ crc = (crc << 1) ^ 0x04C11DB7; } else { crc = (crc << 1); } } return crc; } guint32 fu_nitrokey_perform_crc32 (const guint8 *data, gsize size) { guint32 crc = 0xffffffff; g_autofree guint32 *data_aligned = NULL; data_aligned = g_new0 (guint32, (size / 4) + 1); memcpy (data_aligned, data, size); for (gsize idx = 0; idx * 4 < size; idx++) { guint32 data_aligned_le = GUINT32_FROM_LE (data_aligned[idx]); crc = fu_nitrokey_perform_crc32_mutate (crc, data_aligned_le); } return crc; } fwupd-1.0.6/plugins/nitrokey/fu-nitrokey-common.h000066400000000000000000000021741325145456600221220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_NITROKEY_COMMON_H #define __FU_NITROKEY_COMMON_H #include G_BEGIN_DECLS guint32 fu_nitrokey_perform_crc32 (const guint8 *data, gsize size); G_END_DECLS #endif /* __FU_NITROKEY_COMMON_H */ fwupd-1.0.6/plugins/nitrokey/fu-nitrokey-device.c000066400000000000000000000234101325145456600220600ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "fu-nitrokey-common.h" #include "fu-nitrokey-device.h" G_DEFINE_TYPE (FuNitrokeyDevice, fu_nitrokey_device, FU_TYPE_USB_DEVICE) #define NITROKEY_TRANSACTION_TIMEOUT 100 /* ms */ #define NITROKEY_NR_RETRIES 5 #define NITROKEY_REQUEST_DATA_LENGTH 59 #define NITROKEY_REPLY_DATA_LENGTH 53 #define NITROKEY_CMD_GET_DEVICE_STATUS (0x20 + 14) typedef struct __attribute__((packed)) { guint8 command; guint8 payload[NITROKEY_REQUEST_DATA_LENGTH]; guint32 crc; } NitrokeyHidRequest; typedef struct __attribute__((packed)) { guint8 _padding; /* always zero */ guint8 device_status; guint32 last_command_crc; guint8 last_command_status; guint8 payload[NITROKEY_REPLY_DATA_LENGTH]; guint32 crc; } NitrokeyHidResponse; /* based from libnitrokey/stick20_commands.h */ typedef struct __attribute__((packed)) { guint8 _padding[24]; guint8 SendCounter; guint8 SendDataType; guint8 FollowBytesFlag; guint8 SendSize; guint16 MagicNumber_StickConfig; guint8 ReadWriteFlagUncryptedVolume; guint8 ReadWriteFlagCryptedVolume; guint8 VersionReserved1; guint8 VersionMinor; guint8 VersionReserved2; guint8 VersionMajor; guint8 ReadWriteFlagHiddenVolume; guint8 FirmwareLocked; guint8 NewSDCardFound; guint8 SDFillWithRandomChars; guint32 ActiveSD_CardID; guint8 VolumeActiceFlag; guint8 NewSmartCardFound; guint8 UserPwRetryCount; guint8 AdminPwRetryCount; guint32 ActiveSmartCardID; guint8 StickKeysNotInitiated; } NitrokeyGetDeviceStatusPayload; static void _dump_to_console (const gchar *title, const guint8 *buf, gsize buf_sz) { if (g_getenv ("FWUPD_NITROKEY_VERBOSE") == NULL) return; g_debug ("%s", title); for (gsize i = 0; i < buf_sz; i++) g_debug ("%" G_GSIZE_FORMAT "=0x%02x", i, buf[i]); } static gboolean nitrokey_execute_cmd (GUsbDevice *usb_device, guint8 command, const guint8 *buf_in, gsize buf_in_sz, guint8 *buf_out, gsize buf_out_sz, GCancellable *cancellable, GError **error) { NitrokeyHidResponse res; gboolean ret; gsize actual_len = 0; guint32 crc_tmp; guint8 buf[64]; g_return_val_if_fail (buf_in_sz <= NITROKEY_REQUEST_DATA_LENGTH, FALSE); g_return_val_if_fail (buf_out_sz <= NITROKEY_REPLY_DATA_LENGTH, FALSE); /* create the request */ memset (buf, 0x00, sizeof(buf)); buf[0] = command; if (buf_in != NULL) memcpy (&buf[1], buf_in, buf_in_sz); crc_tmp = fu_nitrokey_perform_crc32 (buf, sizeof(buf) - 4); fu_common_write_uint32 (&buf[NITROKEY_REQUEST_DATA_LENGTH + 1], crc_tmp, G_LITTLE_ENDIAN); /* send request */ _dump_to_console ("request", buf, sizeof(buf)); ret = g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, 0x09, 0x0300, 0x0002, buf, sizeof(buf), &actual_len, NITROKEY_TRANSACTION_TIMEOUT, NULL, error); if (!ret) { g_prefix_error (error, "failed to do HOST_TO_DEVICE: "); return FALSE; } if (actual_len != sizeof(buf)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "only wrote %" G_GSIZE_FORMAT "bytes", actual_len); return FALSE; } /* get response */ memset (buf, 0x00, sizeof(buf)); ret = g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_DEVICE_TO_HOST, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, 0x01, 0x0300, 0x0002, buf, sizeof(buf), &actual_len, NITROKEY_TRANSACTION_TIMEOUT, NULL, error); if (!ret) { g_prefix_error (error, "failed to do DEVICE_TO_HOST: "); return FALSE; } if (actual_len != sizeof(res)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "only wrote %" G_GSIZE_FORMAT "bytes", actual_len); return FALSE; } _dump_to_console ("response", buf, sizeof(buf)); /* verify this is the answer to the question we asked */ memcpy (&res, buf, sizeof(buf)); if (GUINT32_FROM_LE (res.last_command_crc) != crc_tmp) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "got response CRC %x, expected %x", GUINT32_FROM_LE (res.last_command_crc), crc_tmp); return FALSE; } /* verify the response checksum */ crc_tmp = fu_nitrokey_perform_crc32 (buf, sizeof(res) - 4); if (GUINT32_FROM_LE (res.crc) != crc_tmp) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "got packet CRC %x, expected %x", GUINT32_FROM_LE (res.crc), crc_tmp); return FALSE; } /* copy out the payload */ if (buf_out != NULL) memcpy (buf_out, &res.payload, buf_out_sz); /* success */ return TRUE; } static gboolean nitrokey_execute_cmd_full (GUsbDevice *usb_device, guint8 command, const guint8 *buf_in, gsize buf_in_sz, guint8 *buf_out, gsize buf_out_sz, GCancellable *cancellable, GError **error) { for (guint i = 0; i < NITROKEY_NR_RETRIES; i++) { g_autoptr(GError) error_local = NULL; gboolean ret; ret = nitrokey_execute_cmd (usb_device, command, buf_in, buf_in_sz, buf_out, buf_out_sz, cancellable, &error_local); if (ret) return TRUE; if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_FAILED)) { if (error != NULL) *error = g_steal_pointer (&error_local); return FALSE; } g_warning ("retrying command: %s", error_local->message); g_usleep (100 * 1000); } /* failed */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to issue command after %i retries", NITROKEY_NR_RETRIES); return FALSE; } static gboolean fu_nitrokey_device_probe (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); /* not the right kind of device */ if (g_usb_device_get_vid (usb_device) != 0x20a0 || g_usb_device_get_pid (usb_device) != 0x4109) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported with this device"); return FALSE; } /* harcoded */ fu_device_set_name (FU_DEVICE (device), "Nitrokey Storage"); fu_device_set_vendor (FU_DEVICE (device), "Nitrokey"); fu_device_set_summary (FU_DEVICE (device), "A secure memory stick"); fu_device_add_icon (FU_DEVICE (device), "media-removable"); /* also add the USB VID:PID hash of the bootloader */ fu_device_add_guid (FU_DEVICE (device), "USB\\VID_03EB&PID_2FF1"); fu_device_set_remove_delay (FU_DEVICE (device), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE); /* allowed, but requires manual bootloader step */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER); fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION); /* success */ return TRUE; } static gboolean fu_nitrokey_device_open (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); NitrokeyGetDeviceStatusPayload payload; guint8 buf_reply[NITROKEY_REPLY_DATA_LENGTH]; g_autofree gchar *version = NULL; /* claim interface */ if (!g_usb_device_claim_interface (usb_device, 0x02, /* idx */ G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "failed to do claim nitrokey: "); return FALSE; } /* get firmware version */ if (!nitrokey_execute_cmd_full (usb_device, NITROKEY_CMD_GET_DEVICE_STATUS, NULL, 0, buf_reply, sizeof(buf_reply), NULL, error)) { g_prefix_error (error, "failed to do get firmware version: "); return FALSE; } _dump_to_console ("payload", buf_reply, sizeof(buf_reply)); memcpy (&payload, buf_reply, sizeof(buf_reply)); version = g_strdup_printf ("%u.%u", payload.VersionMinor, payload.VersionMajor); fu_device_set_version (FU_DEVICE (device), version); /* success */ return TRUE; } static gboolean fu_nitrokey_device_close (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); g_autoptr(GError) error_local = NULL; /* reconnect kernel driver */ if (!g_usb_device_release_interface (usb_device, 0x02, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, &error_local)) { g_warning ("failed to release interface: %s", error_local->message); } return TRUE; } static void fu_nitrokey_device_init (FuNitrokeyDevice *device) { } static void fu_nitrokey_device_class_init (FuNitrokeyDeviceClass *klass) { FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); klass_usb_device->open = fu_nitrokey_device_open; klass_usb_device->close = fu_nitrokey_device_close; klass_usb_device->probe = fu_nitrokey_device_probe; } FuNitrokeyDevice * fu_nitrokey_device_new (GUsbDevice *usb_device) { FuNitrokeyDevice *device; device = g_object_new (FU_TYPE_NITROKEY_DEVICE, "usb-device", usb_device, NULL); return FU_NITROKEY_DEVICE (device); } fwupd-1.0.6/plugins/nitrokey/fu-nitrokey-device.h000066400000000000000000000026521325145456600220720ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_NITROKEY_DEVICE_H #define __FU_NITROKEY_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_NITROKEY_DEVICE (fu_nitrokey_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuNitrokeyDevice, fu_nitrokey_device, FU, NITROKEY_DEVICE, FuUsbDevice) struct _FuNitrokeyDeviceClass { FuUsbDeviceClass parent_class; }; FuNitrokeyDevice *fu_nitrokey_device_new (GUsbDevice *usb_device); G_END_DECLS #endif /* __FU_NITROKEY_DEVICE_H */ fwupd-1.0.6/plugins/nitrokey/fu-plugin-nitrokey.c000066400000000000000000000027151325145456600221240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-nitrokey-device.h" #include "fu-nitrokey-common.h" gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuNitrokeyDevice) device = NULL; /* open the device */ device = fu_nitrokey_device_new (usb_device); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; /* success */ fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } fwupd-1.0.6/plugins/nitrokey/fu-self-test.c000066400000000000000000000031031325145456600206620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include "fu-nitrokey-common.h" static void fu_nitrokey_func (void) { const guint8 buf[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; g_assert_cmpint (fu_nitrokey_perform_crc32 (buf, 16), ==, 0x081B46CA); g_assert_cmpint (fu_nitrokey_perform_crc32 (buf, 15), ==, 0xED7320AB); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); /* tests go here */ g_test_add_func ("/fwupd/nitrokey", fu_nitrokey_func); return g_test_run (); } fwupd-1.0.6/plugins/nitrokey/lsusb.txt000066400000000000000000000165571325145456600201120ustar00rootroot00000000000000Bus 001 Device 007: ID 20a0:4109 Clay Logic Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x20a0 Clay Logic idProduct 0x4109 bcdDevice 1.00 iManufacturer 1 Nitrokey iProduct 2 Nitrokey Storage iSerial 3 0000000000000 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 141 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 11 Chip/SmartCard bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 ChipCard Interface Descriptor: bLength 54 bDescriptorType 33 bcdCCID 1.10 (Warning: Only accurate for version 1.0) nMaxSlotIndex 0 bVoltageSupport 2 3.0V dwProtocols 2 T=1 dwDefaultClock 3600 dwMaxiumumClock 3600 bNumClockSupported 0 dwDataRate 9677 bps dwMaxDataRate 116129 bps bNumDataRatesSupp. 0 dwMaxIFSD 261 dwSyncProtocols 00000000 dwMechanical 00000000 dwFeatures 000104BA Auto configuration based on ATR Auto voltage selection Auto clock change Auto baud rate change Auto PPS made by CCID Auto IFSD exchange TPDU level exchange dwMaxCCIDMsgLen 271 bClassGetResponse 00 bClassEnvelope 00 wlcdLayout none bPINSupport 0 bMaxCCIDBusySlots 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0010 1x 16 bytes bInterval 16 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x85 EP 5 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 71 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x86 EP 6 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 Device Status: 0x0000 (Bus Powered) Bus 001 Device 055: ID 03eb:2ff1 Atmel Corp. at32uc3a3 DFU bootloader Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x03eb Atmel Corp. idProduct 0x2ff1 at32uc3a3 DFU bootloader bcdDevice 10.00 iManufacturer 1 ATMEL iProduct 2 AT32UC3A DFU iSerial 3 1.0.3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 27 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xc0 Self Powered MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 254 Application Specific Interface bInterfaceSubClass 1 Device Firmware Update bInterfaceProtocol 2 iInterface 0 Device Firmware Upgrade Interface Descriptor: bLength 9 bDescriptorType 33 bmAttributes 15 Will Detach Manifestation Tolerant Upload Supported Download Supported wDetachTimeout 0 milliseconds wTransferSize 65535 bytes bcdDFUVersion 1.01 Device Status: 0x0001 Self Powered fwupd-1.0.6/plugins/nitrokey/meson.build000066400000000000000000000015741325145456600203540ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginNitrokey"'] shared_module('fu_plugin_nitrokey', sources : [ 'fu-nitrokey-device.c', 'fu-nitrokey-common.c', 'fu-plugin-nitrokey.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], ) if get_option('tests') e = executable( 'nitrokey-self-test', sources : [ 'fu-nitrokey-common.c', 'fu-self-test.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, valgrind, ], link_with : [ libfwupdprivate, ], ) test('nitrokey-self-test', e) endif fwupd-1.0.6/plugins/steelseries/000077500000000000000000000000001325145456600166665ustar00rootroot00000000000000fwupd-1.0.6/plugins/steelseries/README.md000066400000000000000000000003561325145456600201510ustar00rootroot00000000000000SteelSeries Support =================== Introduction ------------ This plugin is used to get the correct version number on SteelSeries gaming mice. These mice have updatable firmware but so far no updates are available from the vendor. fwupd-1.0.6/plugins/steelseries/fu-plugin-steelseries.c000066400000000000000000000026231325145456600232700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-steelseries-device.h" gboolean fu_plugin_usb_device_added (FuPlugin *plugin, GUsbDevice *usb_device, GError **error) { g_autoptr(FuSteelseriesDevice) device = NULL; g_autoptr(FuDeviceLocker) locker = NULL; device = fu_steelseries_device_new (usb_device); locker = fu_device_locker_new (device, error); if (locker == NULL) return FALSE; fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } fwupd-1.0.6/plugins/steelseries/fu-steelseries-device.c000066400000000000000000000114141325145456600232270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fu-steelseries-device.h" #define STEELSERIES_TRANSACTION_TIMEOUT 1000 /* ms */ G_DEFINE_TYPE (FuSteelseriesDevice, fu_steelseries_device, FU_TYPE_USB_DEVICE) static gboolean fu_steelseries_device_probe (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); /* not the right kind of device */ if (g_usb_device_get_vid (usb_device) != 0x1038 || g_usb_device_get_pid (usb_device) != 0x1702) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not supported with this device"); return FALSE; } /* hardcoded */ fu_device_set_name (FU_DEVICE (device), "SteelSeries Rival 100"); fu_device_set_vendor (FU_DEVICE (device), "SteelSeries"); fu_device_set_summary (FU_DEVICE (device), "An optical gaming mouse"); fu_device_add_icon (FU_DEVICE (device), "input-mouse"); /* success */ return TRUE; } static gboolean fu_steelseries_device_open (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); const guint8 iface_idx = 0x00; gboolean ret; gsize actual_len = 0; guint8 data[32]; g_autofree gchar *version = NULL; /* get firmware version on SteelSeries Rival 100 */ if (!g_usb_device_claim_interface (usb_device, iface_idx, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "failed to claim interface: "); return FALSE; } memset (data, 0x00, sizeof(data)); data[0] = 0x16; ret = g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, 0x09, 0x0200, 0x0000, data, sizeof(data), &actual_len, STEELSERIES_TRANSACTION_TIMEOUT, NULL, error); if (!ret) { g_prefix_error (error, "failed to do control transfer: "); return FALSE; } if (actual_len != 32) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "only wrote %" G_GSIZE_FORMAT "bytes", actual_len); return FALSE; } ret = g_usb_device_interrupt_transfer (usb_device, 0x81, /* EP1 IN */ data, sizeof(data), &actual_len, STEELSERIES_TRANSACTION_TIMEOUT, NULL, error); if (!ret) { g_prefix_error (error, "failed to do EP1 transfer: "); return FALSE; } if (actual_len != 32) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "only read %" G_GSIZE_FORMAT "bytes", actual_len); return FALSE; } version = g_strdup_printf ("%i.%i.%i", data[0], data[1], data[2]); fu_device_set_version (FU_DEVICE (device), version); /* success */ return TRUE; } static gboolean fu_steelseries_device_close (FuUsbDevice *device, GError **error) { GUsbDevice *usb_device = fu_usb_device_get_dev (device); const guint8 iface_idx = 0x00; /* we're done here */ if (!g_usb_device_release_interface (usb_device, iface_idx, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "failed to release interface: "); return FALSE; } /* success */ return TRUE; } static void fu_steelseries_device_init (FuSteelseriesDevice *device) { } static void fu_steelseries_device_class_init (FuSteelseriesDeviceClass *klass) { FuUsbDeviceClass *klass_usb_device = FU_USB_DEVICE_CLASS (klass); klass_usb_device->open = fu_steelseries_device_open; klass_usb_device->close = fu_steelseries_device_close; klass_usb_device->probe = fu_steelseries_device_probe; } FuSteelseriesDevice * fu_steelseries_device_new (GUsbDevice *usb_device) { FuSteelseriesDevice *device = NULL; device = g_object_new (FU_TYPE_STEELSERIES_DEVICE, "usb-device", usb_device, NULL); return device; } fwupd-1.0.6/plugins/steelseries/fu-steelseries-device.h000066400000000000000000000027171325145456600232420ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_STEELSERIES_DEVICE_H #define __FU_STEELSERIES_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_STEELSERIES_DEVICE (fu_steelseries_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuSteelseriesDevice, fu_steelseries_device, FU, STEELSERIES_DEVICE, FuUsbDevice) struct _FuSteelseriesDeviceClass { FuUsbDeviceClass parent_class; }; FuSteelseriesDevice *fu_steelseries_device_new (GUsbDevice *usb_device); G_END_DECLS #endif /* __FU_STEELSERIES_DEVICE_H */ fwupd-1.0.6/plugins/steelseries/meson.build000066400000000000000000000006461325145456600210360ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginSteelSeries"'] shared_module('fu_plugin_steelseries', sources : [ 'fu-plugin-steelseries.c', 'fu-steelseries-device.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], ) fwupd-1.0.6/plugins/synapticsmst/000077500000000000000000000000001325145456600171005ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/README.md000066400000000000000000000033751325145456600203670ustar00rootroot00000000000000# Synaptics MST This plugin supports querying and flashing Synaptics MST hubs used in Dell systems and docks. ## Requirements ### (Kernel) DP Aux Interface Kernel 4.6 introduced an DRM DP Aux interface for manipulation of the registers needed to access an MST hub. This patch can be backported to earlier kernels: https://github.com/torvalds/linux/commit/e94cb37b34eb8a88fe847438dba55c3f18bf024a ### libsmbios At compilation time and runtime you will need libsmbios_c version 2.3.0 or later * source: https://github.com/dell/libsmbios * rpms: https://apps.fedoraproject.org/packages/libsmbios * debs (Debian): http://tracker.debian.org/pkg/libsmbios * debs (Ubuntu): http://launchpad.net/ubuntu/+source/libsmbios If you don't want or need this functionality you can use the `--disable-dell` option. ## Usage Supported devices will be displayed in `# fwupdmgr get-devices` output. Here is an example output from a Dell WD15 dock: ``` Dell WD15/TB16 wired Dock Synaptics VMM3332 Guid: 653cd006-5433-57db-8632-0413af4d3fcc DeviceID: MST-1-1-0-0 Plugin: synapticsmst Flags: allow-online Version: 3.10.002 Created: 2017-01-13 Modified: 2017-01-13 Trusted: none ``` Payloads can be flashed just like any other plugin from LVFS. ## Supported devices Not all Dell systems or accessories contain MST hubs. Here is a sample list of systems known to support them however: 1. Dell WD15 dock 2. Dell TB16 dock 3. Latitude E5570 4. Latitude E5470 5. Latitude E5270 6. Latitude E7470 7. Latitude E7270 8. Latitude E7450 9. Latitude E7250 10. Latitude E5550 11. Latitude E5450 12. Latitude E5250 13. Latitude Rugged 5414 14. Latitude Rugged 7214 15. Latitude Rugged 7414 fwupd-1.0.6/plugins/synapticsmst/fu-plugin-synapticsmst.c000066400000000000000000000312341325145456600237140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Mario Limonciello * Copyright (C) 2017 Peichen Huang * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "synapticsmst-device.h" #include "synapticsmst-common.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "fu-device-metadata.h" #define SYNAPTICS_FLASH_MODE_DELAY 3 #define HWID_DELL_INC "85d38fda-fc0e-5c6f-808f-076984ae7978" struct FuPluginData { gchar *dock_type; gchar *system_type; }; static gboolean synapticsmst_common_check_supported_system (FuPlugin *plugin, GError **error) { if (g_getenv ("FWUPD_SYNAPTICSMST_FW_DIR") != NULL) { g_debug ("Running Synaptics plugin in test mode"); return TRUE; } /* tests for "Dell Inc." manufacturer string * this isn't strictly a complete tests due to OEM rebranded * systems being excluded, but should cover most cases */ if (!fu_plugin_check_hwid (plugin, HWID_DELL_INC)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "MST firmware updating not supported by OEM"); return FALSE; } if (!g_file_test (SYSFS_DRM_DP_AUX, G_FILE_TEST_IS_DIR)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "MST firmware updating not supported, missing kernel support."); return FALSE; } return TRUE; } static gboolean fu_plugin_synaptics_add_device (FuPlugin *plugin, SynapticsMSTDevice *device, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(FuDevice) dev = NULL; const gchar *kind_str = NULL; const gchar *board_str = NULL; const gchar *guid_str = NULL; g_autofree gchar *name = NULL; g_autofree gchar *dev_id_str = NULL; g_autofree gchar *layer_str = NULL; g_autofree gchar *rad_str = NULL; const gchar *aux_node; guint8 layer; guint16 rad; aux_node = synapticsmst_device_get_aux_node (device); if (!synapticsmst_device_enumerate_device (device, data->dock_type, data->system_type, error)) { g_debug ("error enumerating device at %s", aux_node); return FALSE; } layer = synapticsmst_device_get_layer (device); rad = synapticsmst_device_get_rad (device); board_str = synapticsmst_device_board_id_to_string (synapticsmst_device_get_board_id (device)); name = g_strdup_printf ("Synaptics %s inside %s", synapticsmst_device_get_chip_id (device), board_str); guid_str = synapticsmst_device_get_guid (device); if (guid_str == NULL) { g_debug ("invalid GUID for board ID %x", synapticsmst_device_get_board_id(device)); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid device"); return FALSE; } /* Store $KIND-$AUXNODE-$LAYER-$RAD as device ID */ kind_str = synapticsmst_device_kind_to_string (synapticsmst_device_get_kind (device)); dev_id_str = g_strdup_printf ("MST-%s-%s-%u-%u", kind_str, aux_node, layer, rad); layer_str = g_strdup_printf ("%u", layer); rad_str = g_strdup_printf ("%u", rad); if (board_str == NULL) { g_debug ("invalid board ID (%x)", synapticsmst_device_get_board_id (device)); g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid device"); return FALSE; } /* create the device */ dev = fu_device_new (); fu_device_set_id (dev, dev_id_str); fu_device_set_metadata (dev, "SynapticsMSTKind", kind_str); fu_device_set_metadata (dev, "SynapticsMSTAuxNode", aux_node); fu_device_set_metadata (dev, "SynapticsMSTLayer", layer_str); fu_device_set_metadata (dev, "SynapticsMSTRad", rad_str); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_name (dev, name); fu_device_set_vendor (dev, "Synaptics"); fu_device_set_summary (dev, "Multi-Stream Transport Device"); fu_device_add_icon (dev, "computer"); fu_device_set_version (dev, synapticsmst_device_get_version (device)); fu_device_add_guid (dev, guid_str); fu_plugin_device_add (plugin, dev); fu_plugin_cache_add (plugin, dev_id_str, dev); return TRUE; } static gboolean fu_plugin_synaptics_scan_cascade (FuPlugin *plugin, SynapticsMSTDevice *device, GError **error) { g_autoptr(SynapticsMSTDevice) cascade_device = NULL; g_autofree gchar *dev_id_str = NULL; FuDevice *fu_dev = NULL; const gchar *aux_node; aux_node = synapticsmst_device_get_aux_node (device); if (!synapticsmst_device_open (device, error)) { g_prefix_error (error, "failed to open aux node %s again", aux_node); return FALSE; } for (guint8 j = 0; j < 2; j++) { guint8 layer = synapticsmst_device_get_layer (device) + 1; guint16 rad = synapticsmst_device_get_rad (device) | (j << (2 * (layer - 1))); dev_id_str = g_strdup_printf ("MST-REMOTE-%s-%u-%u", aux_node, layer, rad); fu_dev = fu_plugin_cache_lookup (plugin, dev_id_str); /* run the scan */ if (!synapticsmst_device_scan_cascade_device (device, error, j)) return FALSE; /* check if cascaded device was found */ if (!synapticsmst_device_get_cascade (device)) { /* not found, nothing new to see here, move along */ if (fu_dev == NULL) continue; /* not found, but should have existed - remove it */ else { fu_plugin_device_remove (plugin, fu_dev); fu_plugin_cache_remove (plugin, dev_id_str); /* don't scan any deeper on this node */ continue; } /* Found a device, add it */ } else { cascade_device = synapticsmst_device_new (SYNAPTICSMST_DEVICE_KIND_REMOTE, aux_node, layer, rad); /* new device */ if (fu_dev == NULL) { g_debug ("Adding remote device %s", dev_id_str); if (!fu_plugin_synaptics_add_device (plugin, cascade_device, error)) return FALSE; } else g_debug ("Skipping previously added device %s", dev_id_str); /* check recursively for more devices */ if (!fu_plugin_synaptics_scan_cascade (plugin, cascade_device, error)) return FALSE; } } return TRUE; } static void fu_plugin_synapticsmst_remove_cascaded (FuPlugin *plugin, const gchar *aux_node) { g_autofree gchar *dev_id_str = NULL; FuDevice *fu_dev = NULL; for (guint8 i=0; i < 8; i++) { for (guint16 j=0; j < 256; j++) { dev_id_str = g_strdup_printf ("MST-REMOTE-%s-%u-%u", aux_node, i, j); fu_dev = fu_plugin_cache_lookup (plugin, dev_id_str); if (fu_dev != NULL) { fu_plugin_device_remove (plugin, fu_dev); fu_plugin_cache_remove (plugin, dev_id_str); continue; } break; } } } static gboolean fu_plugin_synapticsmst_enumerate (FuPlugin *plugin, GError **error) { g_autoptr(GDir) dir = NULL; const gchar *dp_aux_dir; const gchar *aux_node = NULL; g_autofree gchar *dev_id_str = NULL; dp_aux_dir = g_getenv ("FWUPD_SYNAPTICSMST_FW_DIR"); if (dp_aux_dir == NULL) dp_aux_dir = SYSFS_DRM_DP_AUX; else g_debug ("Using %s to look for MST devices", dp_aux_dir); dir = g_dir_open (dp_aux_dir, 0, NULL); do { g_autoptr(GError) error_local = NULL; g_autoptr(SynapticsMSTDevice) device = NULL; FuDevice *fu_dev = NULL; aux_node = g_dir_read_name (dir); if (aux_node == NULL) break; dev_id_str = g_strdup_printf ("MST-DIRECT-%s-0-0", aux_node); fu_dev = fu_plugin_cache_lookup (plugin, dev_id_str); /* If we open succesfully a device exists here */ device = synapticsmst_device_new (SYNAPTICSMST_DEVICE_KIND_DIRECT, aux_node, 0, 0); if (!synapticsmst_device_open (device, NULL)) { /* No device exists here, but was there - remove from DB */ if (fu_dev != NULL) { g_debug ("Removing devices on %s", aux_node); fu_plugin_device_remove (plugin, fu_dev); fu_plugin_cache_remove (plugin, dev_id_str); fu_plugin_synapticsmst_remove_cascaded (plugin, aux_node); } else { /* Nothing to see here - move on*/ g_debug ("No device found on %s", aux_node); } continue; } /* Add direct devices */ if (fu_dev == NULL) { g_debug ("Adding direct device %s", dev_id_str); if (!fu_plugin_synaptics_add_device (plugin, device, &error_local)) g_warning ("failed to add device: %s", error_local->message); } else { g_debug ("Skipping previously added device %s", dev_id_str); } /* recursively look for cascade devices */ if (!fu_plugin_synaptics_scan_cascade (plugin, device, error)) return FALSE; } while(TRUE); return TRUE; } static void fu_synapticsmst_write_progress_cb (goffset current, goffset total, gpointer user_data) { FuDevice *device = FU_DEVICE (user_data); fu_device_set_progress_full (device, current, total); } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(SynapticsMSTDevice) device = NULL; SynapticsMSTDeviceKind kind; const gchar *aux_node; guint8 layer; guint8 rad; /* extract details to build a new device */ kind = synapticsmst_device_kind_from_string (fu_device_get_metadata (dev, "SynapticsMSTKind")); aux_node = fu_device_get_metadata (dev, "SynapticsMSTAuxNode"); layer = g_ascii_strtoull (fu_device_get_metadata (dev, "SynapticsMSTLayer"), NULL, 0); rad = g_ascii_strtoull (fu_device_get_metadata (dev, "SynapticsMSTRad"), NULL, 0); /* sleep to allow device wakeup to complete */ g_debug ("waiting %d seconds for MST hub wakeup", SYNAPTICS_FLASH_MODE_DELAY); fu_device_set_status (dev, FWUPD_STATUS_DEVICE_BUSY); g_usleep (SYNAPTICS_FLASH_MODE_DELAY * 1000000); device = synapticsmst_device_new (kind, aux_node, layer, rad); if (!synapticsmst_device_enumerate_device (device, data->dock_type, data->system_type, error)) return FALSE; if (synapticsmst_device_board_id_to_string (synapticsmst_device_get_board_id (device)) != NULL) { fu_device_set_status (dev, FWUPD_STATUS_DEVICE_WRITE); if (!synapticsmst_device_write_firmware (device, blob_fw, fu_synapticsmst_write_progress_cb, dev, error)) { g_prefix_error (error, "failed to flash firmware: "); return FALSE; } } else { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Unknown device"); return FALSE; } /* Re-run device enumeration to find the new device version */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); if (!synapticsmst_device_enumerate_device (device, data->dock_type, data->system_type, error)) { return FALSE; } fu_device_set_version (dev, synapticsmst_device_get_version (device)); return TRUE; } void fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) { FuPluginData *data = fu_plugin_get_data (plugin); const gchar *tmp; /* dell plugin */ if (g_strcmp0 (fu_device_get_plugin (device), "dell") == 0) { /* only look at external devices from dell plugin */ if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) return; tmp = fu_device_get_metadata (device, FU_DEVICE_METADATA_DELL_DOCK_TYPE); if (tmp) data->dock_type = g_strdup (tmp); } } static gboolean fu_plugin_synapticsmst_coldplug (FuPlugin *plugin, GError **error) { /* verify that this is a supported system */ if (!synapticsmst_common_check_supported_system (plugin, error)) return FALSE; /* look for host devices or already plugged in dock devices */ if (!fu_plugin_synapticsmst_enumerate (plugin, error)) g_debug ("error enumerating"); return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { return fu_plugin_synapticsmst_coldplug (plugin, error); } gboolean fu_plugin_recoldplug (FuPlugin *plugin, GError **error) { return fu_plugin_synapticsmst_coldplug (plugin, error); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_free(data->dock_type); g_free(data->system_type); } void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); data->system_type = g_strdup (fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_SKU)); /* make sure dell is already coldplugged */ fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "dell"); } fwupd-1.0.6/plugins/synapticsmst/fu-self-test.c000066400000000000000000000062261325145456600215700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Mario Limonciello * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "fu-plugin-private.h" static void _plugin_device_added_cb (FuPlugin *plugin, FuDevice *device, gpointer user_data) { GPtrArray **devices = (GPtrArray **) user_data; g_ptr_array_add (*devices, device); } static void fu_plugin_synapticsmst_func (void) { gboolean ret; guint device_count; GPtrArray *devices = NULL; g_autoptr(GError) error = NULL; FuDevice *device = NULL; g_autoptr(FuPlugin) plugin = NULL; const gchar *test_directory; devices = g_ptr_array_new (); plugin = fu_plugin_new (); g_signal_connect (plugin, "device-added", G_CALLBACK (_plugin_device_added_cb), &devices); ret = fu_plugin_open (plugin, PLUGINBUILDDIR "/libfu_plugin_synapticsmst.so", &error); g_assert_no_error (error); g_assert (ret); ret = fu_plugin_runner_startup (plugin, &error); g_assert_no_error (error); g_assert (ret); /* Test with no Synaptics MST devices */ test_directory = "./tests/no_devices"; if (g_file_test (test_directory, G_FILE_TEST_IS_DIR)) { g_setenv ("FWUPD_SYNAPTICSMST_FW_DIR", test_directory, TRUE); ret = fu_plugin_runner_coldplug (plugin, &error); g_assert_no_error (error); g_assert (ret); } /* Emulate adding/removing a Dell TB16 dock */ test_directory = "./tests/tb16_dock"; if (g_file_test (test_directory, G_FILE_TEST_IS_DIR)) { g_setenv ("FWUPD_SYNAPTICSMST_FW_DIR", test_directory, TRUE); ret = fu_plugin_runner_coldplug (plugin, &error); g_assert_no_error (error); g_assert (ret); device_count = devices->len; for (guint i = 0; i < device_count; i++) { device = g_ptr_array_index (devices, i); g_assert_cmpstr (fu_device_get_version (device), ==, "3.10.002"); g_ptr_array_remove (devices, device); fu_plugin_device_remove (plugin, device); } } g_ptr_array_unref (devices); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_assert_cmpint (g_mkdir_with_parents ("/tmp/fwupd-self-test/var/lib/fwupd", 0755), ==, 0); /* tests go here */ g_test_add_func ("/fwupd/plugin{synapticsmst}", fu_plugin_synapticsmst_func); return g_test_run (); } fwupd-1.0.6/plugins/synapticsmst/meson.build000066400000000000000000000033061325145456600212440ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginSynapticsMST"'] shared_module('fu_plugin_synapticsmst', sources : [ 'fu-plugin-synapticsmst.c', 'synapticsmst-common.c', 'synapticsmst-device.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', ], dependencies : [ plugin_deps, efivar, ], # https://github.com/hughsie/fwupd/issues/207 override_options : [ 'werror=false', ] ) executable( 'synapticsmst-tool', sources : [ 'synapticsmst-tool.c', 'synapticsmst-device.c', 'synapticsmst-common.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, ], c_args : cargs, # https://github.com/hughsie/fwupd/issues/207 override_options : [ 'werror=false', ] ) if get_option('tests') cargs += '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"' cargs += '-DPLUGINBUILDDIR="' + meson.current_build_dir() + '"' e = executable( 'synapticsmst-self-test', sources : [ 'fu-self-test.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, sqlite, valgrind, ], link_with : [ fwupd, libfwupdprivate, ], c_args : [ cargs, '-DLOCALSTATEDIR="/tmp/fwupd-self-test/var"', ], ) test('synapticsmst-self-test', e) endif fwupd-1.0.6/plugins/synapticsmst/synapticsmst-common.c000066400000000000000000000224301325145456600232740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * Copyright (C) 2016 Mario Limonciello * Copyright (C) 2017 Peichen Huang * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include #include #include #include "synapticsmst-common.h" #include "synapticsmst-device.h" #define UNIT_SIZE 32 #define MAX_WAIT_TIME 3 /* unit : second */ struct _SynapticsMSTConnection { gint fd; /* not owned by the connection */ guint8 layer; guint8 remain_layer; guint8 rad; }; guint8 synapticsmst_common_aux_node_read (SynapticsMSTConnection *connection, gint offset, gint *buf, gint length) { if (lseek (connection->fd, offset, SEEK_SET) != offset) return DPCD_SEEK_FAIL; if (read (connection->fd, buf, length) != length) return DPCD_ACCESS_FAIL; return DPCD_SUCCESS; } static guint8 synapticsmst_common_aux_node_write (SynapticsMSTConnection *connection, gint offset, const gint *buf, gint length) { if (lseek (connection->fd, offset, SEEK_SET) != offset) return DPCD_SEEK_FAIL; if (write (connection->fd, buf, length) != length) return DPCD_ACCESS_FAIL; return DPCD_SUCCESS; } void synapticsmst_common_free (SynapticsMSTConnection *connection) { g_free (connection); } SynapticsMSTConnection * synapticsmst_common_new (gint fd, guint8 layer, guint rad) { SynapticsMSTConnection *connection = g_new0 (SynapticsMSTConnection, 1); connection->fd = fd; connection->layer = layer; connection->remain_layer = layer; connection->rad = rad; return connection; } guint8 synapticsmst_common_read_dpcd (SynapticsMSTConnection *connection, gint offset, gint *buf, gint length) { if (connection->layer && connection->remain_layer) { guint8 rc, node; connection->remain_layer--; node = (connection->rad >> connection->remain_layer * 2) & 0x03; rc = synapticsmst_common_rc_get_command (connection, UPDC_READ_FROM_TX_DPCD + node, length, offset, (guint8 *)buf); connection->remain_layer++; return rc; } return synapticsmst_common_aux_node_read (connection, offset, buf, length); } guint8 synapticsmst_common_write_dpcd (SynapticsMSTConnection *connection, gint offset, const gint *buf, gint length) { if (connection->layer && connection->remain_layer) { guint8 rc, node; connection->remain_layer--; node = (connection->rad >> connection->remain_layer * 2) & 0x03; rc = synapticsmst_common_rc_set_command (connection, UPDC_WRITE_TO_TX_DPCD + node, length, offset, (guint8 *)buf); connection->remain_layer++; return rc; } return synapticsmst_common_aux_node_write (connection, offset, buf, length); } guint8 synapticsmst_common_rc_set_command (SynapticsMSTConnection *connection, gint rc_cmd, gint length, gint offset, const guint8 *buf) { guint8 rc = 0; gint cur_offset = offset; gint cur_length; gint data_left = length; gint cmd; gint readData = 0; long deadline; struct timespec t_spec; do{ if (data_left > UNIT_SIZE) { cur_length = UNIT_SIZE; } else { cur_length = data_left; } if (cur_length) { /* write data */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_DATA, (gint *)buf, cur_length); if (rc) break; /* write offset */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_OFFSET, &cur_offset, 4); if (rc) break; /* write length */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_LEN, &cur_length, 4); if (rc) break; } /* send command */ cmd = 0x80 | rc_cmd; rc = synapticsmst_common_write_dpcd (connection, REG_RC_CMD, &cmd, 1); if (rc) break; /* wait command complete */ clock_gettime (CLOCK_REALTIME, &t_spec); deadline = t_spec.tv_sec + MAX_WAIT_TIME; do { rc = synapticsmst_common_read_dpcd (connection, REG_RC_CMD, &readData, 2); clock_gettime (CLOCK_REALTIME, &t_spec); if (t_spec.tv_sec > deadline) { rc = -1; } } while (rc == 0 && readData & 0x80); if (rc) break; else if (readData & 0xFF00) { rc = (readData >> 8) & 0xFF; break; } buf += cur_length; cur_offset += cur_length; data_left -= cur_length; } while (data_left); return rc; } guint8 synapticsmst_common_rc_get_command (SynapticsMSTConnection *connection, gint rc_cmd, gint length, gint offset, guint8 *buf) { guint8 rc = 0; gint cur_offset = offset; gint cur_length; gint data_need = length; gint cmd; gint readData = 0; long deadline; struct timespec t_spec; while (data_need) { if (data_need > UNIT_SIZE) { cur_length = UNIT_SIZE; } else { cur_length = data_need; } if (cur_length) { /* write offset */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_OFFSET, &cur_offset, 4); if (rc) break; /* write length */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_LEN, &cur_length, 4); if (rc) break; } /* send command */ cmd = 0x80 | rc_cmd; rc = synapticsmst_common_write_dpcd (connection, REG_RC_CMD, &cmd, 1); if (rc) break; /* wait command complete */ clock_gettime (CLOCK_REALTIME, &t_spec); deadline = t_spec.tv_sec + MAX_WAIT_TIME; do { rc = synapticsmst_common_read_dpcd (connection, REG_RC_CMD, &readData, 2); clock_gettime (CLOCK_REALTIME, &t_spec); if (t_spec.tv_sec > deadline) { rc = -1; } } while (rc == 0 && readData & 0x80); if (rc) break; else if (readData & 0xFF00) { rc = (readData >> 8) & 0xFF; break; } if (cur_length) { rc = synapticsmst_common_read_dpcd (connection, REG_RC_DATA, (gint *)buf, cur_length); if (rc) break; } buf += cur_length; cur_offset += cur_length; data_need -= cur_length; } return rc; } guint8 synapticsmst_common_rc_special_get_command (SynapticsMSTConnection *connection, gint rc_cmd, gint cmd_length, gint cmd_offset, guint8 *cmd_data, gint length, guint8 *buf) { guint8 rc = 0; gint readData = 0; gint cmd; long deadline; struct timespec t_spec; if (cmd_length) { /* write cmd data */ if (cmd_data != NULL) { rc = synapticsmst_common_write_dpcd (connection, REG_RC_DATA, (gint *)cmd_data, cmd_length); if (rc) return rc; } /* write offset */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_OFFSET, &cmd_offset, 4); if (rc) return rc; /* write length */ rc = synapticsmst_common_write_dpcd (connection, REG_RC_LEN, &cmd_length, 4); if (rc) return rc; } /* send command */ cmd = 0x80 | rc_cmd; rc = synapticsmst_common_write_dpcd (connection, REG_RC_CMD, &cmd, 1); if (rc) return rc; /* wait command complete */ clock_gettime (CLOCK_REALTIME, &t_spec); deadline = t_spec.tv_sec + MAX_WAIT_TIME; do { rc = synapticsmst_common_read_dpcd (connection, REG_RC_CMD, &readData, 2); clock_gettime (CLOCK_REALTIME, &t_spec); if (t_spec.tv_sec > deadline) return -1; } while (readData & 0x80); if (rc) return rc; else if (readData & 0xFF00) { rc = (readData >> 8) & 0xFF; return rc; } if (length) { rc = synapticsmst_common_read_dpcd (connection, REG_RC_DATA, (gint *)buf, length); if (rc) return rc; } return rc; } guint8 synapticsmst_common_enable_remote_control (SynapticsMSTConnection *connection) { const gchar *sc = "PRIUS"; guint8 rc = 0; for (gint i = 0; i <= connection->layer; i++) { g_autoptr(SynapticsMSTConnection) connection_tmp = NULL; connection_tmp = synapticsmst_common_new (connection->fd, i, connection->rad); rc = synapticsmst_common_rc_set_command (connection_tmp, UPDC_ENABLE_RC, 5, 0, (guint8*)sc); if (rc) break; } return rc; } guint8 synapticsmst_common_disable_remote_control (SynapticsMSTConnection *connection) { guint8 rc = 0; for (gint i = connection->layer; i >= 0; i--) { g_autoptr(SynapticsMSTConnection) connection_tmp = NULL; connection_tmp = synapticsmst_common_new (connection->fd, i, connection->rad); rc = synapticsmst_common_rc_set_command (connection_tmp, UPDC_DISABLE_RC, 0, 0, NULL); if (rc) break; } return rc; } fwupd-1.0.6/plugins/synapticsmst/synapticsmst-common.h000066400000000000000000000072221325145456600233030ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Mario Limonciello * Copyright (C) 2017 Peichen Huang * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __SYNAPTICSMST_COMMON_H #define __SYNAPTICSMST_COMMON_H #include #include #define ADDR_CUSTOMER_ID 0X10E #define ADDR_BOARD_ID 0x10F #define REG_RC_CAP 0x4B0 #define REG_RC_STATE 0X4B1 #define REG_RC_CMD 0x4B2 #define REG_RC_RESULT 0x4B3 #define REG_RC_LEN 0x4B8 #define REG_RC_OFFSET 0x4BC #define REG_RC_DATA 0x4C0 #define REG_VENDOR_ID 0x500 #define REG_CHIP_ID 0x507 #define REG_FIRMWARE_VERSION 0x50A typedef enum { DPCD_SUCCESS = 0, DPCD_SEEK_FAIL, DPCD_ACCESS_FAIL, } SynapticsMstDpcdRc; typedef enum { UPDC_COMMAND_SUCCESS = 0, UPDC_COMMAND_INVALID, UPDC_COMMAND_UNSUPPORT, UPDC_COMMAND_FAILED, UPDC_COMMAND_DISABLED, } SynapticsMstUpdcRc; typedef enum { UPDC_ENABLE_RC = 1, UPDC_DISABLE_RC, UPDC_GET_ID, UPDC_GET_VERSION, UPDC_ENABLE_FLASH_CHIP_ERASE = 8, UPDC_CAL_EEPROM_CHECKSUM = 0X11, UPDC_FLASH_ERASE = 0X14, UPDC_CAL_EEPROM_CHECK_CRC8 = 0X16, UPDC_CAL_EEPROM_CHECK_CRC16, UPDC_WRITE_TO_EEPROM = 0X20, UPDC_WRITE_TO_TX_DPCD = 0x22, UPDC_READ_FROM_EEPROM = 0x30, UPDC_READ_FROM_TX_DPCD = 0x32, } SynapticsMstUpdcCmd; typedef struct _SynapticsMSTConnection SynapticsMSTConnection; void synapticsmst_common_free (SynapticsMSTConnection *connection); SynapticsMSTConnection *synapticsmst_common_new (gint fd, guint8 layer, guint rad); guint8 synapticsmst_common_aux_node_read (SynapticsMSTConnection *connection, gint offset, gint *buf, gint length); guint8 synapticsmst_common_read_dpcd (SynapticsMSTConnection *connection, gint offset, gint *buf, gint length); guint8 synapticsmst_common_write_dpcd (SynapticsMSTConnection *connection, gint offset, const gint *buf, gint length); guint8 synapticsmst_common_rc_set_command (SynapticsMSTConnection *connection, gint rc_cmd, gint length, gint offset, const guint8 *buf); guint8 synapticsmst_common_rc_get_command (SynapticsMSTConnection *connection, gint rc_cmd, gint length, gint offset, guint8 *buf); guint8 synapticsmst_common_rc_special_get_command (SynapticsMSTConnection *connection, gint rc_cmd, gint cmd_length, gint cmd_offset, guint8 *cmd_data, gint length, guint8 *buf); guint8 synapticsmst_common_enable_remote_control (SynapticsMSTConnection *connection); guint8 synapticsmst_common_disable_remote_control (SynapticsMSTConnection *connection); G_DEFINE_AUTOPTR_CLEANUP_FUNC(SynapticsMSTConnection, synapticsmst_common_free) #endif /* __SYNAPTICSMST_COMMON_H */ fwupd-1.0.6/plugins/synapticsmst/synapticsmst-device.c000066400000000000000000000510751325145456600232520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2017 Richard Hughes * Copyright (C) 2016 Mario Limonciello * Copyright (C) 2017 Peichen Huang * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include "synapticsmst-device.h" #include "synapticsmst-common.h" #define BLOCK_UNIT 64 typedef struct { SynapticsMSTDeviceKind kind; gchar *version; SynapticsMSTDeviceBoardID board_id; gchar *chip_id; gchar *guid; gchar *aux_node; guint8 layer; guint16 rad; gint fd; gboolean has_cascade; gchar *fw_dir; gboolean test_mode; } SynapticsMSTDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (SynapticsMSTDevice, synapticsmst_device, G_TYPE_OBJECT) #define GET_PRIVATE(o) (synapticsmst_device_get_instance_private (o)) SynapticsMSTDeviceKind synapticsmst_device_kind_from_string (const gchar *kind) { if (g_strcmp0 (kind, "DIRECT") == 0) return SYNAPTICSMST_DEVICE_KIND_DIRECT; if (g_strcmp0 (kind, "REMOTE") == 0) return SYNAPTICSMST_DEVICE_KIND_REMOTE; return SYNAPTICSMST_DEVICE_KIND_UNKNOWN; } const gchar * synapticsmst_device_kind_to_string (SynapticsMSTDeviceKind kind) { if (kind == SYNAPTICSMST_DEVICE_KIND_DIRECT) return "DIRECT"; if (kind == SYNAPTICSMST_DEVICE_KIND_REMOTE) return "REMOTE"; return NULL; } const gchar * synapticsmst_device_board_id_to_string (SynapticsMSTDeviceBoardID board_id) { if (board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_X6) return "Dell X6 Platform"; if (board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_X7) return "Dell X7 Platform"; if (board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_WD15_TB16_WIRE) return "Dell WD15/TB16 wired Dock"; if (board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_WLD15_WIRELESS) return "Dell WLD15 Wireless Dock"; if (board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_X7_RUGGED) return "Dell Rugged Platform"; if ((board_id & 0xFF00) == SYNAPTICSMST_DEVICE_BOARDID_EVB) return "SYNA evb board"; return "Unknown Platform"; } const gchar * synapticsmst_device_get_guid (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->guid; } static void synapticsmst_device_finalize (GObject *object) { SynapticsMSTDevice *device = SYNAPTICSMST_DEVICE (object); SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); if (priv->fd > 0) close (priv->fd); g_free (priv->fw_dir); g_free (priv->aux_node); g_free (priv->version); g_free (priv->chip_id); g_free (priv->guid); G_OBJECT_CLASS (synapticsmst_device_parent_class)->finalize (object); } static void synapticsmst_device_init (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); const gchar *tmp; priv->test_mode = FALSE; priv->fw_dir = g_strdup ("/dev"); tmp = g_getenv ("FWUPD_SYNAPTICSMST_FW_DIR"); if (tmp != NULL) { priv->test_mode = TRUE; priv->fw_dir = g_strdup (tmp); } } static void synapticsmst_device_class_init (SynapticsMSTDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = synapticsmst_device_finalize; } SynapticsMSTDeviceKind synapticsmst_device_get_kind (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->kind; } SynapticsMSTDeviceBoardID synapticsmst_device_get_board_id (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->board_id; } static gboolean synapticsmst_device_enable_remote_control (SynapticsMSTDevice *device, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(SynapticsMSTConnection) connection = NULL; /* in test mode we need to open a different file node instead */ if (priv->test_mode) { g_autofree gchar *filename = NULL; close(priv->fd); filename = g_strdup_printf ("%s/remote/%s", priv->fw_dir, priv->aux_node); if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "no device exists %s", filename); return FALSE; } priv->fd = open (filename, O_RDWR); if (priv->fd == -1) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "cannot open device %s", filename); return FALSE; } return TRUE; } connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); if (synapticsmst_common_enable_remote_control (connection)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to enable MST remote control"); return FALSE; } else { return TRUE; } } static gboolean synapticsmst_device_disable_remote_control (SynapticsMSTDevice *device, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(SynapticsMSTConnection) connection = NULL; /* in test mode we need to open a different file node instead */ if (priv->test_mode) { g_autofree gchar *filename = NULL; close(priv->fd); filename = g_strdup_printf ("%s/%s", priv->fw_dir, priv->aux_node); if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "no device exists %s", filename); return FALSE; } priv->fd = open (filename, O_RDWR); if (priv->fd == -1) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "cannot open device %s", filename); return FALSE; } return TRUE; } connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); if (synapticsmst_common_disable_remote_control (connection)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to disable MST remote control"); return FALSE; } else { return TRUE; } } gboolean synapticsmst_device_scan_cascade_device (SynapticsMSTDevice *device, GError ** error, guint8 tx_port) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); guint8 layer = priv->layer + 1; guint16 rad = priv->rad | (tx_port << (2 * (priv->layer))); guint8 byte[4]; guint8 rc; g_autoptr(SynapticsMSTConnection) connection = NULL; if (priv->test_mode) return TRUE; /* reset */ priv->has_cascade = FALSE; if (!synapticsmst_device_enable_remote_control (device, error)) { g_prefix_error (error, "failed to scan cascade device on tx_port %d: ", tx_port); return FALSE; } connection = synapticsmst_common_new (priv->fd, layer, rad); rc = synapticsmst_common_read_dpcd (connection, REG_RC_CAP, (gint *)byte, 1); if (rc == DPCD_SUCCESS ) { if (byte[0] & 0x04) { synapticsmst_common_read_dpcd (connection, REG_VENDOR_ID, (gint *)byte, 3); if (byte[0] == 0x90 && byte[1] == 0xCC && byte[2] == 0x24) priv->has_cascade = TRUE; } } if (!synapticsmst_device_disable_remote_control (device, error)) { g_prefix_error (error, "failed to scan cascade device on tx_port %d: ", tx_port); return FALSE; } return TRUE; } static gboolean synapticsmst_device_read_board_id (SynapticsMSTDevice *device, SynapticsMSTConnection *connection, guint8 *byte, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); guint8 rc; if (priv->test_mode) { g_autofree gchar *filename = NULL; gint fd; filename = g_strdup_printf ("%s/remote/%s_eeprom", priv->fw_dir, priv->aux_node); if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "no device exists %s", filename); return FALSE; } fd = open (filename, O_RDONLY); if (fd == -1) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "cannot open device %s", filename); return FALSE; } if (read (fd, byte, 2) != 2) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "error reading EEPROM file %s", filename); close (fd); return FALSE; } close (fd); } else { rc = synapticsmst_common_rc_get_command (connection, UPDC_READ_FROM_EEPROM, 2, ADDR_CUSTOMER_ID, byte); if (rc) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to read from EEPROM of device"); return FALSE; } } return TRUE; } gboolean synapticsmst_device_enumerate_device (SynapticsMSTDevice *device, const gchar *dock_type, const gchar *system_type, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); guint8 byte[16]; g_autofree gchar *system = NULL; guint8 rc; g_autoptr(SynapticsMSTConnection) connection = NULL; //FIXME? if (!synapticsmst_device_open (device, error)) { g_prefix_error (error, "Failed to open device in DP Aux Node %s: ", synapticsmst_device_get_aux_node (device)); return FALSE; } /* enable remote control */ if (!synapticsmst_device_enable_remote_control (device, error)) return FALSE; /* read firmware version */ connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); rc = synapticsmst_common_read_dpcd (connection, REG_FIRMWARE_VERSION, (gint *)byte, 3); if (rc) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to read dpcd from device"); return FALSE; } priv->version = g_strdup_printf ("%1d.%02d.%03d", byte[0], byte[1], byte[2]); /* read board ID */ if (!synapticsmst_device_read_board_id (device, connection, byte, error)) return FALSE; priv->board_id = (byte[0] << 8) | (byte[1]); /* read board chip_id */ rc = synapticsmst_common_read_dpcd (connection, REG_CHIP_ID, (gint *)byte, 2); if (rc) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to read dpcd from device"); return FALSE; } priv->chip_id = g_strdup_printf ("VMM%02x%02x", byte[0], byte[1]); switch (priv->board_id >> 8) { /* only dell is supported for today */ case CUSTOMERID_DELL: /* If this is a dock, use dock ID*/ if (priv->test_mode) system = g_strdup_printf ("test-%s", priv->chip_id); else if (priv->board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_WD15_TB16_WIRE) { system = g_strdup_printf ("%s-%s", dock_type, priv->chip_id); system = g_ascii_strdown (system, -1); } else if (priv->board_id == SYNAPTICSMST_DEVICE_BOARDID_DELL_WLD15_WIRELESS) system = g_strdup ("wld15"); /* This is a host system, use system ID */ else system = g_strdup (system_type); /* set up GUID * GUID is MST-$SYSTEMID-$BOARDID * $BOARDID includes CUSTOMERID in first byte, BOARD in second byte */ if (system != NULL) priv->guid = g_strdup_printf ("MST-%s-%u", system, priv->board_id); break; /* EVB development board */ case 0: priv->board_id = (byte[0] << 8 | byte[1]); break; /* unknown */ default: g_warning ("Unknown board_id %x", priv->board_id); priv->board_id = 0xFF; } /* disable remote control */ if (!synapticsmst_device_disable_remote_control (device, error)) return FALSE; return TRUE; } const gchar * synapticsmst_device_get_aux_node (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->aux_node; } const gchar * synapticsmst_device_get_version (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->version; } const gchar * synapticsmst_device_get_chip_id (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->chip_id; } guint16 synapticsmst_device_get_rad (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->rad; } guint8 synapticsmst_device_get_layer (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->layer; } gboolean synapticsmst_device_get_cascade (SynapticsMSTDevice *device) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); return priv->has_cascade; } static gboolean synapticsmst_device_get_flash_checksum (SynapticsMSTDevice *device, gint length, gint offset, guint32 *checksum, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(SynapticsMSTConnection) connection = NULL; connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); if (synapticsmst_common_rc_special_get_command (connection, UPDC_CAL_EEPROM_CHECKSUM, length, offset, NULL, 4, (guint8 *)checksum)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to get flash checksum"); return FALSE; } else { return TRUE; } } gboolean synapticsmst_device_write_firmware (SynapticsMSTDevice *device, GBytes *fw, GFileProgressCallback progress_cb, gpointer progress_data, GError **error) { const guint8 *payload_data; guint32 payload_len; guint32 code_size = 0; guint32 checksum = 0; guint32 flash_checksum = 0; guint32 offset = 0; guint32 write_loops = 0; guint32 data_to_write = 0; guint8 percentage = 0; guint8 rc = 0; guint16 tmp; guint16 erase_code = 0xFFFF; SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); g_autoptr(SynapticsMSTConnection) connection = NULL; /* get firmware data and check size */ payload_data = g_bytes_get_data (fw, NULL); payload_len = g_bytes_get_size (fw); if (payload_len > 0x10000 || payload_len == 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "invalid file size"); return FALSE; } /* check firmware content */ for (guint8 i = 0; i < 128; i++) checksum += *(payload_data + i); if (checksum & 0xFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "EDID checksum error"); return FALSE; } checksum = 0; offset = 128; for (guint8 i = 0; i < 128; i++) checksum += *(payload_data + offset + i); if (checksum & 0xFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "EDID checksum error"); return FALSE; } checksum = 0; offset = 0x100; for (guint16 i = 0; i < 256; i++) checksum += *(payload_data + offset + i); if (checksum & 0xFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "configuration checksum error"); return FALSE; } checksum = 0; offset = 0x200; for (guint16 i = 0; i < 256; i++) checksum += *(payload_data + offset + i); if (checksum & 0xFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "configuration checksum error"); return FALSE; } checksum = 0; offset = 0x400; code_size = (*(payload_data + offset) << 8) + *(payload_data + offset + 1); if (code_size >= 0xFFFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "invalid firmware size"); return FALSE; } for (guint32 i = 0; i < (code_size + 17); i++) checksum += *(payload_data + offset + i); if (checksum & 0xFF) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware checksum error"); return FALSE; } /* TODO: May need a way to override this to cover field * issues of invalid firmware flashed*/ /* check firmware and board ID again */ tmp = (*(payload_data + ADDR_CUSTOMER_ID) << 8) + *(payload_data + ADDR_BOARD_ID); if (tmp != synapticsmst_device_get_board_id (device)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "board ID mismatch"); return FALSE; } if (!synapticsmst_device_open (device, error)) { g_prefix_error (error, "can't open DP Aux node %s", synapticsmst_device_get_aux_node (device)); return FALSE; } /* enable remote control */ if (!synapticsmst_device_enable_remote_control (device, error)) return FALSE; /* erase SPI flash */ connection = synapticsmst_common_new (priv->fd, priv->layer, priv->rad); if (synapticsmst_common_rc_set_command (connection, UPDC_FLASH_ERASE, 2, 0, (guint8 *)&erase_code)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "can't erase flash"); return FALSE; } /* update firmware */ write_loops = (payload_len / BLOCK_UNIT); data_to_write = payload_len; rc = 0; offset = 0; if (payload_len % BLOCK_UNIT) write_loops++; if (progress_cb == NULL) g_debug ("updating... 0%%"); for (guint32 i = 0; i < write_loops; i++) { guint8 length = BLOCK_UNIT; if (data_to_write < BLOCK_UNIT) length = data_to_write; rc = synapticsmst_common_rc_set_command (connection, UPDC_WRITE_TO_EEPROM, length, offset, payload_data + offset); if (rc) { /* repeat once */ rc = synapticsmst_common_rc_set_command (connection, UPDC_WRITE_TO_EEPROM, length, offset, payload_data + offset); } if (rc) break; offset += length; data_to_write -= length; percentage = i * 100 / (write_loops - 1); if (progress_cb != NULL) { progress_cb ((goffset) i * 100, (goffset) (write_loops -1) * 100, progress_data); } else { g_debug ("updating... %d%%\n", percentage); } } if (rc) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "can't write flash at offset 0x%04x", offset); } else { /* check data just written */ checksum = 0; for (guint32 i = 0; i < payload_len; i++) { checksum += *(payload_data + i); } flash_checksum = 0; if (synapticsmst_device_get_flash_checksum (device, payload_len, 0, &flash_checksum, error)) { if (checksum != flash_checksum) { rc = -1; g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "checksum mismatch"); } } else { rc = -1; } } /* disable remote control and close aux node */ if (!synapticsmst_device_disable_remote_control (device, error)) return FALSE; if (rc) { return FALSE; } else { return TRUE; } } SynapticsMSTDevice * synapticsmst_device_new (SynapticsMSTDeviceKind kind, const gchar *aux_node, guint8 layer, guint16 rad) { SynapticsMSTDevice *device; SynapticsMSTDevicePrivate *priv; device = g_object_new (SYNAPTICSMST_TYPE_DEVICE, NULL); priv = GET_PRIVATE (device); priv->aux_node = g_strdup(aux_node); priv->kind = kind; priv->version = NULL; priv->layer = layer; priv->rad = rad; priv->has_cascade = FALSE; return SYNAPTICSMST_DEVICE (device); } gboolean synapticsmst_device_open (SynapticsMSTDevice *device, GError **error) { SynapticsMSTDevicePrivate *priv = GET_PRIVATE (device); g_autofree gchar *filename = NULL; guint8 byte[4]; g_autoptr(SynapticsMSTConnection) connection = NULL; /* file doesn't exist on this system */ filename = g_strdup_printf ("%s/%s", priv->fw_dir, priv->aux_node); if (!g_file_test (filename, G_FILE_TEST_EXISTS)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "no device exists %s", filename); return FALSE; } /* can't open aux node, try use sudo to get the permission */ priv->fd = open (filename, O_RDWR); if (priv->fd == -1) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, "cannot open device %s", filename); return FALSE; } connection = synapticsmst_common_new (priv->fd, 0, 0); if (synapticsmst_common_aux_node_read (connection, REG_RC_CAP, (gint *)byte, 1) == DPCD_SUCCESS) { if (byte[0] & 0x04) { synapticsmst_common_aux_node_read (connection, REG_VENDOR_ID, (gint *)byte, 3); if (byte[0] == 0x90 && byte[1] == 0xCC && byte[2] == 0x24) return TRUE; } } /* not a correct device */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "no device"); close (priv->fd); priv->fd = 0; return FALSE; } fwupd-1.0.6/plugins/synapticsmst/synapticsmst-device.h000066400000000000000000000100541325145456600232470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * Copyright (C) 2016 Mario Limonciello * Copyright (C) 2017 Peichen Huang * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __SYNAPTICSMST_DEVICE_H #define __SYNAPTICSMST_DEVICE_H #include #include G_BEGIN_DECLS #define SYNAPTICSMST_TYPE_DEVICE (synapticsmst_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (SynapticsMSTDevice, synapticsmst_device, SYNAPTICSMST, DEVICE, GObject) #define SYSFS_DRM_DP_AUX "/sys/class/drm_dp_aux_dev" struct _SynapticsMSTDeviceClass { GObjectClass parent_class; }; /** * SynapticsMSTDeviceKind: * @SYNAPTICSMST_DEVICE_KIND_UNKNOWN: Type invalid or not known * @SYNAPTICSMST_DEVICE_KIND_DIRECT: Directly addressable * @SYNAPTICSMST_DEVICE_KIND_REMOTE: Requires remote register work * * The device type. **/ typedef enum { SYNAPTICSMST_DEVICE_KIND_UNKNOWN, SYNAPTICSMST_DEVICE_KIND_DIRECT, SYNAPTICSMST_DEVICE_KIND_REMOTE, /*< private >*/ SYNAPTICSMST_DEVICE_KIND_LAST } SynapticsMSTDeviceKind; typedef enum { SYNAPTICSMST_DEVICE_BOARDID_EVB = 0x00, SYNAPTICSMST_DEVICE_BOARDID_DELL_X6 = 0x110, SYNAPTICSMST_DEVICE_BOARDID_DELL_X7, SYNAPTICSMST_DEVICE_BOARDID_DELL_WD15_TB16_WIRE, SYNAPTICSMST_DEVICE_BOARDID_DELL_WLD15_WIRELESS, SYNAPTICSMST_DEVICE_BOARDID_DELL_X7_RUGGED = 0X115, SYNAPTICSMST_DEVICE_BOARDID_UNKNOWN = 0xFF, } SynapticsMSTDeviceBoardID; #define CUSTOMERID_DELL 0x1 SynapticsMSTDevice *synapticsmst_device_new (SynapticsMSTDeviceKind kind, const gchar *aux_node, guint8 layer, guint16 rad); /* helpers */ SynapticsMSTDeviceKind synapticsmst_device_kind_from_string (const gchar *kind); const gchar *synapticsmst_device_kind_to_string (SynapticsMSTDeviceKind kind); const gchar *synapticsmst_device_board_id_to_string (SynapticsMSTDeviceBoardID board_id); const gchar *synapticsmst_device_get_guid (SynapticsMSTDevice *device); gboolean synapticsmst_device_scan_cascade_device (SynapticsMSTDevice *device, GError **error, guint8 tx_port); gboolean synapticsmst_device_open (SynapticsMSTDevice *device, GError **error); /* getters */ SynapticsMSTDeviceKind synapticsmst_device_get_kind (SynapticsMSTDevice *device); SynapticsMSTDeviceBoardID synapticsmst_device_get_board_id (SynapticsMSTDevice *device); const gchar *synapticsmst_device_get_version (SynapticsMSTDevice *device); const gchar *synapticsmst_device_get_chip_id (SynapticsMSTDevice *device); const gchar *synapticsmst_device_get_aux_node (SynapticsMSTDevice *device); guint16 synapticsmst_device_get_rad (SynapticsMSTDevice *device); guint8 synapticsmst_device_get_layer (SynapticsMSTDevice *device); gboolean synapticsmst_device_get_cascade (SynapticsMSTDevice *device); /* object methods */ gboolean synapticsmst_device_enumerate_device (SynapticsMSTDevice *devices, const gchar *dock_type, const gchar *sytem_type, GError **error); gboolean synapticsmst_device_write_firmware (SynapticsMSTDevice *device, GBytes *fw, GFileProgressCallback progress_cb, gpointer user_data, GError **error); G_END_DECLS #endif /* __SYNAPTICSMST_DEVICE_H */ fwupd-1.0.6/plugins/synapticsmst/synapticsmst-tool.c000066400000000000000000000306661325145456600227730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Mario Limonciello * Copyright (C) 2017 Peichen Huang * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "synapticsmst-common.h" #include "synapticsmst-device.h" #include #include #include #include #include #include typedef struct { GCancellable *cancellable; GPtrArray *cmd_array; gboolean force; GPtrArray *device_array; } SynapticsMSTToolPrivate; static void synapticsmst_tool_private_free (SynapticsMSTToolPrivate *priv) { if (priv == NULL) return; g_object_unref (priv->cancellable); g_ptr_array_unref (priv->device_array); if (priv->cmd_array != NULL) g_ptr_array_unref (priv->cmd_array); g_free (priv); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(SynapticsMSTToolPrivate, synapticsmst_tool_private_free) typedef gboolean (*FuUtilPrivateCb) (SynapticsMSTToolPrivate *util, gchar **values, guint8 device_index, GError **error); typedef struct { gchar *name; gchar *arguments; gchar *description; FuUtilPrivateCb callback; } FuUtilItem; static void synapticsmst_tool_item_free (FuUtilItem *item) { g_free (item->name); g_free (item->arguments); g_free (item->description); g_free (item); } static gint synapticsmst_tool_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2) { return g_strcmp0 ((*item1)->name, (*item2)->name); } static void synapticsmst_tool_add (GPtrArray *array, const gchar *name, const gchar *arguments, const gchar *description, FuUtilPrivateCb callback) { g_auto(GStrv) names = NULL; g_return_if_fail (name != NULL); g_return_if_fail (description != NULL); g_return_if_fail (callback != NULL); /* add each one */ names = g_strsplit (name, ",", -1); for (guint i = 0; names[i] != NULL; i++) { FuUtilItem *item = g_new0 (FuUtilItem, 1); item->name = g_strdup (names[i]); if (i == 0) { item->description = g_strdup (description); } else { /* TRANSLATORS: this is a command alias, e.g. 'get-devices' */ item->description = g_strdup_printf (_("Alias to %s"), names[0]); } item->arguments = g_strdup (arguments); item->callback = callback; g_ptr_array_add (array, item); } } static gchar * synapticsmst_tool_get_descriptions (GPtrArray *array) { gsize len; const gsize max_len = 31; GString *str; /* print each command */ str = g_string_new (""); for (guint i = 0; i < array->len; i++) { FuUtilItem *item = g_ptr_array_index (array, i); g_string_append (str, " "); g_string_append (str, item->name); len = strlen (item->name) + 2; if (item->arguments != NULL) { g_string_append (str, " "); g_string_append (str, item->arguments); len += strlen (item->arguments) + 1; } if (len < max_len) { for (gsize j = len; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } else { g_string_append_c (str, '\n'); for (gsize j = 0; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } } /* remove trailing newline */ if (str->len > 0) g_string_set_size (str, str->len - 1); return g_string_free (str, FALSE); } static gboolean synapticsmst_tool_scan_aux_nodes (SynapticsMSTToolPrivate *priv, GError **error) { SynapticsMSTDevice *cascade_device = NULL; GDir *dir; const gchar *aux_node; guint8 layer = 0; guint16 rad = 0; dir = g_dir_open (SYSFS_DRM_DP_AUX, 0, NULL); do { g_autoptr(GError) error_local = NULL; g_autoptr(SynapticsMSTDevice) device = NULL; aux_node = g_dir_read_name (dir); if (aux_node == NULL) break; /* can we open the device? */ device = synapticsmst_device_new (SYNAPTICSMST_DEVICE_KIND_DIRECT, aux_node, 0, 0); if (!synapticsmst_device_open (device, &error_local)) { if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) { g_set_error (error, error_local->domain, error_local->code, "failed to open aux node: %s", error_local->message); return FALSE; } /* ignore */ continue; } /* add device to results */ g_ptr_array_add (priv->device_array, g_object_ref (device)); } while (TRUE); /* no devices */ if (priv->device_array->len == 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "No Synaptics MST Device Found"); return FALSE; } /* add all cascaded devices */ for (guint8 i = 0; i < priv->device_array->len; i++) { SynapticsMSTDevice *device = g_ptr_array_index (priv->device_array, i); aux_node = synapticsmst_device_get_aux_node (device); if (!synapticsmst_device_open (device, error)) { g_prefix_error (error, "failed to open aux node %s again", aux_node); return FALSE; } for (guint8 j = 0; j < 2; j++) { if (!synapticsmst_device_scan_cascade_device (device, error, j)) return FALSE; if (!synapticsmst_device_get_cascade (device)) continue; layer = synapticsmst_device_get_layer (device) + 1; rad = synapticsmst_device_get_rad (device) | (j << (2 * (layer - 1))); cascade_device = synapticsmst_device_new (SYNAPTICSMST_DEVICE_KIND_REMOTE, aux_node, layer, rad); g_ptr_array_add (priv->device_array, cascade_device); } } /* success */ return TRUE; } static gboolean synapticsmst_tool_enumerate (SynapticsMSTToolPrivate *priv, gchar **values, guint8 device_index, GError **error) { SynapticsMSTDevice *device = NULL; /* check avaliable dp aux nodes and add devices */ if (!synapticsmst_tool_scan_aux_nodes (priv, error)) return FALSE; g_print ("\nMST Devices:\n"); /* enumerate all devices one by one */ for (guint8 i = 0; i < priv->device_array->len; i++) { const gchar *board_id = NULL; device = g_ptr_array_index (priv->device_array, i); g_print ("[Device %1d]\n", i+1); if (!synapticsmst_device_enumerate_device (device, NULL, NULL, error)) return FALSE; board_id = synapticsmst_device_board_id_to_string (synapticsmst_device_get_board_id (device)); if (board_id != NULL) { g_print ("Device: %s with Synaptics %s\n", board_id, synapticsmst_device_get_chip_id (device)); g_print ("Connect Type: %s in DP Aux Node %s\n", synapticsmst_device_kind_to_string (synapticsmst_device_get_kind (device)), synapticsmst_device_get_aux_node (device)); g_print ("Firmware version: %s\n", synapticsmst_device_get_version (device)); } else { g_print ("Unknown Device\n"); } g_print ("\n"); } return TRUE; } static gboolean synapticsmst_tool_flash (SynapticsMSTToolPrivate *priv, gchar **values, guint8 device_index, GError **error) { SynapticsMSTDevice *device = NULL; gsize len; g_autofree guint8 *data = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(GError) error_local = NULL; /* incorrect args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Incorrect arguments, expected FILENAME]"); return FALSE; } /* check avaliable dp aux nodes and add devices */ if (!synapticsmst_tool_scan_aux_nodes (priv, error)) return FALSE; device = g_ptr_array_index (priv->device_array, (device_index - 1)); if (!synapticsmst_device_enumerate_device (device, NULL, NULL, error)) return FALSE; if (synapticsmst_device_board_id_to_string (synapticsmst_device_get_board_id (device)) == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "failed to flash firmware: unknown device"); return FALSE; } if (!g_file_get_contents (values[0], (gchar **) &data, &len, &error_local)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Failed to flash firmware: " "can't load file %s: %s", values[0], error_local->message); return FALSE; } fw = g_bytes_new (data, len); if (!synapticsmst_device_write_firmware (device, fw, NULL, NULL, error)) { g_prefix_error (error, "failed to flash firmware: "); return FALSE; } g_print ("Update Sucessfully. Please reset device to apply new firmware\n"); return TRUE; } static gboolean synapticsmst_tool_run (SynapticsMSTToolPrivate *priv, const gchar *command, gchar **values, guint8 device_index, GError **error) { /* find command */ for (guint i = 0; i < priv->cmd_array->len; i++) { FuUtilItem *item = g_ptr_array_index (priv->cmd_array, i); if (g_strcmp0 (item->name, command) == 0) return item->callback (priv, values, device_index, error); } /* not found */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, /* TRANSLATORS: error message */ _("Command not found")); return FALSE; } static gboolean synapticsmst_tool_sigint_cb (gpointer user_data) { SynapticsMSTToolPrivate *priv = (SynapticsMSTToolPrivate *) user_data; g_debug ("Handling SIGINT"); g_cancellable_cancel (priv->cancellable); return FALSE; } int main (int argc, char **argv) { gboolean ret; gboolean verbose = FALSE; guint8 device_index = 0; g_autofree gchar *cmd_descriptions = NULL; g_autoptr (SynapticsMSTToolPrivate) priv = g_new0 (SynapticsMSTToolPrivate, 1); g_autoptr (GError) error = NULL; g_autoptr (GOptionContext) context = NULL; const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Print verbose debug statements", NULL }, { "force", '\0', 0, G_OPTION_ARG_NONE, &priv->force, "Force the action ignoring all warnings", NULL }, { NULL} }; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* list of devices */ priv->device_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) synapticsmst_tool_item_free); synapticsmst_tool_add (priv->cmd_array, "enumerate", NULL, /* TRANSLATORS: command description */ _("Enumerate all Synaptics MST devices"), synapticsmst_tool_enumerate); synapticsmst_tool_add (priv->cmd_array, "flash", NULL, /* TRANSLATORS: command description */ _("Flash firmware file to MST device"), synapticsmst_tool_flash); /* do stuff on ctrl+c */ priv->cancellable = g_cancellable_new (); g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT, synapticsmst_tool_sigint_cb, priv, NULL); /* sort by command name */ g_ptr_array_sort (priv->cmd_array, (GCompareFunc) synapticsmst_tool_sort_command_name_cb); /* get a list of the commands */ context = g_option_context_new (NULL); cmd_descriptions = synapticsmst_tool_get_descriptions (priv->cmd_array); g_option_context_set_summary (context, cmd_descriptions); g_set_application_name (_("Synaptics Multistream Transport Utility")); g_option_context_add_main_entries (context, options, NULL); ret = g_option_context_parse (context, &argc, &argv, &error); if (!ret) { /* TRANSLATORS: the user didn't read the man page */ g_print ("%s: %s\n", _("Failed to parse arguments"), error->message); return EXIT_FAILURE; } /* set verbose? */ if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); /* run the specified command */ if (argc == 4) device_index = strtol (argv[3], NULL, 10); ret = synapticsmst_tool_run (priv, argv[1], (gchar**) &argv[2], device_index, &error); if (!ret) { g_print ("%s\n", error->message); return EXIT_FAILURE; } /* success/ */ return EXIT_SUCCESS; } fwupd-1.0.6/plugins/synapticsmst/tests/000077500000000000000000000000001325145456600202425ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/no_devices/000077500000000000000000000000001325145456600223605ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/no_devices/drm_dp_aux0000066400000000000000000003720001325145456600245070ustar00rootroot00000000000000 A   wU@fwupd-1.0.6/plugins/synapticsmst/tests/no_devices/drm_dp_aux1000066400000000000000000000000001325145456600244740ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/no_devices/drm_dp_aux2000066400000000000000000000000001325145456600244750ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/000077500000000000000000000000001325145456600220165ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/drm_dp_aux0000066400000000000000000003720001325145456600241450ustar00rootroot00000000000000 A   wU@fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/drm_dp_aux1000066400000000000000000011610001325145456600241430ustar00rootroot00000000000000wO wO  ?TESLA$SYNA30 ,] Non-PnP fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/drm_dp_aux2000066400000000000000000011610001325145456600241440ustar00rootroot00000000000000|O |O  ?TESLA$SYNA3  G0fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/000077500000000000000000000000001325145456600233115ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/drm_dp_aux0000066400000000000000000007640001325145456600254450ustar00rootroot00000000000000 A   wU@fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/drm_dp_aux1000066400000000000000000003720001325145456600254410ustar00rootroot00000000000000* *  ?TESLAIUS$SYNA30 ,] Non-PnP fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/drm_dp_aux1_eeprom000066400000000000000000000000021325145456600267760ustar00rootroot00000000000000fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/drm_dp_aux2000066400000000000000000007640001325145456600254470ustar00rootroot000000000000002 , 2 ,  ?TESLAPRIUS$SYNA3  ,] Non-PnP fwupd-1.0.6/plugins/synapticsmst/tests/tb16_dock/remote/drm_dp_aux2_eeprom000066400000000000000000000000021325145456600267770ustar00rootroot00000000000000fwupd-1.0.6/plugins/test/000077500000000000000000000000001325145456600153165ustar00rootroot00000000000000fwupd-1.0.6/plugins/test/README.md000066400000000000000000000001741325145456600165770ustar00rootroot00000000000000Test Support ============ Introduction ------------ This plugin is used when running the self tests in the fwupd project. fwupd-1.0.6/plugins/test/fu-plugin-test.c000066400000000000000000000107001325145456600203430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" struct FuPluginData { GMutex mutex; }; void fu_plugin_init (FuPlugin *plugin) { fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); g_debug ("init"); } void fu_plugin_destroy (FuPlugin *plugin) { //FuPluginData *data = fu_plugin_get_data (plugin); g_debug ("destroy"); } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { g_autoptr(FuDevice) device = NULL; device = fu_device_new (); fu_device_set_id (device, "FakeDevice"); fu_device_add_guid (device, "b585990a-003e-5270-89d5-3705a17f9a43"); fu_device_set_name (device, "Integrated_Webcam(TM)"); fu_device_add_icon (device, "preferences-desktop-keyboard"); fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_set_summary (device, "A fake webcam"); fu_device_set_vendor (device, "ACME Corp."); fu_device_set_vendor_id (device, "USB:0x046D"); fu_device_set_version_bootloader (device, "0.1.2"); fu_device_set_version (device, "1.2.2"); fu_device_set_version_lowest (device, "1.2.0"); if (g_strcmp0 (g_getenv ("FWUPD_PLUGIN_TEST"), "registration") == 0) { fu_plugin_device_register (plugin, device); if (fu_device_get_metadata (device, "BestDevice") == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "Device not set by another plugin"); return FALSE; } } fu_plugin_device_add (plugin, device); return TRUE; } void fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) { fu_device_set_metadata (device, "BestDevice", "/dev/urandom"); } gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *device, FuPluginVerifyFlags flags, GError **error) { if (g_strcmp0 (fu_device_get_version (device), "1.2.3") == 0) { fu_device_add_checksum (device, "7998cd212721e068b2411135e1f90d0ad436d730"); fu_device_add_checksum (device, "dbae6a0309b3de8e850921631916a60b2956056e109fc82c586e3f9b64e2401a"); return TRUE; } if (g_strcmp0 (fu_device_get_version (device), "1.2.4") == 0) { fu_device_add_checksum (device, "2b8546ba805ad10bf8a2e5ad539d53f303812ba5"); fu_device_add_checksum (device, "b546c241029ce4e16c99eb6bfd77b86e4490aa3826ba71b8a4114e96a2d69bcd"); return TRUE; } g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no checksum for %s", fu_device_get_version (device)); return FALSE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { if (g_strcmp0 (g_getenv ("FWUPD_PLUGIN_TEST"), "fail") == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "device was not in supported mode"); return FALSE; } fu_device_set_status (device, FWUPD_STATUS_DECOMPRESSING); for (guint i = 1; i <= 100; i++) { g_usleep (1000); fu_device_set_progress (device, i); } fu_device_set_status (device, FWUPD_STATUS_DEVICE_WRITE); for (guint i = 1; i <= 100; i++) { g_usleep (1000); fu_device_set_progress (device, i); } fu_device_set_status (device, FWUPD_STATUS_DEVICE_VERIFY); for (guint i = 1; i <= 100; i++) { g_usleep (1000); fu_device_set_progress (device, i); } /* upgrade, or downgrade */ if (flags & FWUPD_INSTALL_FLAG_ALLOW_OLDER) { fu_device_set_version (device, "1.2.2"); } else { fu_device_set_version (device, "1.2.3"); } return TRUE; } gboolean fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error) { fu_device_set_update_state (device, FWUPD_UPDATE_STATE_SUCCESS); fu_device_set_update_error (device, NULL); return TRUE; } fwupd-1.0.6/plugins/test/meson.build000066400000000000000000000007151325145456600174630ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginTest"'] install_dummy = false if get_option('plugin_dummy') install_dummy = true endif shared_module('fu_plugin_test', sources : [ 'fu-plugin-test.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : install_dummy, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], ) fwupd-1.0.6/plugins/thunderbolt-power/000077500000000000000000000000001325145456600200235ustar00rootroot00000000000000fwupd-1.0.6/plugins/thunderbolt-power/fu-plugin-thunderbolt-power.c000066400000000000000000000210551325145456600255620ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Dell Inc. * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "fu-plugin-vfuncs.h" #include "fu-device-metadata.h" #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) #endif /* empirically measured amount of time for the TBT device to come and go */ #define TBT_NEW_DEVICE_TIMEOUT 2 /* s */ struct FuPluginData { GUdevClient *udev; gchar *force_path; gboolean needs_forcepower; guint timeout_id; }; static void fu_plugin_thunderbolt_power_get_path (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(GList) devices = NULL; const gchar *basepath; const gchar *driver; /* in case driver went away */ if (data->force_path != NULL) { g_free (data->force_path); data->force_path = NULL; } devices = g_udev_client_query_by_subsystem (data->udev, "wmi"); for (GList* l = devices; l != NULL; l = l->next) { g_autofree gchar *built_path = NULL; GUdevDevice *device = l->data; /* only supports intel-wmi-thunderbolt for now */ driver = g_udev_device_get_driver (device); if (g_strcmp0 (driver, "intel-wmi-thunderbolt") != 0) continue; /* check for the attribute to be loaded */ basepath = g_udev_device_get_sysfs_path (device); if (basepath == NULL) continue; built_path = g_build_path ("/", basepath, "force_power", NULL); if (g_file_test (built_path, G_FILE_TEST_IS_REGULAR)) { data->force_path = g_steal_pointer (&built_path); g_debug ("Detected force power support at %s", data->force_path); break; } } g_list_foreach (devices, (GFunc) g_object_unref, NULL); } static gboolean fu_plugin_thunderbolt_power_supported (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); return data->force_path != NULL; } static gboolean fu_plugin_thunderbolt_power_set (FuPlugin *plugin, gboolean enable, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); gint fd; gint ret; if (!fu_plugin_thunderbolt_power_supported (plugin)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "unable to set power to %d (missing kernel support)", enable); return FALSE; } g_debug ("Setting force power to %d", enable); fd = g_open (data->force_path, O_WRONLY); if (fd == -1) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to open %s", data->force_path); return FALSE; } ret = write (fd, enable ? "1" : "0", 1); if (ret < 1) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not write to force_power': %s", g_strerror (errno)); g_close (fd, NULL); return FALSE; } return g_close (fd, error); } static gboolean fu_plugin_thunderbolt_power_reset_cb (gpointer user_data) { FuPlugin *plugin = FU_PLUGIN (user_data); FuPluginData *data = fu_plugin_get_data (plugin); if (!fu_plugin_thunderbolt_power_set (plugin, FALSE, NULL)) g_warning ("failed to reset thunderbolt power"); data->timeout_id = 0; return FALSE; } static gboolean udev_uevent_cb (GUdevClient *udev, const gchar *action, GUdevDevice *device, gpointer user_data) { FuPlugin *plugin = FU_PLUGIN(user_data); if (action == NULL) return TRUE; g_debug ("uevent for %s: %s", g_udev_device_get_sysfs_path (device), action); /* intel-wmi-thunderbolt has been loaded/unloaded */ if (g_str_equal (action, "change")) { fu_plugin_thunderbolt_power_get_path (plugin); if (fu_plugin_thunderbolt_power_supported (plugin)) { fu_plugin_set_enabled (plugin, TRUE); fu_plugin_request_recoldplug (plugin); } else { fu_plugin_set_enabled (plugin, FALSE); } } return TRUE; } /* virtual functions */ void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); const gchar *subsystems[] = { "wmi", NULL }; data->udev = g_udev_client_new (subsystems); g_signal_connect (data->udev, "uevent", G_CALLBACK (udev_uevent_cb), plugin); /* initially set to true, will wait for a device_register to reset */ data->needs_forcepower = TRUE; /* determines whether to run device_registered */ fu_plugin_thunderbolt_power_get_path (plugin); /* make sure it's tried to coldplug */ fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "thunderbolt"); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); if (data->timeout_id != 0) g_source_remove (data->timeout_id); g_object_unref (data->udev); g_free (data->force_path); } void fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device) { FuPluginData *data = fu_plugin_get_data (plugin); /* thunderbolt plugin */ if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") == 0 && fu_plugin_thunderbolt_power_supported (plugin)) { data->needs_forcepower = FALSE; if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) { fu_device_set_metadata_boolean (device, FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER, TRUE); } } } gboolean fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(GUdevDevice) udevice = NULL; const gchar *devpath; /* only run for thunderbolt plugin */ if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") != 0) return TRUE; devpath = fu_device_get_metadata (device, "sysfs-path"); udevice = g_udev_client_query_by_sysfs_path (data->udev, devpath); if (udevice != NULL) { data->needs_forcepower = FALSE; return TRUE; } if (!fu_plugin_thunderbolt_power_set (plugin, TRUE, error)) return FALSE; data->needs_forcepower = TRUE; /* wait for the device to come back onto the bus */ fu_device_set_status (device, FWUPD_STATUS_DEVICE_RESTART); for (guint i = 0; i < 5; i++) { g_autoptr(GUdevDevice) udevice_tmp = NULL; g_usleep (TBT_NEW_DEVICE_TIMEOUT * G_USEC_PER_SEC); udevice_tmp = g_udev_client_query_by_sysfs_path (data->udev, devpath); if (udevice_tmp != NULL) return TRUE; } /* device did not wake up */ g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "device did not wake up when required"); return FALSE; } gboolean fu_plugin_update_cleanup (FuPlugin *plugin, FuDevice *device, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); /* only run for thunderbolt plugin */ if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") != 0) return TRUE; if (data->needs_forcepower && !fu_plugin_thunderbolt_power_set (plugin, FALSE, error)) return FALSE; return TRUE; } static gboolean fu_plugin_thunderbolt_power_coldplug (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); if (!fu_plugin_thunderbolt_power_supported (plugin)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "missing kernel support for intel-wmi-thunderbolt"); return FALSE; } /* this means no devices were found at coldplug by thunderbolt plugin */ if (data->needs_forcepower) { if (!fu_plugin_thunderbolt_power_set (plugin, TRUE, error)) return FALSE; /* in case this was a re-coldplug */ if (data->timeout_id != 0) g_source_remove (data->timeout_id); /* reset force power to off after enough time to enumerate */ data->timeout_id = g_timeout_add (TBT_NEW_DEVICE_TIMEOUT * 10000, fu_plugin_thunderbolt_power_reset_cb, plugin); } return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { return fu_plugin_thunderbolt_power_coldplug (plugin, error); } gboolean fu_plugin_recoldplug (FuPlugin *plugin, GError **error) { return fu_plugin_thunderbolt_power_coldplug (plugin, error); } fwupd-1.0.6/plugins/thunderbolt-power/meson.build000066400000000000000000000007011325145456600221630ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginThunderboltPower"'] fu_plugin_thunderbolt_power = shared_module('fu_plugin_thunderbolt_power', sources : [ 'fu-plugin-thunderbolt-power.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, gudev, ], ) fwupd-1.0.6/plugins/thunderbolt/000077500000000000000000000000001325145456600166715ustar00rootroot00000000000000fwupd-1.0.6/plugins/thunderbolt/README.md000066400000000000000000000044321325145456600201530ustar00rootroot00000000000000Thunderbolt™ Support ==================== Introduction ------------ Thunderbolt™ is the brand name of a hardware interface developed by Intel that allows the connection of external peripherals to a computer. Versions 1 and 2 use the same connector as Mini DisplayPort (MDP), whereas version 3 uses USB Type-C. Runtime Power Management ------------------------ Thunderbolt controllers are slightly unusual in that they power down completely when no thunderbolt devices are detected. This poses a problem for fwupd as it can't coldplug devices to see if there are firmware updates available, and also can't ensure the controller stays awake during a firmware upgrade. On Dell hardware the `Thunderbolt::CanForcePower` metadata value is set as the system can force the thunderbolt controller on during coldplug or during the firmware update process. This is typically done calling a SMI or ACPI method which asserts the GPIO for the duration of the request. On non-Dell hardware you will have to insert a Thunderbolt device (e.g. a dock) into the laptop to be able to update the controller itself. Safe Mode --------- Thunderbolt hardware is also slightly unusual in that it goes into "safe mode" whenever it encounters a critical firmware error, for instance if an update failed to be completed. In this safe mode you cannot query the controller vendor or model and therefore the thunderbolt plugin cannot add the correct GUID used to match it to the correct firmware. In this case the metadata value `Thunderbolt::IsSafeMode` is set which would allow a different plugin to add the correct GUID based on some out-of-band device discovery. At the moment this only happens on Dell hardware. GUID generation for LVFS ------------------------ The GUID for the controller, which must appear in the metadata when uploading an NVM to LVFS, can be generated by a tool like `appstream-util` (with `generate-guid` command) or by Python (with `uuid.uuid5(uuid.NAMESPACE_DNS, 'string')`). The format of the string used as input is "TBT-vvvvdddd", where vvvvv is the vendor ID and dddd is the device ID, both in hex, as appear in the controller's DROM and exposed in the relevant sysfs attributes. If the controller is in native enumeration mode, the string "-native" is added at the end so the format is "TBT-vvvvdddd-native". fwupd-1.0.6/plugins/thunderbolt/fu-plugin-thunderbolt.c000066400000000000000000000562341325145456600233050ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Christian J. Kellner * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "fu-plugin-thunderbolt.h" #include "fu-plugin-vfuncs.h" #include "fu-device-metadata.h" #include "fu-thunderbolt-image.h" #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) #endif typedef void (*UEventNotify) (FuPlugin *plugin, GUdevDevice *udevice, const gchar *action, gpointer user_data); struct FuPluginData { GUdevClient *udev; /* in the case we are updating */ UEventNotify update_notify; gpointer update_data; /* the timeout we wait for the device * to be updated to re-appear, in ms. * defaults to: * FU_PLUGIN_THUNDERBOLT_UPDATE_TIMEOUT_MS */ guint timeout; }; static gchar * fu_plugin_thunderbolt_gen_id_from_syspath (const gchar *syspath) { gchar *id; id = g_strdup_printf ("tbt-%s", syspath); g_strdelimit (id, "/:.-", '_'); return id; } static gchar * fu_plugin_thunderbolt_gen_id (GUdevDevice *device) { const gchar *syspath = g_udev_device_get_sysfs_path (device); return fu_plugin_thunderbolt_gen_id_from_syspath (syspath); } static guint64 udev_device_get_sysattr_guint64 (GUdevDevice *device, const gchar *name, GError **error) { const gchar *sysfs; guint64 val; sysfs = g_udev_device_get_sysfs_attr (device, name); if (sysfs == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed get id %s for %s", name, sysfs); return 0x0; } val = g_ascii_strtoull (sysfs, NULL, 16); if (val == 0x0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to parse %s", sysfs); return 0x0; } return val; } static guint16 fu_plugin_thunderbolt_udev_get_id (GUdevDevice *device, const gchar *name, GError **error) { guint64 id; id = udev_device_get_sysattr_guint64 (device, name, error); if (id == 0x0) return id; if (id > G_MAXUINT16) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "vendor id overflows"); return 0x0; } return (guint16) id; } static gboolean fu_plugin_thunderbolt_is_host (GUdevDevice *device) { g_autoptr(GUdevDevice) parent = NULL; const gchar *name; /* the (probably safe) assumption this code makes is * that the thunderbolt device which is a direct child * of the domain is the host controller device itself */ parent = g_udev_device_get_parent (device); name = g_udev_device_get_name (parent); if (name == NULL) return FALSE; return g_str_has_prefix (name, "domain"); } static GFile * fu_plugin_thunderbolt_find_nvmem (GUdevDevice *udevice, gboolean active, GError **error) { const gchar *nvmem_dir = active ? "nvm_active" : "nvm_non_active"; const gchar *devpath; const gchar *name; g_autoptr(GDir) d = NULL; devpath = g_udev_device_get_sysfs_path (udevice); if (G_UNLIKELY (devpath == NULL)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Could not determine sysfs path for device"); return NULL; } d = g_dir_open (devpath, 0, error); if (d == NULL) return NULL; while ((name = g_dir_read_name (d)) != NULL) { if (g_str_has_prefix (name, nvmem_dir)) { g_autoptr(GFile) parent = g_file_new_for_path (devpath); g_autoptr(GFile) nvm_dir = g_file_get_child (parent, name); return g_file_get_child (nvm_dir, "nvmem"); } } g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Could not find non-volatile memory location"); return NULL; } static gboolean fu_plugin_thunderbolt_is_native (GUdevDevice *udevice, gboolean *is_native, GError **error) { g_autoptr(GFile) nvmem = NULL; g_autoptr(GBytes) controller_fw = NULL; gchar *content; gsize length; nvmem = fu_plugin_thunderbolt_find_nvmem (udevice, TRUE, error); if (nvmem == NULL) return FALSE; if (!g_file_load_contents (nvmem, NULL, &content, &length, NULL, error)) return FALSE; controller_fw = g_bytes_new_take (content, length); return fu_plugin_thunderbolt_controller_is_native (controller_fw, is_native, error); } static gchar * fu_plugin_thunderbolt_parse_version (const gchar *version_raw) { g_auto(GStrv) split = NULL; if (version_raw == NULL) return NULL; split = g_strsplit (version_raw, ".", -1); if (g_strv_length (split) != 2) return NULL; return g_strdup_printf ("%02x.%02x", (guint) g_ascii_strtoull (split[0], NULL, 16), (guint) g_ascii_strtoull (split[1], NULL, 16)); } static void fu_plugin_thunderbolt_add (FuPlugin *plugin, GUdevDevice *device) { FuDevice *dev_tmp; const gchar *name; const gchar *uuid; const gchar *vendor; const gchar *version_raw; const gchar *devpath; const gchar *devtype; gboolean is_host; gboolean is_safemode = FALSE; gboolean is_native = FALSE; guint16 did; guint16 vid; g_autofree gchar *id = NULL; g_autofree gchar *version = NULL; g_autofree gchar *vendor_id = NULL; g_autofree gchar *device_id = NULL; g_autoptr(FuDevice) dev = NULL; g_autoptr(GError) error = NULL; uuid = g_udev_device_get_sysfs_attr (device, "unique_id"); if (uuid == NULL) { /* most likely the domain itself, ignore */ return; } devpath = g_udev_device_get_sysfs_path (device); devtype = g_udev_device_get_devtype (device); if (g_strcmp0 (devtype, "thunderbolt_device") != 0) { g_debug ("ignoring %s device at %s", devtype, devpath); return; } g_debug ("adding udev device: %s at %s", uuid, devpath); id = fu_plugin_thunderbolt_gen_id (device); dev_tmp = fu_plugin_cache_lookup (plugin, id); if (dev_tmp != NULL) { /* devices that are force-powered are re-added */ g_debug ("ignoring duplicate %s", id); return; } vid = fu_plugin_thunderbolt_udev_get_id (device, "vendor", &error); if (vid == 0x0) g_warning ("failed to get Vendor ID: %s", error->message); did = fu_plugin_thunderbolt_udev_get_id (device, "device", &error); if (did == 0x0) g_warning ("failed to get Device ID: %s", error->message); dev = fu_device_new (); /* test for safe mode */ is_host = fu_plugin_thunderbolt_is_host (device); version_raw = g_udev_device_get_sysfs_attr (device, "nvm_version"); version = fu_plugin_thunderbolt_parse_version (version_raw); if (is_host && version == NULL) { g_autofree gchar *test_safe = NULL; g_autofree gchar *safe_path = NULL; /* glib can't return a properly mapped -ENODATA but the * kernel only returns -ENODATA or -EAGAIN */ safe_path = g_build_path ("/", devpath, "nvm_version", NULL); if (!g_file_get_contents (safe_path, &test_safe, NULL, &error) && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_warning ("%s is in safe mode -- VID/DID will " "need to be set by another plugin", devpath); version = g_strdup ("00.00"); is_safemode = TRUE; device_id = g_strdup ("TBT-safemode"); fu_device_set_metadata_boolean (dev, FU_DEVICE_METADATA_TBT_IS_SAFE_MODE, TRUE); } fu_plugin_add_report_metadata (plugin, "ThunderboltSafeMode", is_safemode ? "True" : "False"); } if (!is_safemode) { if (is_host) { if (!fu_plugin_thunderbolt_is_native (device, &is_native, &error)) { g_warning ("failed to get native mode status: %s", error->message); return; } fu_plugin_add_report_metadata (plugin, "ThunderboltNative", is_native ? "True" : "False"); } vendor_id = g_strdup_printf ("TBT:0x%04X", (guint) vid); device_id = g_strdup_printf ("TBT-%04x%04x%s", (guint) vid, (guint) did, is_native ? "-native" : ""); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); } fu_device_set_platform_id (dev, uuid); fu_device_set_metadata (dev, "sysfs-path", devpath); name = g_udev_device_get_sysfs_attr (device, "device_name"); if (name != NULL) { if (is_host) { g_autofree gchar *pretty_name = NULL; pretty_name = g_strdup_printf ("%s Thunderbolt Controller", name); fu_device_set_name (dev, pretty_name); } else { fu_device_set_name (dev, name); } } if (is_host) { fu_device_set_summary (dev, "Unmatched performance for high-speed I/O"); fu_device_add_icon (dev, "computer"); } else { fu_device_add_icon (dev, "audio-card"); } vendor = g_udev_device_get_sysfs_attr (device, "vendor_name"); if (vendor != NULL) fu_device_set_vendor (dev, vendor); if (vendor_id != NULL) fu_device_set_vendor_id (dev, vendor_id); if (device_id != NULL) fu_device_add_guid (dev, device_id); if (version != NULL) fu_device_set_version (dev, version); if (is_host) fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); fu_plugin_cache_add (plugin, id, dev); fu_plugin_device_add (plugin, dev); } static void fu_plugin_thunderbolt_remove (FuPlugin *plugin, GUdevDevice *device) { FuDevice *dev; g_autofree gchar *id = NULL; id = fu_plugin_thunderbolt_gen_id (device); dev = fu_plugin_cache_lookup (plugin, id); if (dev == NULL) return; /* on supported systems other plugins may use a GPIO to force * power on supported devices even when in low power mode -- * this will happen in coldplug_prepare and prepare_for_update */ if (fu_plugin_thunderbolt_is_host (device) && fu_device_get_metadata_boolean (dev, FU_DEVICE_METADATA_TBT_CAN_FORCE_POWER)) { g_debug ("ignoring remove event as force powered"); return; } fu_plugin_device_remove (plugin, dev); fu_plugin_cache_remove (plugin, id); } static void fu_plugin_thunderbolt_change (FuPlugin *plugin, GUdevDevice *device) { FuDevice *dev; const gchar *version; g_autofree gchar *id = NULL; id = fu_plugin_thunderbolt_gen_id (device); dev = fu_plugin_cache_lookup (plugin, id); if (dev == NULL) { g_warning ("got change event for unknown device, adding instead"); fu_plugin_thunderbolt_add (plugin, device); return; } version = g_udev_device_get_sysfs_attr (device, "nvm_version"); fu_device_set_version (dev, version); } static gboolean udev_uevent_cb (GUdevClient *udev, const gchar *action, GUdevDevice *device, gpointer user_data) { FuPlugin *plugin = (FuPlugin *) user_data; FuPluginData *data = fu_plugin_get_data (plugin); if (action == NULL) return TRUE; g_debug ("uevent for %s: %s", g_udev_device_get_sysfs_path (device), action); if (data->update_notify != NULL) { g_debug ("using update notify handler for uevent"); data->update_notify (plugin, device, action, data->update_data); return TRUE; } if (g_str_equal (action, "add")) { fu_plugin_thunderbolt_add (plugin, device); } else if (g_str_equal (action, "remove")) { fu_plugin_thunderbolt_remove (plugin, device); } else if (g_str_equal (action, "change")) { fu_plugin_thunderbolt_change (plugin, device); } return TRUE; } static FuPluginValidation fu_plugin_thunderbolt_validate_firmware (GUdevDevice *udevice, GBytes *blob_fw, GError **error) { g_autoptr(GFile) nvmem = NULL; g_autoptr(GBytes) controller_fw = NULL; gchar *content; gsize length; nvmem = fu_plugin_thunderbolt_find_nvmem (udevice, TRUE, error); if (nvmem == NULL) return VALIDATION_FAILED; if (!g_file_load_contents (nvmem, NULL, &content, &length, NULL, error)) return VALIDATION_FAILED; controller_fw = g_bytes_new_take (content, length); return fu_plugin_thunderbolt_validate_image (controller_fw, blob_fw, error); } static gboolean fu_plugin_thunderbolt_trigger_update (GUdevDevice *udevice, GError **error) { const gchar *devpath; ssize_t n; int fd; int r; g_autofree gchar *auth_path = NULL; devpath = g_udev_device_get_sysfs_path (udevice); auth_path = g_build_filename (devpath, "nvm_authenticate", NULL); fd = open (auth_path, O_WRONLY | O_CLOEXEC); if (fd < 0) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not open 'nvm_authenticate': %s", g_strerror (errno)); return FALSE; } do { n = write (fd, "1", 1); if (n < 1 && errno != EINTR) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could write to 'nvm_authenticate': %s", g_strerror (errno)); (void) close (fd); return FALSE; } } while (n < 1); r = close (fd); if (r < 0 && errno != EINTR) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could close 'nvm_authenticate': %s", g_strerror (errno)); return FALSE; } return TRUE; } static gboolean fu_plugin_thunderbolt_write_firmware (FuDevice *device, GUdevDevice *udevice, GBytes *blob_fw, GError **error) { gsize fw_size; gsize nwritten; gssize n; g_autoptr(GFile) nvmem = NULL; g_autoptr(GOutputStream) os = NULL; nvmem = fu_plugin_thunderbolt_find_nvmem (udevice, FALSE, error); if (nvmem == NULL) return FALSE; os = (GOutputStream *) g_file_append_to (nvmem, G_FILE_CREATE_NONE, NULL, error); if (os == NULL) return FALSE; nwritten = 0; fw_size = g_bytes_get_size (blob_fw); fu_device_set_progress_full (device, nwritten, fw_size); do { g_autoptr(GBytes) fw_data = NULL; fw_data = g_bytes_new_from_bytes (blob_fw, nwritten, fw_size - nwritten); n = g_output_stream_write_bytes (os, fw_data, NULL, error); if (n < 0) return FALSE; nwritten += n; fu_device_set_progress_full (device, nwritten, fw_size); } while (nwritten < fw_size); if (nwritten != fw_size) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "Could not write all data to nvmem"); return FALSE; } return g_output_stream_close (os, NULL, error); } typedef struct UpdateData { gboolean have_device; GMainLoop *mainloop; const gchar *target_uuid; guint timeout_id; GHashTable *changes; } UpdateData; static gboolean on_wait_for_device_timeout (gpointer user_data) { UpdateData *data = (UpdateData *) user_data; g_main_loop_quit (data->mainloop); data->timeout_id = 0; return FALSE; } static void on_wait_for_device_added (FuPlugin *plugin, GUdevDevice *device, UpdateData *up_data) { FuDevice *dev; const gchar *uuid; const gchar *path; const gchar *version; g_autofree gchar *id = NULL; uuid = g_udev_device_get_sysfs_attr (device, "unique_id"); if (uuid == NULL) return; dev = g_hash_table_lookup (up_data->changes, uuid); if (dev == NULL) { /* a previously unknown device, add it via * the normal way */ fu_plugin_thunderbolt_add (plugin, device); return; } /* ensure the device path is correct */ path = g_udev_device_get_sysfs_path (device); fu_device_set_metadata (dev, "sysfs-path", path); /* make sure the version is correct, might have changed * after update. */ version = g_udev_device_get_sysfs_attr (device, "nvm_version"); fu_device_set_version (dev, version); id = fu_plugin_thunderbolt_gen_id (device); fu_plugin_cache_add (plugin, id, dev); g_hash_table_remove (up_data->changes, uuid); /* check if this device is the target*/ if (g_str_equal (uuid, up_data->target_uuid)) { up_data->have_device = TRUE; g_debug ("target (%s) re-appeared", uuid); g_main_loop_quit (up_data->mainloop); } } static void on_wait_for_device_removed (FuPlugin *plugin, GUdevDevice *device, UpdateData *up_data) { g_autofree gchar *id = NULL; FuDevice *dev; const gchar *uuid; id = fu_plugin_thunderbolt_gen_id (device); dev = fu_plugin_cache_lookup (plugin, id); if (dev == NULL) return; fu_plugin_cache_remove (plugin, id); uuid = fu_device_get_platform_id (dev); g_hash_table_insert (up_data->changes, (gpointer) uuid, g_object_ref (dev)); /* check if this device is the target */ if (g_str_equal (uuid, up_data->target_uuid)) { up_data->have_device = FALSE; g_debug ("target (%s) disappeared", uuid); } } static void on_wait_for_device_notify (FuPlugin *plugin, GUdevDevice *device, const char *action, gpointer user_data) { UpdateData *up_data = (UpdateData *) user_data; /* nb: action cannot be NULL since we are only called from * udev_event_cb, which ensures that */ if (g_str_equal (action, "add")) { on_wait_for_device_added (plugin, device, up_data); } else if (g_str_equal (action, "remove")) { on_wait_for_device_removed (plugin, device, up_data); } else if (g_str_equal (action, "change")) { fu_plugin_thunderbolt_change (plugin, device); } } static void remove_leftover_devices (gpointer key, gpointer value, gpointer user_data) { FuPlugin *plugin = FU_PLUGIN (user_data); FuDevice *dev = FU_DEVICE (value); const gchar *syspath = fu_device_get_metadata (dev, "sysfs-path"); g_autofree gchar *id = NULL; id = fu_plugin_thunderbolt_gen_id_from_syspath (syspath); fu_plugin_cache_remove (plugin, id); fu_plugin_device_remove (plugin, dev); } static gboolean fu_plugin_thunderbolt_wait_for_device (FuPlugin *plugin, FuDevice *dev, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); UpdateData up_data = { TRUE, }; g_autoptr(GMainLoop) mainloop = NULL; g_autoptr(GHashTable) changes = NULL; up_data.mainloop = mainloop = g_main_loop_new (NULL, FALSE); up_data.target_uuid = fu_device_get_platform_id (dev); /* this will limit the maximum amount of time we wait for * the device (i.e. 'dev') to re-appear. */ up_data.timeout_id = g_timeout_add (data->timeout, on_wait_for_device_timeout, &up_data); /* this will capture the device added, removed, changed * signals while we are updating. */ data->update_data = &up_data; data->update_notify = on_wait_for_device_notify; changes = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); up_data.changes = changes; /* now we wait ... */ g_main_loop_run (mainloop); /* restore original udev change handler */ data->update_data = NULL; data->update_notify = NULL; if (up_data.timeout_id > 0) g_source_remove (up_data.timeout_id); if (!up_data.have_device) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "timed out while waiting for device"); return FALSE; } g_hash_table_foreach (changes, remove_leftover_devices, plugin); return TRUE; } /* internal interface */ void fu_plugin_thunderbolt_set_timeout (FuPlugin *plugin, guint timeout_ms) { FuPluginData *data = fu_plugin_get_data (plugin); data->timeout = timeout_ms; } /* virtual functions */ void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); const gchar *subsystems[] = { "thunderbolt", NULL }; data->udev = g_udev_client_new (subsystems); g_signal_connect (data->udev, "uevent", G_CALLBACK (udev_uevent_cb), plugin); data->timeout = FU_PLUGIN_THUNDERBOLT_UPDATE_TIMEOUT_MS; } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_object_unref (data->udev); } static gboolean fu_plugin_thunderbolt_coldplug (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); GList *devices; devices = g_udev_client_query_by_subsystem (data->udev, "thunderbolt"); for (GList *l = devices; l != NULL; l = l->next) { GUdevDevice *device = l->data; fu_plugin_thunderbolt_add (plugin, device); } g_list_foreach (devices, (GFunc) g_object_unref, NULL); g_list_free (devices); return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { return fu_plugin_thunderbolt_coldplug (plugin, error); } gboolean fu_plugin_recoldplug (FuPlugin *plugin, GError **error) { return fu_plugin_thunderbolt_coldplug (plugin, error); } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); const gchar *devpath; guint64 status; g_autoptr(GUdevDevice) udevice = NULL; g_autoptr(GError) error_local = NULL; gboolean force = (flags & FWUPD_INSTALL_FLAG_FORCE) != 0; FuPluginValidation validation; devpath = fu_device_get_metadata (dev, "sysfs-path"); g_return_val_if_fail (devpath, FALSE); udevice = g_udev_client_query_by_sysfs_path (data->udev, devpath); if (udevice == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "could not find thunderbolt device at %s", devpath); return FALSE; } validation = fu_plugin_thunderbolt_validate_firmware (udevice, blob_fw, &error_local); if (validation != VALIDATION_PASSED) { g_autofree gchar* msg = NULL; switch (validation) { case VALIDATION_FAILED: msg = g_strdup_printf ("could not validate firmware: %s", error_local->message); break; case UNKNOWN_DEVICE: msg = g_strdup ("firmware validation seems to be passed but the device is unknown"); break; default: break; } if (!force) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "%s. " "See https://github.com/hughsie/fwupd/wiki/Thunderbolt:-Validation-failed-or-unknown-device for more information.", msg); return FALSE; } g_warning ("%s", msg); } fu_device_set_status (dev, FWUPD_STATUS_DEVICE_WRITE); if (!fu_plugin_thunderbolt_write_firmware (dev, udevice, blob_fw, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "could not write firmware to thunderbolt device at %s: %s", devpath, error_local->message); return FALSE; } if (!fu_plugin_thunderbolt_trigger_update (udevice, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Could not start thunderbolt device upgrade: %s", error_local->message); return FALSE; } fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); /* the device will disappear and we need to wait until it reappears, * and then check if we find an error */ if (!fu_plugin_thunderbolt_wait_for_device (plugin, dev, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "could not detect device after update: %s", error_local->message); return FALSE; } /* now check if the update actually worked */ status = udev_device_get_sysattr_guint64 (udevice, "nvm_authenticate", &error_local); /* anything else then 0x0 means we got an error */ if (status != 0x0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "update failed (status %" G_GINT64_MODIFIER "x)", status); return FALSE; } return TRUE; } fwupd-1.0.6/plugins/thunderbolt/fu-plugin-thunderbolt.h000066400000000000000000000023131325145456600232770ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Christian J. Kellner * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_PLUGIN_THUNDERBOLT_H__ #define __FU_PLUGIN_THUNDERBOLT_H__ #include "fu-plugin.h" #define FU_PLUGIN_THUNDERBOLT_UPDATE_TIMEOUT_MS 60 * 1000 void fu_plugin_thunderbolt_set_timeout (FuPlugin *plugin, guint timeout_ms); #endif /* __FU_PLUGIN_THUNDERBOLT_H__ */ fwupd-1.0.6/plugins/thunderbolt/fu-self-test.c000066400000000000000000001016131325145456600213550ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Christian J. Kellner * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fu-plugin-private.h" #include "fu-plugin-thunderbolt.h" #include "fu-thunderbolt-image.h" #include "fu-test.h" static gchar * udev_mock_add_domain (UMockdevTestbed *bed, int id) { gchar *path; g_autofree gchar *name = NULL; name = g_strdup_printf ("domain%d", id); path = umockdev_testbed_add_device (bed, "thunderbolt", name, NULL, "security", "secure", NULL, "DEVTYPE", "thunderbolt_domain", NULL); g_assert_nonnull (path); return path; } static gchar * udev_mock_add_nvmem (UMockdevTestbed *bed, gboolean active, const char *parent, int id) { g_autofree gchar *name = NULL; gchar *path; name = g_strdup_printf ("%s%d", active ? "nvm_active" : "nvm_non_active", id); path = umockdev_testbed_add_device (bed, "nvmem", name, parent, "nvmem", "", NULL, NULL); g_assert_nonnull (path); return path; } typedef struct MockDevice MockDevice; struct MockDevice { const char *name; /* sysfs: device_name */ const char *id; /* sysfs: device */ const char *nvm_version; int delay_ms; int domain_id; struct MockDevice *children; /* optionally filled out */ const char *uuid; }; typedef struct MockTree MockTree; struct MockTree { const MockDevice *device; MockTree *parent; GPtrArray *children; gchar *sysfs_parent; int sysfs_id; int sysfs_nvm_id; gchar *uuid; UMockdevTestbed *bed; gchar *path; gchar *nvm_non_active; gchar *nvm_active; guint nvm_authenticate; gchar *nvm_version; FuDevice *fu_device; }; static MockTree * mock_tree_new (MockTree *parent, MockDevice *device, int *id) { MockTree *node = g_slice_new0 (MockTree); int current_id = (*id)++; node->device = device; node->sysfs_id = current_id; node->sysfs_nvm_id = current_id; node->parent = parent; if (device->uuid) node->uuid = g_strdup (device->uuid); else node->uuid = g_uuid_string_random (); node->nvm_version = g_strdup (device->nvm_version); return node; } static void mock_tree_free (MockTree *tree) { for (guint i = 0; i < tree->children->len; i++) { MockTree *child = g_ptr_array_index (tree->children, i); mock_tree_free (child); } g_ptr_array_free (tree->children, TRUE); if (tree->fu_device) g_object_unref (tree->fu_device); g_free (tree->uuid); if (tree->bed != NULL) { if (tree->nvm_active) { umockdev_testbed_uevent (tree->bed, tree->nvm_active, "remove"); umockdev_testbed_remove_device (tree->bed, tree->nvm_active); } if (tree->nvm_non_active) { umockdev_testbed_uevent (tree->bed, tree->nvm_non_active, "remove"); umockdev_testbed_remove_device (tree->bed, tree->nvm_non_active); } if (tree->path) { umockdev_testbed_uevent (tree->bed, tree->path, "remove"); umockdev_testbed_remove_device (tree->bed, tree->path); } g_object_unref (tree->bed); } g_free (tree->nvm_version); g_free (tree->nvm_active); g_free (tree->nvm_non_active); g_free (tree->path); g_free (tree->sysfs_parent); g_slice_free (MockTree, tree); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (MockTree, mock_tree_free); static GPtrArray * mock_tree_init_children (MockTree *node, int *id) { GPtrArray *children = g_ptr_array_new (); MockDevice *iter; for (iter = node->device->children; iter && iter->name; iter++) { MockTree *child = mock_tree_new (node, iter, id); g_ptr_array_add (children, child); child->children = mock_tree_init_children (child, id); } return children; } static MockTree * mock_tree_init (MockDevice *device) { MockTree *tree; int devices = 0; tree = mock_tree_new (NULL, device, &devices); tree->children = mock_tree_init_children (tree, &devices); return tree; } static void mock_tree_dump (const MockTree *node, int level) { if (node->path) { g_debug ("%*s * %s [%s] at %s", level, " ", node->device->name, node->uuid, node->path); g_debug ("%*s non-active nvmem at %s", level, " ", node->nvm_non_active); g_debug ("%*s active nvmem at %s", level, " ", node->nvm_active); } else { g_debug ("%*s * %s [%s] %d", level, " ", node->device->name, node->uuid, node->sysfs_id); } for (guint i = 0; i < node->children->len; i++) { const MockTree *child = g_ptr_array_index (node->children, i); mock_tree_dump (child, level + 2); } } static void mock_tree_firmware_verify (const MockTree *node, GBytes *data) { g_autoptr(GFile) nvm_device = NULL; g_autoptr(GFile) nvm = NULL; g_autoptr(GInputStream) is = NULL; g_autoptr(GChecksum) chk = NULL; g_autoptr(GError) error = NULL; g_autofree gchar *sum_data = NULL; const gchar *sum_disk = NULL; gsize s; sum_data = g_compute_checksum_for_bytes (G_CHECKSUM_SHA1, data); chk = g_checksum_new (G_CHECKSUM_SHA1); g_assert_nonnull (node); g_assert_nonnull (node->nvm_non_active); nvm_device = g_file_new_for_path (node->nvm_non_active); nvm = g_file_get_child (nvm_device, "nvmem"); is = (GInputStream *) g_file_read (nvm, NULL, &error); g_assert_no_error (error); g_assert_nonnull (is); do { g_autoptr(GBytes) b = NULL; const guchar *d; b = g_input_stream_read_bytes (is, 4096, NULL, &error); g_assert_no_error (error); g_assert_nonnull (is); d = g_bytes_get_data (b, &s); if (s > 0) g_checksum_update (chk, d, (gssize) s); } while (s > 0); sum_disk = g_checksum_get_string (chk); g_assert_cmpstr (sum_data, ==, sum_disk); } typedef gboolean (* MockTreePredicate) (const MockTree *node, gpointer data); static const MockTree * mock_tree_contains (const MockTree *node, MockTreePredicate predicate, gpointer data) { if (predicate (node, data)) return node; for (guint i = 0; i < node->children->len; i++) { const MockTree *child; const MockTree *match; child = g_ptr_array_index (node->children, i); match = mock_tree_contains (child, predicate, data); if (match != NULL) return match; } return NULL; } static gboolean mock_tree_all (const MockTree *node, MockTreePredicate predicate, gpointer data) { if (!predicate (node, data)) return FALSE; for (guint i = 0; i < node->children->len; i++) { const MockTree *child; child = g_ptr_array_index (node->children, i); if (!mock_tree_all (child, predicate, data)) return FALSE; } return TRUE; } static gboolean mock_tree_compare_uuid (const MockTree *node, gpointer data) { const gchar *uuid = (const gchar *) data; return g_str_equal (node->uuid, uuid); } static const MockTree * mock_tree_find_uuid (const MockTree *root, const char *uuid) { return mock_tree_contains (root, mock_tree_compare_uuid, (gpointer) uuid); } static gboolean mock_tree_node_have_fu_device (const MockTree *node, gpointer data) { return node->fu_device != NULL; } static void write_controller_fw (const gchar *nvm) { g_autoptr(GFile) nvm_device = NULL; g_autoptr(GFile) nvmem = NULL; g_autofree gchar *fw_path = NULL; g_autoptr(GFile) fw_file = NULL; g_autoptr(GInputStream) is = NULL; g_autoptr(GOutputStream) os = NULL; g_autoptr(GError) error = NULL; gssize n; fw_path = fu_test_get_filename (TESTDATADIR, "thunderbolt/minimal-fw-controller.bin"); g_assert_nonnull (fw_path); fw_file = g_file_new_for_path (fw_path); g_assert_nonnull (fw_file); nvm_device = g_file_new_for_path (nvm); g_assert_nonnull (nvm_device); nvmem = g_file_get_child (nvm_device, "nvmem"); g_assert_nonnull (nvmem); os = (GOutputStream *) g_file_append_to (nvmem, G_FILE_CREATE_NONE, NULL, &error); g_assert_no_error (error); g_assert_nonnull (os); is = (GInputStream *) g_file_read (fw_file, NULL, &error); g_assert_no_error (error); g_assert_nonnull (is); n = g_output_stream_splice (os, is, G_OUTPUT_STREAM_SPLICE_NONE, NULL, &error); g_assert_no_error (error); g_assert_cmpuint (n, >, 0); } static gboolean mock_tree_attach_device (gpointer user_data) { MockTree *tree = (MockTree *) user_data; const MockDevice *dev = tree->device; g_autofree gchar *idstr = NULL; g_autofree gchar *authenticate = NULL; g_assert_nonnull (tree); g_assert_nonnull (tree->sysfs_parent); g_assert_nonnull (dev); idstr = g_strdup_printf ("%d-%d", dev->domain_id, tree->sysfs_id); authenticate = g_strdup_printf ("0x%x", tree->nvm_authenticate); tree->path = umockdev_testbed_add_device (tree->bed, "thunderbolt", idstr, tree->sysfs_parent, "device_name", dev->name, "device", dev->id, "vendor", "042", "vendor_name", "GNOME.org", "authorized", "0", "nvm_authenticate", authenticate, "nvm_version", tree->nvm_version, "unique_id", tree->uuid, NULL, "DEVTYPE", "thunderbolt_device", NULL); tree->nvm_non_active = udev_mock_add_nvmem (tree->bed, FALSE, tree->path, tree->sysfs_id); tree->nvm_active = udev_mock_add_nvmem (tree->bed, TRUE, tree->path, tree->sysfs_id); g_assert_nonnull (tree->path); g_assert_nonnull (tree->nvm_non_active); g_assert_nonnull (tree->nvm_active); write_controller_fw (tree->nvm_active); for (guint i = 0; i < tree->children->len; i++) { MockTree *child; child = g_ptr_array_index (tree->children, i); child->bed = g_object_ref (tree->bed); child->sysfs_parent = g_strdup (tree->path); g_timeout_add (child->device->delay_ms, mock_tree_attach_device, child); } return FALSE; } typedef struct SyncContext { MockTree *tree; GMainLoop *loop; } SyncContext; static gboolean on_sync_timeout (gpointer user_data) { SyncContext *ctx = (SyncContext *) user_data; g_main_loop_quit (ctx->loop); return FALSE; } static void sync_device_added (FuPlugin *plugin, FuDevice *device, gpointer user_data) { SyncContext *ctx = (SyncContext *) user_data; MockTree *tree = ctx->tree; const gchar *uuid = fu_device_get_platform_id (device); MockTree *target; target = (MockTree *) mock_tree_find_uuid (tree, uuid); if (target == NULL) { g_critical ("Got device that could not be matched: %s", uuid); return; } if (target->fu_device != NULL) g_object_unref (target->fu_device); target->fu_device = g_object_ref (device); } static void sync_device_removed (FuPlugin *plugin, FuDevice *device, gpointer user_data) { SyncContext *ctx = (SyncContext *) user_data; MockTree *tree = ctx->tree; const gchar *uuid = fu_device_get_platform_id (device); MockTree *target; target = (MockTree *) mock_tree_find_uuid (tree, uuid); if (target == NULL) { g_warning ("Got device that could not be matched: %s", uuid); return; } else if (target->fu_device == NULL) { g_warning ("Got remove event for out-of-tree device %s", uuid); return; } g_object_unref (target->fu_device); target->fu_device = NULL; } static void mock_tree_sync (MockTree *root, FuPlugin *plugin, int timeout_ms) { g_autoptr(GMainLoop) mainloop = g_main_loop_new (NULL, FALSE); gulong id_add; gulong id_del; SyncContext ctx = { .tree = root, .loop = mainloop, }; id_add = g_signal_connect (plugin, "device-added", G_CALLBACK (sync_device_added), &ctx); id_del = g_signal_connect (plugin, "device-removed", G_CALLBACK (sync_device_removed), &ctx); if (timeout_ms > 0) g_timeout_add (timeout_ms, on_sync_timeout, &ctx); g_main_loop_run (mainloop); g_signal_handler_disconnect (plugin, id_add); g_signal_handler_disconnect (plugin, id_del); } typedef struct AttachContext { /* in */ MockTree *tree; GMainLoop *loop; /* out */ gboolean complete; } AttachContext; static void mock_tree_plugin_device_added (FuPlugin *plugin, FuDevice *device, gpointer user_data) { AttachContext *ctx = (AttachContext *) user_data; MockTree *tree = ctx->tree; const gchar *uuid = fu_device_get_platform_id (device); MockTree *target; target = (MockTree *) mock_tree_find_uuid (tree, uuid); if (target == NULL) { g_warning ("Got device that could not be matched: %s", uuid); return; } target->fu_device = g_object_ref (device); if (mock_tree_all (tree, mock_tree_node_have_fu_device, NULL)) { ctx->complete = TRUE; g_main_loop_quit (ctx->loop); } } static gboolean mock_tree_settle (MockTree *root, FuPlugin *plugin) { g_autoptr(GMainLoop) mainloop = g_main_loop_new (NULL, FALSE); gulong id; AttachContext ctx = { .tree = root, .loop = mainloop, }; id = g_signal_connect (plugin, "device-added", G_CALLBACK (mock_tree_plugin_device_added), &ctx); g_main_loop_run (mainloop); g_signal_handler_disconnect (plugin, id); return ctx.complete; } static gboolean mock_tree_attach (MockTree *root, UMockdevTestbed *bed, FuPlugin *plugin) { root->bed = g_object_ref (bed); root->sysfs_parent = udev_mock_add_domain (bed, root->device->domain_id); g_assert_nonnull (root->sysfs_parent); g_timeout_add (root->device->delay_ms, mock_tree_attach_device, root); return mock_tree_settle (root, plugin); } /* the unused parameter makes the function signature compatible * with 'MockTreePredicate' */ static gboolean mock_tree_node_is_detached (const MockTree *node, gpointer unused) { gboolean ret = node->path == NULL; /* consistency checks: if ret, make sure we are * fully detached */ if (ret) { g_assert_null (node->nvm_active); g_assert_null (node->nvm_non_active); g_assert_null (node->bed); } else { g_assert_nonnull (node->nvm_active); g_assert_nonnull (node->nvm_non_active); g_assert_nonnull (node->bed); } return ret; } static void mock_tree_detach (MockTree *node) { UMockdevTestbed *bed; if (mock_tree_node_is_detached (node, NULL)) return; for (guint i = 0; i < node->children->len; i++) { MockTree *child = g_ptr_array_index (node->children, i); mock_tree_detach (child); g_free (child->sysfs_parent); child->sysfs_parent = NULL; } bed = node->bed; umockdev_testbed_uevent (bed, node->nvm_active, "remove"); umockdev_testbed_remove_device (bed, node->nvm_active); umockdev_testbed_uevent (bed, node->nvm_non_active, "remove"); umockdev_testbed_remove_device (bed, node->nvm_non_active); umockdev_testbed_uevent (bed, node->path, "remove"); umockdev_testbed_remove_device (bed, node->path); g_free (node->path); g_free (node->nvm_non_active); g_free (node->nvm_active); node->path = NULL; node->nvm_non_active = NULL; node->nvm_active = NULL; g_object_unref (bed); node->bed = NULL; } typedef enum UpdateResult { UPDATE_SUCCESS = 0, /* nvm_authenticate will report error condition */ UPDATE_FAIL_DEVICE_INTERNAL = 1, /* device to be updated will NOT re-appear */ UPDATE_FAIL_DEVICE_NOSHOW = 2 } UpdateResult; typedef struct UpdateContext { GFileMonitor *monitor; UpdateResult result; guint timeout; GBytes *data; UMockdevTestbed *bed; FuPlugin *plugin; MockTree *node; gchar *version; } UpdateContext; static void update_context_free (UpdateContext *ctx) { if (ctx == NULL) return; g_object_unref (ctx->bed); g_object_unref (ctx->plugin); g_object_unref (ctx->monitor); g_bytes_unref (ctx->data); g_free (ctx->version); g_free (ctx); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (UpdateContext, update_context_free); static gboolean reattach_tree (gpointer user_data) { UpdateContext *ctx = (UpdateContext *) user_data; MockTree *node = ctx->node; g_debug ("Mock update done, reattaching tree..."); node->bed = g_object_ref (ctx->bed); g_timeout_add (node->device->delay_ms, mock_tree_attach_device, node); return FALSE; } static void udev_file_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { UpdateContext *ctx = (UpdateContext *) user_data; gboolean ok; gsize len; g_autofree gchar *data = NULL; g_autoptr(GError) error = NULL; g_debug ("Got update trigger"); ok = g_file_monitor_cancel (monitor); g_assert_true (ok); ok = g_file_load_contents (file, NULL, &data, &len, NULL, &error); g_assert_no_error (error); g_assert_true (ok); if (!g_str_has_prefix (data, "1")) return; /* verify the firmware is correct */ mock_tree_firmware_verify (ctx->node, ctx->data); g_debug ("Removing tree below and including: %s", ctx->node->path); mock_tree_detach (ctx->node); ctx->node->nvm_authenticate = (guint) ctx->result; /* update the version only on "success" simulations */ if (ctx->result == UPDATE_SUCCESS) { g_free (ctx->node->nvm_version); ctx->node->nvm_version = g_strdup (ctx->version); } g_debug ("Simulating update to '%s' with result: 0x%x", ctx->version, ctx->node->nvm_authenticate); if (ctx->result == UPDATE_FAIL_DEVICE_NOSHOW) { g_debug ("Simulating no-show fail:" " device tree will not reappear"); return; } g_debug ("Device tree reattachment in %3.2f seconds", ctx->timeout / 1000.0); g_timeout_add (ctx->timeout, reattach_tree, ctx); } static UpdateContext * mock_tree_prepare_for_update (MockTree *node, FuPlugin *plugin, const char *version, GBytes *fw_data, guint timeout_ms) { UpdateContext *ctx; g_autoptr(GFile) dir = NULL; g_autoptr(GFile) f = NULL; g_autoptr(GError) error = NULL; GFileMonitor *monitor; ctx = g_new0 (UpdateContext, 1); dir = g_file_new_for_path (node->path); f = g_file_get_child (dir, "nvm_authenticate"); monitor = g_file_monitor_file (f, G_FILE_MONITOR_NONE, NULL, &error); g_assert_no_error (error); g_assert_nonnull (monitor); ctx->node = node; ctx->plugin = g_object_ref (plugin); ctx->bed = g_object_ref (node->bed); ctx->timeout = timeout_ms; ctx->monitor = monitor; ctx->version = g_strdup (version); ctx->data = g_bytes_ref (fw_data); g_signal_connect (monitor, "changed", G_CALLBACK (udev_file_changed_cb), ctx); return ctx; } static MockDevice root_one = { .name = "Laptop", .id = "0x23", .nvm_version = "20.0", .children = (MockDevice[]) { { .name = "Thunderbolt Cable", .id = "0x24", .nvm_version = "20.0", .children = (MockDevice[]) { { .name = "Thunderbolt Dock", .id = "0x25", .nvm_version = "10.0", }, { NULL, } }, }, { .name = "Thunderbolt Cable", .id = "0x24", .nvm_version = "23.0", .children = (MockDevice[]) { { .name = "Thunderbolt SSD", .id = "0x26", .nvm_version = "5.0", }, { NULL, } }, }, { NULL, }, }, }; typedef struct TestParam { gboolean initialize_tree; gboolean attach_and_coldplug; const char *firmware_file; } TestParam; typedef enum TestFlags { TEST_INITIALIZE_TREE = 1 << 0, TEST_ATTACH_AND_COLDPLUG = 1 << 1, TEST_PREPARE_FIRMWARE = 1 << 2, TEST_PREPARE_ALL = TEST_INITIALIZE_TREE | TEST_ATTACH_AND_COLDPLUG | TEST_PREPARE_FIRMWARE } TestFlags; #define TEST_INIT_FULL (GUINT_TO_POINTER (TEST_PREPARE_ALL)) #define TEST_INIT_NONE (GUINT_TO_POINTER (0)) typedef struct ThunderboltTest { UMockdevTestbed *bed; FuPlugin *plugin; /* if TestParam::initialize_tree */ MockTree *tree; /* if TestParam::firmware_file is nonnull */ GMappedFile *fw_file; GBytes *fw_data; } ThunderboltTest; static void test_set_up (ThunderboltTest *tt, gconstpointer params) { TestFlags flags = GPOINTER_TO_UINT(params); gboolean ret; g_autoptr(GError) error = NULL; tt->bed = umockdev_testbed_new (); g_assert_nonnull (tt->bed); g_debug ("mock sysfs at %s", umockdev_testbed_get_sys_dir (tt->bed)); tt->plugin = fu_plugin_new (); g_assert_nonnull (tt->plugin); ret = fu_plugin_open (tt->plugin, PLUGINBUILDDIR "/libfu_plugin_thunderbolt.so", &error); g_assert_no_error (error); g_assert_true (ret); ret = fu_plugin_runner_startup (tt->plugin, &error); g_assert_no_error (error); g_assert_true (ret); if (flags & TEST_INITIALIZE_TREE) { tt->tree = mock_tree_init (&root_one); g_assert_nonnull (tt->tree); } if (!umockdev_in_mock_environment ()) { g_warning ("Need to run within umockdev wrapper (umockdev-wrapper %s)!", program_invocation_short_name); return; } if (flags & TEST_ATTACH_AND_COLDPLUG) { g_assert_true (flags & TEST_INITIALIZE_TREE); ret = fu_plugin_runner_coldplug (tt->plugin, &error); g_assert_no_error (error); g_assert_true (ret); ret = mock_tree_attach (tt->tree, tt->bed, tt->plugin); g_assert_true (ret); } if (flags & TEST_PREPARE_FIRMWARE) { g_autofree gchar *fw_path = NULL; fw_path = fu_test_get_filename (TESTDATADIR, "thunderbolt/minimal-fw.bin"); g_assert_nonnull (fw_path); tt->fw_file = g_mapped_file_new (fw_path, FALSE, &error); g_assert_no_error (error); g_assert_nonnull (tt->fw_file); tt->fw_data = g_mapped_file_get_bytes (tt->fw_file); g_assert_nonnull (tt->fw_data); } } static void test_tear_down (ThunderboltTest *tt, gconstpointer user_data) { g_object_unref (tt->plugin); g_object_unref (tt->bed); if (tt->tree) mock_tree_free (tt->tree); if (tt->fw_data) g_bytes_unref (tt->fw_data); if (tt->fw_file) g_mapped_file_unref (tt->fw_file); } static gboolean test_tree_uuids (const MockTree *node, gpointer data) { const MockTree *root = (MockTree *) data; const gchar *uuid = node->uuid; const MockTree *found; g_assert_nonnull (uuid); g_debug ("Looking for %s", uuid); found = mock_tree_find_uuid (root, uuid); g_assert_nonnull (found); g_assert_cmpstr (node->uuid, ==, found->uuid); /* return false so we traverse the whole tree */ return FALSE; } static void test_tree (ThunderboltTest *tt, gconstpointer user_data) { const MockTree *found; gboolean ret; g_autoptr(MockTree) tree = NULL; g_autoptr(GError) error = NULL; tree = mock_tree_init (&root_one); g_assert_nonnull (tree); mock_tree_dump (tree, 0); (void) mock_tree_contains (tree, test_tree_uuids, tree); found = mock_tree_find_uuid (tree, "nonexistentuuid"); g_assert_null (found); ret = fu_plugin_runner_coldplug (tt->plugin, &error); g_assert_no_error (error); g_assert_true (ret); ret = mock_tree_attach (tree, tt->bed, tt->plugin); g_assert_true (ret); mock_tree_detach (tree); ret = mock_tree_all (tree, mock_tree_node_is_detached, NULL); g_assert_true (ret); } static void test_image_validation (ThunderboltTest *tt, gconstpointer user_data) { FuPluginValidation val; g_autofree gchar *ctl_path = NULL; g_autofree gchar *fwi_path = NULL; g_autofree gchar *bad_path = NULL; g_autoptr(GMappedFile) fwi_file = NULL; g_autoptr(GMappedFile) ctl_file = NULL; g_autoptr(GMappedFile) bad_file = NULL; g_autoptr(GBytes) fwi_data = NULL; g_autoptr(GBytes) ctl_data = NULL; g_autoptr(GBytes) bad_data = NULL; g_autoptr(GError) error = NULL; /* image as if read from the controller (i.e. no headers) */ ctl_path = fu_test_get_filename (TESTDATADIR, "thunderbolt/minimal-fw-controller.bin"); g_assert_nonnull (ctl_path); ctl_file = g_mapped_file_new (ctl_path, FALSE, &error); g_assert_no_error (error); g_assert_nonnull (ctl_file); ctl_data = g_mapped_file_get_bytes (ctl_file); g_assert_nonnull (ctl_data); /* valid firmware update image */ fwi_path = fu_test_get_filename (TESTDATADIR, "thunderbolt/minimal-fw.bin"); g_assert_nonnull (fwi_path); fwi_file = g_mapped_file_new (fwi_path, FALSE, &error); g_assert_no_error (error); g_assert_nonnull (fwi_file); fwi_data = g_mapped_file_get_bytes (fwi_file); g_assert_nonnull (fwi_data); /* a wrong/bad firmware update image */ bad_path = fu_test_get_filename (TESTDATADIR, "colorhug/firmware.bin"); g_assert_nonnull (bad_path); bad_file = g_mapped_file_new (bad_path, FALSE, &error); g_assert_no_error (error); g_assert_nonnull (bad_file); bad_data = g_mapped_file_get_bytes (bad_file); g_assert_nonnull (bad_data); /* now for some testing ... this should work */ val = fu_plugin_thunderbolt_validate_image (ctl_data, fwi_data, &error); g_assert_no_error (error); g_assert_cmpint (val, ==, VALIDATION_PASSED); /* these all should fail */ /* valid controller, bad update data */ val = fu_plugin_thunderbolt_validate_image (ctl_data, ctl_data, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_READ); g_assert_cmpint (val, ==, VALIDATION_FAILED); g_debug ("expected image validation error [ctl, ctl]: %s", error->message); g_clear_error (&error); val = fu_plugin_thunderbolt_validate_image (ctl_data, bad_data, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_READ); g_assert_cmpint (val, ==, VALIDATION_FAILED); g_debug ("expected image validation error [ctl, bad]: %s", error->message); g_clear_error (&error); /* bad controller data, valid update data */ val = fu_plugin_thunderbolt_validate_image (fwi_data, fwi_data, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert_cmpint (val, ==, VALIDATION_FAILED); g_debug ("expected image validation error [fwi, fwi]: %s", error->message); g_clear_error (&error); val = fu_plugin_thunderbolt_validate_image (bad_data, fwi_data, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert_cmpint (val, ==, VALIDATION_FAILED); g_debug ("expected image validation error [bad, fwi]: %s", error->message); g_clear_error (&error); /* both bad */ val = fu_plugin_thunderbolt_validate_image (bad_data, bad_data, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_READ); g_assert_cmpint (val, ==, VALIDATION_FAILED); g_debug ("expected image validation error [bad, bad]: %s", error->message); g_clear_error (&error); } static void test_change_uevent (ThunderboltTest *tt, gconstpointer user_data) { FuPlugin *plugin = tt->plugin; MockTree *tree = tt->tree; gboolean ret; const gchar *version_after; /* test sanity check */ g_assert_nonnull (tree); /* simulate change of version via a change even, i.e. * without add, remove. */ umockdev_testbed_set_attribute (tt->bed, tree->path, "nvm_version", "42.23"); umockdev_testbed_uevent (tt->bed, tree->path, "change"); /* we just "wait" for 500ms, should be enough */ mock_tree_sync (tree, plugin, 500); /* the tree should not have changed */ ret = mock_tree_all (tree, mock_tree_node_have_fu_device, NULL); g_assert_true (ret); /* we should have the version change in the FuDevice */ version_after = fu_device_get_version (tree->fu_device); g_assert_cmpstr (version_after, ==, "42.23"); } static void test_update_working (ThunderboltTest *tt, gconstpointer user_data) { FuPlugin *plugin = tt->plugin; MockTree *tree = tt->tree; GBytes *fw_data = tt->fw_data; gboolean ret; const gchar *version_after; g_autoptr(GError) error = NULL; g_autoptr(UpdateContext) up_ctx = NULL; /* test sanity check */ g_assert_nonnull (tree); g_assert_nonnull (fw_data); /* simulate an update, where the device goes away and comes back * after the time in the last parameter (given in ms) */ up_ctx = mock_tree_prepare_for_update (tree, plugin, "42.23", fw_data, 1000); ret = fu_plugin_runner_update (plugin, tree->fu_device, NULL, fw_data, 0, &error); g_assert_no_error (error); g_assert_true (ret); version_after = fu_device_get_version (tree->fu_device); g_debug ("version after update: %s", version_after); g_assert_cmpstr (version_after, ==, "42.23"); /* we wait until the plugin has picked up all the * subtree changes */ ret = mock_tree_settle (tree, plugin); g_assert_true (ret); /* now we check if the every tree node has a corresponding FuDevice, * this implicitly checks that we are handling uevents correctly * after the event, and that we are in sync with the udev tree */ ret = mock_tree_all (tree, mock_tree_node_have_fu_device, NULL); g_assert_true (ret); } static void test_update_fail (ThunderboltTest *tt, gconstpointer user_data) { FuPlugin *plugin = tt->plugin; MockTree *tree = tt->tree; GBytes *fw_data = tt->fw_data; gboolean ret; const gchar *version_after; g_autoptr(GError) error = NULL; g_autoptr(UpdateContext) up_ctx = NULL; /* test sanity check */ g_assert_nonnull (tree); g_assert_nonnull (fw_data); /* simulate an update, as in test_update_working, * but simulate an error indicated by the device */ up_ctx = mock_tree_prepare_for_update (tree, plugin, "42.23", fw_data, 1000); up_ctx->result = UPDATE_FAIL_DEVICE_INTERNAL; ret = fu_plugin_runner_update (plugin, tree->fu_device, NULL, fw_data, 0, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL); g_assert_false (ret); /* version should *not* have changed */ version_after = fu_device_get_version (tree->fu_device); g_debug ("version after update: %s", version_after); g_assert_cmpstr (version_after, ==, tree->device->nvm_version); /* we wait until the plugin has picked up all the * subtree changes, and make sure we still receive * udev updates correctly and are in sync */ ret = mock_tree_settle (tree, plugin); g_assert_true (ret); ret = mock_tree_all (tree, mock_tree_node_have_fu_device, NULL); g_assert_true (ret); } static void test_update_fail_nowshow (ThunderboltTest *tt, gconstpointer user_data) { FuPlugin *plugin = tt->plugin; MockTree *tree = tt->tree; GBytes *fw_data = tt->fw_data; gboolean ret; g_autoptr(GError) error = NULL; g_autoptr(UpdateContext) up_ctx = NULL; /* test sanity check */ g_assert_nonnull (tree); g_assert_nonnull (fw_data); /* simulate an update, as in test_update_working, * but simulate an error indicated by the device */ up_ctx = mock_tree_prepare_for_update (tree, plugin, "42.23", fw_data, 1000); up_ctx->result = UPDATE_FAIL_DEVICE_NOSHOW; /* lets make the plugin only wait a second for the device */ fu_plugin_thunderbolt_set_timeout (plugin, 1000); ret = fu_plugin_runner_update (plugin, tree->fu_device, NULL, fw_data, 0, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND); g_assert_false (ret); } static void test_update_fail_tooslow (ThunderboltTest *tt, gconstpointer user_data) { FuPlugin *plugin = tt->plugin; MockTree *tree = tt->tree; GBytes *fw_data = tt->fw_data; gboolean ret; g_autoptr(GError) error = NULL; g_autoptr(UpdateContext) up_ctx = NULL; /* test sanity check */ g_assert_nonnull (tree); g_assert_nonnull (fw_data); /* simulate an update, as in test_update_working, that is also working, * but that takes longer then our timeout, i.e. set_timeout < last * param in prepare_for_update. We will report an error, but we want * to make sure that the device tree afterwards is still correct */ up_ctx = mock_tree_prepare_for_update (tree, plugin, "42.23", fw_data, 2000); up_ctx->result = UPDATE_SUCCESS; /* lets make the plugin only wait half a second (1/4 of update time) */ fu_plugin_thunderbolt_set_timeout (plugin, 500); ret = fu_plugin_runner_update (plugin, tree->fu_device, NULL, fw_data, 0, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND); g_assert_false (ret); /* we wait until we see all devices again */ ret = mock_tree_settle (tree, plugin); g_assert_true (ret); ret = mock_tree_all (tree, mock_tree_node_have_fu_device, NULL); g_assert_true (ret); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_test_add ("/thunderbolt/basic", ThunderboltTest, NULL, test_set_up, test_tree, test_tear_down); g_test_add ("/thunderbolt/image-validation", ThunderboltTest, TEST_INIT_NONE, test_set_up, test_image_validation, test_tear_down); g_test_add ("/thunderbolt/change-uevent", ThunderboltTest, GUINT_TO_POINTER (TEST_INITIALIZE_TREE | TEST_ATTACH_AND_COLDPLUG), test_set_up, test_change_uevent, test_tear_down); g_test_add ("/thunderbolt/update{working}", ThunderboltTest, TEST_INIT_FULL, test_set_up, test_update_working, test_tear_down); g_test_add ("/thunderbolt/update{failing}", ThunderboltTest, TEST_INIT_FULL, test_set_up, test_update_fail, test_tear_down); g_test_add ("/thunderbolt/update{failing-noshow}", ThunderboltTest, TEST_INIT_FULL, test_set_up, test_update_fail_nowshow, test_tear_down); g_test_add ("/thunderbolt/update{failing-tooslow}", ThunderboltTest, TEST_INIT_FULL, test_set_up, test_update_fail_tooslow, test_tear_down); return g_test_run (); } fwupd-1.0.6/plugins/thunderbolt/fu-thunderbolt-image.c000066400000000000000000000500171325145456600230620ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Intel Corporation. * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-thunderbolt-image.h" #include #include enum FuThunderboltSection { DIGITAL_SECTION, DROM_SECTION, ARC_PARAMS_SECTION, DRAM_UCODE_SECTION, SECTION_COUNT }; typedef struct { enum FuThunderboltSection section; /* default is DIGITAL_SECTION */ guint32 offset; guint32 len; guint8 mask; /* 0 means "no mask" */ const gchar *description; } FuThunderboltFwLocation; typedef struct { const guint8 *data; gsize len; guint32 *sections; } FuThunderboltFwObject; typedef struct { guint16 id; guint gen; guint ports; } FuThunderboltHwInfo; static const FuThunderboltHwInfo * get_hw_info (guint16 id) { static const FuThunderboltHwInfo hw_info_arr[] = { { 0x156D, 2, 2 }, /* FR 4C */ { 0x156B, 2, 1 }, /* FR 2C */ { 0x157E, 2, 1 }, /* WR */ { 0x1578, 3, 2 }, /* AR 4C */ { 0x1576, 3, 1 }, /* AR 2C */ { 0x15C0, 3, 1 }, /* AR LP */ { 0x15D3, 3, 2 }, /* AR-C 4C */ { 0x15DA, 3, 1 }, /* AR-C 2C */ { 0x15E7, 3, 1 }, /* TR 2C */ { 0x15EA, 3, 2 }, /* TR 4C */ { 0x15EF, 3, 2 }, /* TR 4C device */ { 0 } }; for (gint i = 0; hw_info_arr[i].id != 0; i++) if (hw_info_arr[i].id == id) return hw_info_arr + i; return NULL; } static inline gboolean valid_farb_pointer (guint32 pointer) { return pointer != 0 && pointer != 0xFFFFFF; } /* returns NULL on error */ static GByteArray * read_location (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *fw, GError **error) { guint32 location_start = fw->sections[location->section] + location->offset; g_autoptr(GByteArray) read = g_byte_array_new (); if (location_start > fw->len || location_start + location->len > fw->len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_READ, "Given location is outside of the given FW (%s)", location->description ? location->description : "N/A"); return NULL; } read = g_byte_array_append (read, fw->data + location_start, location->len); if (location->mask) read->data[0] &= location->mask; return g_steal_pointer (&read); } static gboolean read_farb_pointer_impl (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *fw, guint32 *value, GError **error) { g_autoptr(GByteArray) farb = read_location (location, fw, error); if (farb == NULL) return FALSE; *value = 0; memcpy (value, farb->data, farb->len); *value = GUINT32_FROM_LE (*value); return TRUE; } /* returns invalid FARB pointer on error */ static guint32 read_farb_pointer (const FuThunderboltFwObject *fw, GError **error) { const FuThunderboltFwLocation farb0 = { .offset = 0, .len = 3, .description = "farb0" }; const FuThunderboltFwLocation farb1 = { .offset = 0x1000, .len = 3, .description = "farb1" }; guint32 value; if (!read_farb_pointer_impl (&farb0, fw, &value, error)) return 0; if (valid_farb_pointer (value)) return value; if (!read_farb_pointer_impl (&farb1, fw, &value, error)) return 0; if (!valid_farb_pointer (value)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Invalid FW image file format"); return 0; } return value; } static gboolean compare (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *controller_fw, const FuThunderboltFwObject *image_fw, gboolean *result, GError **error) { g_autoptr(GByteArray) controller_data = NULL; g_autoptr(GByteArray) image_data = NULL; controller_data = read_location (location, controller_fw, error); if (controller_data == NULL) return FALSE; image_data = read_location (location, image_fw, error); if (image_data == NULL) return FALSE; *result = memcmp (controller_data->data, image_data->data, location->len) == 0; return TRUE; } static gboolean read_bool (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *fw, gboolean *val, GError **error) { g_autoptr(GByteArray) read = read_location (location, fw, error); if (read == NULL) return FALSE; for (gsize i = 0; i < read->len; i++) if (read->data[i] != 0) { *val = TRUE; return TRUE; } *val = FALSE; return TRUE; } static gboolean read_uint16 (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *fw, guint16 *value, GError **error) { g_autoptr(GByteArray) read = read_location (location, fw, error); g_assert_cmpuint (location->len, ==, sizeof (guint16)); if (read == NULL) return FALSE; *value = 0; memcpy (value, read->data, read->len); *value = GUINT16_FROM_LE (*value); return TRUE; } static gboolean read_uint32 (const FuThunderboltFwLocation *location, const FuThunderboltFwObject *fw, guint32 *value, GError **error) { g_autoptr(GByteArray) read = read_location (location, fw, error); g_assert_cmpuint (location->len, ==, sizeof (guint32)); if (read == NULL) return FALSE; *value = 0; memcpy (value, read->data, read->len); *value = GUINT32_FROM_LE (*value); return TRUE; } /* * Size of ucode sections is uint16 value saved at the start of the section, * it's in DWORDS (4-bytes) units and it doesn't include itself. We need the * offset to the next section, so we translate it to bytes and add 2 for the * size field itself. * * offset parameter must be relative to digital section */ static gboolean read_ucode_section_len (guint32 offset, const FuThunderboltFwObject *fw, guint16 *value, GError **error) { const FuThunderboltFwLocation section_size = { .offset = offset, .len = 2, .description = "size field" }; if (!read_uint16 (§ion_size, fw, value, error)) return FALSE; *value *= sizeof (guint32); *value += section_size.len; return TRUE; } /* * Takes a FwObject and fills its section array up * Assumes sections[DIGITAL_SECTION].offset is already set */ static gboolean read_sections (const FuThunderboltFwObject *fw, gboolean is_host, guint gen, GError **error) { const FuThunderboltFwLocation arc_params_offset = { .offset = 0x75, .len = 4, .description = "arc params offset" }; const FuThunderboltFwLocation drom_offset = { .offset = 0x10E, .len = 4, .description = "DROM offset" }; guint32 offset; if (gen >= 3 || gen == 0) { if (!read_uint32 (&drom_offset, fw, &offset, error)) return FALSE; fw->sections[DROM_SECTION] = offset + fw->sections[DIGITAL_SECTION]; } if (!is_host) { if (!read_uint32 (&arc_params_offset, fw, &offset, error)) return FALSE; fw->sections[ARC_PARAMS_SECTION] = offset + fw->sections[DIGITAL_SECTION]; } if (is_host && gen > 2) { /* * Algorithm: * To find the DRAM section, we have to jump from section to * section in a chain of sections. * available_sections location tells what sections exist at all * (with a flag per section). * ee_ucode_start_addr location tells the offset of the first * section in the list relatively to the digital section start. * After having the offset of the first section, we have a loop * over the section list. If the section exists, we read its * length (2 bytes at section start) and add it to current * offset to find the start of the next section. Otherwise, we * already have the next section offset... */ const unsigned DRAM_FLAG = 1 << 6; const FuThunderboltFwLocation available_sections_loc = { .offset = 0x2, .len = 1, .description = "sections" }; const FuThunderboltFwLocation ee_ucode_start_addr_loc = { .offset = 0x3, .len = 2, .description = "ucode start" }; guint16 ucode_offset; g_autoptr(GByteArray) available_sections = read_location (&available_sections_loc, fw, error); if (available_sections == NULL) return FALSE; if (!read_uint16 (&ee_ucode_start_addr_loc, fw, &ucode_offset, error)) return FALSE; offset = ucode_offset; if ((available_sections->data[0] & DRAM_FLAG) == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Can't find needed FW sections in the FW image file"); return FALSE; } for (unsigned u = 1; u < DRAM_FLAG; u <<= 1) if (u & available_sections->data[0]) { if (!read_ucode_section_len (offset, fw, &ucode_offset, error)) return FALSE; offset += ucode_offset; } fw->sections[DRAM_UCODE_SECTION] = offset + fw->sections[DIGITAL_SECTION]; } return TRUE; } static inline gboolean missing_needed_drom (const FuThunderboltFwObject *fw, gboolean is_host, guint gen) { if (fw->sections[DROM_SECTION] != 0) return FALSE; if (is_host && gen < 3) return FALSE; return TRUE; } /* * Controllers that can have 1 or 2 ports have additional locations to check in * the 2 ports case. To make this as generic as possible, both sets are stored * in the same array with an empty entry separating them. The 1 port case should * stop comparing at the separator and the 2 ports case should continue * iterating the array to compare the rest. */ static const FuThunderboltFwLocation * get_host_locations (guint16 id) { static const FuThunderboltFwLocation FR[] = { { .offset = 0x10, .len = 4, .description = "PCIe Settings" }, { .offset = 0x143, .len = 1, .description = "CIO-Port0_TX" }, { .offset = 0x153, .len = 1, .description = "CIO-Port0_RX" }, { .offset = 0x147, .len = 1, .description = "CIO-Port1_TX" }, { .offset = 0x157, .len = 1, .description = "CIO-Port1_RX" }, { .offset = 0x211, .len = 1, .description = "Snk0_0(DP-in)" }, { .offset = 0x215, .len = 1, .description = "Snk0_1(DP-in)" }, { .offset = 0x219, .len = 1, .description = "Snk0_2(DP-in)" }, { .offset = 0x21D, .len = 1, .description = "Snk0_3(DP-in)" }, { .offset = 0X2175, .len = 1, .description = "PA(DP-out)" }, { .offset = 0X2179, .len = 1, .description = "PB(DP-out)" }, { .offset = 0X217D, .len = 1, .description = "Src0(DP-out)", .mask = 0xAA }, { 0 }, { .offset = 0x14B, .len = 1, .description = "CIO-Port2_TX" }, { .offset = 0x15B, .len = 1, .description = "CIO-Port2_RX" }, { .offset = 0x14F, .len = 1, .description = "CIO-Port3_TX" }, { .offset = 0x15F, .len = 1, .description = "CIO-Port3_RX" }, { .offset = 0X11C3, .len = 1, .description = "Snk1_0(DP-in)" }, { .offset = 0X11C7, .len = 1, .description = "Snk1_1(DP-in)" }, { .offset = 0X11CB, .len = 1, .description = "Snk1_2(DP-in)" }, { .offset = 0X11CF, .len = 1, .description = "Snk1_3(DP-in)" }, { 0 } }; static const FuThunderboltFwLocation WR[] = { { .offset = 0x10, .len = 4, .description = "PCIe Settings" }, { .offset = 0x14F, .len = 1, .description = "CIO-Port0_TX" }, { .offset = 0x157, .len = 1, .description = "CIO-Port0_RX" }, { .offset = 0x153, .len = 1, .description = "CIO-Port1_TX" }, { .offset = 0x15B, .len = 1, .description = "CIO-Port1_RX" }, { .offset = 0x1F1, .len = 1, .description = "Snk0_0(DP-in)" }, { .offset = 0x1F5, .len = 1, .description = "Snk0_1(DP-in)" }, { .offset = 0x1F9, .len = 1, .description = "Snk0_2(DP-in)" }, { .offset = 0x1FD, .len = 1, .description = "Snk0_3(DP-in)" }, { .offset = 0X11A5, .len = 1, .description = "PA(DP-out)" }, { 0 } }; static const FuThunderboltFwLocation AR[] = { { .offset = 0x10, .len = 4, .description = "PCIe Settings" }, { .offset = 0x12, .len = 1, .description = "PA", .mask = 0xCC, .section = DRAM_UCODE_SECTION }, { .offset = 0x121, .len = 1, .description = "Snk0" }, { .offset = 0x129, .len = 1, .description = "Snk1" }, { .offset = 0x136, .len = 1, .description = "Src0", .mask = 0xF0 }, { .offset = 0xB6, .len = 1, .description = "PA/PB (USB2)", .mask = 0xC0 }, { .offset = 0x7B, .len = 1, .description = "Native", .mask = 0x20 }, { 0 }, { .offset = 0x13, .len = 1, .description = "PB", .mask = 0xCC, .section = DRAM_UCODE_SECTION }, { 0 } }; static const FuThunderboltFwLocation AR_LP[] = { { .offset = 0x10, .len = 4, .description = "PCIe Settings" }, { .offset = 0x12, .len = 1, .description = "PA", .mask = 0xCC, .section = DRAM_UCODE_SECTION }, { .offset = 0x13, .len = 1, .description = "PB", .mask = 0x44, .section = DRAM_UCODE_SECTION }, { .offset = 0x121, .len = 1, .description = "Snk0" }, { .offset = 0xB6, .len = 1, .description = "PA/PB (USB2)", .mask = 0xC0 }, { .offset = 0x7B, .len = 1, .description = "Native", .mask = 0x20 }, { 0 } }; static const FuThunderboltFwLocation TR[] = { { .offset = 0x10, .len = 4, .description = "PCIe Settings" }, { .offset = 0x12, .len = 1, .description = "PA", .mask = 0xCC, .section = DRAM_UCODE_SECTION }, { .offset = 0x121, .len = 1, .description = "Snk0" }, { .offset = 0x129, .len = 1, .description = "Snk1" }, { .offset = 0x136, .len = 1, .description = "Src0", .mask = 0xF0 }, { .offset = 0xB6, .len = 1, .description = "PA/PB (USB2)", .mask = 0xC0 }, { .offset = 0x5E, .len = 1, .description = "Aux", .mask = 0x0F }, { 0 }, { .offset = 0x13, .len = 1, .description = "PB", .mask = 0xCC, .section = DRAM_UCODE_SECTION }, { .offset = 0x5E, .len = 1, .description = "Aux (PB)", .mask = 0x10 }, { 0 } }; switch (id) { case 0x156D: case 0x156B: return FR; case 0x157E: return WR; case 0x1578: case 0x1576: case 0x15D3: case 0x15DA: return AR; case 0x15C0: return AR_LP; case 0x15E7: case 0x15EA: return TR; default: return NULL; } } static const FuThunderboltFwLocation * get_device_locations (guint16 id) { static const FuThunderboltFwLocation locations[] = { { .offset = 0x124, .len = 1, .section = ARC_PARAMS_SECTION, .description = "X of N" }, { 0 } }; switch (id) { case 0x1578: case 0x1576: case 0x15D3: case 0x15DA: case 0x15C0: return locations; default: return NULL; } } /* * Compares the given locations, assuming locations is an array. * Returns FALSE and sets error upon failure. * locations points to the end of the array (the empty entry) upon * successful return. */ static gboolean compare_locations (const FuThunderboltFwLocation **locations, const FuThunderboltFwObject *controller, const FuThunderboltFwObject *image, GError **error) { gboolean result; do { if (!compare (*locations, controller, image, &result, error)) return FALSE; if (!result) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "FW image image not compatible to this controller (%s)", (*locations)->description); return FALSE; } } while ((++(*locations))->offset != 0); return TRUE; } FuPluginValidation fu_plugin_thunderbolt_validate_image (GBytes *controller_fw, GBytes *blob_fw, GError **error) { gboolean is_host; guint16 device_id; gboolean compare_result; const FuThunderboltHwInfo *hw_info; const FuThunderboltHwInfo unknown = { 0 }; const FuThunderboltFwLocation *locations; gsize fw_size; const guint8 *fw_data = g_bytes_get_data (controller_fw, &fw_size); gsize blob_size; const guint8 *blob_data = g_bytes_get_data (blob_fw, &blob_size); guint32 controller_sections[SECTION_COUNT] = { [DIGITAL_SECTION] = 0 }; guint32 image_sections [SECTION_COUNT] = { 0 }; const FuThunderboltFwObject controller = { fw_data, fw_size, controller_sections }; const FuThunderboltFwObject image = { blob_data, blob_size, image_sections }; const FuThunderboltFwLocation is_host_loc = { .offset = 0x10, .len = 1, .mask = 1 << 1, .description = "host flag" }; const FuThunderboltFwLocation device_id_loc = { .offset = 0x5, .len = 2, .description = "devID" }; image_sections[DIGITAL_SECTION] = read_farb_pointer (&image, error); if (image_sections[DIGITAL_SECTION] == 0) return VALIDATION_FAILED; if (!read_bool (&is_host_loc, &controller, &is_host, error)) return VALIDATION_FAILED; if (!read_uint16 (&device_id_loc, &controller, &device_id, error)) return VALIDATION_FAILED; hw_info = get_hw_info (device_id); if (hw_info == NULL) { if (is_host) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Unknown controller"); return FALSE; } hw_info = &unknown; } if (!compare (&is_host_loc, &controller, &image, &compare_result, error)) return VALIDATION_FAILED; if (!compare_result) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "The FW image file is for a %s controller", is_host ? "device" : "host"); return VALIDATION_FAILED; } if (!compare (&device_id_loc, &controller, &image, &compare_result, error)) return VALIDATION_FAILED; if (!compare_result) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "The FW image file is for a different HW type"); return VALIDATION_FAILED; } if (!read_sections (&controller, is_host, hw_info->gen, error)) return VALIDATION_FAILED; if (missing_needed_drom (&controller, is_host, hw_info->gen)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, "Can't find needed FW sections in the controller"); return VALIDATION_FAILED; } if (!read_sections (&image, is_host, hw_info->gen, error)) return VALIDATION_FAILED; if (missing_needed_drom (&image, is_host, hw_info->gen)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Can't find needed FW sections in the FW image file"); return VALIDATION_FAILED; } if (controller.sections[DROM_SECTION] != 0) { const FuThunderboltFwLocation drom_locations[] = { { .offset = 0x10, .len = 2, .section = DROM_SECTION, .description = "vendor ID" }, { .offset = 0x12, .len = 2, .section = DROM_SECTION, .description = "model ID" }, { 0 } }; locations = drom_locations; if (!compare_locations (&locations, &controller, &image, error)) return VALIDATION_FAILED; } /* * 0 is for the unknown device case, for being future-compatible with * new devices; so we can't know which locations to check besides the * vendor and model IDs that were validated already, but those should be * good enough validation. */ if (hw_info->id == 0) return UNKNOWN_DEVICE; locations = is_host ? get_host_locations (hw_info->id) : get_device_locations (hw_info->id); if (locations == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "FW locations to check not found for this controller"); return VALIDATION_FAILED; } if (!compare_locations (&locations, &controller, &image, error)) return VALIDATION_FAILED; if (is_host && hw_info->ports == 2) { locations++; if (!compare_locations (&locations, &controller, &image, error)) return VALIDATION_FAILED; } return VALIDATION_PASSED; } gboolean fu_plugin_thunderbolt_controller_is_native (GBytes *controller_fw, gboolean *is_native, GError **error) { guint32 controller_sections[SECTION_COUNT] = { [DIGITAL_SECTION] = 0 }; gsize fw_size; const guint8 *fw_data = g_bytes_get_data (controller_fw, &fw_size); const FuThunderboltFwObject controller = { fw_data, fw_size, controller_sections }; const FuThunderboltFwLocation location = { .offset = 0x7B, .len = 1, .description = "Native", .mask = 0x20 }; return read_bool (&location, &controller, is_native, error); } fwupd-1.0.6/plugins/thunderbolt/fu-thunderbolt-image.h000066400000000000000000000025731325145456600230730ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Intel Corporation. * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_THUNDERBOLT_IMAGE_H__ #define __FU_THUNDERBOLT_IMAGE_H__ #include typedef enum { VALIDATION_PASSED, VALIDATION_FAILED, UNKNOWN_DEVICE, } FuPluginValidation; FuPluginValidation fu_plugin_thunderbolt_validate_image (GBytes *controller_fw, GBytes *blob_fw, GError **error); gboolean fu_plugin_thunderbolt_controller_is_native (GBytes *controller_fw, gboolean *is_native, GError **error); #endif /* __FU_THUNDERBOLT_IMAGE_H__ */ fwupd-1.0.6/plugins/thunderbolt/fu-thunderbolt-tool.c000066400000000000000000000056431325145456600227620ustar00rootroot00000000000000/* -*- mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Intel Corporation. * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "fu-thunderbolt-image.h" #include "fu-plugin-vfuncs.h" #include "fu-test.h" static gsize read_farb_pointer (gchar *image) { gsize ret = 0; memcpy (&ret, image, 3); ret = GSIZE_FROM_LE (ret); if (ret != 0 && ret != 0xFFFFFF) return ret; ret = 0; memcpy (&ret, image + 0x1000, 3); ret = GSIZE_FROM_LE (ret); g_assert (ret != 0 && ret != 0xFFFFFF); return ret; } int main (int argc, char **argv) { g_autoptr(GError) error = NULL; g_autoptr(GFile) fw_file = NULL; gboolean ok; gsize len; gchar *data = NULL; g_autoptr(GBytes) image = NULL; g_autoptr(GBytes) controller = NULL; FuPluginValidation validation; if (argc < 2 || argc > 3) { g_print ("Usage: %s []\n", argv[0]); g_print ("Runs image validation on 'filename', comparing it to itself\n" "after removing the headers or to 'controller' if given\n"); return 1; } fw_file = g_file_new_for_path (argv[1]); g_assert_nonnull (fw_file); ok = g_file_load_contents (fw_file, NULL, &data, &len, NULL, &error); g_assert_no_error (error); g_assert_true (ok); image = g_bytes_new_take (data, len); if (argc == 2) { gssize header_size = read_farb_pointer (data); g_assert_cmpuint (header_size, !=, 0); g_assert_cmpuint (header_size, <, len); controller = g_bytes_new_from_bytes (image, header_size, len - header_size); } else { g_autoptr(GFile) controller_file = NULL; gsize controller_len; gchar *controller_data = NULL; controller_file = g_file_new_for_path (argv[2]); g_assert_nonnull (controller_file); ok = g_file_load_contents (controller_file, NULL, &controller_data, &controller_len, NULL, &error); g_assert_no_error (error); g_assert_true (ok); controller = g_bytes_new_take (controller_data, controller_len); } validation = fu_plugin_thunderbolt_validate_image (controller, image, &error); g_assert_no_error (error); g_assert_cmpint (validation, ==, VALIDATION_PASSED); g_print ("test passed\n"); return 0; } fwupd-1.0.6/plugins/thunderbolt/meson.build000066400000000000000000000036041325145456600210360ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginThunderbolt"'] fu_plugin_thunderbolt = shared_module('fu_plugin_thunderbolt', sources : [ 'fu-plugin-thunderbolt.c', 'fu-thunderbolt-image.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, gudev, ], ) testdatadir_src = join_paths(meson.source_root(), 'data', 'tests') testdatadir_dst = join_paths(meson.build_root(), 'data', 'tests') cargs += '-DTESTDATADIR="' + testdatadir_src + ':' + testdatadir_dst + '"' executable('tbtfwucli', sources : [ 'fu-thunderbolt-tool.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], c_args : cargs, link_with : [ fu_plugin_thunderbolt, fwupd, libfwupdprivate, ], dependencies : [ plugin_deps, gudev, ], ) # we use functions from 2.52 in the tests if get_option('tests') and umockdev.found() and gio.version().version_compare('>= 2.52') cargs += '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"' cargs += '-DPLUGINBUILDDIR="' + meson.current_build_dir() + '"' e = executable( 'thunderbolt-self-test', sources : [ 'fu-self-test.c', 'fu-plugin-thunderbolt.c', 'fu-thunderbolt-image.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, gudev, umockdev, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs ) test_env = environment() test_env.prepend('LD_PRELOAD', 'libumockdev-preload.so.0') test('thunderbolt-self-test', e, env: test_env, timeout : 120) endif fwupd-1.0.6/plugins/udev/000077500000000000000000000000001325145456600153025ustar00rootroot00000000000000fwupd-1.0.6/plugins/udev/README.md000066400000000000000000000006171325145456600165650ustar00rootroot00000000000000UDev Support ============ Introduction ------------ This plugin reads the version numbers of PCI devices. It cannot deploy firmware onto devices but is used to list devices with known firmware updates that may require booting into another operating system to apply. This plugin is also able to read and parse the firmware of some PCI devices which allows some host state verification to be done. fwupd-1.0.6/plugins/udev/fu-plugin-udev.c000066400000000000000000000175311325145456600203240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "fu-plugin.h" #include "fu-rom.h" #include "fu-plugin-vfuncs.h" struct FuPluginData { GUdevClient *gudev_client; }; gboolean fu_plugin_verify (FuPlugin *plugin, FuDevice *device, FuPluginVerifyFlags flags, GError **error) { GPtrArray *checksums; const gchar *rom_fn; g_autoptr(GFile) file = NULL; g_autoptr(FuRom) rom = NULL; /* open the file */ rom_fn = fu_device_get_metadata (device, "RomFilename"); if (rom_fn == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Unable to read firmware from device"); return FALSE; } file = g_file_new_for_path (rom_fn); rom = fu_rom_new (); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error)) return FALSE; /* update version */ if (g_strcmp0 (fu_device_get_version (device), fu_rom_get_version (rom)) != 0) { g_debug ("changing version of %s from %s to %s", fu_device_get_platform_id (device), fu_device_get_version (device), fu_rom_get_version (rom)); fu_device_set_version (device, fu_rom_get_version (rom)); } /* Also add the GUID from the firmware as the firmware may be more * generic, which also allows us to match the GUID when doing 'verify' * on a device with a different PID to the firmware */ fu_device_add_guid (device, fu_rom_get_guid (rom)); /* update checksums */ checksums = fu_rom_get_checksums (rom); for (guint i = 0; i < checksums->len; i++) { const gchar *checksum = g_ptr_array_index (checksums, i); fu_device_add_checksum (device, checksum); } return TRUE; } static gchar * fu_plugin_udev_generate_vendor_id (GUdevDevice *device) { const gchar *pci_id; const gchar *subsys; guint64 vid; g_autofree gchar *subsys_up = NULL; g_autofree gchar *vid_str = NULL; /* get upper cased subsystem */ subsys = g_udev_device_get_subsystem (device); if (subsys == NULL) return NULL; subsys_up = g_ascii_strup (subsys, -1); /* get vendor ID */ pci_id = g_udev_device_get_property (device, "PCI_ID"); if (pci_id != NULL) { g_auto(GStrv) split = g_strsplit (pci_id, ":", 2); vid_str = g_strdup (split[0]); } if (vid_str == NULL) { g_warning ("no vendor ID for %s", g_udev_device_get_sysfs_path (device)); return NULL; } vid = g_ascii_strtoull (vid_str, NULL, 16); if (vid == 0x0) { g_warning ("failed to parse %s", vid_str); return NULL; } return g_strdup_printf ("%s:0x%04X", subsys_up, (guint) vid); } static void fu_plugin_udev_add (FuPlugin *plugin, GUdevDevice *device) { FuDevice *dev_tmp; const gchar *display_name; const gchar *guid; const gchar *id = NULL; const gchar *product; const gchar *vendor; g_autofree gchar *rom_fn = NULL; g_autofree gchar *vendor_id = NULL; g_autofree gchar *version = NULL; g_auto(GStrv) split = NULL; g_autoptr(AsProfile) profile = as_profile_new (); g_autoptr(AsProfileTask) ptask = NULL; g_autoptr(FuDevice) dev = NULL; /* interesting device? */ guid = g_udev_device_get_property (device, "FWUPD_GUID"); if (guid == NULL) return; /* get data */ ptask = as_profile_start (profile, "FuPluginUdev:client-add{%s}", guid); g_assert (ptask != NULL); g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (device)); /* is already in database */ id = g_udev_device_get_sysfs_path (device); dev_tmp = fu_plugin_cache_lookup (plugin, id); if (dev_tmp != NULL) { g_debug ("ignoring duplicate %s", id); return; } /* get the FW version from the BCD device revision */ product = g_udev_device_get_property (device, "PRODUCT"); if (product != NULL) { split = g_strsplit (product, "/", -1); if (g_strv_length (split) != 3) { g_warning ("env{PRODUCT} is invalid: %s", product); return; } version = g_strdup (split[2]); } /* did we get enough data */ dev = fu_device_new (); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); fu_device_set_platform_id (dev, id); fu_device_add_guid (dev, guid); fu_device_add_icon (dev, "audio-card"); display_name = g_udev_device_get_property (device, "FWUPD_MODEL"); if (display_name == NULL) display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE"); if (display_name != NULL) fu_device_set_name (dev, display_name); vendor = g_udev_device_get_property (device, "FWUPD_VENDOR"); if (vendor == NULL) vendor = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE"); if (vendor != NULL) fu_device_set_vendor (dev, vendor); if (version != NULL) fu_device_set_version (dev, version); /* set vendor ID */ vendor_id = fu_plugin_udev_generate_vendor_id (device); if (vendor_id != NULL) fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id); /* get the FW version from the rom when unlocked */ rom_fn = g_build_filename (g_udev_device_get_sysfs_path (device), "rom", NULL); if (g_file_test (rom_fn, G_FILE_TEST_EXISTS)) fu_device_set_metadata (dev, "RomFilename", rom_fn); /* insert to hash */ fu_plugin_cache_add (plugin, id, dev); fu_plugin_device_add_delay (plugin, dev); } static void fu_plugin_udev_remove (FuPlugin *plugin, GUdevDevice *device) { FuDevice *dev; const gchar *id; /* interesting device? */ if (g_udev_device_get_property (device, "FWUPD_GUID") == NULL) return; /* already in database */ id = g_udev_device_get_sysfs_path (device); dev = fu_plugin_cache_lookup (plugin, id); if (dev == NULL) return; fu_plugin_device_remove (plugin, dev); } static void fu_plugin_udev_uevent_cb (GUdevClient *gudev_client, const gchar *action, GUdevDevice *udev_device, FuPlugin *plugin) { if (g_strcmp0 (action, "remove") == 0) { fu_plugin_udev_remove (plugin, udev_device); return; } if (g_strcmp0 (action, "add") == 0) { fu_plugin_udev_add (plugin, udev_device); return; } } void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); const gchar *subsystems[] = { "pci", NULL }; data->gudev_client = g_udev_client_new (subsystems); g_signal_connect (data->gudev_client, "uevent", G_CALLBACK (fu_plugin_udev_uevent_cb), plugin); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_object_unref (data->gudev_client); } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); GList *devices; GUdevDevice *udev_device; const gchar *devclass[] = { "pci", NULL }; g_autoptr(AsProfile) profile = as_profile_new (); /* get all devices of class */ for (guint i = 0; devclass[i] != NULL; i++) { g_autoptr(AsProfileTask) ptask = NULL; ptask = as_profile_start (profile, "FuPluginUdev:coldplug{%s}", devclass[i]); g_assert (ptask != NULL); devices = g_udev_client_query_by_subsystem (data->gudev_client, devclass[i]); for (GList *l = devices; l != NULL; l = l->next) { udev_device = l->data; fu_plugin_udev_add (plugin, udev_device); } g_list_foreach (devices, (GFunc) g_object_unref, NULL); g_list_free (devices); } return TRUE; } fwupd-1.0.6/plugins/udev/fu-rom-tool.c000066400000000000000000000155651325145456600176420ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "fwupd-common-private.h" #include "fu-rom.h" #include "fu-common.h" static gboolean fu_fuzzer_rom_parse (const gchar *fn, GError **error) { GPtrArray *checksums; g_autoptr(FuRom) rom = NULL; g_autoptr(GFile) file = NULL; g_debug ("loading %s", fn); file = g_file_new_for_path (fn); rom = fu_rom_new (); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_NONE, NULL, error)) return FALSE; g_print ("filename:%s\n", fn); g_print ("kind:%s\n", fu_rom_kind_to_string (fu_rom_get_kind (rom))); g_print ("version:%s\n", fu_rom_get_version (rom)); checksums = fu_rom_get_checksums (rom); for (guint i = 0; i < checksums->len; i++) { const gchar *checksum = g_ptr_array_index (checksums, i); g_autofree gchar *checksum_display = NULL; checksum_display = fwupd_checksum_format_for_display (checksum); g_print ("checksum:%s\n", checksum_display); } g_print ("guid:%s\n", fu_rom_get_guid (rom)); g_print ("vendor:%u\n", fu_rom_get_vendor (rom)); g_print ("model:%u\n\n", fu_rom_get_model (rom)); return TRUE; } static gboolean fu_fuzzer_write_files (GHashTable *hash, GError **error) { GString *str; g_autoptr(GList) keys = g_hash_table_get_keys (hash); for (GList *l = keys; l != NULL; l = l->next) { g_autofree gchar *filename = NULL; const gchar *fn = l->data; filename = g_build_filename ("fuzzing", fn, NULL); str = g_hash_table_lookup (hash, fn); g_debug ("writing %s", fn); if (!g_file_set_contents (filename, str->str, str->len, error)) { g_prefix_error (error, "could not write file %s: ", filename); return FALSE; } } return TRUE; } static void _g_string_unref (GString *str) { g_string_free (str, TRUE); } static gboolean fu_fuzzer_rom_create (GError **error) { GString *str; guint8 *buffer; g_autofree guint8 *blob_header = NULL; g_autofree guint8 *blob_ifr = NULL; g_autoptr(GHashTable) hash = NULL; hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) _g_string_unref); /* 24 byte header */ blob_header = g_malloc0 (0x200); buffer = blob_header; memcpy (buffer, "\x55\xaa", 2); buffer[0x02] = 1; /* rom_len / 512 */ buffer[0x03] = 0x20; /* entry_point lo to blob just after header */ buffer[0x04] = 'K'; /* entry_point hi (NVIDIA) */ buffer[0x05] = '7'; /* entry_point higher (NVIDIA) */ memcpy (&buffer[0x6], "xxxxxxxxxxxxxxxxxx", 18); /* reserved */ buffer[0x18] = 0x20; /* cpi_ptr lo */ buffer[0x19] = 0x00; /* cpi_ptr hi */ memcpy (&blob_header[0x6], "hdr-no-data ", 18); g_hash_table_insert (hash, (gpointer) "header-no-data.rom", g_string_new_len ((gchar *) blob_header, 512)); /* data for header */ buffer = &blob_header[0x20]; memcpy (&buffer[0x00], "PCIR", 4); /* magic */ memcpy (&buffer[0x04], "\0\0", 2); /* vendor */ memcpy (&buffer[0x06], "\0\0", 2); /* device id */ memcpy (&buffer[0x08], "\0\0", 2); /* device_list_ptr */ buffer[0x0a] = 0x1c; /* data_len lo */ buffer[0x0b] = 0x00; /* data_len hi */ buffer[0x0c] = 0x0; /* data_rev */ memcpy (&buffer[0x0d], "\0\0\0", 3); /* class_code */ buffer[0x10] = 0x01; /* image_len lo / 512 */ buffer[0x11] = 0; /* image_len hi / 512 */ buffer[0x12] = 0; /* revision_level lo */ buffer[0x13] = 0; /* revision_level hi */ buffer[0x14] = 0x00; /* code_type, Intel x86 */ buffer[0x15] = 0x80; /* last_image */ buffer[0x16] = 0x0; /* max_runtime_len lo / 512 */ buffer[0x17] = 0x0; /* max_runtime_len hi / 512 */ buffer[0x18] = 0x00; /* config_header_ptr lo */ buffer[0x19] = 0x00; /* config_header_ptr hi */ buffer[0x1a] = 0x00; /* dmtf_clp_ptr lo (used for Intel FW) */ buffer[0x1b] = 0x00; /* dmtf_clp_ptr hi (used for Intel FW) */ blob_header[0x200-1] = 0x5c; /* checksum */ /* blob */ memcpy (&buffer[0x1c], "Version 1.0", 12); memcpy (&blob_header[0x6], "hdr-data-payload ", 18); g_hash_table_insert (hash, (gpointer) "header-data-payload.rom", g_string_new_len ((gchar *) blob_header, 512)); /* optional IFR header on some NVIDIA blobs */ blob_ifr = g_malloc0 (0x80); buffer = blob_ifr; memcpy (buffer, "NVGI", 4); fu_common_write_uint16 (&buffer[0x15], 0x80, G_BIG_ENDIAN); g_hash_table_insert (hash, (gpointer) "naked-ifr.rom", g_string_new_len ((const gchar *) blob_ifr, 0x80)); str = g_string_new_len ((gchar *) blob_ifr, 0x80); memcpy (&blob_header[0x6], (gpointer) "ifr-hdr-data-payld", 18); g_string_append_len (str, (gchar *) blob_header, 0x200); g_hash_table_insert (hash, (gpointer) "ifr-header-data-payload.rom", str); /* dump to files */ return fu_fuzzer_write_files (hash, error); } int main (int argc, char *argv[]) { gboolean verbose = FALSE; g_autoptr(GError) error_parse = NULL; g_autoptr(GOptionContext) context = NULL; const GOptionEntry options[] = { { "verbose", '\0', 0, G_OPTION_ARG_NONE, &verbose, "Run with debugging output enabled", NULL }, { NULL} }; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, options, NULL); if (!g_option_context_parse (context, &argc, &argv, &error_parse)) { g_print ("failed to parse command line arguments: %s\n", error_parse->message); return EXIT_FAILURE; } if (argc < 3) { g_print ("Not enough arguments, expected 'rom' 'foo.rom'\n"); return EXIT_FAILURE; } if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); if (g_strcmp0 (argv[1], "rom") == 0) { gboolean all_successful = TRUE; for (guint i = 2; i < (guint) argc; i++) { g_autoptr(GError) error = NULL; if (!fu_fuzzer_rom_parse (argv[i], &error)) { g_print ("Failed to parse %s: %s\n", argv[i], error->message); all_successful = FALSE; } } return all_successful ? EXIT_SUCCESS : EXIT_FAILURE; } if (g_strcmp0 (argv[1], "create") == 0) { g_autoptr(GError) error = NULL; if (!fu_fuzzer_rom_create (&error)) { g_print ("Failed to create files: %s\n", error->message); return EXIT_FAILURE; } return EXIT_SUCCESS; } g_print ("Type not known: expected 'rom'\n"); return EXIT_FAILURE; } fwupd-1.0.6/plugins/udev/fu-rom.c000066400000000000000000000572221325145456600166630ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "fu-rom.h" static void fu_rom_finalize (GObject *object); /* data from http://resources.infosecinstitute.com/pci-expansion-rom/ */ typedef struct { guint8 *rom_data; guint32 rom_len; guint32 rom_offset; guint32 entry_point; guint8 reserved[18]; guint16 cpi_ptr; guint16 vendor_id; guint16 device_id; guint16 device_list_ptr; guint16 data_len; guint8 data_rev; guint32 class_code; guint32 image_len; guint16 revision_level; guint8 code_type; guint8 last_image; guint32 max_runtime_len; guint16 config_header_ptr; guint16 dmtf_clp_ptr; } FuRomPciHeader; typedef struct { GPtrArray *checksums; GInputStream *stream; FuRomKind kind; gchar *version; gchar *guid; guint16 vendor_id; guint16 device_id; GPtrArray *hdrs; /* of FuRomPciHeader */ } FuRomPrivate; G_DEFINE_TYPE_WITH_PRIVATE (FuRom, fu_rom, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fu_rom_get_instance_private (o)) static void fu_rom_pci_header_free (FuRomPciHeader *hdr) { g_free (hdr->rom_data); g_free (hdr); } const gchar * fu_rom_kind_to_string (FuRomKind kind) { if (kind == FU_ROM_KIND_UNKNOWN) return "unknown"; if (kind == FU_ROM_KIND_ATI) return "ati"; if (kind == FU_ROM_KIND_NVIDIA) return "nvidia"; if (kind == FU_ROM_KIND_INTEL) return "intel"; if (kind == FU_ROM_KIND_PCI) return "pci"; return NULL; } static guint8 * fu_rom_pci_strstr (FuRomPciHeader *hdr, const gchar *needle) { gsize needle_len; guint8 *haystack; gsize haystack_len; if (needle == NULL || needle[0] == '\0') return NULL; if (hdr->rom_data == NULL) return NULL; if (hdr->data_len > hdr->rom_len) return NULL; haystack = &hdr->rom_data[hdr->data_len]; haystack_len = hdr->rom_len - hdr->data_len; needle_len = strlen (needle); if (needle_len > haystack_len) return NULL; for (guint i = 0; i < haystack_len - needle_len; i++) { if (memcmp (haystack + i, needle, needle_len) == 0) return &haystack[i]; } return NULL; } static guint fu_rom_blank_serial_numbers (guint8 *buffer, guint buffer_sz) { guint i; for (i = 0; i < buffer_sz; i++) { if (buffer[i] == 0xff || buffer[i] == '\0' || buffer[i] == '\n' || buffer[i] == '\r') break; buffer[i] = '\0'; } return i; } static gchar * fu_rom_get_hex_dump (guint8 *buffer, guint32 sz) { GString *str = g_string_new (""); for (guint32 i = 0; i < sz; i++) g_string_append_printf (str, "%02x ", buffer[i]); g_string_append (str, " "); for (guint32 i = 0; i < sz; i++) { gchar tmp = '?'; if (g_ascii_isprint (buffer[i])) tmp = (gchar) buffer[i]; g_string_append_printf (str, "%c", tmp); } return g_string_free (str, FALSE); } typedef struct { guint8 segment_kind; guint8 *data; guint16 data_len; guint16 next_offset; } FooRomPciCertificateHdr; static void fu_rom_pci_print_certificate_data (guint8 *buffer, gssize sz) { guint16 off = 0; g_autofree gchar *hdr_str = NULL; /* 27 byte header, unknown purpose */ hdr_str = fu_rom_get_hex_dump (buffer+off, 27); g_debug (" ISBN header: %s", hdr_str); buffer += 27; while (TRUE) { /* 29 byte header to the segment, then data: * 0x01 = type. 0x1 = certificate, 0x2 = hashes? * 0x13,0x14 = offset to next segment */ FooRomPciCertificateHdr h; g_autofree gchar *segment_str = NULL; segment_str = fu_rom_get_hex_dump (buffer+off, 29); g_debug (" ISBN segment @%02x: %s", off, segment_str); h.segment_kind = buffer[off+1]; h.next_offset = (guint16) (((guint16) buffer[off+14] << 8) + buffer[off+13]); h.data = &buffer[off+29]; /* calculate last block length automatically */ if (h.next_offset == 0) h.data_len = (guint16) (sz - off - 29 - 27); else h.data_len = (guint16) (h.next_offset - off - 29); /* print the certificate */ if (h.segment_kind == 0x01) { g_autofree gchar *tmp = NULL; tmp = fu_rom_get_hex_dump (h.data, h.data_len); g_debug ("%s(%i)", tmp, h.data_len); } else if (h.segment_kind == 0x02) { g_autofree gchar *tmp = NULL; tmp = fu_rom_get_hex_dump (h.data, h.data_len < 32 ? h.data_len : 32); g_debug ("%s(%i)", tmp, h.data_len); } else { g_warning ("unknown segment kind %i", h.segment_kind); } /* last block */ if (h.next_offset == 0x0000) break; off = h.next_offset; } } static const gchar * fu_rom_pci_code_type_to_string (guint8 code_type) { if (code_type == 0) return "Intel86"; if (code_type == 1) return "OpenFirmware"; if (code_type == 2) return "PA-RISC"; if (code_type == 3) return "EFI"; return "reserved"; } static guint8 fu_rom_pci_header_get_checksum (FuRomPciHeader *hdr) { guint8 chksum_check = 0x00; for (guint i = 0; i < hdr->rom_len; i++) chksum_check += hdr->rom_data[i]; return chksum_check; } static void fu_rom_pci_print_header (FuRomPciHeader *hdr) { guint8 chksum_check; guint8 *buffer; g_autofree gchar *data_str = NULL; g_autofree gchar *reserved_str = NULL; g_debug ("PCI Header"); g_debug (" RomOffset: 0x%04x", hdr->rom_offset); g_debug (" RomSize: 0x%04x", hdr->rom_len); g_debug (" EntryPnt: 0x%06x", hdr->entry_point); reserved_str = fu_rom_get_hex_dump (hdr->reserved, 18); g_debug (" Reserved: %s", reserved_str); g_debug (" CpiPtr: 0x%04x", hdr->cpi_ptr); /* sanity check */ if (hdr->cpi_ptr > hdr->rom_len) { g_debug (" PCI DATA: Invalid as cpi_ptr > rom_len"); return; } if (hdr->data_len > hdr->rom_len) { g_debug (" PCI DATA: Invalid as data_len > rom_len"); return; } /* print the data */ buffer = &hdr->rom_data[hdr->cpi_ptr]; g_debug (" PCI Data"); g_debug (" VendorID: 0x%04x", hdr->vendor_id); g_debug (" DeviceID: 0x%04x", hdr->device_id); g_debug (" DevList: 0x%04x", hdr->device_list_ptr); g_debug (" DataLen: 0x%04x", hdr->data_len); g_debug (" DataRev: 0x%04x", hdr->data_rev); if (hdr->image_len < 0x0f) { data_str = fu_rom_get_hex_dump (&buffer[hdr->data_len], hdr->image_len); g_debug (" ImageLen: 0x%04x [%s]", hdr->image_len, data_str); } else if (hdr->image_len >= 0x0f) { data_str = fu_rom_get_hex_dump (&buffer[hdr->data_len], 0x0f); g_debug (" ImageLen: 0x%04x [%s...]", hdr->image_len, data_str); } else { g_debug (" ImageLen: 0x%04x", hdr->image_len); } g_debug (" RevLevel: 0x%04x", hdr->revision_level); g_debug (" CodeType: 0x%02x [%s]", hdr->code_type, fu_rom_pci_code_type_to_string (hdr->code_type)); g_debug (" LastImg: 0x%02x [%s]", hdr->last_image, hdr->last_image == 0x80 ? "yes" : "no"); g_debug (" MaxRunLen: 0x%04x", hdr->max_runtime_len); g_debug (" ConfigHdr: 0x%04x", hdr->config_header_ptr); g_debug (" ClpPtr: 0x%04x", hdr->dmtf_clp_ptr); /* dump the ISBN */ if (hdr->code_type == 0x70 && memcmp (&buffer[hdr->data_len], "ISBN", 4) == 0) { fu_rom_pci_print_certificate_data (&buffer[hdr->data_len], hdr->image_len); } /* verify the checksum byte */ if (hdr->image_len <= hdr->rom_len && hdr->image_len > 0) { buffer = hdr->rom_data; chksum_check = fu_rom_pci_header_get_checksum (hdr); if (chksum_check == 0x00) { g_debug (" ChkSum: 0x%02x [valid]", buffer[hdr->image_len-1]); } else { g_debug (" ChkSum: 0x%02x [failed, got 0x%02x]", buffer[hdr->image_len-1], chksum_check); } } else { g_debug (" ChkSum: 0x?? [unknown]"); } } gboolean fu_rom_extract_all (FuRom *rom, const gchar *path, GError **error) { FuRomPrivate *priv = GET_PRIVATE (rom); FuRomPciHeader *hdr; for (guint i = 0; i < priv->hdrs->len; i++) { g_autofree gchar *fn = NULL; hdr = g_ptr_array_index (priv->hdrs, i); fn = g_strdup_printf ("%s/%02u.bin", path, i); g_debug ("dumping ROM #%u at 0x%04x [0x%02x] to %s", i, hdr->rom_offset, hdr->rom_len, fn); if (hdr->rom_len == 0) continue; if (!g_file_set_contents (fn, (const gchar *) hdr->rom_data, (gssize) hdr->rom_len, error)) return FALSE; } return TRUE; } static void fu_rom_find_and_blank_serial_numbers (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); FuRomPciHeader *hdr; guint8 *tmp; /* bail if not likely */ if (priv->kind == FU_ROM_KIND_PCI || priv->kind == FU_ROM_KIND_INTEL) { g_debug ("no serial numbers likely"); return; } for (guint i = 0; i < priv->hdrs->len; i++) { hdr = g_ptr_array_index (priv->hdrs, i); g_debug ("looking for PPID at 0x%04x", hdr->rom_offset); tmp = fu_rom_pci_strstr (hdr, "PPID"); if (tmp != NULL) { guint len; guint8 chk; len = fu_rom_blank_serial_numbers (tmp, hdr->rom_len - hdr->data_len); g_debug ("cleared %u chars @ 0x%04lx", len, (gulong) (tmp - &hdr->rom_data[hdr->data_len])); /* we have to fix the checksum */ chk = fu_rom_pci_header_get_checksum (hdr); hdr->rom_data[hdr->rom_len - 1] -= chk; fu_rom_pci_print_header (hdr); } } } static gboolean fu_rom_pci_parse_data (FuRomPciHeader *hdr) { guint8 *buffer; /* check valid */ if (hdr->cpi_ptr == 0x0000) { g_debug ("No PCI DATA @ 0x%04x", hdr->rom_offset); return FALSE; } if (hdr->rom_len > 0 && hdr->cpi_ptr > hdr->rom_len) { g_debug ("Invalid PCI DATA @ 0x%04x", hdr->rom_offset); return FALSE; } /* gahh, CPI is out of the first chunk */ if (hdr->cpi_ptr > hdr->rom_len) { g_debug ("No available PCI DATA @ 0x%04x : 0x%04x > 0x%04x", hdr->rom_offset, hdr->cpi_ptr, hdr->rom_len); return FALSE; } /* check signature */ buffer = &hdr->rom_data[hdr->cpi_ptr]; if (memcmp (buffer, "PCIR", 4) != 0) { if (memcmp (buffer, "RGIS", 4) == 0 || memcmp (buffer, "NPDS", 4) == 0 || memcmp (buffer, "NPDE", 4) == 0) { g_debug ("-- using NVIDIA DATA quirk"); } else { g_debug ("Not PCI DATA: %02x%02x%02x%02x [%c%c%c%c]", buffer[0], buffer[1], buffer[2], buffer[3], buffer[0], buffer[1], buffer[2], buffer[3]); return FALSE; } } /* parse */ hdr->vendor_id = ((guint16) buffer[0x05] << 8) + buffer[0x04]; hdr->device_id = ((guint16) buffer[0x07] << 8) + buffer[0x06]; hdr->device_list_ptr = ((guint16) buffer[0x09] << 8) + buffer[0x08]; hdr->data_len = ((guint16) buffer[0x0b] << 8) + buffer[0x0a]; hdr->data_rev = buffer[0x0c]; hdr->class_code = ((guint16) buffer[0x0f] << 16) + ((guint16) buffer[0x0e] << 8) + buffer[0x0d]; hdr->image_len = (((guint16) buffer[0x11] << 8) + buffer[0x10]) * 512; hdr->revision_level = ((guint16) buffer[0x13] << 8) + buffer[0x12]; hdr->code_type = buffer[0x14]; hdr->last_image = buffer[0x15]; hdr->max_runtime_len = (((guint16) buffer[0x17] << 8) + buffer[0x16]) * 512; hdr->config_header_ptr = ((guint16) buffer[0x19] << 8) + buffer[0x18]; hdr->dmtf_clp_ptr = ((guint16) buffer[0x1b] << 8) + buffer[0x1a]; return TRUE; } static FuRomPciHeader * fu_rom_pci_get_header (guint8 *buffer, guint32 sz) { FuRomPciHeader *hdr; /* check signature */ if (memcmp (buffer, "\x55\xaa", 2) != 0) { if (memcmp (buffer, "\x56\x4e", 2) == 0) { g_debug ("-- using NVIDIA ROM quirk"); } else { g_autofree gchar *sig_str = NULL; sig_str = fu_rom_get_hex_dump (buffer, MIN (16, sz)); g_debug ("Not PCI ROM %s", sig_str); return NULL; } } /* decode structure */ hdr = g_new0 (FuRomPciHeader, 1); hdr->rom_len = buffer[0x02] * 512; /* fix up misreporting */ if (hdr->rom_len == 0) { g_debug ("fixing up last image size"); hdr->rom_len = sz; } /* copy this locally to the header */ hdr->rom_data = g_memdup (buffer, hdr->rom_len); /* parse out CPI */ hdr->entry_point = ((guint32) buffer[0x05] << 16) + ((guint16) buffer[0x04] << 8) + buffer[0x03]; memcpy (&hdr->reserved, &buffer[6], 18); hdr->cpi_ptr = ((guint16) buffer[0x19] << 8) + buffer[0x18]; /* parse the header data */ g_debug ("looking for PCI DATA @ 0x%04x", hdr->cpi_ptr); fu_rom_pci_parse_data (hdr); return hdr; } static gchar * fu_rom_find_version_pci (FuRomPciHeader *hdr) { gchar *str; /* ARC storage */ if (memcmp (hdr->reserved, "\0\0ARC", 5) == 0) { str = (gchar *) fu_rom_pci_strstr (hdr, "BIOS: "); if (str != NULL) return g_strdup (str + 6); } return NULL; } static gchar * fu_rom_find_version_nvidia (FuRomPciHeader *hdr) { gchar *str; /* static location for some firmware */ if (memcmp (hdr->rom_data + 0x013d, "Version ", 8) == 0) return g_strdup ((gchar *) &hdr->rom_data[0x013d + 8]); /* usual search string */ str = (gchar *) fu_rom_pci_strstr (hdr, "Version "); if (str != NULL) return g_strdup (str + 8); /* broken */ str = (gchar *) fu_rom_pci_strstr (hdr, "Vension:"); if (str != NULL) return g_strdup (str + 8); str = (gchar *) fu_rom_pci_strstr (hdr, "Version"); if (str != NULL) return g_strdup (str + 7); /* fallback to VBIOS */ if (memcmp (hdr->rom_data + 0xfa, "VBIOS Ver", 9) == 0) return g_strdup ((gchar *) &hdr->rom_data[0xfa + 9]); return NULL; } static gchar * fu_rom_find_version_intel (FuRomPciHeader *hdr) { gchar *str; /* 2175_RYan PC 14.34 06/06/2013 21:27:53 */ str = (gchar *) fu_rom_pci_strstr (hdr, "Build Number:"); if (str != NULL) { g_auto(GStrv) split = NULL; split = g_strsplit (str + 14, " ", -1); for (guint i = 0; split[i] != NULL; i++) { if (g_strstr_len (split[i], -1, ".") == NULL) continue; return g_strdup (split[i]); } } /* fallback to VBIOS */ str = (gchar *) fu_rom_pci_strstr (hdr, "VBIOS "); if (str != NULL) return g_strdup (str + 6); return NULL; } static gchar * fu_rom_find_version_ati (FuRomPciHeader *hdr) { gchar *str; str = (gchar *) fu_rom_pci_strstr (hdr, " VER0"); if (str != NULL) return g_strdup (str + 4); /* broken */ str = (gchar *) fu_rom_pci_strstr (hdr, " VR"); if (str != NULL) return g_strdup (str + 4); return NULL; } static gchar * fu_rom_find_version (FuRomKind kind, FuRomPciHeader *hdr) { if (kind == FU_ROM_KIND_PCI) return fu_rom_find_version_pci (hdr); if (kind == FU_ROM_KIND_NVIDIA) return fu_rom_find_version_nvidia (hdr); if (kind == FU_ROM_KIND_INTEL) return fu_rom_find_version_intel (hdr); if (kind == FU_ROM_KIND_ATI) return fu_rom_find_version_ati (hdr); return NULL; } gboolean fu_rom_load_data (FuRom *rom, guint8 *buffer, gsize buffer_sz, FuRomLoadFlags flags, GCancellable *cancellable, GError **error) { FuRomPrivate *priv = GET_PRIVATE (rom); FuRomPciHeader *hdr = NULL; guint32 sz = buffer_sz; guint32 jump = 0; guint32 hdr_sz = 0; g_autofree gchar *id = NULL; g_autoptr(GChecksum) checksum_sha1 = g_checksum_new (G_CHECKSUM_SHA1); g_autoptr(GChecksum) checksum_sha256 = g_checksum_new (G_CHECKSUM_SHA256); g_return_val_if_fail (FU_IS_ROM (rom), FALSE); /* detect optional IFR header and skip to option ROM */ if (memcmp (buffer, "NVGI", 4) == 0) { guint16 ifr_sz_raw; memcpy (&ifr_sz_raw, &buffer[0x15], 2); hdr_sz = GUINT16_FROM_BE (ifr_sz_raw); g_debug ("detected IFR header, skipping %x bytes", hdr_sz); } /* read all the ROM headers */ while (sz > hdr_sz + jump) { guint32 jump_sz; g_debug ("looking for PCI ROM @ 0x%04x", hdr_sz + jump); hdr = fu_rom_pci_get_header (&buffer[hdr_sz + jump], sz - hdr_sz - jump); if (hdr == NULL) { gboolean found_data = FALSE; /* check it's not just NUL padding */ for (guint i = jump + hdr_sz; i < buffer_sz; i++) { if (buffer[i] != 0x00) { found_data = TRUE; break; } } if (found_data) { g_debug ("found junk data, adding fake"); hdr = g_new0 (FuRomPciHeader, 1); hdr->vendor_id = 0x0000; hdr->device_id = 0x0000; hdr->code_type = 0x00; hdr->last_image = 0x80; hdr->rom_offset = hdr_sz + jump; hdr->rom_len = sz - hdr->rom_offset; hdr->rom_data = g_memdup (&buffer[hdr->rom_offset], hdr->rom_len); hdr->image_len = hdr->rom_len; g_ptr_array_add (priv->hdrs, hdr); } else { g_debug ("ignoring 0x%04x bytes of padding", (guint) (buffer_sz - (jump + hdr_sz))); } break; } /* save this so we can fix checksums */ hdr->rom_offset = hdr_sz + jump; /* we can't break on hdr->last_image as * NVIDIA uses packed but not merged extended headers */ g_ptr_array_add (priv->hdrs, hdr); /* NVIDIA don't always set a ROM size for extensions */ jump_sz = hdr->rom_len; if (jump_sz == 0) jump_sz = hdr->image_len; if (jump_sz == 0x0) break; jump += jump_sz; } /* we found nothing */ if (priv->hdrs->len == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to detect firmware header [%02x%02x]", buffer[0], buffer[1]); return FALSE; } /* print all headers */ for (guint i = 0; i < priv->hdrs->len; i++) { hdr = g_ptr_array_index (priv->hdrs, i); fu_rom_pci_print_header (hdr); } /* find first ROM header */ hdr = g_ptr_array_index (priv->hdrs, 0); priv->vendor_id = hdr->vendor_id; priv->device_id = hdr->device_id; priv->kind = FU_ROM_KIND_PCI; /* detect intel header */ if (memcmp (hdr->reserved, "00000000000", 11) == 0) hdr_sz = (guint32) (((guint16) buffer[0x1b] << 8) + buffer[0x1a]); if (hdr_sz > sz) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware corrupt (overflow)"); return FALSE; } if (hdr->entry_point == 0x374beb) { priv->kind = FU_ROM_KIND_NVIDIA; } else if (memcmp (buffer + hdr_sz, "$VBT", 4) == 0) { priv->kind = FU_ROM_KIND_INTEL; } else if (memcmp(buffer + 0x30, " 761295520", 10) == 0) { priv->kind = FU_ROM_KIND_ATI; } /* nothing */ if (priv->kind == FU_ROM_KIND_UNKNOWN) { g_autofree gchar *str = NULL; str = fu_rom_get_hex_dump (buffer + hdr_sz, 0x32); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to detect firmware kind from [%s]", str); return FALSE; } /* find version string */ priv->version = fu_rom_find_version (priv->kind, hdr); if (priv->version != NULL) { g_strstrip (priv->version); g_strdelimit (priv->version, "\r\n ", '\0'); } /* update checksum */ if (flags & FU_ROM_LOAD_FLAG_BLANK_PPID) fu_rom_find_and_blank_serial_numbers (rom); for (guint i = 0; i < priv->hdrs->len; i++) { hdr = g_ptr_array_index (priv->hdrs, i); g_checksum_update (checksum_sha1, hdr->rom_data, hdr->rom_len); g_checksum_update (checksum_sha256, hdr->rom_data, hdr->rom_len); } /* done updating checksums */ g_ptr_array_add (priv->checksums, g_strdup (g_checksum_get_string (checksum_sha1))); g_ptr_array_add (priv->checksums, g_strdup (g_checksum_get_string (checksum_sha256))); /* update guid */ id = g_strdup_printf ("PCI\\VEN_%04X&DEV_%04X", priv->vendor_id, priv->device_id); priv->guid = as_utils_guid_from_string (id); g_debug ("using %s for %s", priv->guid, id); /* not known */ if (priv->version == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "Firmware version extractor not known"); return FALSE; } return TRUE; } gboolean fu_rom_load_file (FuRom *rom, GFile *file, FuRomLoadFlags flags, GCancellable *cancellable, GError **error) { FuRomPrivate *priv = GET_PRIVATE (rom); const gssize buffer_sz = 0x400000; gssize sz; guint number_reads = 0; g_autoptr(GError) error_local = NULL; g_autofree gchar *fn = NULL; g_autofree guint8 *buffer = NULL; g_autoptr(GFileOutputStream) output_stream = NULL; g_autoptr(AsProfile) profile = as_profile_new (); g_autoptr(AsProfileTask) ptask = NULL; g_return_val_if_fail (FU_IS_ROM (rom), FALSE); /* open file */ ptask = as_profile_start_literal (profile, "FuRom:reading-data"); g_assert (ptask != NULL); priv->stream = G_INPUT_STREAM (g_file_read (file, cancellable, &error_local)); if (priv->stream == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_AUTH_FAILED, error_local->message); return FALSE; } /* we have to enable the read for devices */ fn = g_file_get_path (file); if (g_str_has_prefix (fn, "/sys")) { output_stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, cancellable, error); if (output_stream == NULL) return FALSE; if (g_output_stream_write (G_OUTPUT_STREAM (output_stream), "1", 1, cancellable, error) < 0) return FALSE; } /* read out the header */ buffer = g_malloc ((gsize) buffer_sz); sz = g_input_stream_read (priv->stream, buffer, buffer_sz, cancellable, error); if (sz < 0) return FALSE; if (sz < 512) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Firmware too small: %" G_GSSIZE_FORMAT " bytes", sz); return FALSE; } /* ensure we got enough data to fill the buffer */ while (sz < buffer_sz) { gssize sz_chunk; sz_chunk = g_input_stream_read (priv->stream, buffer + sz, buffer_sz - sz, cancellable, error); if (sz_chunk == 0) break; g_debug ("ROM returned 0x%04x bytes, adding 0x%04x...", (guint) sz, (guint) sz_chunk); if (sz_chunk < 0) return FALSE; sz += sz_chunk; /* check the firmware isn't serving us small chunks */ if (number_reads++ > 16) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "firmware not fulfilling requests"); return FALSE; } } g_debug ("ROM buffer filled %" G_GSSIZE_FORMAT "kb/%" G_GSSIZE_FORMAT "kb", sz / 0x400, buffer_sz / 0x400); return fu_rom_load_data (rom, buffer, sz, flags, cancellable, error); } FuRomKind fu_rom_get_kind (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); g_return_val_if_fail (FU_IS_ROM (rom), FU_ROM_KIND_UNKNOWN); return priv->kind; } const gchar * fu_rom_get_version (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); g_return_val_if_fail (FU_IS_ROM (rom), NULL); return priv->version; } const gchar * fu_rom_get_guid (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); g_return_val_if_fail (FU_IS_ROM (rom), NULL); return priv->guid; } guint16 fu_rom_get_vendor (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); g_return_val_if_fail (FU_IS_ROM (rom), 0x0000); return priv->vendor_id; } guint16 fu_rom_get_model (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); g_return_val_if_fail (FU_IS_ROM (rom), 0x0000); return priv->device_id; } GPtrArray * fu_rom_get_checksums (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); return priv->checksums; } static void fu_rom_class_init (FuRomClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fu_rom_finalize; } static void fu_rom_init (FuRom *rom) { FuRomPrivate *priv = GET_PRIVATE (rom); priv->checksums = g_ptr_array_new_with_free_func (g_free); priv->hdrs = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_rom_pci_header_free); } static void fu_rom_finalize (GObject *object) { FuRom *rom = FU_ROM (object); FuRomPrivate *priv = GET_PRIVATE (rom); g_free (priv->version); g_free (priv->guid); g_ptr_array_unref (priv->checksums); g_ptr_array_unref (priv->hdrs); if (priv->stream != NULL) g_object_unref (priv->stream); G_OBJECT_CLASS (fu_rom_parent_class)->finalize (object); } FuRom * fu_rom_new (void) { FuRom *rom; rom = g_object_new (FU_TYPE_ROM, NULL); return FU_ROM (rom); } fwupd-1.0.6/plugins/udev/fu-rom.h000066400000000000000000000043551325145456600166670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_ROM_H #define __FU_ROM_H #include #include G_BEGIN_DECLS #define FU_TYPE_ROM (fu_rom_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuRom, fu_rom, FU, ROM, GObject) struct _FuRomClass { GObjectClass parent_class; }; typedef enum { FU_ROM_KIND_UNKNOWN, FU_ROM_KIND_ATI, FU_ROM_KIND_NVIDIA, FU_ROM_KIND_INTEL, FU_ROM_KIND_PCI, FU_ROM_KIND_LAST } FuRomKind; typedef enum { FU_ROM_LOAD_FLAG_NONE, FU_ROM_LOAD_FLAG_BLANK_PPID = 1, FU_ROM_LOAD_FLAG_LAST } FuRomLoadFlags; FuRom *fu_rom_new (void); gboolean fu_rom_load_file (FuRom *rom, GFile *file, FuRomLoadFlags flags, GCancellable *cancellable, GError **error); gboolean fu_rom_load_data (FuRom *rom, guint8 *buffer, gsize buffer_sz, FuRomLoadFlags flags, GCancellable *cancellable, GError **error); gboolean fu_rom_extract_all (FuRom *rom, const gchar *path, GError **error); FuRomKind fu_rom_get_kind (FuRom *rom); const gchar *fu_rom_get_version (FuRom *rom); GPtrArray *fu_rom_get_checksums (FuRom *rom); const gchar *fu_rom_get_guid (FuRom *rom); guint16 fu_rom_get_vendor (FuRom *rom); guint16 fu_rom_get_model (FuRom *rom); const gchar *fu_rom_kind_to_string (FuRomKind kind); G_END_DECLS #endif /* __FU_ROM_H */ fwupd-1.0.6/plugins/udev/fu-self-test.c000066400000000000000000000113021325145456600177610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "fu-keyring.h" #include "fu-history.h" #include "fu-plugin-private.h" #include "fu-rom.h" #include "fu-test.h" static void fu_rom_func (void) { struct { FuRomKind kind; const gchar *fn; const gchar *ver; const gchar *csum; guint16 vendor; guint16 model; } data[] = { { FU_ROM_KIND_ATI, "Asus.9800PRO.256.unknown.031114.rom", "008.015.041.001", "3137385685298bbf7db2c8304f60d89005c731ed", 0x1002, 0x4e48 }, { FU_ROM_KIND_ATI, /* atombios */ "Asus.R9290X.4096.131014.rom", "015.039.000.006.003515", "d8e32fa09a00ab9dcc96a990266f3fe5a99eacc5", 0x1002, 0x67b0 }, { FU_ROM_KIND_ATI, /* atombios, with serial */ "Asus.HD7970.3072.121018.rom", "015.023.000.002.000000", "ba8b6ce38f2499c8463fc9d983b8e0162b1121e4", 0x1002, 0x6798 }, { FU_ROM_KIND_NVIDIA, "Asus.GTX480.1536.100406_1.rom", "70.00.1A.00.02", "3fcab24e60934850246fcfc4f42eceb32540a0ad", 0x10de, 0x06c0 }, { FU_ROM_KIND_NVIDIA, /* nvgi */ "Asus.GTX980.4096.140905.rom", "84.04.1F.00.02", "98f58321145bd347156455356bc04c5b04a292f5", 0x10de, 0x13c0 }, { FU_ROM_KIND_NVIDIA, /* nvgi, with serial */ "Asus.TitanBlack.6144.140212.rom", "80.80.4E.00.01", "3c80f35d4e3c440ffb427957d9271384113d7721", 0x10de, 0x100c }, { FU_ROM_KIND_UNKNOWN, NULL, NULL, NULL, 0x0000, 0x0000 } }; for (guint i = 0; data[i].fn != NULL; i++) { gboolean ret; g_autoptr(GError) error = NULL; g_autofree gchar *filename = NULL; g_autoptr(FuRom) rom = NULL; g_autoptr(GFile) file = NULL; rom = fu_rom_new (); g_assert (rom != NULL); /* load file */ filename = fu_test_get_filename (TESTDATADIR, data[i].fn); if (filename == NULL) continue; g_print ("\nparsing %s...", filename); file = g_file_new_for_path (filename); ret = fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error); g_assert_no_error (error); g_assert (ret); g_assert_cmpstr (fu_rom_get_version (rom), ==, data[i].ver); g_assert_cmpstr (g_ptr_array_index (fu_rom_get_checksums (rom), 0), ==, data[i].csum); g_assert_cmpint (fu_rom_get_kind (rom), ==, data[i].kind); g_assert_cmpint (fu_rom_get_vendor (rom), ==, data[i].vendor); g_assert_cmpint (fu_rom_get_model (rom), ==, data[i].model); } } static void fu_rom_all_func (void) { GDir *dir; g_autofree gchar *path = NULL; /* may or may not exist */ path = fu_test_get_filename (TESTDATADIR, "roms"); if (path == NULL) return; g_print ("\n"); dir = g_dir_open (path, 0, NULL); do { const gchar *fn; gboolean ret; g_autoptr(GError) error = NULL; g_autofree gchar *filename = NULL; g_autoptr(FuRom) rom = NULL; g_autoptr(GFile) file = NULL; fn = g_dir_read_name (dir); if (fn == NULL) break; filename = g_build_filename (path, fn, NULL); g_print ("\nparsing %s...", filename); file = g_file_new_for_path (filename); rom = fu_rom_new (); ret = fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error); if (!ret) { g_print ("%s %s : %s\n", fu_rom_kind_to_string (fu_rom_get_kind (rom)), filename, error->message); continue; } g_assert_cmpstr (fu_rom_get_version (rom), !=, NULL); g_assert_cmpstr (fu_rom_get_version (rom), !=, "\0"); g_assert_cmpint (fu_rom_get_checksums(rom)->len, !=, 0); g_assert_cmpint (fu_rom_get_kind (rom), !=, FU_ROM_KIND_UNKNOWN); } while (TRUE); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); /* tests go here */ g_test_add_func ("/fwupd/rom", fu_rom_func); g_test_add_func ("/fwupd/rom{all}", fu_rom_all_func); return g_test_run (); } fwupd-1.0.6/plugins/udev/fuzzing.md000066400000000000000000000001661325145456600173230ustar00rootroot00000000000000CC=afl-gcc ./configure --disable-shared AFL_HARDEN=1 make afl-fuzz -m 300 -i fuzzing -o findings ./fu-rom-tool rom @@ fwupd-1.0.6/plugins/udev/fuzzing/000077500000000000000000000000001325145456600167765ustar00rootroot00000000000000fwupd-1.0.6/plugins/udev/fuzzing/header-data-payload.rom000066400000000000000000000010001325145456600232720ustar00rootroot00000000000000U K7hdr-data-payload PCIRVersion 1.0\fwupd-1.0.6/plugins/udev/fuzzing/header-no-data.rom000066400000000000000000000010001325145456600222550ustar00rootroot00000000000000U K7hdr-no-data fwupd-1.0.6/plugins/udev/fuzzing/ifr-header-data-payload.rom000066400000000000000000000012001325145456600240520ustar00rootroot00000000000000NVGIU K7ifr-hdr-data-payld PCIRVersion 1.0\fwupd-1.0.6/plugins/udev/fuzzing/naked-ifr.rom000066400000000000000000000002001325145456600213450ustar00rootroot00000000000000NVGIfwupd-1.0.6/plugins/udev/meson.build000066400000000000000000000026551325145456600174540ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginUdev"'] shared_module('fu_plugin_udev', sources : [ 'fu-plugin-udev.c', 'fu-rom.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, gudev, ], ) executable( 'fu-rom-tool', sources : [ 'fu-rom-tool.c', 'fu-rom.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, gudev, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs, ) if get_option('tests') cargs += '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"' cargs += '-DPLUGINBUILDDIR="' + meson.current_build_dir() + '"' testdatadir = join_paths(meson.current_source_dir(), 'tests') cargs += '-DTESTDATADIR="' + testdatadir + '"' e = executable( 'udev-self-test', sources : [ 'fu-self-test.c', 'fu-rom.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, gudev, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs ) test('udev-self-test', e) endif fwupd-1.0.6/plugins/udev/tests/000077500000000000000000000000001325145456600164445ustar00rootroot00000000000000fwupd-1.0.6/plugins/udev/tests/get-nonfree.sh000077500000000000000000000007251325145456600212200ustar00rootroot00000000000000rm *.rom wget http://www.techpowerup.com/vgabios/375/Asus.9800PRO.256.unknown.031114.rom wget http://www.techpowerup.com/vgabios/133037/Asus.HD7970.3072.121018.rom wget http://www.techpowerup.com/vgabios/148214/Asus.R9290X.4096.131014.rom wget http://www.techpowerup.com/vgabios/74257/Asus.GTX480.1536.100406_1.rom wget http://www.techpowerup.com/vgabios/162406/Asus.GTX980.4096.140905.rom wget http://www.techpowerup.com/vgabios/157835/Asus.TitanBlack.6144.140212.rom fwupd-1.0.6/plugins/uefi/000077500000000000000000000000001325145456600152675ustar00rootroot00000000000000fwupd-1.0.6/plugins/uefi/README.md000066400000000000000000000031351325145456600165500ustar00rootroot00000000000000UEFI Support ============ Introduction ------------ The Unified Extensible Firmware Interface (UEFI) is a specification that defines the software interface between an OS and platform firmware. With the UpdateCapsule boot service it can be used to update system firmware. Build Requirements ------------------ For UEFI capsule support, you need to install fwupdate 0.5 or later. * source: https://github.com/rhinstaller/fwupdate * rpms: https://pjones.fedorapeople.org/fwupdate/ * debs (Debian): https://tracker.debian.org/pkg/fwupdate * debs (Ubuntu): https://launchpad.net/ubuntu/+source/fwupdate If you don't want or need this functionality you can use the `--disable-uefi` option. UEFI Unlock Support ------------------- On some Dell systems it is possible to turn on and off UEFI capsule support from within the BIOS. This functionality can also be adjusted from within the OS by fwupd. This requires using fwupdate 5 or later and compiling it with libsmbios support. When fwupd and fwupdate have been compiled with this support you will be able to enable UEFI support on the device by using the `unlock` command. Custom EFI System Partition location --------------------- `fwupdate` 10 and later allow using an EFI system partition location at runtime that is different than the location compiled into the library. fwupd 1.0.6 and later can take advantage of this feature by allowing users to modify `/etc/fwupd/uefi.conf`. An option titled *OverrideESPMountPoint* is available that can be uncommented and set to any valid directory on the system. Setting an invalid directory will disable the fwupd plugin. fwupd-1.0.6/plugins/uefi/fu-plugin-uefi.c000066400000000000000000000552261325145456600203010ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #ifndef HAVE_FWUP_GET_ESP_MOUNTPOINT #define FWUP_SUPPORTED_STATUS_UNSUPPORTED 0 #define FWUP_SUPPORTED_STATUS_UNLOCKED 1 #define FWUP_SUPPORTED_STATUS_LOCKED_CAN_UNLOCK 2 #define FWUP_SUPPORTED_STATUS_LOCKED_CAN_UNLOCK_NEXT_BOOT 3 #define FWUPDATE_GUID EFI_GUID(0x0abba7dc,0xe516,0x4167,0xbbf5,0x4d,0x9d,0x1c,0x73,0x94,0x16) #endif struct FuPluginData { gboolean ux_capsule; gchar *esp_path; gint esrt_status; }; /* drop when upgrading minimum required version of efivar to 33 */ #if !defined (efi_guid_ux_capsule) #define efi_guid_ux_capsule EFI_GUID(0x3b8c8162,0x188c,0x46a4,0xaec9,0xbe,0x43,0xf1,0xd6,0x56,0x97) #endif void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); data->ux_capsule = FALSE; data->esp_path = NULL; fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "upower"); fu_plugin_add_report_metadata (plugin, "FwupdateVersion", LIBFWUP_LIBRARY_VERSION); fu_plugin_add_report_metadata (plugin, "EfivarVersion", EFIVAR_LIBRARY_VERSION); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_free (data->esp_path); } static gchar * fu_plugin_uefi_guid_to_string (efi_guid_t *guid_raw) { g_autofree gchar *guid = g_strdup ("00000000-0000-0000-0000-000000000000"); if (efi_guid_to_str (guid_raw, &guid) < 0) return NULL; return g_steal_pointer (&guid); } static fwup_resource * fu_plugin_uefi_find (fwup_resource_iter *iter, const gchar *guid_str, GError **error) { efi_guid_t *guid_raw; fwup_resource *re_matched = NULL; fwup_resource *re = NULL; /* get the hardware we're referencing */ while (fwup_resource_iter_next (iter, &re) > 0) { g_autofree gchar *guid_tmp = NULL; /* convert to strings */ fwup_get_guid (re, &guid_raw); guid_tmp = fu_plugin_uefi_guid_to_string (guid_raw); if (guid_tmp == NULL) { g_warning ("failed to convert guid to string"); continue; } /* FIXME: also match hardware_instance too */ if (g_strcmp0 (guid_str, guid_tmp) == 0) { re_matched = re; break; } } /* paradoxically, no hardware matched */ if (re_matched == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No UEFI firmware matched %s", guid_str); } return re_matched; } static void _fwup_resource_iter_free (fwup_resource_iter *iter) { fwup_resource_iter_destroy (&iter); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(fwup_resource_iter, _fwup_resource_iter_free); gboolean fu_plugin_clear_results (FuPlugin *plugin, FuDevice *device, GError **error) { fwup_resource *re = NULL; g_autoptr(fwup_resource_iter) iter = NULL; /* get the hardware we're referencing */ fwup_resource_iter_create (&iter); re = fu_plugin_uefi_find (iter, fu_device_get_guid_default (device), error); if (re == NULL) return FALSE; if (fwup_clear_status (re) < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot create clear UEFI status for %s", fu_device_get_guid_default (device)); return FALSE; } return TRUE; } gboolean fu_plugin_get_results (FuPlugin *plugin, FuDevice *device, GError **error) { const gchar *tmp; fwup_resource *re = NULL; guint32 status = 0; guint32 version = 0; time_t when = 0; g_autoptr(fwup_resource_iter) iter = NULL; /* get the hardware we're referencing */ fwup_resource_iter_create (&iter); re = fu_plugin_uefi_find (iter, fu_device_get_guid_default (device), error); if (re == NULL) return FALSE; if (fwup_get_last_attempt_info (re, &version, &status, &when) < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot get UEFI status for %s", fu_device_get_guid_default (device)); return FALSE; } if (status == FWUP_LAST_ATTEMPT_STATUS_SUCCESS) { fu_device_set_update_state (device, FWUPD_UPDATE_STATE_SUCCESS); } else { g_autofree gchar *err_msg = NULL; g_autofree gchar *version_str = g_strdup_printf ("%u", version); fu_device_set_update_state (device, FWUPD_UPDATE_STATE_FAILED); tmp = fwup_last_attempt_status_to_string (status); if (tmp == NULL) { err_msg = g_strdup_printf ("failed to update to %s", version_str); } else { err_msg = g_strdup_printf ("failed to update to %s: %s", version_str, tmp); } fu_device_set_update_error (device, err_msg); } return TRUE; } static gboolean fu_plugin_uefi_update_resource (fwup_resource *re, guint64 hardware_instance, GBytes *blob, GError **error) { int rc; rc = fwup_set_up_update_with_buf (re, hardware_instance, g_bytes_get_data (blob, NULL), g_bytes_get_size (blob)); if (rc < 0) { g_autoptr(GString) str = g_string_new (NULL); rc = 1; for (int i = 0; rc > 0; i++) { char *filename = NULL; char *function = NULL; char *message = NULL; int line = 0; int err = 0; rc = efi_error_get (i, &filename, &function, &line, &message, &err); if (rc <= 0) break; g_string_append_printf (str, "{error #%d} %s:%d %s(): %s: %s\t", i, filename, line, function, message, strerror (err)); } if (str->len > 1) g_string_truncate (str, str->len - 1); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "UEFI firmware update failed: %s", str->str); return FALSE; } return TRUE; } static GBytes * fu_plugin_uefi_get_splash_data (guint width, guint height, GError **error) { const gchar * const *langs = g_get_language_names (); const gchar *localedir = LOCALEDIR; const gsize chunk_size = 1024 * 1024; gsize buf_idx = 0; gsize buf_sz = chunk_size; gssize len; g_autofree gchar *basename = NULL; g_autofree guint8 *buf = NULL; g_autoptr(GBytes) compressed_data = NULL; g_autoptr(GConverter) conv = NULL; g_autoptr(GInputStream) stream_compressed = NULL; g_autoptr(GInputStream) stream_raw = NULL; /* ensure this is sane */ if (!g_str_has_prefix (localedir, "/")) localedir = "/usr/share/locale"; /* find the closest locale match, falling back to `en` and `C` */ basename = g_strdup_printf ("fwupd-%u-%u.bmp.gz", width, height); for (guint i = 0; langs[i] != NULL; i++) { g_autofree gchar *fn = NULL; if (g_str_has_suffix (langs[i], ".UTF-8")) continue; fn = g_build_filename (localedir, langs[i], "LC_IMAGES", basename, NULL); if (g_file_test (fn, G_FILE_TEST_EXISTS)) { compressed_data = fu_common_get_contents_bytes (fn, error); if (compressed_data == NULL) return NULL; break; } g_debug ("no %s found", fn); } /* we found nothing */ if (compressed_data == NULL) { g_autofree gchar *tmp = g_strjoinv (",", (gchar **) langs); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to get splash file for %s in %s", tmp, localedir); return NULL; } /* decompress data */ stream_compressed = g_memory_input_stream_new_from_bytes (compressed_data); conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP)); stream_raw = g_converter_input_stream_new (stream_compressed, conv); buf = g_malloc0 (buf_sz); while ((len = g_input_stream_read (stream_raw, buf + buf_idx, buf_sz - buf_idx, NULL, error)) > 0) { buf_idx += len; if (buf_sz - buf_idx < chunk_size) { buf_sz += chunk_size; buf = g_realloc (buf, buf_sz); } } if (len < 0) { g_prefix_error (error, "failed to decompress file: "); return NULL; } g_debug ("decompressed image to %" G_GSIZE_FORMAT "kb", buf_idx / 1024); return g_bytes_new_take (g_steal_pointer (&buf), buf_idx); } static gboolean fu_plugin_uefi_update_splash (GError **error) { fwup_resource *re = NULL; guint best_idx = G_MAXUINT; guint32 lowest_border_pixels = G_MAXUINT; #ifdef HAVE_FWUP_GET_BGRT_INFO int rc; #endif guint32 screen_height = 768; guint32 screen_width = 1024; g_autoptr(fwup_resource_iter) iter = NULL; g_autoptr(GBytes) image_bmp = NULL; struct { guint32 width; guint32 height; } sizes[] = { { 640, 480 }, /* matching the sizes in po/make-images */ { 800, 600 }, { 1024, 768 }, { 1920, 1080 }, { 3840, 2160 }, { 5120, 2880 }, { 5688, 3200 }, { 7680, 4320 }, { 0, 0 } }; /* get the boot graphics resource table data */ #ifdef HAVE_FWUP_GET_BGRT_INFO rc = fwup_get_ux_capsule_info (&screen_width, &screen_height); if (rc < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to get BGRT screen size"); return FALSE; } g_debug ("BGRT screen size %" G_GUINT32_FORMAT " x%" G_GUINT32_FORMAT, screen_width, screen_height); #endif /* find the 'best sized' pre-generated image */ for (guint i = 0; sizes[i].width != 0; i++) { guint32 border_pixels; /* disregard any images that are bigger than the screen */ if (sizes[i].width > screen_width) continue; if (sizes[i].height > screen_height) continue; /* is this the best fit for the display */ border_pixels = (screen_width * screen_height) - (sizes[i].width * sizes[i].height); if (border_pixels < lowest_border_pixels) { lowest_border_pixels = border_pixels; best_idx = i; } } if (best_idx == G_MAXUINT) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to find a suitable image to use"); return FALSE; } /* get the raw data */ image_bmp = fu_plugin_uefi_get_splash_data (sizes[best_idx].width, sizes[best_idx].height, error); if (image_bmp == NULL) return FALSE; /* perform the upload */ return fu_plugin_uefi_update_resource (re, 0, image_bmp, error); } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *device, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); fwup_resource *re = NULL; guint64 hardware_instance = 0; /* FIXME */ g_autoptr(fwup_resource_iter) iter = NULL; const gchar *str; g_autofree gchar *efibootmgr_path = NULL; g_autofree gchar *boot_variables = NULL; g_autoptr(GError) error_splash = NULL; /* get the hardware we're referencing */ fwup_resource_iter_create (&iter); re = fu_plugin_uefi_find (iter, fu_device_get_guid_default (device), error); if (re == NULL) return FALSE; /* TRANSLATORS: this is shown when updating the firmware after the reboot */ str = _("Installing firmware update…"); g_assert (str != NULL); /* perform the update */ g_debug ("Performing UEFI capsule update"); fu_device_set_status (device, FWUPD_STATUS_SCHEDULING); if (data->ux_capsule) { if (!fu_plugin_uefi_update_splash (&error_splash)) { g_warning ("failed to upload UEFI UX capsule text: %s", error_splash->message); } } if (!fu_plugin_uefi_update_resource (re, hardware_instance, blob_fw, error)) return FALSE; /* record boot information to system log for future debugging */ efibootmgr_path = g_find_program_in_path ("efibootmgr"); if (efibootmgr_path != NULL) { if (!g_spawn_command_line_sync ("efibootmgr -v", &boot_variables, NULL, NULL, error)) return FALSE; g_message ("Boot Information:\n%s", boot_variables); } return TRUE; } static AsVersionParseFlag fu_plugin_uefi_get_version_format_for_type (FuPlugin *plugin, guint32 uefi_type) { const gchar *content; const gchar *quirk; /* we have no information for devices */ if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) return AS_VERSION_PARSE_FLAG_USE_TRIPLET; content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER); if (content == NULL) return AS_VERSION_PARSE_FLAG_USE_TRIPLET; /* any quirks match */ quirk = fu_plugin_lookup_quirk_by_id (plugin, FU_QUIRKS_UEFI_VERSION_FORMAT, content); if (g_strcmp0 (quirk, "none") == 0) return AS_VERSION_PARSE_FLAG_NONE; /* fall back */ return AS_VERSION_PARSE_FLAG_USE_TRIPLET; } gboolean fu_plugin_unlock (FuPlugin *plugin, FuDevice *device, GError **error) { gint rc; g_debug ("unlocking UEFI device %s", fu_device_get_id (device)); rc = fwup_enable_esrt(); if (rc <= 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to unlock UEFI device"); return FALSE; } else if (rc == 1) g_debug ("UEFI device is already unlocked"); else if (rc == 2) g_debug ("Successfully unlocked UEFI device"); else if (rc == 3) g_debug ("UEFI device will be unlocked on next reboot"); return TRUE; } static const gchar * fu_plugin_uefi_uefi_type_to_string (guint32 uefi_type) { if (uefi_type == FWUP_RESOURCE_TYPE_UNKNOWN) return "Unknown Firmware"; if (uefi_type == FWUP_RESOURCE_TYPE_SYSTEM_FIRMWARE) return "System Firmware"; if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) return "Device Firmware"; if (uefi_type == FWUP_RESOURCE_TYPE_UEFI_DRIVER) return "UEFI Driver"; if (uefi_type == FWUP_RESOURCE_TYPE_FMP) return "Firmware Management Protocol"; return NULL; } static gchar * fu_plugin_uefi_get_name_for_type (FuPlugin *plugin, guint32 uefi_type) { GString *display_name; /* set Display Name prefix for capsules that are not PCI cards */ display_name = g_string_new (fu_plugin_uefi_uefi_type_to_string (uefi_type)); if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) { g_string_prepend (display_name, "UEFI "); } else { const gchar *tmp; tmp = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME); if (tmp != NULL && tmp[0] != '\0') { g_string_prepend (display_name, " "); g_string_prepend (display_name, tmp); } } return g_string_free (display_name, FALSE); } static void fu_plugin_uefi_coldplug_resource (FuPlugin *plugin, fwup_resource *re) { FuPluginData *data = fu_plugin_get_data (plugin); AsVersionParseFlag parse_flags; efi_guid_t *guid_raw; guint32 uefi_type; guint32 version_raw; guint64 hardware_instance = 0; /* FIXME */ g_autofree gchar *guid = NULL; g_autofree gchar *id = NULL; g_autofree gchar *name = NULL; g_autofree gchar *version_lowest = NULL; g_autofree gchar *version = NULL; g_autoptr(FuDevice) dev = NULL; /* detect the fake GUID used for uploading the image */ fwup_get_guid (re, &guid_raw); if (efi_guid_cmp (guid_raw, &efi_guid_ux_capsule) == 0) { data->ux_capsule = TRUE; return; } /* convert to strings */ guid = fu_plugin_uefi_guid_to_string (guid_raw); if (guid == NULL) { g_warning ("failed to convert guid to string"); return; } fwup_get_fw_type (re, &uefi_type); parse_flags = fu_plugin_uefi_get_version_format_for_type (plugin, uefi_type); fwup_get_fw_version (re, &version_raw); version = as_utils_version_from_uint32 (version_raw, parse_flags); id = g_strdup_printf ("UEFI-%s-dev%" G_GUINT64_FORMAT, guid, hardware_instance); dev = fu_device_new (); if (uefi_type == FWUP_RESOURCE_TYPE_DEVICE_FIRMWARE) { /* nothing better in the icon naming spec */ fu_device_add_icon (dev, "audio-card"); } else { /* this is probably system firmware */ fu_device_add_icon (dev, "computer"); } fu_device_set_id (dev, id); fu_device_add_guid (dev, guid); fu_device_set_version (dev, version); name = fu_plugin_uefi_get_name_for_type (plugin, uefi_type); if (name != NULL) fu_device_set_name (dev, name); fwup_get_lowest_supported_fw_version (re, &version_raw); if (version_raw != 0) { version_lowest = as_utils_version_from_uint32 (version_raw, parse_flags); fu_device_set_version_lowest (dev, version_lowest); } fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); if (g_file_test ("/sys/firmware/efi/efivars", G_FILE_TEST_IS_DIR) || g_file_test ("/sys/firmware/efi/vars", G_FILE_TEST_IS_DIR)) { fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT); } else { g_warning ("Kernel support for EFI variables missing"); } fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC); fu_plugin_device_add (plugin, dev); } static void fu_plugin_uefi_test_secure_boot (FuPlugin *plugin) { const efi_guid_t guid = EFI_GLOBAL_GUID; const gchar *result_str = "Disabled"; g_autofree guint8 *data = NULL; gsize data_size = 0; guint32 attributes = 0; gint rc; rc = efi_get_variable (guid, "SecureBoot", &data, &data_size, &attributes); if (rc < 0) return; if (data_size >= 1 && data[0] & 1) result_str = "Enabled"; g_debug ("SecureBoot is: %s", result_str); fu_plugin_add_report_metadata (plugin, "SecureBoot", result_str); } static gboolean fu_plugin_uefi_set_custom_mountpoint (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); const gchar *key = "OverrideESPMountPoint"; /* load from file and keep @key ref'd for the lifetime of the plugin as * libfwupdate does not strdup the value in fwup_set_esp_mountpoint() */ data->esp_path = fu_plugin_get_config_value (plugin, key); if (data->esp_path != NULL) { if (!g_file_test (data->esp_path, G_FILE_TEST_IS_DIR)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Invalid %s specified in %s config: %s", fu_plugin_get_name (plugin), key, data->esp_path); return FALSE; } #ifdef HAVE_FWUP_CUSTOM_ESP fwup_set_esp_mountpoint (data->esp_path); #endif } return TRUE; } static gboolean fu_plugin_uefi_delete_old_capsules (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autofree gchar *pattern = NULL; g_autoptr(GPtrArray) files = NULL; /* delete any files matching the glob in the ESP */ files = fu_common_get_files_recursive (data->esp_path, error); if (files == NULL) return FALSE; pattern = g_build_filename (data->esp_path, "EFI/*/fw/fwupdate-*.cap", NULL); for (guint i = 0; i < files->len; i++) { const gchar *fn = g_ptr_array_index (files, i); if (fnmatch (pattern, fn, 0) == 0) { g_autoptr(GFile) file = g_file_new_for_path (fn); g_debug ("deleting %s", fn); if (!g_file_delete (file, NULL, error)) return FALSE; } } return TRUE; } static gboolean fu_plugin_uefi_delete_old_efivars (FuPlugin *plugin, GError **error) { char *name = NULL; efi_guid_t fwupdate_guid = FWUPDATE_GUID; efi_guid_t *guid = NULL; int rc; while ((rc = efi_get_next_variable_name (&guid, &name)) > 0) { if (efi_guid_cmp (guid, &fwupdate_guid) != 0) continue; if (g_str_has_prefix (name, "fwupdate-")) { g_debug ("deleting %s", name); rc = efi_del_variable (fwupdate_guid, name); if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "failed to delete efi var %s: %s", name, strerror (errno)); return FALSE; } } } if (rc < 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "error listing variables: %s", strerror (errno)); return FALSE; } return TRUE; } /* remove when https://github.com/rhboot/efivar/pull/100 merged */ static int _efi_get_variable_exists (efi_guid_t guid, const char *name) { uint32_t unused_attrs = 0; return efi_get_variable_attributes (guid, name, &unused_attrs); } gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); /* get the supported status */ data->esrt_status = fwup_supported (); if (data->esrt_status == FWUP_SUPPORTED_STATUS_UNSUPPORTED) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "UEFI firmware updating not supported"); return FALSE; } /* load any overriden options */ if (!fu_plugin_uefi_set_custom_mountpoint (plugin, error)) return FALSE; /* get the default compiled-in value for the ESP mountpoint */ #ifdef HAVE_FWUP_GET_ESP_MOUNTPOINT if (data->esp_path == NULL) data->esp_path = g_strdup (fwup_get_esp_mountpoint ()); #endif /* fall back to a sane default */ if (data->esp_path == NULL) data->esp_path = g_strdup ("/boot/efi"); /* delete any existing .cap files to avoid the small ESP partition * from running out of space when we've done lots of firmware updates * -- also if the distro has changed the ESP may be different anyway */ if (_efi_get_variable_exists (EFI_GLOBAL_GUID, "BootNext") == 0) { g_debug ("detected BootNext, not cleaning up"); } else { if (!fu_plugin_uefi_delete_old_capsules (plugin, error)) return FALSE; if (!fu_plugin_uefi_delete_old_efivars (plugin, error)) return FALSE; } /* save in report metadata */ g_debug ("ESP mountpoint set as %s", data->esp_path); fu_plugin_add_report_metadata (plugin, "ESPMountPoint", data->esp_path); return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); fwup_resource *re; g_autoptr(fwup_resource_iter) iter = NULL; g_autofree gchar *name = NULL; const gchar *ux_capsule_str = "Disabled"; /* create a dummy device so we can unlock the feature */ if (data->esrt_status == FWUP_SUPPORTED_STATUS_LOCKED_CAN_UNLOCK) { g_autoptr(FuDevice) dev = fu_device_new (); name = fu_plugin_uefi_get_name_for_type (plugin, FWUP_RESOURCE_TYPE_SYSTEM_FIRMWARE); if (name != NULL) fu_device_set_name (dev, name); fu_device_set_id (dev, "UEFI-dummy-dev0"); fu_device_add_guid (dev, "2d47f29b-83a2-4f31-a2e8-63474f4d4c2e"); fu_device_set_version (dev, "0"); fu_device_add_icon (dev, "computer"); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_LOCKED); fu_plugin_device_add (plugin, dev); return TRUE; } /* add each device */ if (fwup_resource_iter_create (&iter) < 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Cannot create fwup iter"); return FALSE; } while (fwup_resource_iter_next (iter, &re) > 0) fu_plugin_uefi_coldplug_resource (plugin, re); /* for debugging problems later */ fu_plugin_uefi_test_secure_boot (plugin); if (data->ux_capsule) ux_capsule_str = "Enabled"; g_debug ("UX Capsule support : %s", ux_capsule_str); fu_plugin_add_report_metadata (plugin, "UEFIUXCapsule", ux_capsule_str); return TRUE; } fwupd-1.0.6/plugins/uefi/meson.build000066400000000000000000000007131325145456600174320ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginUefi"'] install_data(['uefi.conf'], install_dir : join_paths(sysconfdir, 'fwupd') ) shared_module('fu_plugin_uefi', sources : [ 'fu-plugin-uefi.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, fwup, ], ) fwupd-1.0.6/plugins/uefi/uefi.conf000066400000000000000000000001551325145456600170670ustar00rootroot00000000000000[uefi] # For fwupdate 10+ allow overriding # the compiled EFI system partition path #OverrideESPMountPoint= fwupd-1.0.6/plugins/unifying/000077500000000000000000000000001325145456600161675ustar00rootroot00000000000000fwupd-1.0.6/plugins/unifying/README.md000066400000000000000000000025501325145456600174500ustar00rootroot00000000000000Unifying Support ================ Introduction ------------ This plugin can flash the firmware on Logitech Unifying dongles, both the Nordic (U0007) device and the Texas Instruments (U0008) version. This plugin will not work with the different "Nano" dongle (U0010) as it does not use the Unifying protocol. Some bootloader protocol infomation was taken from the Mousejack[1] project, specifically logitech-usb-restore.py and unifying.py. Other documentation was supplied by Logitech. Additional constants were taken from the Solaar[2] project. Design Notes ------------ When a dongle is detected in bootloader mode we detach the hidraw driver from the kernel and use raw control transfers. This ensures that we don't accidentally corrupt the uploading firmware. For application firmware we use hidraw which means the hardware keeps working while probing, and also allows us to detect paired devices. Verification ------------ If you do not have Unifying hardware you can emulate writing firmware using: unifying-tool write file.hex -v --emulate=bootloader-nordic This can also be used to produce protocol data to the command line to compare against USB dumps. This plugin should interact with the hardware exactly like the Logitech-provided flashing tool, although only a few devices have been tested. [1] https://www.mousejack.com/ [2] https://pwr.github.io/Solaar/ fwupd-1.0.6/plugins/unifying/data/000077500000000000000000000000001325145456600171005ustar00rootroot00000000000000fwupd-1.0.6/plugins/unifying/data/dump.csv.gz000066400000000000000000003104571325145456600212130ustar00rootroot00000000000000ɺIXdump.csv]n]S,7-GDA18I^>i)l=s7O36O2$%j/۶HSɦI~ԧ\ki}tso׻b9]쮾g7o]'6o7 _}M~tv1i態/!C6}v||qx|9|yܜ]]mNwnsջͫ?^\Wf1˜)n䟓?n>_뛋ݻ団v/nvnް/.CWhWjw^_\,o?]^ޒocmy mMr˵XyC3˫ݼ9~ w ՇO>]^Fqk^&)إfe?ݏGIj1]l)OPLI5e)b|R`K ԟ7 fŵ[yˣyKjʒ)|e5)h3Y|/yX[|%ڵ[̜eXS[*5g NVBܙ@LmإwrCYt"vpmN\q9lreYЧzWp9?_]bBL`PDd",ʦٜ|_)856 Ո!(%X'RѕPC y5ɄxۧuPNAyoF ~F}`4"E%JoJVOOF閣#%(>hՠA%d"T,ysqoLX3Gu D. 2ycna"܏%\k6[]z|iJ#[1)cA?u][j{#][d,i6bN?UזF&*9B(S/?3Te-R-\,ǔϷ@b~7ϋw JUU$? wh k$~[q 7}|٨A"h'>^v;SĂ=Y_> TbA2f184PHɲb$#fWѻw{c QG<,戮ÎpAI:uiZAviS8YҚ]"s,^M7Fmd/Bv_EP7${ !WNtsqǿW7W.w8娝:uLdaTdC6:V6}g &uK,mUJσ'(x|* JJrkMG0].rBTl<N,vK5ViPRJtMxpx*YZnҀ얚 =v^߃* HR0`ڂr54v^߃* 5v uB!PedMPUnطz=Ҁ`rAUrTik YrSi"t:JOwujSF%%C;A:uZn* !iaTi@ɾ)'jk\@R`|{Pg]CX:]؆:ϼUxg$T[l\Ҡd?Թ+ug^Tx5ԉ#r * <4Hkg^Txvu+զ\THJ'y}OPicP'X-4qcxB6Ҡ$ۼ'4L)uS:>|j#sCZ8y}OTi,'6w“ڲruTi )a^UgCr!lTǽ*y}OTi@$g8QAI =0* u"\ȚYGAc#QD$x(ΡNvW4()'4L׹k Yg} 4Q}[=ư)4Hry6!7Vi)їÓTD~t ur%ky64V)7I* L;p(W'%%aj$/Ax((rK* hSCܼ'4V&(W';>qҀ6!qHxJڄ\{J8}CkPQaP2~$vt XTPA`u˼.'HL3‘b-" yˏ]:p:" yNj_²:~n67*2t7f%uO67x/dS ʳQ5K.oqښ;bNMytO}oǐf2C:oÁrt%ÍkZ<}?3/y/wOkϏpɧdJZn`+WAu/kgu^.@k4gOyL?sRTrc|N2֨LЮoPSZGh5wFX" GʬԀډ $#6F}Ϡ`Z.y 5E 8VڔH^g$3׈}Or+M X pfc_ÉRmJd$2s?&(DhcmRO8}cW[W vx"(͋,grsJ'pb* :LtS,4<֖ľT LO߸Tupb* x Y?dB,3(ol\ * $#i{- [yxzM:ńgܿsFS< c6S _T)8pꓞ VJ9o 2rDzGٗڅ'嵚8Ww+I9VXl\NFbWyQOz2W9]<)wU.6T' `FN|QH% -<;?9 G`@w$UY{k\$>ڙv+Y! o<ŃbP<;:U0F}'7NJMRWx;xȓ᝟ѻp-QM)D fD"(iM;?~(ۃ,Nh+: ynyFTFP< 0=7yO`m":Ǽ])(xZr]{E ]Փ~D^+q|ky=DB `}z^^o{yՖ٣+<"$cV&S@|&{j4.x~^Qf>f׎aAOWԆ8M7''WUShD@U/ɫ6|yBw<:e$y]t@m}0L!\%>rrth$(o[h4z=G2R(L~`k~ӽy! T<)<ӠXĆ9؁)W &`2R KK??=xXrxĆGqsJ0Y|uB5H<壯I$8GV/Cx8z%'~)3-q$к>/WΝ Y6<u: B8Gh-1\4ԢQ~.Ix$Gˏ>A@o7rxp~To1r[kl/V%;tl? >ʒgx 7>A[ÎVCPsj=GJ|+@f`% d+y{\\?-NRE}7 i|5 s.4w2uYO3~g'禊/Ԟgw4*cgx$xLZs/S|0|)?f-*^$_Jj9RG;Gˏ>A@} ꃫ!(xyp.Y՛>x/`Dq#F(·*ԣ>g[9>CȏhG&Noiݛ"gsjċU\>*gA)s?k!hxϣ`DRM>|kQT@^=z?=_޷}ų!{[_Uo9>A.!hx#okG򃏹v_)xׯxw+u+G?T  L >OC'ʏVO3`^=ZC|Wޞ)'xfVDA|_f!<,E~ p[h??>"?W,--jxyiJ)-? xaGnFg51Z8P}?| {HyZHgL5 4>AXc- _,N{  0n޾Ghd!?G@3YU'Cu}eGӔ3<<9xᑀGz$xmHѼ,w.3p^+[SGydx_ﮅQG## Vo=ex+^:Ɨ!)xtpw=17GApݵ<,vه ~ 8 l%ĜԶ'5Q"oGT|N ޞ[? zCjsH=s?Cn o#ԨO{=۸8hK;e-E}7~A4<$ݎ!G:D[Ń~/rl+gZ|N G79BBF껙rD~ϩpV q g7}h7u<?k.9"?<q~}ܻa<8?|N ~ƵL'+A6S}Sv*gx~Aܨ gȭ»-R?v~nZS?ɭaqWC:Ghfm1P~$8?OSŝo&Cu)gs~4<܌0on WW~8Oe>~wUp9Bs69] A|C]gȭ`"VoqU<7>'  L>"^W19"Vo=x>hhsU3w0~=,bmFf!D>Dr>)'x x3k!hxϹ!GM>|E0!Yz|q-_qw:sgƣe'7_>]l#1W W׋F6-;^\[>~wQo/g,d}w5 9ICbg(gx]Nwwsg~>ϢLWC_~Ww]z?)x93\2<ϋ(ݵ<Z2Q؟4 HaOU@:L7dI|vLm*sg>/LKVCSKg(͟.Q7@hǨP4D|noW̆Io E{AGde|}GD-~^؟8Ga[kFԎz=sOVQpQБ80] A#2C~4>O {GK]Aj"oq͍W/yuW j!hx4>OԒ1tu{ x#>~/T$^D [8ic5%#Sg?\~g ƼU␂9k! Q84?_<.^wpax@kxq'Yu?D ^8<ϰ|?g(g?\~0x㊗9Ѳ}S\pE}p2!hxI#  KJ{̓]_I="Jw}f}S?%g? B4<$n~~%g;GyV]O?U%g~ Vo{] ApA<8?D c|@*[0Toa$?.Q?+g+3!L>QPD L?|^bhKlG!?10lY?\~UoG?xtj֋3`_wZ/W,'bL<Ȁ?G!hxϩ%ٟphq"6s X^qOLBw sj $w]N\C<$$vB{am NJy! A4qz5 ;+ Bd gokzï?d?v.;,8D7%k1hޝH!q?DɒNMsIh"Y|RzRB`h:Cv>roU<$(I#|d-eoz%QV\iC< j8HPuzZOkVa%}"i%8dNVc {$Ɋ+H(K=TaZ kKV/NoH@akeIBy¬| =qH$K2Nm)NCRc//H>qC)$YzqƠAz*^-dI'$ć5eɶԷH=!Hw8/YA7CG$˾$ *vm+4H@r9oBnvpqƠ@_LW; BR CR<$޶YH^;{p EδJVWr,U獑,1{{p@8ǵ$p*ʎ 88?Ʒ!YA6s:#YҎ;ejB$zIZGޟ#Czאx4H@%@ؗ+YҼKxZ\]W`8ԚY}@ ǡJaw2⩐$+Xu8,{iC@itq~5 F֧ c``dI$%n:K‰"sUq8dIw7Z $qH$K{&짹?zɜfR`:Wd ]Msppq^As'3D^ 8jBȳLƪ5쏷z>Ô_zUU\!tU 6h񜌃Vc q@w/Yɇ/Y$wߑTq@=4z/As2a/4HHCy C 9NsIpom~pٸJnye>9)Λq k5 ;a"ɇ/$eشݙofI@y"x- лv$K7hOr ;oL"]Fg']qArn &t2i~ L w2A@ ,iXTv/"&}on$yS 9'88LWc s'PqDй}@2zR16vJ˴Y oB%wHb s'X%8Ift֦=zYUZRaQP$w Aylq5 {9tvXQ#PTm'in|u=7$SH2N㐷y.YANg!ɒ%Yz' @2ְ?dGeW^YKl(K!KyIx8d3ǵ Q8ڭnt$tbtBFw^ŠAzN=+HW^D yzҿtM{7@Nz,7/g:<Ա ;Ɗ[,z MW? -;5 UH6~_V^D~x:xU%n; > :YH<ɇ/)n^,}Yp{1%nz=k\$wjzqh~Ocj $wj(Οx$QfoMUkWg߉b<(3]b ǷviMu!Uqޢu2,>";KbP E]6<9o¢&u!h1U/PrS񴼿|u`|;CK)ZNơA24 轈F;d !SWiHDk72E/s/u%sP;D:`:i4H@%9i%U]!O'.^r,|+#5OW\+$6mk%w8%k1h} qH$KKPK(KZ%x&U>;$:/UVo [}QVGO| Cq4H 9t'Y^jXDZC2z|4U>iѸ?MuA̿pk7f35䛺⪆u$MEmu$Ar%-ѫi]<+aƠAFD!,!k}kCS2}Wy\E#+lѓ4}CT׺6ӝ1h@R8!H@, :_`k3(a5x67#>x =wՕIj> $8Yd5 ;w2 UXXdл ;4<6q|cjD7X~ˠw*[Xd;C *k1h($%"ȠwZ7VHƍS ? ]:I 'U/)wsHZ;C1H Fkmzw%fzXhŸm--^@pUYzq( 4H@tB:@5IIdtŕP7ʿۿ>_C[l[U@z' \VNPZ%xih5 лk//H@O_.:\.ZDtJ~y3;jީ9-;y$*ŠAzюL\aQ@wz5{&S+cowj(7;ôj !!v!z Kj Yn>nH}uQՓ A8wj(WmڶC 0]_AED )K4f/V񾗒#v=mgowЯ!);tq~5 ;w2UdIA#eI*5 o!S+KY_Ya}]d !C ;!,q(Kfݴs;ʹ'ڸG!U{ HSyFnCy+1hޓ̡8m{HF!r3O6ި`H =7}lrfo@<Ӷ61({9t`\{,=j Rw-=6YzhOd5H@p I;C4H@t#A*;|d.Wk,{Aтe4K@pU vYzqr5 ;HPNnfpYz/%ezak=ᨭ`@g {i)$Yzq.ίƠAz/2@"738,=K lmU\vk2M4oͷi4z78Yz/Iw:dC4z7JsgswnW~V@y kYb8P1{:KbP aHdI[Hh [鼑)Z?4z7_ε,qXd- F:dIFPveZC~(BjrۭI$Ar%YƁӐŠA̡#x, MoЪFTzyg`۬GAi4z7T}dIq68_Aѻvɒ,in,e,5{~־)y3km+awy I@4zqj $w+s$A$ K@6 -;5dcڻUX}>xށޝb9$-Kaf5zwĊ ×0/)Mkx;T#^Q&0_=L ;w\B8YUq5 лÐD+xē_bf=K&M2SI~\ށ]9$zqhö61h޹abH i}04(lyK^ȫnӡ]]Wyw64H@>@ fHZ/wwR:}i_}X,$w,IHt;C=ѻ ݗ#$W  N_HF+j *W;KgZijii`%l7!}Oރy$Ơ@A5Zq9x{ا 3{hiW-OX~/4W%ˆV==HrKtz/Lb s'$ $ ʒ6Ҽ!K}fVFt*G[%S.;t%x5 ;w2d z <=$KJhoYzq0n~ZA^,dݻv߬|ӗq.yՂ,1 >Ǥ!4i(K"أ#y`kV4H@%r #Yb@ 2J+Ώ^wkwp!]/y'kb?ʎѻݶY#y1(Fv3/& |@2UaM@mڍ_{tWcwV>$cqGH"-R2|=٭i ̷Otȫg߁, Tt!| 8aKVc inK7w8YPUax`4} ċaxZ4zܘ. ;C7zqj $ aH£#|@2|kwp<4H IUr>fpcqhy~CI$"L\ $ }({hozS,ǿU Iwj0Wzo>{H6 AeGz%v6o'2VM$wj0Wy .|8|d- ;7 \ޑ@ zoUkk^dlj \b}w@ܘ= K@< 49 9W Yz/e5[)Q7/THЛ@ܘquG$:ǡ̶CƠAzwee]Zg]>B2%UkxП=;m*C΍Wyw;}!j $wo!_e\:7ܪրr\zAq!YnWWõCM/ `Ae5Y9,IRPIsvV'}HRoR{z*\*$fpZ`<ŠAzf) 4H/B2ntZ`~ܮ<'t?ZgCidd NWc h,Y%w qv7:ļؤ{k0!KDtH@q)u<v0j $hz dIAީ/ĹW=OnZ t9PN;kZgcpqhz-?1hcF{ErY/×8? h Iڟ'arS=S ksIKt8vHZg6KF<%dTº?`qI_o 琴#\dlq~5 {<C$tf=Ukܿ< ;7f\]}u2aKVc rKd =SJlӾW+įh{arMe$wn̸:6d as~5 {$F K@9 -;ޫPktc;͋>a\,7f\UA޳_d- {.mD K@G6Uk[~=9)x"~1铧 pS1I͒:j ! pCb%KCB&6Wc ikơ|hnuBa{N tDi$@F qHF2e>Kb I$ 9H% $[{ y%94)e8~ +ΑKge%MڬƠAQKN#K;%!O> \Cث!\xV YAuliͰ#: ݫp>ح~U!+4zwd1IKtq̪1h4zwaA ;B3psKg=m92Wut88;{ k5 ;tء|Î%w%$nx%Zm12 ;U%8d ݦ$Z $w5ګK ;B3p/8?ڦ}oZ[%!Q =K@dq IDޝ Z $wjpCzIÎ.\ 5U!uLU%8:HZ稥 f%!\VuWR+x$wjpWC8,@ X%X!BkpsVQBUON K@<aV{_ANmHdd !l%Qc>ۋBZQZ]3*>1hީ 8vxv%wj<eOȶݐ^dAzM<Yzqh _. =:% N>MOTo)ǣ6{<*,kvkHZ;DkCbP k"X!Bkp/$5c?9.`yYcU'ѷZvkvwYou2<|g5 ;w2 ]"^:G6>OO\x\N[uV lmu2.YADg,MTyoݹcv >Ss%:ݿfkZHBwW!K@<e~ZA^;  N6aL޷z'Nh@]jIBwW K@4~ ;Hd l2h`³M;mG=}T.kM $8s{ Z $=w2 iGq%k'w gvF?39Z$wSHѻtj $wdD!"z Z"|lzV׋D 5}d a4H@N.w%wGY[ngƵ8HZ [N!WcP kw2dI,i un y:KDku3u1,kCZA8$%" f;g3ĂDү'~Z}7O% Yzq(Z $w/s$I$!K@tD-?0N:(խ;\|hi$d ǡO\k1hރ̡CHdd .ˈ4$5|W|OR6:]dd !lzj $w$b,#fd .ˈfr_g3/ q/(se%]ZB Z $ptIrYFley,ޟlf?gfh_]lVSZZ Y ne8kVc GCGD.ˈ:OMUGϗ<ZC3A9uh%~CN, @,8i4H@I!H8K҆,SBDOspG/Isf#]NSq_P/ptBjN09  IH%wjB$zWY'P/3In_?:TZ邅pU N}- {9t,SByVi5O홅ް=:ހhcuMky`!\]Bkd-,s'#YnpԄ4pe³O嗀-FGZ邅pU NM!N!ob BjNFZ &89ZÞ칵Bޫm W8Z $"sHXXΓp[%xƸgyUoX7 ;[E"W8yz_A{d"HZHi2K^Uk聼z q.pP4 w8LiƠARIDu' *5~o%rWިlj^U%8A{k G'HZHsCmIuw@R'W;š0⭩8l$HRN!:su|Fy{Wc S $Y$#K@$\0YzU>ojt̥gwr:/+} µNơUWcP k]2dI;ZH$[exPa;$w:/+} µNa4H@QБ,)%%"@BY*u5CϽ2AAi׺@'}IAy+1hީ`Β!K@$\QoW8l|q\kӎp t?^U,8LƠAz8Ԧ7' K@$\Vσg_Uk<\W"\d{Wc S@*g#Yb ipf خ?Vp %V},8,@ :%V"K@$\gx ;>խ"\f AiҴj $&s$%Y=ptpxxYˬ4H UQ8@v%} µ!M>$2@%K5u*Bj s&) Xt8!?=T"\"]0 $8LƠA=R($%Y=p HF;TUk^zyC 蝴tU Y]aںy5 ;iiE{Yz'=I])R6-4 EEU%8d a4H@BPɢv @kIf`%"8Yp4}4HZkHZ@kCv5EHCmY׺Hu-; yr8tpt @*gN!sZ $wHC,v @k]$^ZѶFto_\׺HJ0Z'0mر POpkrB=Dy;%BF4[׺H @,8Jp璵4H@?0 dIFIγ5-Q - ]gw5+ W$wM՟}u2yb S@59#K@$\ݻh /i.o$nՍϰ9Yeu_׺HJ0Z'0 \b9tɒv @k]$:Jݦџw%}F)Azk!A\dZ% r $(s$r @nuk@2U4[+L\*Q`knj9$wO`!ð{4H@?0 gIِ%w67q)+|LsTfGz/=pd*pqfKc 'C )H%wK+{7[+Hj"H||xY^8 ;Yǧ+w8>4H@Yl%Yz'cL"c1)Fp!.eS/<ԭ"\"Y_C8YÎHZ 狑,iu2Y 6[$zqηyg|V ;YJpA\xϒ4H@?,1%C?µ.p]K&$;-V/oi~~YN}u2n>Kb CG %Yz'LiӻռPKI˾獏;6 .=Crv}u21h4zO9@r>qY,ic TDep_M6i?|LΦ oe HB7O'.Naְc9 H"0,qȒHx`HľޕnԫDr#% 2&nG%U14K>:6HZ̡CH 4HH.%j8@F A\df1h8@!^HXKxxK=ABX$ znh@Rj8o:4yr $ޓ8,Q )ABM%׉kM[Ph0~FGϦ6?V\pK~+ 8̶i/ǠAzc$K% K@ԄP&V!]k-L'Yz'|զ]0ۦ f:ob eDɒXOě$Ybրms*t07u4?*pK~pq(1h} xJ%C?µdkMָLsEI{-0+Lc! |YOHt;C1&/ǠAz'<9_RH2ihqTA qу_2)=bo ;ϗD84H@[%@%@Yb'W\j _$}by8= \$,kC&m|ZAuX%8K4׺)KdTzIabO:93}׏6m%:_.e \d+1h"Y<#\R,A%xn^Vbl(ǴtIy$w:YP);]ƠAz劫Hd =mHW\5X]m}}OIXBMCpKtWAydr $$s5$v(KAeIzYZexf}%AzW! K@<4H@? IH% MRtexI uNJB͒:ٞBZf$K~k]ʔ%ԧ!k?Ը!e$%:_.*{zq =zM{ %C?.ʒIÎ=[3jnh_i׺D'Ž{;ìr $!%Yz/%yzuo;߾"{r#Q׺D'Y<"K@<m1hiHXdIQIĴ?Cz-?Rg>l~4ztŴsH%wYw4HMHdC@lklDtKǽ uN3$'=%pqu^Auy9tɒ桟ZFsgi6k;{jy?@= ĵ,k'4Hgr$g5.yɒ桟ZM$yT^?W5?@y G4zq4$k1h@R8E,LR2~e`=Fa7La(3^Uhܞ}9O}jسsHeƤoU_#eڗ=s דܖA$k I*rhs*^R2ZgcC@2ϒehl=9EF`Xk`}IEfyld5 /`Pf8dtJ-vՍyZrpU},m⛧* Wr-3'#Ъvˣ`E13;[zw\11MR⦊VQw\1\'`dF#pYG40s ʌ2G>WՀ7} '},qŚ}FAf${0Z`n[7rQx/qUo䘺D֞>&lɿǸbcUϴ 8\aw5 pM|cCzm>1ZrUxJL8|r^(6jW81~]\q x[ BY Anqɼ97+P;MDU~R/v&.5JADNhWU Bc- 0s4(PG-* гfY=Y:>1W0+t\ydW>q2y~Q_x7n^ A|e WH\vfU~>4zG>D=?1V 0A4'ٵ$GG\Y_=l~9A!|N!{8?mr:կpԾݣўۭ҇z;}p$szTj!Z %4*:]VE4c\_*lr@ҫvA"p\G')U<˾exuk0Ekxi|;b|arrMÃ8ίϝۻ%"jxȏ`0mIGⵋhG6#*ȋc gT7zRsAAX A#5<(➄hDkZa4<^Α>.1@',9>-w#7 Mt:]ۭE~yljs:?C~ϩBxp{ҳzY\TUG; + ÀywWCP0sw#]8?eqـϩxꃡ{tܣ#٥p#,;+L5g>Ck]>A4Usxx7k!hxcs~xlnh4g޻gUrs:.#?<4aYuC7s\2v0 Lb>/2usR}'*حr'u|Y~ϋJY~$Wk!hxϋL#o >'z~vx"^_Ț(ڵK|`m^|-<s!hx4>70GF~4>7>V/ .|5G;ۡj>5>7nϳk|΃|3#@>7񱬟M>|E0[k֗[: }'9*#x w">Gs ?2 4xJY[%()xwUoo{?OGsC-cx6p-ȏ<(?`0hYx ֶN҂\p7}ᑀG ? x7] A#!!ȏg1^ {^|5g$]ţ񹡓6GAo_ A|N-~6qݐsRl=/n>\xeW?Cs: G>A0G3|NshQ_0Co*\_]>.áywWCS :w?{9ct?x8\16KgxIxs>A4Ax>2u"?>nQ?xWL|N'E}סyWCS >'xQ4|{><i?VCP Sbls#9C.j_5}e z?us: /w:!>2uќsd*V[ҽs: :aZ18b |N:h#"[/c->O"GGB4c%ƣɷ?+Jߦ>'ys4|Nl}w5 yu: t>81+?³W~Ivs0}jG`?n>'?1x *B-_ۺt/2G9ᢿE!LwWCӨtD9D7<xYÐ=s ǿ:??GyiJ|s7_/Y A|^b+<  Szf}[U>Aq5n2u^wv [2!:e[ϒPq*g {rj|.0}jx9?iH#OW8/ܨ2dj2cϭiJY~dGA_jϭsΏh|nɊ>z{,q=_##?xGs8;_ᑀLxΏHwGa얨½±jKGsJU ?=t}w5 A7GsKn1O?R?byo&1XOLU<KRiU/~G >Aȵ^js'b gSq~SxUŃegY|N:x{d`r`?n >'?ꉣ%b?{6R}3/ޟg9ᢾ4qc- utd9tMWxG7,$3@\ To tq,x?B/Y Ap@7,VOӝ~\Д3<8i޾F껞<gx*kxI]? A_w7k!hx }9uTŃZ[S\|>:ٜRy|΃0߾<(QM>|EJ\ŃۃzmvL`{/>g%  L>/CȏdMÃ\Ҭ_x(eGt*Ssi:+y^ΖTRp LWCP?-C}GA4{8쵿;BYطK~lZ'\綦TGn8A _ A#ܦK<8?2#=?2w\Ńӟ; kPT~Z?c%^!Mܑ ?;:MgUZg>QpJ 9 i?<笃z'6ʏк +r'vx+ON'Sמ? +\ox ?Gl[~gZs8U g%:a޾Q<,E~⑇rm=mQ/s)gxؖAﮆ8SK<8?lF4c=Wԓ߯'kO'قy+`[~Nԣ%!hxσL8?C4 rEqzz`$hy1m? +Wx8w4%̿wzc)st<]wCh82۟z{4}?.1Z-U<[mz=q1Wx`퓣*,l^#܆_ppΑ.:'0헱GsO-y[8? 'h?uiG2[_'>> (#Ve tNa4< sΏ(e,U'@* !?s/<p2a?BP?vQ~D>RjQDRNHO.8bL,Pn~88[o_ A|NqF#sy+N6ҽWxAQ9Na4]3,ꉝ<Naڟz5y/SI?zBkor{\ŃvΓ~/9dWC:`_ A|Nq񧎬v1޽U`;4[vpʍ'%pΑRyҟ82OZH}7:#"G ԃnU |N'E}7p<Wk!hxϩ w|)?t~xxdoދP.۞?x?B|< |墾82OZ6O?6?8(?~.@ wt+ Єϝt\w#:'Zl]Ljgʏ oU/G}Gi/`pgAꛂ<闫.:'Z Ewd? +[.J <| v#@? B#[ A#! GvGD4#xoU<zu\%uTƺ^&˟pN—nF'{Vo_ Aãy+P}7__,ȏP~IVŃG,.IK< t}5 <Ľp~4=+6O}Nzq|tRi&Zګz`L*O)N=C`z@R8)dځzV V}_*wUQ@ɕ'޴qkA֭ovI,cz3 ȝedzqz4&kA醀2R~O<Lub2ZcFP1&]b a TL@4nĄ<{>9pɬ&0 08PzOV0m\+YΓ$@ߑa|^9h/SǬ_7KbQ5QTx<[\ B= #e65w4LY{"iexx:O`,rbup`2-E|7tׇ0pU=O=b8>A `}F7њZ O:'0튲Ihe$o'ys=<~C?TSvk2\}`<mIIxi TL6 c'xUz?!F:gULT'x&WP1;G0alzIȺ[ uyǽb$'x0ǯbw2`ybzl]Qu*K~ Eo }'y:Zj&ގb¶ٺOSiҶ=_ 5+Ox {YGX%3LzOd<&kẠ#p&hmQI%V зULN1yqv'_ Bdy'-۶yGgH 8>LzOdo<\ BOMp'xҲm *=yTLT'x2'kA㩩ԅ3gOZ ?@}ApU G:tt1*a{ L'0]_ Bt1<: =`w=p"(o|%Nt( o~aNyw:sZ*&$&l矃4LHvf]c:ĽSrɪ_b<'u<=sZ*&xj*Ą𨋤eq>遪Bp̒qa'=\ԅsR`]TVP1gGɬç.dmYcJg0$_50ǓIT`mfxZ BesUIwnW稤z0Y]$=%ϳpqp5 4L`WIÄxEݬdz]fw*$!RSN'Wyi.ډ;8ߵ ,IϯhϬz<ƒg_F7_>%Pڧb8>Q}l{ b'\/IDMvV_l0!-}Jx4o騾 S';j*&xj*#uyƤ 8LJkgtnR9LMD (x*ڋp=pqXd-p<5ؑp8OLp  {G1w{/\,rv<n{5p&1&LѾgӊ+ZK an訾`OLzi_ b0&' 8w0Gb]$a4#kbNi 8ۋOঽ=VP1LJA `8O\p<5&<Qc*&x:.zyqpӮAָO ~V(6?/.? 7>w_bҮ6օWP01KQL<牏=`By'9U2la{U9.Q}wQ/zq 8>mØpiPcӘ Ͼdqֵ_|gy\OGE]'xio TLIZ} ' 8ɨJ8}>o7>w)*yb0v TLYс< ' 8JI7WtˁOՅ]Ez[UL`{yoV\ B(&$<ScOӘL""sflf>oQmo |R.U< <ϝCOV0]*1 I2= 5&Q?WP>R821t쯡^[1KWy,O>w2~+Ạ$Γ{<ՅG{^UzHQZOӝb_9%?W_T&=O<yr5yۆ1<=OgjLr.s<ǿ'y6w'eo\ B$A `W$xdOE!<^#ז%o^`Ry'IqXd-w<OւP1i`:@!1;|=q|~!]`,O4;. {=SHj**`y+35*tmsEWPam׳O=`Uؑ ~WVP>ITLPLҸ (i&1'zI^E T_F{neu.J/?HC|8{b5 P~ 瞷Ȱ%ng:y-%k{LkkLLgaA E[Bx H ,GX-o_KzP[XƽgAYsCaAO"sZ*,|8#EcrbX`o`IeQ&h{%ewBX:ܡ_b`$( @<ӵ(TX@tɖгOjw% VUg/=Up: 'r,[zd(J==@^BO}~Z/سOwlQ3w'e;֗YgLGZ*, #]fc:#[&*UM?jW \xAo/C1]_B4KXz»lyS?롶.+QpM[Ǔ.FBgHيd   }˻#Rp;{=3 y4XP, ,MװH,$Hm',V}/gR!sʿx;2L aq(fZPai_Ll=[ ƹݪR^uJőE=ZIg ( f(_bd9 P>-| f2wXo, ;Ⱦ*,|ׄsXzy(f}Pa;PG`1-g (n",1߯ówYk-&‚ d(,e& uTid .#00++s+1;H'M_]&o߈= oBYM6<VA΃ (\PaXG`W>O1"rvy+_w+^[W|J-lP,G'#0NzKPX[DOË-=jP>\S/Py_BdBI-| mu<fZ aE/#/4׳OCg—Pa4dʧ ̽-*xvJ} gVګ Wd x(b f߰EB!Qlyda#H~|RI'?5X@d*P]r*,(Hx\O``W!ٹݚR=[}Ϩ/q\?yJXrg ("ζ/GO>lnpoIRA%q8c X _DP~jBY =A<r*,|3CdzD~z%V sCsý9Jn&fK)@a| ( Pل°tOx,Rw/?}ݒWp1#շ+Vp .[00ӓm _BfzL PDɖn+;Yj5c*<^9_Chn',|n+ ܷ`'C*ȣQ`ɖ,GBNe[DxQKw ( r硘YB_" -$ɖnS= }b޷~Dyj̽]+2#SaA,=A<9L1(TX>[[~\f [$nG۷G;_hqҎ |%xyoz( tj׆bLd9 XG1 $ӳʖ47U8pDZT-z뵡ȳ+(Xl۟X9K)Vw=ʖIoZܚ;E5X)!^a`^Y(TX` mBH,V=ʖVASN o+~yjdGV-DJ1|[ QJկO gKǡ(+(TXB<Fal[ϖ`yġ lS_`-웪TdKS=7M%z (Un=[@4+Ew2"bz1[]eȈ|H}l*>cGր.%XʧH e- waKKO} ;")\ 4)k@d*v րi(ty5 P>yġ¾ k@א'x!稚ًD:MlO'=RjP>%pk{i(Ҭr*,|/,b`mP>5d7o8qjn,*['Xzy(f[×Pam׳O} yoR4>2+qN i/jP>% u=[@<~r*,|HC}+v lS_`5VAtH* |1z}bAt>]-.6Ce- P~ {/*K.ZP>}Kn<^9A\NdU Me{"Qas[U.ZP>E G+kQ# U%X%X '2x[%_Qkh;8P>% =A<Q# U%гO} y5ܶ{Mw(L|zE (?!Xzy($ (<Pي]=[@א$~2D(;LQcU,Ov 骰oa`(be9 '*^q%{D-eTUOj? Hk4oL-u|n+2|CQ&O/G'Ӈ4rJXr(%?H*2SNIsGa߁ P>E(TX@1K= @-elRP#VE:P>X>Z,SyWPa{zXXt'X'2x(r*jʧTXRӕM=AEԉ]j*,&r'nHgK|CNLObv\i ,Ply(r,8 Kl ;YU U*7z )__`v~% K|c,һ||CNeoR!7SWO2YJ/X` U;͖ҳQ>E[VPa %6H e ~e| (~7Wֲ{~ )lI8n~[BQ#_8[\N 9 \9(۪T|,>j8_U_-i=(|Uw[ϖF2~V4^BoEyg (ʤ(r_gOܷZM-O| ;x>ʷDE@N&!X$[zwB;>3==Z5ʇSĝ;q P>)װPubT (u43-"[Jgk\lw[=(g_tX@b\o|VnNEʧ{c_^γIW|HO-zEP(TX@W:XbAi;2-<fxA;5=ƾ,|jWd[,"(̚/GO]X{QRV|qUH25L^ݒ!My4X(`A'P> E12j, rl Q`)="RsKlox~{ / (UǾ}" OCQ+ȫQQ$]4 KoHL3$.6&P[eή6sJaʧ,ÆQs{5I- }3i?ظ=>_^GK- O-P4+-/עPa#` [,(5|x+xۖ{Kbl%׍'fL"#ʧrY- _D|YBO}UEJp KeTRG|鏇]fP>X KPZ,QF2V  찴hJ렝)/bG)6OZ AYۨ4ʷbQ. O$7ʗ.FK8’`  `lmHJKፁ K,l 8aV\BQF2V ],r|k `/컪T4r?r#<,-X\Dr|sPaI% qp"'Bْab{0!N|*HOy zSIXJկaRq(|y- FEFal"7ʷ%O/En.<۱ iK4.-X¾}"Q Ŵj,oeB|bịExet%RadA 'g' (\,X(=kvOmXe5 P u [XbQ@f]*V bJKbŗ're{H;Q'aYBO"-l1[]*}U*Vx!X_7WO^WŢ\}o(|'4,kQ򩯠 Xb= `ąbwj~tX@bQ*ȾX}b (TX@^&X YOb&)7"ED׏lqp߳b1K= *O[VP`qp߳A&!X$[bge *Ó(Txlw]{Z,Uaߣ}ٲ (#` =(؎I=cv P~(U(=g (?,(TX@Q&!X$[|P~lqոjWW껭 SPaG?硘_BeBE\,ʏ-tkj*,a-g (?SAŷ!bhMq:V/{6*ҳCf[,VPa嗍)UFɖԳ_)|7\&w@q I-p߳WԳCe- P~ {/|$[R÷ rU*a#D9k{6K@{!Xpߓȳ-Qh}ϖ2KXJ(ŔiXD[^̶N؁;2}m Ay(xVPai9nܾ-94R|_>bUa %Utpߓ( (TX`,Q`m&RAN/j+/-峆XQ3r-gK0Ӟ/Q4P&"=;ɐ[]BϾd yll74XPzKOF1j*,sR{D%`ݷvQWI㺥Nz C[9,HyP3[|YB{sW qk2;,Efp߲ (s". {O;,| U)\"t}==G*SD^ EAX%؞-|o i UhF|7cC\~m=)LY9RUkxPLF={5YX80@Wډϊ:/u{Η!Xpߓ (TX@W`JLZ,Bo ;kɐ& D|s[#azt=|կ.f{2Ӆ(TX@WX'1i{Z,*5j|u=ϡʧ sU{2(TX@W`ZÃXb=G-6-'vQ[<{^(Z,a-pߓ_BO}fȊ'HE-psbag;CU* Sg3WÕ X~-pߓ5!%E!{\[FeX.l"zՃ ϥx!*,|rn0WDCaWPaS*ȢqH=[@ԝf=_bU*ps{΅WA{*DCZ,psEXdKo7zRx&59)*,|j0WX}NwF?4G\qKRzD-% vv3eK|O-[,AVA&ui[֢Pai﩯" =7{ynl'CN,UX`C@ ,kQ$xBIJ`c}SwkQ,O,5X{rn'=j*,=5 RD-pԝfoiyf3zyjWX}Ob j,pW`PYZ,Bo 2U@$(É*,=X0,Z~o E_E([&+XXb=O-.N"JrIH-w)}S؏{2ӷFʧr:Ei{Z,:,/)Ց =2)IN Ê}S b=4-kQL#HE p%MS(ε^;UN]JOa1=[@<Ӆ(TX@N&!X$[zwlAa%V,[KdtkΗ'=O,PLW`!h%[z[\^=`yObRaS|{2eT (ߋ;-b{wOXƷiʋ|n?Ğ}ϓ"o*"'C1F" Iw'}χcƱ*6m( 'z <)װ-| 7ݱ (#`q-;{>`~T* ,`b6Ho4'=*,|RY(=\P> Fʏ"[dKN{Ynk4\ÇJ,p۫~Pj,p16/һ#eNT<^Cw{M4$ w|چ`A}MWPassPa?zɖb=jChEJt Q{ϫ+iVT}/s,-e(ZoX֢PaI% "7Rܳ%xeTR&(IR 3oo{e9l)8)VPaiLCH-5Y+T k4m:ğή{ȝp# Ee- #,r#Eč{Kj'Cą}g|tu#^0r-}sҖ}Z*,=8,- 7Rxk0뙝lȍ ٚ2G4W liC᧯]BoeB%ɍiʧ2jMJ/\ZG^ gl۰Z*,|',-g (w6Xy ,\Pɶ^hYDU'= l1=[@4_֢Pa ,r#E2=[@>n< L4I[g +U;= og)5 2}pC$7R$HZTljfzӻDhSvRa{_lAC.F2"7R$%xێN;Dz ^ 4[lP>Ŵj*, ,-g (daBtQWkJ?ᯛ<%~r=[@<~T (:˩h.!-|ì{JvǍ<y6s[`]2Ig (b (?ʄ:-b|P>a%!,ĥ$Yye/qz-p d$= j,p Q&X.!.}/ f=_rU*zoz8RIOv  {2ׁFʧQX$[{l2W"z_"&P>iBP>tkj*,$,гOZ>`[rU*hu1iIWzy([WPagPG(_{Il)f寘:1ή{kXbP>Eϖ(TX@$`~-?Ş-|ìEJzLc`^ -_S'CQkQh}/*IԵ|ì~J)zL5ꔘTX@ r'C1 (Ȅ:hkp G VsU*$-{=OIg ("L_ KɄ:dKIˏfRoUYm ۓxckI}"LF’KEԵ|E-dȋo}ji_`҇//|e D XJJaRa(´kj*, ud%&Z~Z>"iN[R>f=SsO/alH^$-?\V=PA^B{Ȅ:-姮}/QAl+U8"Gs]ASaq l ty5 FQX8[rIˏ/*^׉ẉ {w HZ~ }ObT (0TA΢}/[y^J qzj$?E HZ~ }Ob (Ʉ:-Yܵ|ElkxJ|LI6'ٶڟOGrN(<"i5 أHt-{4[,' (pUA]ˇEA^BOv gsIO"*ā7ޜS>"i᪂= 21E2"ҵ|ElkxJ1ӷK>I˿kp㡈ӭQsEܵ|EӬEi7_2i}/*ȹkp㡈n>[֢`^$;UhkpߋQ-T% Kf'-?^V= 7-kQL#HZ~5[U*ceʣmol_[IX-]ˇ ta5 Fi۠+^8$e3n poIp\'Cn/Iclcot9t?p(?S>tva pߓ^Q$S?`V`=|2zn>hBGBtyUHTERK$(8 m`5 X2tŋ)rK÷8YUB^آFtz"1"^L|5XྗzPY?(4Xྗ?ꃌ<]}fU"]ߛؠ߭Љ_zJ&‚^<(ߊ:1-kQ]{/(ll!Zz[hMV yX!E*Ejvט.{Z,aAE E3s71fZ ,{ RŢ"}/QE&wvɭVmkE{k (Z,X>㖂=4 ( PaHEAE^*0*Wku5  jUX@b lP>(TX@W\ËX۳O-e|J60rɃ (Z,`ʧHӮQ UX׳O-.E%^w,}WaSE-|4 ( P~z"VoUe>?y(>4Oᾗ"] Z,x(Ҵ=j,pKQ&!X$[bྗX'C|wtK^teO]b'CZ*,(j$&--{Z,Nۊ!'r-wk~ʧt߳C  Z*,|+HCEZ,Jʧ<{)l/+|Mt}/}/QE/g (?:1-Q i(g (Z,v^ ?zK{dXM Kש"]UK硘6s_BeBi(g (Z,r 6$ݫRl_Pq+yz] X++=8+FT⋴XzD-UG]Uw6;}< XI {)_f Dd(R-ԉ (EPaİG`2zѽ)wj9 a4H|EʧS/Ҩ2#[@b),{2ӮQ ہ}d =|2Z|OxJ"žyqo&ESe؍c-p>SCfȫQQ$ۡlaq[B f-v2$RL-oV3쨢\կOa}"pߓܲ 25e ,GX([.Q+gx_5>g rU>=i+(TX@(RUIl)=| K^ ?R![o^l}VMj(U}/G;G}ObZoYBG1-0,,nRfM<բT3X@1UzߎSCg(TX@17ܷx.Up J?LAO};" G!쓃~X@ߗ2Y|Tuqx|yǽhL`'#Pg44`SDXFQ!^A_柝nd|@ T}VflUT8ܜ2Tgh O܂{;Jl [NU@r 8{<+ŠVm)uǧ֋O^ٚ }rzR ´j * 6}^B>~TUc  k\S`'3d-F\=)h ="s͵yu RH =C L %1]~(yn@Fgf;e`>6E2p~$y2 ?+d5  @J=ɏm r_;*ߦ>n5Qss HrX ej * u(#vF*'q@u*){e9c?$I* un˸8$O!ͪU1ԝU#(0+2ԟULpcHI$Y:QAR熌 ~x2ӷۮƠRwc2>5^q*Yel͸J0* ubdH?zc<i)d5~bxSi@@XiEÜ4OOYk1h ʐ~VvxbZwgUݍ\b)2r?S ;B G3<e;zj * `ϳ5^ hqY-cT}pϿMq8RG Hrqt}5:s;33`jղUK8ǐñ~7L! hU@@dQ.'9H=0y|q5:9s TgH= "Z“̾1mVK'-gH= õT@@QF eHR!w<`Io]n]!ruR$eZ "w{޶J2X|a(IZw A~;"+xX8S)&1yo] BĞ0&0REJ" Jn& aj*&,&`zݳ;`2Z}VQajOV˔v3mo_no =Lzylsj*&,&' >Si׌>6sT:o͌J(ŐM{auWX꿲#=O<ծb/vyb{;`2>w[ڛдq%{iSejDTR#>wj O`s'kAhn_~q#p&'qrzUuAR]ihda^= s< 5ʙgEǝôj*&̣8i=ܾdօUO+=7U bIlt'4Z*&aL8O\ϓL(OPtxUAy#+E}%v(TQ󴣱Iq.b&r9{qLF9q7Uߑ%`Bh=DGUF;ŤIq0x5Ld<)GϿ@e7~hy{~>.CqblGb&y"vۂW0_;Bё_Γ{< HٝΓ XXD_ĆW\o#s DL8i TL609'xI>`2Z~u{+yz#Ca'~ 8ޙ*pa{i:& TLNс<' 8Qvqp򪒃 ˆkbE>Q.\ 8Lzi̴ij*&x'&' 8Qv/Y.Y q4, 4LT O`lk5p$Γ&"<17 ΦZ޿Fq6>Vl&4Z&eс=ɬͫIreztY;w_ S*FjkW!O8 WP1GGn< 84l;[~Cľqv顼qs' 8>Lzyʸ 8$ALJ͞'xR]<: OzWa_bv@B#Pd5?-уIgym=8aV 8><: I=8x£WϽU!Z8{?룶yOzz8yLւP1Ǔ= Ozj| x-,mBY)Zt=&Oz ۮp47ǻLUzHM,~+I?0 $6Lμ:z4qu TL0IØpt=>`Byb'- 8[_`򢑜zq!=\ut=>${;/IxC:3P<ǓpZ8{'[2rߣ'oxw}:*&*bsq<`ʰ#j*&Db O|`Lr$ҵ&UzxwD?&qaz48«Ah n{{ GclfUzCxeA WWPOy@2y lØpdiPc mQvÍS/a|wȼ |<0=O<yGb5p|Ĉ#IyƄ*=.Tf7EE;iCY+<8r*&M#y9OJp<5&VVj*zj@^Oh.}A_[8>I'>3.b2`7/O ~DxL xI\R38>*ybqd9p|yt\t0fp<5&x3W[q[2,sBp]o}+JN1yqpV+Ạ#p'xjLvϣ{hg;|@h5cHZ?5fp|'̽baybz17dH̝p-as)&=O4nc9p|8L8Olp<5&x7W[A8>;׻_g>TXuW_%SsI8y>Y Bạ̈1*=쯏xr+޳R 8ɉEp<ϓ TLmƄ4Ԙ[]x7u4t%Ix*yy8^ac9L1r5y ɤ۪|pΕLJN1yq0Y BŤq54‹  q<0w܏؛,z5P|=o'qefݶP1)s~op" LXnX=oUչ+m*ybr=ma{9`R8Kn H[xk4 }n->QT1io騾 ;8,b7IRDny}ULtT]ؠkA㩩ԅ]<=Oe2=wUIr=_gyc-6p<wua{yf{P1SS&Qdy'-O^D*ԣ[틢#Kgi|g2]iQ}wQv 8a TLNL8ORpw6iLDzؓc$;H{ir*& ȍr' 8l`2Jpt=T<: Iy%1WL7G,[4HOG/1)=O<Wa.b1L Iy'-;L d9$9b@3BṀ~}]x>wZ=z |d<a;KM~.\:x&eTA\cJx/ 0Q}u"z |df/\Bds1&'az"]ͷXLzQMtT'x0/ 8><:\hz"KR=c{PP~|cu|,gdMp7b'Y:/<8p/b2`yb{ {-MjZ'u;(DB/1Q}Q)Hq a;[dr&'yzR,}xB[]RT*HROG1ANơՅxd-p<5 byLb>G7/?Hq+O4wtT_ԅyqXAb8m2\Dyz`By2_lm^^B[w?=|uaz4qXd-Ld\th8蝝Ggϝ#=8Yo TL;ҡ0a='2b*=|5x쫻Y>dmΑϒI w=>w<ac9 9ҡH]س;g&}J3ֶΨt UL;Y^;۟t=>w<k`Ixgexx9#ƒ=J;%>|툪]"nO{T1Ǔ/z}sfVP1[GG0wx`2ߵoHx :&xE]w=>w2A~S~c 8t0RΑ~b􀣱6}R&sLJds'0ý |yt}sHaz&XGqMs_c<ϝìr*&x_1\ Nay9pw.4ףM{3kF&}p=wI3N!c 8>QLX]ϝ#=ֻlmo.?XHnA轱Ftϝ#=>\Յ;Y 4LsHCuaCs#*=)mMXl9F,ZtiIux8ϸ 8>\ԅCs.lR4Z*&xҡH]8;Gz|d_x{'"R_:;hI¡qẠ#pt=>we0 ݖ2)T\m5LsH5x8` |\ytCsH kWpNT'C7 )|)/&x1A!NׅWP1Ǔ= Is7ggGUAޯ-DCpnJ_O ?zsI3!ϸIxO:t CsIOnr@ZRO;O/¡qXd-Ld'??qUzؓ>k]p+w}0IxOz%&]ϝt]x5QLX]ϝ'=>oo-'1ni~Γ/¡qhuQ 4LsI#uz|z<|^ԅCs'0]_ BŤq2`z|z<|t=>w2.<|q5p >wxQ]ϝt]x5pytΓ{7s޵48KyElE;Oz||]ϝôj&^LX]ϝ'=> *=Xi3wX.; !Γj]ϝCմVP1Ǔ= IsI&گCտ Ul{֐/ۉT_wΓ]C^ BO:t ;Oz|nkWȭ2 -EmckxyU]q&y 8><: Is#_~<"=R3=RdnKmUk;Oz%&]C^ B(&LJΓ4&ֆsJ w }ZIϝ'=>^Յg8$;Z &>wt8Tf=>Bi;`2^мZs{W1Ǔ.# ;`2'kẠטD# ;Oz|v@}IIZMOzrKJG+ GX;Γ.w2q 8tAL8OgsՏ?]zOo/ƫʬsHOuzyf\BŤq| :ԅ#< $M޵GvTV1I$Wy'e|ḅ#p'ՅG__pд0t>Z _b{{V6j*&񣘰}ϓL(OfkJ Z] @z| G>w2u 4LsHN#uz|sH&_:BmOw|+E?4dzv?s'0T[ BŤq|2`z|sH/4NjDt7Ƌ=ySkPsHOz4qӵ TLVL8Obp< 8tQ 8!O b'z cy'=.<*=7nhu"H׿bΥy'=>]x{O㐧WP1;GϟDcy'=]ϣ5gH|׷sD @z| Cqu 4Lṣyz|sH/.qNp<ט Os'0}j*&xҡ;&'w7E# @z|A rL߮պҲ)_|[\23oW >w|/spw|푺;j*&$&']] = _nhP/ *&xE]8u=>w2=ܫAIÄxぉܟ*=t,C]bIIux8L b2^O el5*=H,ݔX(Ms>w|QL]ϝCݟaPw뵤G+4f /x`iyHq?XH-?ߌrES;Ijd]璕Ō\yt"OXO.pdo%4顾\ѳ÷cY_Nfϓs<|ט OsPz]xzOnCLCObyz<|qlaRT*tkKnlyyVsI3&sP^CL:GҡL]8T]<(Obm%4!Vq3R|Cr]|"_8;\ bI&Okc94veޛ#9Nu~~?dO>Ĥs|4v)Cl1q0 bIHMy;y˘cb|d94nNmi:"JK?5~]4k1Aǡ,Ej*(3a&y754>Վ|ﲎǺ1.ZSgL>w2Yz^CL:Gj*(3u8OBx:&d|Ф(<߿M0[]i͓2A 1SS$&'Qo)OV=Z_cɯ>h_Χz>MNac7!&xj*(vBM$j?a2;wžuõɅžSkh7ywI$)ϝCX}? b 8<:'$iI\&=ӡy|5;Na{7!&xj*Ą$0-յK>byqX1dhIYDz-w͜q9 0.F;Nơ1OMsΓy%CQwkz HLscjGL'q:bk7&QL(Oqhx&}$kO|hiw7!&$5&Ix:&1sHg&t+$SD׶{A 1SS$&'F(OV=b*YYI25ʻ0|bL 1ў8Pm{ 㩩ԅiOh?a2w.6!=OQ|_Է(t"HC :q6yI֞8(& {A 1gGg0<'Ly`E)-!c?G>w؎ɇ<ў8,{{1>w<:oz$sKjGL'q뮽 KƄ0)'Lkn\T>[)ގ}%wkaܥ6C 2kO|d6j{A 1G'0q'Ns|:(OV{cߺ3ãB@/ΛG$`)O>w2A 1IDL8OT]"=ެ .=qzx2ge%c'0Q=>w2qoe7!&qU]"=ޠ9sv2u+'N1)K&5#&=O |d*&A 0)K80<_sH&֍N_'&#qXS[ 1m'L8,ϸ<: z|]"=ެօS"ZhXr@m8^w%:&OIx'{A 1< I<ǓLfǧ&=g$i@k rpM^'Qýps&y'=otVOs 8ޥ&}D㰁^CLNL8O 8x`2OŒ6r_ktym}ӓ7.y; ;\ b |yt3Dz]|NMzKe)z5Sa5O4fGb7!& &y'=l_}WҺfhmƣ<쓚J%Gv 8>&}DO㰃^CLAL8O 8x푚pb>.$O' |d}$vaD: _%H/:˰ޭX)cH[2=}!&d!O ; ̣ט Dz] &=ԛleUO!&f0<8,wbOyy'=OIz8ƻ? |RM<8_nCLCpa=pODz0\6zBTm?.o.hyjonCLYL8O 8x1顝&鹙?tG. ; F.G'0a=@/K[HLVrǾe}:WCӲVi6x%E@/qX b 8tIL8O%j>C +oJdK@S&!&3.\ 8ay7!&!&y9>oZ84!f^=q1~]&=\x>y9^ơ1$ ъ$OƓOpuܤ(<Qrvۉ -j;L:gc&0ŞbG' LxCxtLHv>ܹoxm8O<8Lӧ&&6y܅;{^#LsԅIx j>7A"8h>}O);TEHek&0ў8 tT`PUIODŽl`R& s٫!%VK.\`y9=AA 1SS.$hIvI4 =3e{?Ȏɇ 1;$OhO|xl k/!&xg;]]$jI&sH|şϔ1X^S]l'מ8,wbw2`y5Oe;x>Ozt~#5T)n0]c!O>w2˵ F.SS&$ycBZ60;p]L+6}~beG!&x |d=wb;UN'hXR0ǣI1\8,ׅwb]1)'xjLpV?K ǫϧOOwS6>w9&y~¤ Os'㰁^#Lsc f0<)Y&'yVʾ< 5/5`⻾zt`<ϝC^瓽 㓙%Jӈ:*Ԛ[ciËy 8=sY߆NNwΚ hb\|.^k(A`dSw[5])}F}*]y;*&w7q}>ELCQV;v2b$[f | *M$^'9yzmA p} {Mk- { \ ލb >˄:dlS7˓'ΓΫH=رwK;F.>aA™U}k7,@í*>>|W1l_Ea|/MN761< Bͼ~b͎><} t#,);u hnCX@ti鮡x%iD>h~4-~ ;+7nEVw{.5IfKB~_l/ClνX4,Ni$K.HA Կ{(R Vl)<(t/(`l- ,ՓK%x>~]?>>'18.*5d ,d(ۻw bBȇ=5 _ů6ݗK>Nϯ:)<(-Jg(/!,^̑ҬBsznԉ+NvI#,)#<eC(ɐk(N`l[ʖk,t_ |bR}LƷ/tL+ f ("؍b (< z - 7+ʴ< kp㹟4mOK5N=0X>q7!,|%p3%dˣӦپp`/n27S#׵я+l# ry7,p+tEEW~W+}mcn-^NkX4[@<e['YX$[!x%l ph|5㉹Mue8޸8.@j-| \Aލb (, Lw EEM`Wny|z6..+YOC]Zv2N"٢>+V TL}ܙ5V(3 ^CX@U tJl\ʲbqzuׯ1[&yUA6f (LvO2Nb'h!6ߺRiHtBM_}>2#X@O_ 4[@<˅(LSHP>5-Tn":ʠ2z+|*/k -| nCX@dZ0 l1-|k[S*/{ Wdc-˓E1~y%˄:d5Q[&w|ݚR1~nx=' .d<ʧ le r;nCX@E&Xd`l˓X|i+ʧ=lf ("S^CX@ԑѥI3V{ U*a֏r'-sX=ejKN88a7lS>4A<iUۍbP0Tٰ BOЈr?2-_p z$>dw~J,)raєCVkbQ a)%sS$kBْ~~>Zr /EzwF ={^< G4>yfGQiXdQB 6ޚRQovst^:߿g{6Q[q%53,ȖׇbMz7!,dbB4^%`)'Xf[oMף9y 9%tXh j 7A%P,w:,u̖ 4[Bdx4l:֔ y g]i|>ʧ]ofK\e~nCX@ԑ0 dKl WC̵=׫Iݰ (6 -|+VzQ aSG*(5[@$`_Mhހ[ K]d1Łi/ lq|N(F8P u ɖthD.|5){ y[\-y5O (_Ò-OC wʧ0WAN-)hD[\}51~+_Ղ]Yb9 uYׂfZoO;ea?iy(:,{Q aSG,,-YO2x\ujJx!/V<3! (6Շ rlPunًb (?Ȅ:Klɚ-|j)t,$dX27A~%Y [7@ gP>_] F1dBEhIa))(I6z+|AAd | dP, F1Ń#a"RFa!,"J9mc,Rᷯ<+#X(,UjCBP,wF1%L3b$[re})=[X@t5,ڐ@<vQ aPg`-6hDSAjJE --[C 뭀0pUAڐ@4Xϖ(#a(dd K7Ne)ߐBZ~PD:N u[D˷N|2kՕ o/>TYTlW̯TpPKjlQ-?t硈gxF1PgE|Z~(.NbT7|,S!-򣱧(FNIXD˷N {˽ A>й?,}޼GXRJ?Âly(b &e/!,db ,$vJTD)<j8zS!, ilUˏ­v)XPg`-ߪ;ӪŽ)_R?Da^-Buq^哖?fK| >E1o<,-GP>iWd˳V[dd<^EP>ioUˏ| nCX@$`ǩ -ߪA姸ܛR~C6J7](~c3_!, OZ~ [(b(F$P u (|2ܛRs}rEx׃@ǫ}Z~P,"P uj OZ~Z=F~:4{}۴.ia (|J?4'P>E OF1O,,-'P>i"&(m]95il]tJ,Iˏd(bP~ uj OZ~ʋ{S*t~8W!,|eR,'MF1dBEE'-?[O9P_7 '-3(by7,O$,[3( h|N\‘[LDg/eۇ '-?^VUϠ|tNE1Ov TϠ|˽)1?x+^'3(xՃTϠ|P~ u'ZS-?Iϫ"w=3ԟ`oq+)b ( X4[@4iP~ u 3(+ȳMş _;қl哖B-N ʧHge(IE|Z~哖L/_&V lh=llP>i骂T/|VF1LSH_@gˣ;q} '&&Et;V@_âZ~P,F1_dBE|Z~哖bqR*/otu.}%~碌wP>i骂T/| |z^CX@$`"٢Z~哖bѝX)vg?̟4CGg7\1S%-?]UjC\܍bK|Kv ;jS%-ObTâ)_be7!,Ȅ:djʖU{GS*ܣmRn|ʷ5G|KZ5,ay(jr7,o{a.DwkDtK1=n4@w2xsF=؄ϰ)_c(88lQ`)`ɴ2mb&_'M@y8֩Z۴0S7 CC9=EZ_E1S4UAv0,AS%< l)5e@]UpZk i1 ,|`l/C\ߍb (:fal -|sYΖVMeO>{@C]=LJ?uʧQ aPg`ɒ-YO2x =hlgtf ("lًb (?Ȅ:eɖ'ɎG?c@а}ґ= -{Q`z?f (bP>u$P>eJũ$!oq+Wg2{щ_o`gӄҏP>rnCX@ԑ HP> $?'(Uܾ"/E',p߳t} {4$P,{F1{6˄:d)`lY~v'̏Ký{ˇ=>E1_4,VzB28`uv}v'~]KlBl-|޲P>u$ -VO2xYgW*p!,a"؀e/!,! ,NitwlT'KϦT۷o|Ν#X ` O514[:P rAލbK,2N{'4[ `ɀeE :?Ogm,p߫߄ҏق="dve/,psԑ*K=g2,TPou3psdZ>x(YU'wLSH$˳)-ԥt سH=g ILۃԺ۝GmV&T%nl1OZ~:Ы=܃P> eE}.)q5ٔ۳-QZ{ի{o-5o1ps嗫 W-{2˅(F}9P`lQ-{^K8i^n&魡?s?-ps_âZ>d(ϝ܍b ([Ƚ]^|F*51({V*z瓚FI=CS> Eh]Tj܍b (: *ȟuŰd,)^䓣a%^?{(| ~7Oa凃+X4A<[lٍb (?ƎI^`ɚ-@ٲ;C^tR-cίȶq}υ06$}Ob5|7!,|HE%keKZ^ 7P'maH=kpshBǕ6$}Ob\d7,ps@"n)-jDY`T v~d !2nH#J?Rpߓq?e7!,:]fK Ò4"i{ⶣWS*#Yڎȩ}{,ea 'CWȻQ acBCx$)@[aHX^'rUAf (Ob{Q aQL/hS<2{d۫)cs&?6O媂P~ .ٶP~>z dlgڵ+ȳ2ث gXdj,9{ Y\b-pߣPXE(F}ePg`1-&iDfY5y5L~4"WYRleEϗ(tLq-NS?xڙƓViDemӦӡV5V|yS`l <h =m7!,= ^-K= `ݗjJŷKٿq{v#,ASS El5'({KWULl?U&oO1}4KD|Kn (Ƚ3};{MڣS>M >0pߓXm ߎb <7G"GNw$Ԁ,Tpy|WY>KPF;;_]J?Âl EZ0زhDtJ]?1ջ6ɭ#Kw"p-pߓmkO$P~kiڝ=Ep4R۰1ʦwAPM <(g^CX@(_X}X&+5П'wc+8a凣 aєPΗ(ʽWHEV#ʧ^؟l߫,Jf}_%#P> Nz?E1"8}bOiGS*[p}5fy ,Z@+p YʏORu9XȼnTYj'g]|r[_!,~1[<(¬P~,d%-tܗ!# ك~:&|ְTikxhi(깓Q a'y x8EO wOVk@T|Ϸ/.¾O %O}Obu#v#XW}BE9XyN?'VK9l6O>$= ,pߓXߎb (?iXd spԝX&ItqJp5_5GsngX4[@<Q ab%d ,*vV4: )#Kt!,bg`|޲P~q/|ESC׳e/!,q-r"E_LS* TO&ŗz|xM}/] \,,d(zkpXb&["}/ڴ:iR)>U_zF?nbq  =U3(8z KXFX([bM4"ruiW=q([*Gy(:,{Q a=O,E-XIuw~H;D5~lK,ןal/CQVw’K(&NFq^%ʖ3M0%8܏ `MJ?4[=s)?Xyr4[:j7q}wxrfN ![l= ڱjE.{,yv_~ (~pD胹y}Qw)}"{<vՊg;!,|j1SQ\,"\,,u'ŎPvt\W;_Cd bJ?fKlPP u ɖʧر_I_pe˯W}"ʧkXf (^CX@^&X"&P>X8:Y33DaEެ?7GYjXߎb ( falI-|O_LS*u젰sFdUs#Xಂ),d(VxdBEN0p eo'N=~$Jb-u hXCX@`*ICuXʧ{K)jp $^ێlS*c(,u7%Ofhh= [aًb !LTˇ^,NzO>=AOƜux,q d x(ry7!,Ȅ:djpߋ9[湥|R逳AM ;EŜ#@z "i֤Z>x(]AލbKH$,'IT9+ۮT &lu[fÇ JwG7ubIwWǁ&CKQ aI%AWK'@XUˤ~ y+X^ڕs7>9T9ޤՈ:,[~S*x2}WxEBLs (aHyP,wF1BPRf (j6faɴW+4&v\|ۃ JJ?â硈딿P?N|Ζ(ْ4[@) ~w@諚,|Pq4[@<nG1G1KlI-|k0s RA9" XS(nCcs KS}Ob5|7,pߋ{EI%(W{mS*|tdR?綂><,d(=_v'ӇIXXFOW,+1ה Y??녞67^ }/".+ێ'Ca P~w3o;JڝHg{7'.8Y<&_3,|ERݥޢpߓX.F1ߚ#fXEONX|tM?٬d էnK+")p*F1Eɖْ;{l58EvPyt y3;XIwW䬞p؁e/,pߋ |X%hDrOZրD0)%x(|/5P~ ubˇdv'}/@X<FT}pQu "nOD˞!,|RUkxVPeϗ(9̬aXFOW,O/bhFKq!,|jW-p [_E1O}~" =Jpܒ"PF ۸HJL>d(6`ًb (Era? H e[27o~=v?.}P8<}/ҹ,~*d8P!TQ `qpߋ(,A``lY<ԜP$qzྗ\ UAqpߓ谘RnCX:'jS$[pƆ^)_ 9,8{mjOa %4[:P,wKEiN:$TH(>c9GMsy4W- )?ѹfK@kQ a锟QOl-u'UO/'掙ªߊ|xmp}/ѹfK|:XTZyW }הם)n_7[Z2 R{2݊gD(F}/Q[qƆ^jR!iC«kJՄI K{ΕWf8P,F1O"~caI`lYu w݉PɨU3)E->S?D-f (b(IS,-9j",}S*OF@;z4ddHڏe0D-װDP>ŲnCX@W:Xʧx,NTvHj:p2TAHu?v +{Z,Ua?GP> EX|ٍb ( falI-|jy'_FV-M&1%߅ҏ}LObQ`^rJLZ,rQ>]%.[r,Znp][ as,Hyqv"_;fX8%Nvߟh tw734I4O-_3Z,x(²nCX@1HEΚ-|:aЗZcOe$[ Df-#IR{=>ʧ,2nCX@ KX$[f (s+VKZ6u@ 9v (?_Ċf (Ku]f[vʏOȉhD+ȳ[|?iepOzޖ*ᾗHW'R8PҺ%n;}/щq\ΐ[G8l0({^`.~D =@ދb (?Ʉ:K) H{y!7ݸ 쫹xBMT{pRP>EXv戩 r)lӉq5yY_fZ֣ムྗર_f ("܍b (aEN(FO'RĴ(q@>l^&ӃpUA.=hVe7,ptD)^98eSΰLNb)JlSzv]Qږc QL ᪂\{<ezNٺsྗ!VCS*n*XJiL4[:Pe+(LSHDP>5$@}gi5&uR&6vF k֯?rKlPlًb (Β%JDP>5^tZ~hJY#ߣ]^w de: ^Xv ߍb (Ʉ:dKl;])LD4{0l rkn#Xྗx:$[p"_%KhJ7%as,HyPt+}Q a1 q/'RHྗ! l^hJE}3>Lz;*%v?' $L'R>Nppߓ딿P>*r"Eɚ-|k,G3Pg!EGVW5rzP>H1f (b}7!,|2}sd9dP>5-7ӏ9k샿EOP>H/ EC\ߍb (L HQf (R TT$r~p_w}/Ӊ=^#Xྗc[)_Yo(_N(%kDtrLObTH(wє{{ ( $c5d(K8)/!,|:W#T-]uX:"XS*mװ&(yƔm3,57GtP$[;{ )]9n8|q ( .*5P> ,{Q a_5,-NS~! zKlJŹwkc<ǔBmװd(Jl7!, JIhw*e!)6޾5s<}Π];XrJ?â)_y(jnCX `Q̰h*yc?6.`~?vo&1jE[,WZby7,p+W7XB-y=ΐva,״C=,HyP,{F1Q̼spI9a2?5;s\,b+PvH?lq[zPE wOa)|7! {(H3%}t4"ĦN//x2FZEV?{* v{2&/! S#:>&yNw@^-ǦJSa}gC8|F;KC*k~ܭ,;)e[uS;a5|P@ߖV{CV<B Ҳ'0aP3H2lFOWyqɋum[`5,F9x_p+djpzxx ,;0Nih*+h4j$ɫM߱im ]$ӓ[ uWA.W=e/Щ$M(r!t8(*<O-}׻7lA3:fChv!tOө#4{R^H^< V;(3%d2"/B> B=q! uliԩ#ʹyR QRjYé6-cs-Qr`HxWAg0z=7u{/(8x u/Jvirk5Ѷz>! u^HxKpAXd7! rULx:T{3yIY,+-Jy-(VC7zt B^_e0u@Yc vWowtwd8u-gLA/Lχ_CJlZ'@4C=BY_e0$W;ѡ)HYq6ql6m۟,cS`HXO9y01$uHK#OIY:&8vRMMO8O伷bqړ!& v:"_tʛCӤ8ek ٩WcynbҋSln#tI#&ȓqX! bIGg0<ց'uDow{Ǿ|7NNBۋb'< x ya y ٷtwTd0n_~f 8>va<8 L9xΓy'q$w+C4²3l2?olS}ǧm~ʓyqX.1d$pp|p|<8,w1_d$q$p|ybz]x+7%>^7iE7O>V4Ou'{A 1ǗbO;x^C1\ Yb9ސ@S[f2$r=4ד=[ t7 f< 8sh<[1Zxvb駴PKN?IxѹNssA 1DDo)OV7-Mz?d WD] kwV#O28a~7&Owpx[ysD<:ӗ&=>ưgZY3>ڇoٱ~`\xec &İ*}ǻ'"=@7 5]/I=8>} 8u#& qX 1 te`/x0ݯXzj]M SBnm 8&y~8Zup<ކ 3U3fz~U {h "J-4i> 8ާɇ&άs;-I0/x/z{n#L 8>n{=O&z|ClF뭆[=)HxkL!6#&7,s^CL!y$}1t Sk+IQi﹎Wi{1$(h&0q@[^CLў14wq `2?wp^_u.5x-\16#&'xs]{A 1A`y=O=X˦Oc':DNO:jQ ÿ;p|2M{^CLy #Q#aW?i&=إbǟW9ՐG '&ǧ1'8>ް~pS~#aap<]a2_']4>޼p|> $ p|abφ>$m!\1Z/ʷW??#v{pp|MID xcW s f0akyϔ'V?{,S[7 55$zK洺L1_ L 8>ް b 8YLxL4O_0Gޚ PNA`v曹2qh 8&CDWp|/$I'aWoMzJPz=5j)01R y/7򤦵9t L`L `:5M{׷]5mOLxK1sr~7!&3&Nf\B0.aW[NuOq{s[~$d菘dyz]8IG `9 >\B0 î{k]RP%U79[msv+LzqXָ>^aRY4O:[Cyr>Wo]3m?d菘htqHL4&m5O 0#v7!&xj3uaLJh8yrkp:>p=B}>w6M'^쁳p<5zؙpk?p|M:8ǡuv b 8>b"O|dLL3b II~g>Ϙ2 qX b |*#b§i8sgYąE>j҃v9\`O1ANag7!&zsgYĭ5A+l2?޾Sic4O<1O x..VPoRB g5';0jwYDssA 1g߹*Ob`LL3z~S[_ЋvuZ~r OV:8>ް'{A 1"O?qkcb oY-ÅjO=;Wuas'|pn#LsgɗNsgK}jIrv;= M |'qG:|dj r7!&O|Muk8`#R[FjË߲Rpvۇo;-l6CsIxG,Cv;eo twN{$s稿@1óv?n^ʳ7$dOy=qd/!& >^by=s#<)ݚoQ |~;G=h|xܱZ bIxgd{$HQ_=I?Y:U_dJk5a;G=V=qp}A0ϝ3yZ&sWNҸ_/djjI돍0Wj|xt/nCL:;+Q#G>wz$]w ۚi;C$4+:Qi p b 8<: Αw./g^jlCWԛ8p ?u#ᵿ>w| `2'&= *G 'l{΅.y~^>w2u 㹿a. s>{P[ Yq WUo==sK1\8U> b 8fz=Hx/ϝ# ɺbEy+}9!&xn kykA 1G; Hxy' WW;?ĨsM >w.voDϝC^d/&sfj}$<|$|HY?{L\Kl\-ӫ/k;ǭ>>w2\o[{wbOs&##sG—e5xp"?_>WtCkCLpWG>w2e}ݵp<'Lby stF8Mz1")?Gҕ -71Ǔ yqu 3`gmx`ϝƄzIfyBg9Qނ&Oܛ$|Y'xLb'7S|ֆW9jLgޛ@7Wz-9t |Y\b=qg1>w<: Ճ>w`ku$n/0^^{Ј->w>wEמ8x b 8iL8OpNEϝ#-;p߻&%۟5߸<xU֞8e ṭdΓy9ޓ잠{Hyl1|bҳ>$䵏htqX1$Gg0<)' P}rܽIrۦ}66V5K~\ϝ.1ў8.<{nCL:{j*äp͓k:ܛp 7߯{Ä߽? 0 .;~ Dyj*SBy|dV7\C8ׅ#|<1/1 )q뮽 tL܅1&Q阐{I-L(SLKy1p<1|wCsònCL6Mcyb4Oe8w= ˆ2t,˵>7\: 1Ǔg yqu2;w1X'{y'-;?+@R۽>w< Ep0'xewbw2`yb5Oe b |yt,,e^}?y4fOdVpz?Ǐ폶dI{Ldp'xLb2`y5O~G* p .,Yĸ>e5n Co;Oz`kirnCLbz|'x]^ n["kn($ybr~;Oz#|xB yLa;O: ;Oz<0DzOMbiv6q?mӶڥŘxtFyE]8@q~+A 1'G'0a=>@G񷓕b jXb'1Γ 8a.p|JӘpDpsC &LJy'=>p?ۻm7S25(+0O0Ǔ.!jyVvb2`y4OUG̭|J5A;ʛrRa} |<@qX b ||yt;Oz|u^G59 ۂkx>wyEws'd/!&xҡ'1<sI>&=@6j;Ɠ^@zd͓dOMzGߖW5:ihw:R7$`)OIxeo $`" &'E$ʓ[7 EZޭsHĤh{'A 1HÄP4O:cYMzd&ӎIJ)̖&ǭ^ |.z<|d;n#LsHSua Ugt-ߦ[no8>wpQNac7!&フyz|T=>wj䅹֨$)oY}.!&xz|T=>w<q mƄDx“]n}ֶSvIz<|xnCL`z|T=>wk&=`;@ѷ~q4'Ͱ&xE]8;췲pytsH&y"ÏRHz ӛsH=Qx8n#LṣU] =>ZI"jP%'DoVsHuz<|d»A 1Ǔ= ǧ*= \ IheuKKpsHuz<|d}$vb2N`z|T=>wx`2l-⤘--0Ǔ/jQx8,p1dDxSXx0,[ CL_bz<|djk7!&hg1a=>@z<0մMzK:SܳN.6>wxQN!a@:t G ǧ^Oރ&= 8V(45!&xEpT=>w21dz<|)-z6A[zKht /#L_cyqX b 8>%h}">w|"=3Û^;&xu=qȫDA 1SSA htL=a2{ܫ[_#FwN<>wE]8jO|d b 8 L]b@$p|>,ǿ`ٕD{ͷ箝>w O5H)ϝCYA1>w 0I')h<ҲS 9݂aн6_Bw| `2u::l=. ?Zt2.Rk@ :|8|n#Ls?. Xc5`/jQ?y5g`z1z<Ej ;}1r^tM >wRe>n"_tTnbրtQOIqX b 8yJG`LƓOȫɫIw n* ~Hz Cs9~/!&x%Li)JPcl:8ފް{A 1Ƿ L t`Rrv֫[_==b5e _㪫/i2u$Z}>w2A0]Z}3.yoդ['OS6k'$p>w2>ܻA 1{m/H#;F^F5={kzɾ;H=ט s'g>{7!&x H3I=#ZI_o-U讖rd!{x%]tQO#;eo 7 H$푀]zfKn5W-Ž }Ƈ;.RD'푀ϝF~/!&x H3u=I{$sG"I7]zJ{nʙP8|"H o; $hg1H=X{?HR!QmQ)ُ~atQOHqȫ 7 H$H$E&D_y*chޟGy՟aD]tQNA ٵvCLI LG"p\a5ta?#_bkL4O>{LbO2`y5OY0^ IKoo[uHzէyqȫ=A 1g{c = R<ǓgAqkp4Nn{[Þ1SqW6 EY'x$8Uo F.fG'=  |"yE/``O7_W3YMb%!&xE> N-1b 8<: {$$E,(/6*\|߯L{|]$Y=_ 8/ o1 spdpEo/Ȧi+ ʬ[tz 1)$6Sd͓2aObRIn{Qdς;F'?h-fdv`U}aĭWw!N!.A0]"w2=A 1q$r3P]>P,zIrV5q@~ dL:'n C$8po1Ĥs|"]̿7!ss}#Nī i$sl`PҲYa>H6},es|\Eǡϸp?^] >wt >Hbneϗ\?D@ri;m|GLq(=A 1{AL IxI8a2i&=CEӺwϴ< 1sk7zxzfvCLtnQoj}4IPw)by1'nu YZX=z_37"ܥ%Ox |d;nCLwnĄgP,pӤkIaypGΓyϔ'qQ۫v9ӷ5r3>w 08l1>w)<:'$fPd_} [y!i?p|<ϝêvCLb8Ox:& 'pzkT:؇[֫zMN\L ůKw4ٲA 1̣3p .',VlߺqrYx4+q~f7|LV_4O:8Pm{=~7!&ILAyR͓R,z{pDzs{nób\_nfb9>gA C$Y.ֻvb9>^2Rس 玮qdOJuUo?ޟ!smjGL4;s ]մvbڋ]Ysm}̢J !x)t&vL޿3x$8un#LsWYLس .;]vI >w2~+A 1ǻA`yς xK4) I|8m>a=qXb 8޻>^ {y'^wnm#]_:[L>`yqXFb 8&r8p&|"+f|};RK&!5ykO|dV1b |ryt(Oz~G6遈/nCS2{(CmChO|d{wb2N`9Ot?|r'Lf¶ؗד}9]~̽O15#&'x b 8>fD= s0~+5DjVZE˔l3wEh 8>&y~D= s'PbO,YPԳ>w9gY6AY=/1ǧ8:8ǡ= vbOщ= z箂GoW=lߺa A f1&4&Y;sa,&YPԳ>w9&.㞩/>sluz,b Oس\;][Mz{?OZ'h .c0=1_ 1'|C >wuRڊkgi&&ϧQAs'3X7%].]4w|x̲nCL%%&wdp|I'Lfk[_q ~>b}j`u*0Irt&;1Ĥs|9 tۋ0P>w| t@>Jmxdկ1鹞s'V31$P>wϘ| Kx[IQP2Þ Bw!N31Ĥs|Z=P_sWW'Lf]kc((=3|GL4O:8,wbI f0<)'PZ}rMzsE2LLJ&JX6ٍbJ' nb1\CLqQ>]Zx~.(啌3k}H{y[甽(aUl\&@1_9:6xfi]N >?ty z)2Ndk7,+"`XC) %2 5KشBqNMo`S5,pXލb ؞ e@d KD(LlD#t0|OV ,I);~isQ aSׇ Sb2bFX$Kw)ǣ0=e))XSvʧ3]Cqf (:jWkbD{ ܻ c[P>ŲnCX@1 dlSӁ;ai~XbMW/{|$J0M ?2x(rn#X~WäII༇ B}e~{t9aew%&~< 2-vF1Rlq-8!P3%cQ%C2+w'_ʏfE,]Q aS9w~O(VX\&s| (E%)ʏ"GJoًb (?Fb&[|bX¡teH6A+э' (Ew BSOCa(ΜYCf (z[butrY`$A2d(kQ aSCP$[bЈ:,ԉXf+Ⱦ~â)硈Q aSg,,Q`Q>]ekGq< 7<'7`/kHׇbynCX` gfK,-(OThYRU;ߔ[4XWyxIgSMP> [>s7!,|n*#٢ OeuR" )r?D |K~X a"*ji((L3XN|2?۾Y$'s֘xzY~mI`|R'`ADP>[F1%[s,-ڝAMXfOTж{59mX@Ȼ^%y(uv戩¾q-ڝAdO{N{T¾ - O-~Д /k'bo]( <(bc7!,|+hrUH9*gN-)‹ch!yd5 ZCg^#X2(# ba;!!:䇦T݃|^ /]( 7rPlw)ߐ gW)ߐC0˓(b=U2S~ox)/wKEE+r,-vy, {H[< aI E ,rF/Q aoȸdZXN,,lE :5;#p~d?X:Ӆϰhtzba)E&)X$["|JwݤK 'yr#WϿnVSAǸ_ cboZiA{ܥ?=Rt__ݯӟowo.^fD?{^~Я?wi?Wm6`2!Gjn +l>Ws]*C?)/J-\9J;w'I?[xO>~?oW-_ԫ^Q׉~K_,u2%&HYJYɯ(us+9eiρI%XcWn0|R~QmEcTMd*V*1/p9M~S.kj2<$7a wZt5ѯ*fenKo2O7iChϮ]Rf3kts{-2E{ ~_wifg\Z>=g[wJ9cf][>.Y%ɩ{ݛ}<;xOԉM|o}Vч;2W}7;څEgQM"uhE`wN 2$GS-1Zvbeslx;u\k~B^pW];HvQ.oumJLG$Gd7qFx|I؞6W5*δ97om:S<5q#l6ߔ6B0qŞs V8E=?-o hh& Bg{3IlM} ;S\(r9Aװ|kߺwǬ13oz"WٷyG5bF1o{̜c6_37>Y]rrs\'h)^;3fafkt >ɦ=gI,1sjb .t z$25| ?ߏ`e?ҬOYr?UW Q_[&Еt&+?lX@=KFt=t.T֖C*NшX]ȆhˀM9 hpN1ٟ0Gt%'fC}T3k>Xs.݃/4qhLm|1h-Ԇ1mC] L\7v7n"AlxPw?mP!=76[%kϯ`.X{1v}qӰD sAއ| ʵ+;N N2(.(zP\ ) 5?R!ݍ;Wt}je5ça֧ׯA EҸ@.F9DVfXv;Q2]Tµa! 5FӯN~D7zFݬ^FEƾ_4.*6T ko> )e:5yƖz>huAµ6Op'_iJͲ5c?jI-֫<Nk~pS&?[5NTL4wpes]0E%\d(Na ⸥k\W%9ܟLUVu}S*A4j[097te]cfN'+a, WTպUwfX4!z-7}1ozSM$D0ozHxB`UE1OQx:r$rҏŪ&WN9ebvHb~49ap_L/oxX0?.1;,51S7[pfbu,S1Ucy,/Pt:ċM K}N Q{,s^rfB#l5 id{4 HIvo&:_$em{}m[~"wspu"?@l9Ȣi]ő*vN`QC'cӅ 8X4 # Hd-%-a6it7iFFs8qʚyM)H{Ry/f{Ao{_?ßo72J!Wjzr1s9#,8&*s .zjԐ2WȎr9%:XHc,]3W1V]7}残=0: \r]ZzޣE[GЀmp>uaR==Zt%wC1Anq[R Z5kV]t ok {2[)Ŷ }w޼;.5 _?-w=,!r_ϼ~Nn}EH:O]}M/* \Õ_>%sOW;W%fL]qfҀɆXa )#x'N2{?0eW_)a8VB:O"^_BE뀼޾׬ȥ /};|rnj*$xG *{-GL de11o k vAbc>eyߎ?k y[>tlVboʯ~zEeƸk l[Qm>(Em ~3Nmvha{G}e 2V뽺]nKBuڠ`oS4}r[5I > wJxҜxnp.+Ċ+EoH5Øu~aV ӯ?Quezfw{׿l2t! fwupd-1.0.6/plugins/unifying/data/dump.tdc000066400000000000000000025021401325145456600205450ustar00rootroot00000000000000TPDC?7IX !!   ,\% X7IX| Of l @`.   `  9!-e -`-  > @`8%` Q8  ld3@@@=O2`@v`v@k-X&`'jk #7  b8Z= k`=!uA"@7` m uu `= uuр7s E1 u "a =j Wuu7#4aB@u>ruA@-k W `;= k 3@urC`;=h uB@u!>`;=,u Wu 3@u#C`;=sK+ @c@@~?i`;= k 3@uul u`;=, u 3@u-C`;=9.u 3@u#v +i'E. A ;F`=1A5@G = d @3K @ @7?@@`6@@`@B! % C ,@7J>J J `J E-F +@B{F @' @x@A FP`CE ER@aR @[=H = ` RJ! @R@ @l `6@@ awEK )AQ" + II Q`IQQ# >@B^ QQ@x@A AQ$`Ej6@Q@=% +@@4Lr@BH/{!' G@@ " @arA(I I `IiqB) B@a Bl@@x@A A* #+@㷀@ " @$5@B, GB ! Bi- +@a B@U  @x@AB^`En7@ EAkc/ @p@4:/8@J A0 .@-@,A1JJ  `A2 "@@By@`8@B @x@A AR3`'E ER@aR4 @=R#5@?@ " @eA NB6II QA7 B@B_ b a[Q@x@A AQ,``E9@ Q,@=-`@4+@`y@"A ($: @ ={%$!;@x@ @ (N A<I٣I $4 IwA= B@`BA@x@A A.R$%A?@@ " @ɥA@B$A!`a BA"A@x@AB^B @`E ]:@A@! {=S;`=J#J! D <@@,AEJJ A*`@B@x@A AR` `EԀ 0!H :؀=`SI@B׀@p@S@"!+@#րI R`SA!`a BaA@x@A AQLDE<@N QeAM +@@4*E@`@AN A;=h{@=!$ O )@ݐ@o@~@ API@J#J#^X .@ @,AYJVJ  `Z +@@B@x@A AR[`CE4   aR\ &ƀ="A]@qŀ@k@S"!A1B^IĀI A_ B@QB@x@A AQ``E}?@QeAa +@@4Jb ;A;=O{- Ac@ʀ@ @ }AdI+IXAe "@`B@x@A EAY$%Ag G@@ Y" @$5@Bh Bg BAi B@a BA@x@ABj`CEB9@@Nؠ$on ;ck +\d`=! l@܀@,AmJ*J  dCAn "@@BA@x@A ARo`CEe@NRA@<@\BA~ K@x@AA\h `E0Fa\*BCa\@n=\( {@@@V!\ @"@B B;BBJv aB{@UJ5"@'@x@@AJ|N @"GaJ@E DDE=m=`=$v~>[`v` 8$8Xn8_~a 9! =&r`v! <@$@'%B J`J M  +@B_B@x@A B`CE/߀b +aR @=R#M@n@ #M @ /@D3!@B Ϡ B B@BJ @x@AAJ @`Esb_Q J@-aJ P`=HH(! @@@3 @ HARJJ J +@a B|B&d @x@A AR`CEPaaR 9R*T=NH@EQ@H@HT \/ B@\BC%@x@AA\`E a\ſa\ =\Z =#@ @~!\" B)BS B@aBx@J@x@AAJ`CEǀ|aJ 9@pla! #@ʃ@J #AJ6J  B@B~ dR@x@A AR .@`E!>a aR ;RD=R#dR2@^?@5" @1 @DK "".1 /C !" ҿAj 0  B@a$B  @x@A$Aj @`Ejaj ;=j@`E<,a JaJ ;@p`==%U@@!U#dAJ_J UBP@x@A AREIaR UaR =R=#U!z@@@S" @+:` K  xAN @3  B@B "9@x@AAN @`E^aNaN ;'`=N#N#@@!N @ BB B@aB@x@AAJe `EՀBaJ :JFaJ"qX+! J# )@@ "AJ J  B@a B B@x@A AR`CELa aR 9 R=#R=i <@'N@G)" @/ @! KUSB6mBo tL a<e9J8Ah (`M`@ B@BLHZ@x@A"Ah @`Erahah ;ŀ=h$@5@u'!h @ BĀ B B@aB@x@AAJ`CEaJQaJ 9J=`="@B<@!D _4AJ;J  +@RBy@x@A AR`CEDaRR= RcA@-@  B B@BG @x@A`Abp.=R{``>O k-kS`k@: =0 0` ka - -z:a!T A  `=؟* 5 .@uր@!. ;sJՠJ . +@Bz.@x@A B*`CEaR 8aR @ܔ=&.{@@6sT\T\ F B@BB)@x@AA\ @`EGL\a\ ;\N= ')@wM@ )B ) B@aBz@٣Bs@x@AAJ`CEaJ)aJ 9@p(ƀ=(3+0@Ā@!# AJàJ  +@B@x@A AR`CE~aR aR 9Rہ=RL@@@S" @f smAS @8wKc `@`  K u &&V Ac4 X [l|[ c `[P5@? cB  @x@2 =Ac6 @`EF7`ac7 = == >8 = @ @  b"AJ9 ? Bu BB&r:@? aBh@x8 9AAJ; @`ETaJ(e/r5FX< = =+ J! = = @ǀ@X %#<fX> G J`J P R? , a BX@x@A AR@``E{aR`.66aRA  =K=T.LB = @@ bL 8BC _ bb j`D@? a$B| q@x@A$AjEE<j77+F=%b\d!I2@ " = A{!H = @8=@1~4`@!9g yA.TԌhv/G?qI _ bb% iXWJ@? aB !c@x@A$A,K E ED,+L = @uC@ " @$g@BM ? BBB ! BN@? a B@q@x@ABO@/ `E89d P = =b! Q = @@ "w$asR G J{J sS@? a Bk¢@x@A ARTEna s::aRU = 8v=R#V = @q@s0;%jBW _ bb jsX@? jBy s@x@A$AjYE*j;;ajZ = -=j#$[ = @@ \ ? B`, B] ? JB !K@x@AAJ^  E倈b N@,<Qf_=$F$=&` = {M*a& `@3Ba @H@ ! @bAb _ bLb b `Lc@? abB !@x@A$AdE7+a,RSbe = jÀ=j%pj%f = @@,g G J6J 4th@? aRB@x@A ARiEEz,aR`.TTaRj  =R%k = @U}@`;k%l _ b|bjm@? jB@x@A$AjnE5-aj jUUajo = [9="p = @8@ $(%"Dq ? BBJr@? JB@x@AAJsERVket=ӤFu = WY=a% F"v = @T@: ) @BaAw _ bSb b륱 aB@x@A$Ay E>a, lmbz =$π=j { = @̀@,QJ̠J \}@? a B@x@A AR~E?aR FnnaR = =" = @@`;dB _ bhb @? jB@x@A$AjEzA@jooaj = D=%p(+c = @W@  ? BC,5 JB@x@AAJcs Epe@ =| = =ePa% % = @I`@ ! @bbAAOb_b b @? a$B@x@A$AEQa,>b = ڀ=^(f = @ـ@b=M'%IB>" G JؠJ J , aRB @x@A AR@CERaR aR = H=! = @@`;EiB _ bb j@? jBz !@x@A$AjE)MSjaj = P=j = @@ $( @"AJ ? BaO Bc@? JBC!K@x@AAJETaJe=1| = pc`{%  = @k@ $F @BۣA _ b]b bc@? aB@x@A$AED&da,R = z=" = @@h5' G JGJ J aRB@x@A AR@ `EQeaR aR = ==R(o = @U@`;B _ bb j@? a$Bc@x@A$AjEXfjaj = X\=(%p(+c = @[@ r ? B J@? B@C@x@AAJ@/ E_gaJe=F |{`|v`{% "@w@ ! @b:}bb b B@`B !@x@A$AE1wa,b = =j(f = @y@ m' @c G JJ @? aRB@x@A ARExaR aR = =" = @@ `;oD _ bdb j@? jB@x@A$AjEdyjaj = h= = @sg@$ ? BfB J@? JBc@x@AAJE zaJe=2| = `{%  = @U@ $F @BB _ bb b @? aB@x@A$AE=a,yb = =j%pj% = @,@, G JJ F@? aRB@x@A AREaR aR = T=R(o = @@ `;lB _ b#b j@? jB@x@A$AjE6paj2 jaj = s=j = @@~ `@"AJ ? Bvr J@? JB@c@x@AAJ@/ E+aJe==>| = {`{% F" = @@c"{A _ bfb ! @? abB@x@A$AEPIa,b = v `=" = @@ m'%c G JCJ @? aRB@x@A ARE^@XA FaR = Ȁ=! = @fÀ@`;ĭB _ b b ĩ@? jB@x@A$AjE{b jaj = U= = @~@~ ? BB [@? JB@o/l@x@AAJ@/ Ek7aJ@==Fc = {i`{%  = @@ $F @c"ZgB _ bb @? abB@x@A$AjETa, V = )`=j^% = @@, G JJ @? aRB@x@A ARE ̀ F  aR = Ӏ=R(o = @π@`;$y!`&'}Πb@6#$E`Bx oy@x@A$AjEb j  aj = ɠ=%-(6@w@+B׉BB$  B@JB@x@AAJECaJ !e=UF = `{%p" @e@ ! @biA båb bO B@aBy@x@A$A7 E`a,"#b  >`= `= @A@,JJ F B@B@x@A ARE F$$aR =RM߀=R"@ڀ@`|bb  B@jB@x@A$AjEBb j%%aj =jҖ=%-(%@.@ $( @K BB B@JB@x@AAJENaJ&;e=JaF =ζ`{% "@@ ' @B brb b륱 B@aB@x@A$A!E]la,y<=b" =j,`=^"#@*@,$J\JA#% B@aRBh@x@A AR&Ej"j>>aR' =R= (@j@`|eN)bb@6j* B@jB@x@A$Aj+Ebj??aj, =j}=j%p(%n-@ء@ .B9Bc/ B@JB@x@AAJ0ExZaJ@Ue1=F2 =`{% %3@½@ B! @bA4b!b ! b 5 B@aB W.X,@x@A$A6E xa,VWb7 =j)8`="8@6@,9J5J : B@aRB@x@A AR;E XXaR< =R=R"=@1@`|D>bb@6? B@jB$@x@A$Aj@Eb jYYajA =j(=( B@@~ $( @(DCBB$BD B@JB@$@x@AAJEE'faJZoeF=F,G =@(`{% H@qɀ@"!IbȀb ! cJ B@`B@x@A$AKEa,pqbL =jC`=^"M@NB@, NJAJ O B@aRB@x@A ARPE FrraRQ =R}$R%R@~ o+o`|ySbHb@6jcT B@jB@x@A$AjUEO, jssajV =jӹ=(%-(+cW@.@ rXB$ yY B@JB@@x@AAJZEqbwte[=WF\ =@, % "]@ Հ@ ! @;m^bԀb bco `B@x@A$A` @Eja,ba = ?`=zO`=$j%b@M@ m2 @,cJHJ d B@B@x@A AReEwa FaRf =R=R"g@ @`|hbb@6#i B@jB@x@A$AjjE jajk =jzŀ=j%-%l@Ā@$mB:B Jn B@JB@@x@AAJoE}bBep=Fq =@!`{% "r@@c" sb.b t B@`Bc@x@A$AuE"a,ybv =jA[#`="cw@Y@ mxJJ kM aRB`B/@x@A ARe `E&$a FY+{=&|@.@ N}bb@8'~ B@a$B@x@A$AjÈ2 jb =@퀃5р=j @Ѐ@ ) @(EBB B@B@x@AAJE3%bce=F =94`{% @}@ ! @c"z6bbj bc B@aBc@x@A$AEǦ5a,* b =jf6`="@Ze@,JdJA#F B@aRB@x@A ARE7a FaR =R%=R(o@ @`|bQb@6j B@jB{ o@x@A$AjE[٠@Y jaj =j܀=j%p(+c@>@ $( @ťBۀ B B@JB @x@AAJE8be=cF = ÀG`{% "@,@ ) @B[!bbj B@`B@x@A$AEvHa,cb =jrI`="@p@,JeJ R B@aRB@x@A ARE)Ja FaR =R41=R"@,@ `|$Dbbj B@jB@x@A$AjE @YY i 8aj =@=%p(%@@ BFBJ B@Bc@x@AAJEKbe=F =[`{%p"@@ ! @brAb:b bc B@aB@x@A$AE%b =jE~\aj^%@|@,JJA# B@aRBPB@x@A ARE25]a FaR =R<= @?8@"`|yBb7b  B@jB@x@A$AjEjaj =jI=j @@~r `@"AJBB B@JB@x@AAJE@^b @==F, =In`{% @@  c"Abb ! 륱 B@aB@x@A$AjEɀ Z^`.   A joaj"@c@,JχJ > B@aRB@x@A ARE@pa@Y R!8 8aR =@H=R(o@C@$`|ezBbUb@6j B@B@x@A$AjEh@YAXaj =@=( @F@ BJ$ , B@B@١B2a@x@AAJEqbc%e=pʄF =@`{% @8@ ! @c")bb b, B@`B@x@A$AEՀ&'b =jj(f@@,JJ  B@aRB@x@A ARELa F((aR =RDT="@O@&`|DEbb@6j B@jB@x@A$AjEj))aj =j =(%-(1@ @ r$( @"@BBOB J B@JB@@x@AAJEÀc*?e=քF =@+a% (@&@  c"qAbKb 륱 B@`B !R@x@A$AE2@Ab =jYj @@ !j @J$J  B@aRB}@@x@A AR@/ `E?Xa BBaR =R_=!@O[@(`||BbZb@6' B@a$B@x@A$AjEjCCaj =jR=j%pj%@@$B J B@JB@x@AAJEMπDYe O`ΤF =V7a% %@2@c";Ab1b  B@a$Bc@x@A$AE쀈Z[b =jaj(f @g@, JӪJA#F B@aRB|#B@x@A AR Eca\\aR =Rk= @f@*`|Bb^b@6j B@jB@x@A$AjEuaj ]]aj =j"=j @R@~ЏcB! B B@JB@x@AAJEڀ^se=Fc =Ca% @H>@ ) @BwBb=` ! b  B@aB@x@ =A @Etub =jø`"@"@, JJ F! B@a B@x@A AR"EoavvaR# =RHw=R(o$@r@,`|B%bb@6j& B@jBL6@x@A$Aj'E$+ajF wwaj( =j.=j )@@~*Bp- B$ + B@JB@x@AAJ,E怈xe-=+a. =N`="/@I@  bztB0bSb ! b1 B@aB@x@A$A2E>a,,b3 =jiĀ=j+c4@€@,5J5JA#F6 B@aRB@x@A AR7EL{aR@Y FaR8 =R=FR%9@\~@v @oK0.`|B:b}b j; B@jB~  @x@A$Aj<E6aj jaj= =jV:=%-1>@9@ nc?BB$ @ B@JBc@x@AAJAEYeB=ڤFC =_Za% "D@U@ `@B[AEbb F B@aBc@x@A$AGEa,cbH =j$Ѐ=j$j%I@΀@,JJ͠JA#(K B@aRB{@x@A ARLEaRcaRM =R=FR"N@@c0`|%qBObsb P B@jBc@x@A$AjQEBaj ajR =jE=j%-%S@Z@~rTBD BU B@JB@x@AAJVEeW=|FX =fa% "Y@Ta@ ! @bmZb`b b [ B@aB@x@A$A\Ea,b] =jۀ="^@/ڀ@,_J٠JA#` B@aRB@x@A ARaEaRaRb =R\=R"c@@2`|db)b@6je B@jB@x@A$AjfE0Naj ajg =jQ=( h@@ $( @(EiB|Pj B@JB@,@x@AAJkE aJcel=<|m =@q$% n@l@c"zAob`b cp B@`B,@x@A$AqEK'a,br =q=j"s@@,tJ>J cu B@aRB@x@A ARvEXaR FaRw =R="x@X@4`|dNybĠb@6#z B@jB@x@A$>!EY aj@Y jaj| =jo]=%p(+c}@\@ r~B+B J B@JBc@x@AAJEf aJc@==F =}`{% (@x@"yAbb B@aBc@x@A$AjE2a, b =j(=^%@@ 2%JJA#`  B@aRB@x@A AREaRcaR =R=!@ @6`|ErBbwb@6a`j B@jB@x@A$AjEejaj =ji=j @jh@ BgB B@JB@x@AAJE!aJc`==3|@ =,`{% @\@ $F @B!bb ! b B@aB@x@A$AE>-a,c A =j="@G@,JJA#F B@aRB@x@A ARE.aR AR =RL=R(o@@8`|ybb@6j B@jBF@x@A$AjE=q/jAj =jt=( @)@$cBs J$ #w` 6iy@ JB@x@AAJE,0aJ5n)`==E?| =ɔ?`{% @ @c":mbmb y B@aB@x@A$A EWJ@a,,*+B jq A`=j+c@@,J>J@F B@a B@x@A AREe@Y ,48' =R ɀ="@mĀ@:`|bàb@6 B@jB@x@A$AjE|Bb2 j- &!j =j\=%-(1@@~cBB J B@JB@@x@AAJEr8C!#c.!@==F =@tR`{% (@@" bb ! B@`B  !@x@A$AjEVSa,DEB =j8T`=^%@@ m,%JJ  B@aRBz,@x@A ARE͠@YA FFFAR =RԀ=!@ Ѐ@<`|w#bπbĩ B@jB @x@A$AjEUb jGB% = #= @~@~B㊀B c B@B@٢o!Ky@x@AAJE!DVaJH]`==F =@e`{% @d@ ! @b{Bbʦb  B@`B !@x@A$AEafa,^_B =j!g`=^%@D @,JJ  B@aRB@x@A ARE F``AR =Rd=R(o@ۀ@c>`|ĶBb3b@6# B@jB]L@x@A$AjEIhb jaaAj =j֗=j%-(&@1@ n$( @n"@BBn$B B@JB@x@AAJEOiaJbw`==QbF]L =x`{%p"@@ ) @BZ|Abyb b B@aB@x@A$AEdmya,cxyB =j-z`= @+@,JWJA#F B@aRB@x@A AREr FzzAR =R=R"@~@@`|$Bbbf B@jB@x@A$AjE{b j{{Aj =j|=%-(%@آ@ B8BJ B@JB@x@AAJE[|aJ|`==nFË`{% "@ʾ@ ! @bDAb(b b  B@aB`x@9 A @Eya,B =!=,9`=j^(f@7@,J6J  B@a B@x@A AR E FAR =R=R" @%@B`|OB bb  B@jB@x@A$AjEb jAj =j7=j @@~n$( @"AJBB B@JB@x@AAJE.gaJ; `==Fy =3Ϟ`{% @xʞ`@c"Abɀb ! c B@aB@x@A$AE„`,B =jD`="@EC@,JBJA#c B@aRBF@x@A >E FAR =R|$R% @~ $F'EoD`|eLB! LGb@6j" B@jB|  @x@A$Aj#EV, jAj$ =Һ=(%p(+c%@1@~&B B$ _ JB@!K@x@$ AJ( @Erbw`=)=^FF* =@{ڱ`{% "+@'ր@ " @A,bՀb bc- B@`B@x@A$A.Eqa,B/ =jP`=j$j%0@N@ 52 @y1JXJA#2 B@aRB@x@A AR3E~a FAR4 =R="5@~ @F`|DB6b b@6j7 B@jB@x@A$Aj8E jAj9 =jƀ=%-%:@ŀ@ r$( @"@B;BEB J< B@JB @x@AAJ=E~bB`=>= F* ? =@`{% "@@@ $F @BGAAb9b b륱B B@`B !y@x@A$ACE a,BD =jD\`=j%pj"E@Z@ m!j @FJJ  aRB@x@A ARH @`E-a FARI =R=R"J@5@H`|JBKbb@6jL B@a$B@x@A$AjME jAjN =j@Ҁ=j%p%O@р@$PBЀB JQ B@JB@x@AAJRE;bc`=S=FT = À@`{% "U@@c";AVbb W B@`Bc@x@A$AXEϧa,BY = `h`=%Z@if@,[JeJ F\ B@Bc@x@A AR]EaAR^ =R&=&_@!@J`|B`b`b a B@jB@x@A$AjbEcڀjAjc = ݀=j d@M@ ceB܀ Bf B@B@x@AAJgEbB@=h=kF/i =`{% j@3@ ) @c"ABkbb l B@aB@x@A$AjmE}a,yBn =js`="o@ r@,pJxqJA#Fq B@aRB@x@A ARrE*a aRs =R;2=R(ot@-@L`|Bubb@6jcv B@jB@@x@A$AjwE jajx =j=( y@@~zBVB J{ B@JB@x@AAJ|Ebc-e}=FW~ = `{% @@ ': @bzBBbBb ! b c B@aB@x@A$AE,./b =jXj+c@}@,J'JA#F B@aRB@x@A ARE:6.@T F00aREZR==R% ~@29@@V" @N`;IBb8b@6j B@jB@x@@Aj `E j11aj )E= @@ !j @"AJBB By B@aB@5y@x@AAJEGb2Ge=ȤF =@M`{% @@c"[Abb !  B@`B@x@A$AEʀHIb =j j$j"@n@,JڈJA# @ B@aRBW@x@A AREAa FJJaR =RI=R%@D@D$F @P`|%yHeb@6jcM jBz ,@x@A$Aj @`Eo@ jKKaj =a%p6@M@~cB B$ , B@aBW@x@AAJE Lae=w˄FQ = $a% "@;@bcE" @mbb ! b, B@aBy@x@A$AEրbcb =j–%j$j%@!@,JJ  B@aRBF@x@A AREM&addRh =R?U=R"@P@R`|b b  B@jB@x@A$AjE 'aj eeaj =  ="@@ $(n"EB^ J$B B@B@x@AAJEĀf{@==&ׄF =!?,7a% F"@'@G " bNb B@aBc@x@A$AjE9|}b =jl8j^"@̠@,J8JA# B@aRB@x@A AREFY9a~~aR =R`=R"@N\@T`|dNb[b@6j B@jB@x@A$AjE:jaj =ja=j%-(+c@@ BB B@JB@x@AAJETЀe=դFy =]8Ja% "@3@LF! @c"OAb2b ! b B@aB@@x@A$AE퀈,J =jKaj%@_@,J˫J c B@aRB/@x@A AREdLa aR =Rl=R"@g@V`|Ebeb@6 B@jBc@x@A$AjE| Mjaj =j$=( @a#@ $( @"DB"B$Bc B@JB@x@AAJE܀e=Ja* = ÀD]`=% @K?@  c"!b>b !  B@`B@x@A$AEE =jɹ^j"@*@ 5!j @ JJ F B@aRB@x@A AREp_a aR =RGx="@s@X`|ybb@6ja| B@jB@x@A$AjE+,`jaj =j/=(%-(+c@@ rBg. J$ J B@JB@8y@x@AAJE瀈e=3F =@Opa% (@J@ ! @c":mb[b b B@`B !B@x@A$A@/ EFqa,b =jpŀ=j%pj%@À@ mJ B@`B@x@A$Aj?ER(a,cb@ =j|=j#j"A@@,BJIJ FC B@aRB@x@A ARDE`aR FaRE =R=R"F@h@``|%\BGbԡb@6jH B@jB@x@A$AjIEZjajJ =jo^="K@]@ LB*BM B@JBc@x@AAJNEmaJ1eO=FP =~`{% F"Q@y@c"BRbb ! S B@aB@x@A$ATE4a,23bU =j'=j V@@,WJJ FX B@aRB* @x@A ARYEaR 44aRZ =R=R"[@ @b`|B\bwb[] B@jB; @x@A$Aj^Efaj j55aj_ =jj=+"(+c`@yi@ aBhBJ$ Fb B@JB@:y@x@AAJcE"aJ6Ked=Fe =@!`{% "f@g@c"WAgbńb h B@`Bc@x@A$AiE?a,LMbj =j=j k@G@ m, @,lJJA#m B@aRB@x@A ARnEaR FNNaRo =RS="p@@d`|dBqb"b r B@jB@x@A$AjsEDrjOOajt =ju=%-(%u@(@ vBt,w B@JBc@x@AAJaz E-aJPeem =L@|^pЕ`{% %{!@@ ! @bTA|btb b } B@a$B@x@A$A| E_Ka,,fgb ) `=^1@ @,JRJ  B@a B$X@x@A AREl  hhaR =R ʀ=&@lŀ@f`|E_BbĠb@6f B@jBcB@@x@A$AjE}b jiiaj =j{=j @ր@~$( @"AJB7Bc B@JB@x@AAJEz9aJyje=KF5n =`{% @Ȝ@M) @BەAb'b ! bc B@aB@x@A$AEWa,0Ab =jI`="@@,JJ >c B@aRBc@x@A ARE)EaRA@aR =@L= @5H@A $F @ K u% +EBbGbj B@BF@x@A$AjZ `Ejdf3 j2?u {#fT@@ yA.TԌhv/G?eAKb f B@bB@!$  E@x@A$A, /&,,@,@$B B! s B@a B ! @x@ABE6d AzJZ|bw#J(( ~@z@ & @J)J s B@RBx#B@x@A ARED3a saR =:=R-@<6@.$ aRs%s  ( Cb5b js B@jB~@s@x@A$Aj@/ `E jes=Ңw!~sVD%s = ){{ s@@, ~" @ s#Abfb $f bf> B@bBhW!@x@A$A, E E,$(%s@X@ " @$g@BBo! Bs B@a BY@x@ABEQd sd =J{j`=J%2J! @h@,sJHJA#s B@RB@x@A ARE^!a aR =R)=R%s@_$@ Qd0`zxb#b s B@jBQs@x@A$AjE܀jaj =jm="|@߀@ B)B B@JB@x@AAJEl/@T f=F{. My & =\{&F"@@3! @,2 2Tbb b B@aBm"@x@A$>ESaKb =j`=j @e@,JJ  B@aRBb@x@A ARE aR =RҀ=e6 R"@΀@C@"!+% Enter ICPuaMHobt̀b j B@jBT@x@A$AjEb jaj =j=)6()@k@$BψB . B@JB@!K.@x@AAJEBaJ Je=TFw =@H{% "@HC@ p \Ab  p B@`BP @x@A$AEcb =jaj$j+c@@ m!j @JJ! B@aRB@x@A AREta aR =RD|="@w@ ; u"a:Bbb@.# B@jBy@B@x@A$Aj@/ `E(0jdf=0 =6{#$f@e1@ Z @ZZfVAb f B@bBW!f@x@A$KE E,I8,&,'@7@P( @0$g@BB B  B@a B@! @x@ABEsd =@p۫b ! @>@ sJJ s B@BK@x@A AREb a saR =Rxj=&#@e@ @CuT"8 !=Bb5b js B@jB s@x@A$AjEC aj jaj =j!=j#j$@ @~Bo B B@JB@@x@AAJE Jf =KFz% =@߀{&}" @ۀ@ $F @7A bfڀb b% B@`BZ @x@A$AEQ bb =jU `="@S@,JPJ! B@aRB@x@A ARE^ a:faR =R=%p@r@ Sa pBbb  B@jB@x@A$AjE fdf=% =̀{#@ɀ@ f) @f,AZfAbȀb & b f B@aB@x@A$K% E,Ѐ, @oπ@ !, @Ht'_ BB! BB! B@a B@x@AB"Eld sd # =JC`="s$@A@,4v%J_JA#,s& B@RB@x@A AR'Ey aR( =R+$R(1)@~%[a B*bb@1js+ B@jB@x@A$Aj,E, jes-=s. ={F$s/@<@ asA0b $f 1 B@aBs@x@A$Es2 E,$,$,%03@@ ]rs4BༀB,  5 B@a Bs@x@AB6Eqcsd 7 = 1`=J&8@0@,9Jm/J s: B@B @x@A AR;E aR< =R4=%s=@@ sc9a C>bb@1s? B@jB{@x@A$Aj@Eb jesA=#rB =  {$F!C@Q@ s$F @as0Db f bftE B@aB'@x@A$EsF E,3,$,%sG@@$sHB,  sI B@a B@x@ABJE_bsd K =J`= %sL@4@,sMJJA#sN B@RB@x@A AROE aRP = Lހ=#Q@ـ@ [k*?  wCRbb jS B@B@x@A$AjTE6b jesU=>`V =.{$F!W@q@ [ asAXb f fsY B@aB@x@A$EsZ E,^,$,%s[@@& @$g@B\BB+Bs] B@a B@x@AB^EMbd _ =J `="s`@C @,saJ J sb B@RB? @x@A ARcE aRd =R}̀=R#e@ǀ@ sm+)7fbBb jsg B@jB@x@A$AjhEQb jaji =jՃ="j@2@~kB Jl B@JB@x@AAJmE;aJ Jfn=XNF}o =A{&"p@=@ % @2 A[qbsv@x@A$AsE^bt =j~aj&u@ᵀ@,vJMJ w B@aRB@x@A ARxElna aRy =Rv=R"z@|q@ Ի"P"aGHo{bpb½| B@jBz 4@x@A$Aj}E)aj jaj~ =jf-="@,@ $(w"AJB"BJ B B@JB@x@AAJEy Je=F =e{% @@ p 0Abb B@aB@x@A$AEbb =j8a`=^"@_@,JJA#c B@aRB@x@A ARE  a aR =R=R%@@ "E" aBbb½ B@jB@x@A$AjE jaj =j ׀=(%p(/l@jր@ rBՀB J B@JB@& @x@AAJE!b Je=Fyc =@ {% "@W@ @c P6b ! b B@`B@x@A$AEJ"acb =j #`=j c@( @ m' @ JJ  `JR- B@aRB@x@A ARE aR =R_ɀ="@Ā@ ):Kb%agDb'b j B@jB@x@A$AjE6}$baj =jʀ=j(%@$@B B$ c B@JB!y@x@AAJE8%aJ e==KF~ =>{F% @ :@ p$F @ . bl9b! b B@aB@x@A$AECb = `k&aj%pj+c@β@,J:J B@B@x@A AREPk'a aR =Rr=FR(o@Qn@ "e")c:Dbmb½ B@jB @x@A$AjE&(jaj =jc*=%@)@ nBB J$ g B@JB@x@AAJE^ e=ߤFJ =J{% F"@@c Ab !  B@aB@x@A$AE)bb =j ^*`=j^%@o\@,J[JA#c B@aRB@x@A ARE+a aR =R=R"@@ k`1 )afbbb½ B@jB@x@A$AjEyЀ jaj =jԀ=j%-(%@`Ӏ@$BҀBJ$  B@JB@x@AAJE,e=F = À{% "@=@ c jAbb !  B@`Bc@x@A$AEG-acb =j.`=%@ @,JyJA# B@aRBc@x@A ARE FaR =RTƀ="@@ "u/a^Bbb j B@jB@x@A$AjEz/b jaj =j}=%-(%@@~ncBf| B$  B@JB@x@AAJE50Je="HF. =;{% "@6@c hAb=b  B@aB 8p,@x@A$AE(cb =jM1a^%@@,JJ B@aRB@x@A ARE5h2a FaR =Ro=R"@Ek@ 33@ `cBbjbĩ B@jB.@x@A$AjE#3jaj =j<'=j%- @3A@&@ B%B B@JB@x@AAJ  EC e=ĤF =AT{?{% "@@ c qAb !  B@`B@x@A$AEɚ4b Z b = `Z5`="@TY@, JXJ Ry B@B@x@A AR E6aR@saR =@= @@ $F @K " @ibSbj B@B@x@A$AjE^̀ jaj =jЀ=j @A@~!j @(DBπ $Bc B@JB@x@AAJE7e=fF =Վ{F% @@ @! @ޘbbAy(! bc B@aB@x@A$AEkD8ab = `9`=j$j"@@,JfJ R B@B@x@A AR Ey FaR! =R.À=Rc"@@c3@P#bb½$ B@jBP @x@A$Aj%Ev:b jaj& =jz="'@y@ $(n"E(BCBJ$B) B@JB@J!K@x@AAJ*E2;J@=+=EF9, =@~8{% F"-@3@c A.b"b / B@`B@x@A$Aj0E -qb1 = `=j 2@ @ m, @3JyJ 4 B@B|LWJ@x@A AR5E<aR6 =RC="7@@y"Ø"asN8b b 9 B@jBJ@x@A$Aj:Ee=jaj; = h=%-(6<@@ =B^g > B@Bc@x@AAJ?E >Je@=F*A =!?&{% %B@!@ W @c חACb=b b D B@aB@x@A$AEE(܀bF =jK?aj%pj(fG@@,HJJ nI B@aRB@x@A ARJE5S@a aRK =RZ="L@AV@ #(%paBMbUbO.N B@jB @x@A$AjOEAjajP =j4= Q@@$RBB JS B@JB(#@x@AAJTECʀ eU=ĤFu V =3Ѐ{% F%W@ˀ@ ) @+c BXb ! b Y B@aB@x@A$AZEɅBbb[ =jEC`=j \@`D@,]JCJA#^ B@aRB@x@A AR_E aR` =oDaR"a@~ )!(o 38"%e Bbb;b@&jc B@jB/@@x@A$AjdE], jaje =j޻=j f@<@!j @(AJgB B$Bh B@JB@@x@AAJiEsEbwJej=eFk =@y{F% l@!u@ @}Ambtb! bn B@`B@x@A$AoEk/F/@Tcbp = 0`=j$j"q@@,rJ^J cs B@B@x@A ARtExGaR FaRu =R$=R(ov@@ CKW 8"3IwbbA;#x B@jB| !@x@A$AjyEaHjajz =je=j%-1{@d@ |BGB$ } B@JB@x@AAJ~EIJe=0 =j#{% "@@ c 5Ab"b !  B@aB "@x@A$AE ـb =jEJa @@,JJ F B@aRB@x@A AREPKa aR =RW=R"@.S@ S"ЃЂ@8BbRb@&j B@jB@x@A$AjE Ljaj =@݀5=j%-`3A@@ B B$  B@B@x@AAJE' e=F =̀{% "@dȀ@ * ! @c eAb c B@aBQ@x@A$AEMbb =jBN`="@EA@,J@JA#F B@aRB@x@A ARE aR =RhOaR @~ cos䓣Bb4b@(j B@jB@x@A$AjEB, jaj =j=j%-(+c@@~$( @nK@BBz B B@JB@),@x@AAJEpPbw Je=JF, =@v{%p%@r@ c ]Abeqb! c B@`Bc@x@A$AEP,Qa Z b =jy="@@ m!j$ }@ ! @ ARJGJ(R B@aRB@x@A ARE]RaRaR =R=R"@Y@ !$F!Ro sŃł@ a~bťb  B@jB @x@A$AjE^Sjaj =jxb=(%p(%@a@ !j @ťB4B$Bc B@JBc@x@AAJEkTaJA8@==Fc =@Og {% "@@ @ bb^! b륱 B@`B@x@A$AjEՀcA =jUa^"@t@,JJ {R B@aRB @x@A ARELVa  AR = T=R"@P@ ,e"Qpt b{Obj B@Bc@x@A$AjEWaj jaj =j =(%-(%@i @~B B J$  B@JB@x@AAJE Je=քFB =ɀ{% "@Bŀ@ c _`b !  B@aB@x@A$AEXbb =j?Y`=j)j%@>@,J=JA# @R B@aRBvLWB @x@A ARE aR =R>=R"@@ p tanDb b½ B@jBxc@x@A$AjE'Zb j  aj =j="@@ BsJ$ B@JB@x@AAJEm[J  e=/F =s{% F"@n@ ! @c dBbJb b B@aB .Xy@x@A$AE5)\  b =j-=j @-,@,J+J n B@aRBB@x@A ARE F  aR =Rs="@@ csth`ߊa`]bB4b(b j5 B@jB@x@A$Aj6E jaj7 =j(="8@@ 9BB$y: B@JB@٢o?2a3}@'@x@AAJ;E'hb Je<=F= =@@{% F">@a@ ! @J?b e! b @ B@`B@x@A$AAEXiabB =jj`=^%C@I@ b2$^DJJA#cE B@aRB@x@A ARFEπaRG =Re׀=R"H@Ҁ@  F @>oXEIb3bA;jJ B@jBsZ@x@A$AjKEBkb f  ajL =jŽ=(%-(1M@"@ r$( @"@BNBBiFO B@JB@@x@AAJPEFlJ!!eQ=JYFyR =@L{% "S@H@ W$F @6 ˪ATbeGb bcU B@`By@x@A$AVEOmac"#bW =jv€=^"X@@ m!jYJBJA#Z B@aRB@x@A AR[E]ynaR F$$aR\ =R=R"]@a|@  12 EajB^b{bf_ B@jBc@x@A$Aj`E4oaj2 j%%aja =jp8=(%-(%b@7@~cB,B J) d B@JB@x@AAJeEj J&&ef=F|3|=\ Ag =_{% "h@@@at @6Aibb! bj B@aB 'Z,@x@g =Ak @Epb ''bl =j=%pj%m@@,nJaJ@o B@a By@x@A ARpExgqR((aRq =R,o=R"r@j@cn_fMBsbibA;jt B@jBy@x@A$AjuE"rj))ajv =j{&=j%-%w@%@$xB7B$ y B@JB]L@x@AAJzEހ **e{=| =u{F% "}@߀@ ) @  ~b!b B@aB,@x@A$AE sbc+,b =j0Zt`=j^%@X@,JWJ F B@aRB@x@A AREua --aR =R=R"@@ck_Z1a8LDbb½ B@jB o@x@A$AjE j..aj =j,Ѐ=j(%@π@$B΀B J B@JBc@x@AAJE'v//e=F ={"@`@G Ab ! Zc B@aBc@x@A$AECwa01b =x`=j @(@,JJ B@aRB@x@A ARE F22aR =R[€=R"@@ c#NvBaBb'b@$ B@jB@x@A$AjEBvyb j33aj =jy=j @,@~Bx B$ c B@JB@x@AAJE1zJ44e=JDF =7{% c@3@c lbd2b  B@aB* @x@A$AEO퀈c56b =j|{aW @ޫ@,JJJA#Fc B@aRBc@x@A ARE]d|ay F77aR =R l=R%@mg@ 3ƀԀU)aUEbfb@$j B@jB@x@A$AjE}aj j88aj =jl#=%-(+c@"@~B+B B@JB@,,@x@AAJEj J99e=Fw =@V{% "@܀@ ': @+c QAbb ! b B@`B @x@A$AE~bc:;b =j"W`=^1@U@ m2 @,JTJ(> B@aRB@x@A ARE a <>e=F{ ={% @I@ $F @6 eb ^! bc B@aB@x@A$AE@ac?@b =j`="@%~,JJA# B@aRB@x@A ARE FAAaR =RI=R(o@@ SQ 䓣a<|ybb½ B@jBnb@x@A$AjE'sb jBBaj =jv=(%-(+c@u@~B[B J$  B@JB@x@AAJE.aJ JCCe=2A|c =4{% "@/@, |ybIb!  B@aB (,@x@A$AE4DEb =j^aj(f@@,J+J B@aRB@x@A AREBaa FFaR =Rh=R"@Jd@ cc = `ـ=j^%?@D؀@,@JנJ nA B@B@x@A ARBEaRXXaRC =R\=FR"D@@ N`͈$Pa#,Eb+b@$jF B@jBy@x@A$AjGEALaj YYajH =jO=j I@@~a$( @"DJBN B$BK B@JB@`{&@x@AAJLEJZZeM=I|xcN =@ {% O@ @ , 2Pbdb cQ B@`B$X@x@A$AREOÀ[\bS =ja"T@恀@ m,$UJRJ(>V B@aRB@x@A ARWE\:a F]]aRX =RA=R%Y@`=@  ##E#1sa DfZb=R%@@ `ү"Bbb½ B@jB@x@A$AjE&Iaj jhhaj =jL="@@ BfKJ$&5, B@JB@x@AAJEJiie=.| = {% F"@@ ! @6 ]BbIb by B@aBy@x@A$AE4jkb =jbaj @~@,; J/J  B@aRB@x@A AREA7a FllaR =R>="@M:@ "!kZ兺afgBb9b B@jB@x@A$AjE jmmaj =jH=%-(C@@ r!j @(@BBB J B@JB@@x@AAJEOb Jnne=ФF =@G{% %@@  c •Ab ! 륱 B@`B@@x@A$AEiacopb =j*`=j$j"@d(@ m!j @J'JA# B@aRB @x@A ARE qqaR =R="@@ ,`_aBbOb j B@jB @x@A$AjEjbfrraj =j=j%p%@S@~B B$ c B@JB@@x@AAJEWaJ sse=qjFQ =@]{F% %@,Y@ ! @ =$AbXb! bc B@`B@x@A$AEwttb = `=%pj%@w@,JJ  B@B @x@A ARE uuaR =Rր=R"@р@dWhb^b j B@jB5n@x@A$AjEvvaj =j=%-%@o@ $( @"@BBԌB$B B@JB@@x@AAJE FJwwe=tյ =@K{% "@HG@ ) @ hb  B@`B W'Z@x@A$AEaxyb =j=^"@ @ m!j @cJyJ  B@aRB@x@A ARExaR zzaR =RH=!@{@c` x|KdadDfbb½ B@jB@x@A$AjE&4j{{aj =j7=j%-j%@ @ Bn6 B B@JB@x@AAJE ||e=.|, ={%p%@@, LkbIb c B@aBc@x@A$AE3b Z }~b =jmk`="@i@,J:J F B@aRB@x@A AREA"a(aR =R *=R"@]%@#u`aDb$b j B@jB oB@x@A$AjE AXaj =@T=( @@ BB B@B@x@AAJENb Je=ФF; =?{% @@ * ) @c !cBb ^! b B@aB@x@A$AETab =j`=j+c@`@,JJA#{R B@aRB@x@A AREˀ aR RӀ=R%@΀@ c3ү"K[@T BbOb jjB`x |A$Aj@ aib jaj = >`=튀="@I@rBB$&5 B@B@x@AAJ EBJe =qUFc =H{%  @*D@ c iB bCb  B@aB@x@A$AEw b = `aj @o@,JJ  B@By@x@A ARE RaR =R="@@ cCp ӔP aBbnb  B@jB,@x@A$AjEub jaj =j y=%-(1@jx@ BwBµ B@JB@x@AAJE 1Je=F* =7{% (!@G2@, "b  # B@aB,@x@A$A$E1 b% =j<=j &@@,'J J R( B@aRBc@x@A AR)EaR* =Rͯ=R"+@$@ S~.KlaeD,bb j- B@jBc@x@A$Aj.Ecjaj/ =j#g=j 0@~f@ 1BeB2 B@JB@x@AAJ3E&Je4=.y5 =%{% 6@\ @ ! @4 B7b ^! b 8 B@aBc@x@A$A9Eڀyb: =jޚa1;@?@,<JJA#= B@aRB@x@A AR>EQa aR? =RkY=%@@T@ c+l+lwBAb2b½B B@jBy@x@A$AjCEA jajD =j=j E@(@ $( @"AJFB B$BG B@JB@x@AAJHE eI=IۄF{$XJ =΀{% K@ʀ@  jALbcɀb M B@aBQ@x@A$ANENbO =j눀="P@J@,QJJA#R B@aRB@x@A ARSE?RaRT =RG=R%U@B@ $F%osq 1laφBVbUb jW B@jBc@x@A$AjXE\ fajY =j=(%-(1Z@I@~ƹ!j @ť[B J\ B@JB@x@AAJ]Ee^=F_ =׼{% "`@@t ktAab~b 륱b B@aB ?n@x@A$AcEiraybd =j2`=j$j"e@0@,fJ\J g B@aRB@x@A ARhEw FaRi =R.=R"j@@ p"xa!dkbbĩl B@jB@x@A$AjmEb jajn =j="o@㧀@ pBABJq B@JB@x@AAJrE`Jes=sFBt =xf{% F"u@a@ , 'Lvb b w B@aB@x@A$AxE aby ='܀=^%z@ڀ@ ,% {J٠J | B@aRB`@x@A AR}EaRaR~ =RԚ=R"@@o!Rc~uDk*[bb  B@jB @x@A$AjENaj aj =jR=(+"(!@yQ@ rBPB B@JB@x@AAJE& aJ Je=F@ =.{% "@b @ {Ab  B@aB S"c@x@A$AEŀb =jԅaj$j%@7@,cJJ y B@aRBB@x@A ARE B@aRB{ ]L@x@A ARE[Ѡ DE aR =Rـ=R"@sԀ@ 5n2K%@77%; UBbӀb' B@jB@x@A$Aj  `Eb jaj =jn=(%-(%@ˏ@ rB*BJ B@aB@x` =AJ @EiHJe=FF =]N{% "@I@ 5n! @c5A bb b B@abB ?n,@x@A$A Eab =j#Ā=^% @€@,JJ ( B@aRB @x@A AREzaR FaR =R=R"@~@ 1d3`2% bm}bA; B@jBz ,@x@A$AjE6aj2 jaj = 9=( @M@~G$( @"DB8 J B@B@x@AAJE Je=|y ={% @F@c b ! c B@aB]L@x@A$A Ebb! =jm`= "@l@,#JkJ F$ B@aRB@x@A AR%E$a aR& =Rf,=R%'@'@ N$F @o EDD(bb ) B@jB@l@x@A$Aj*E%jaj+ =j=%p(+c,@@ !j @ť-Ba B. B@JB@x@AAJ/Ee0=-FB1 ={% "2@蜀@  3bHb 륱4 B@aB "c@x@A$A5E3Wab6 =jJ`=j$j"7@@,B8JJ R9 B@aRBy@x@A AR:E@΀ aR; =RՀ="<@Hр@ c# u%`mn!=bРb@"na|> B@jB{ @x@A$Aj?Eljb jaj@ =jC=%-%A@@$BBBC B@JBB@x@AAJDENEaJ JeE=WFBF =:K{% %G@F@, t Hb  I B@aB@x@A$AJEacbK =j=j L@S@,cMJJA#FN B@aRB@x@A AROEwaR aRP =R="Q@z@ o!c3))a*DRbbb@$jS B@jB@x@A$AjTEh3jajU =j6=j V@3@cWB5 B/l X B@JB@&nb@x@AAJYE eZ=pa[ =@{F% \@,@ ! @B]bb! bXF^ B@`B@x@A$A_Evaj b` =j=$j+ca@~@,bJꬠJ c B@aRB @x@A ARdEeRaRe =Rm=R(of@i@,Cuu&׮Bgbhb jh B@jB/@x@A$AjiE!jajj =j %=%-+ck@g$@ $( @"@BlB#B$Bm B@JB@@x@AAJnE eo=|,p =@{% "q@Dހ@ 'L , s\Arb s B@`B@x@A$AtEbbu =jX`=^"v@ W@ m!j @Ϣ 6! !%w VJ x B@aRB@x@A ARyEa aRz =L=R"{@@ SQ * @JW|bb½} B@jB@x@A$Aj~E%ˀ jaj =@݀΀=(%-(%@̀@~B]B B@B@@x@AAJEe=-F =@{ @懀@ ! @c AbHb ! bc B@`B@x@A$AE2Bab =je`=^%@@ mJ1JA# B@aRB{&B9 @x@A ARE@ DE  A@aR =@=R%@H@ c uȿMBbbĩ B@By@x@A$AjEtb@Y jaj =jSx=( @w@ $( @"AJBB J$Bc B@JBy@x@AAJEM0aJ Je=ΤF, =26{% :"@1@ ,  Ab ! 륱 B@aB@x@A$AEb =jaj+"j"@o@,J۩J R B@aRB@x@A AREba aR =Rj=R"@e@ s6 u &ΔBbVbj B@jBB@x@A$AjEhaj jaj =j!="@I@ B J$ B@JB@x@AAJE Je=pF =߀{% F"@*ۀ@ c jfBbڀb B@aB@x@A$AEvbb =jU`=^%@S@ 5cJYJA# B@aRB@x@A ARE a aR =R.=R"@@ 1 0 16%QYBbbf B@jBnb@x@A$AjE jaj =jˀ=(%-(1@ʀ@ rBBB J B@JB@y@x@AAJEb Je=Fxc =@{% "@̄@ m$F @6 nAb-b! b B@`B@x@A$AE?"Gcb =j:=j c@@ m!j @JJA#c B@aRB @x@A ARE%aR aR =RԽ="@5@ , 8E  8a/Bbb@$j B@jBB@x@A$AjEqajF jaj =jF- =ـ{ .@Ԁ@ , w A/bUb 0 B@aBy@x@A$Aj1E@b  E2 =j瓀="3@H@,4JJF5 B@aRBB@x@A AR6EJaR RaR7 =RR=R%8@M@5nu6)aB9bJbj: B@jBB@x@A$Aj;EMjaj< =j =(%-=@9@ r>B J? B@JB@x@AAJ@E FeA=ܤFnbB =ǀ{% "C@À@ 5n`@  BDbp€b E B@aB@x@A$AFEZ}b, bG =j=`=^+cH@;@,IJQJA#J B@aRB@x@A ARKEh@Y   aRL =R=R"M@t@ |y 8BNbbO B@jB@x@A$AjPEb2 j  ajQ = s=( R@ϲ@~SB/B JT B@B@x@AAJUEukaJ  eV=F W =jq{% X@l@Yr @( eBYbb b Z B@aB@x@A$A[E&a b\ =j&=%]@@,^JJA#_ B@aRB@x@A AR`E aR FaRa =R=R%b@@   K^n!cbb cd B@jBB@x@A$AjeEYjajf =j]= g@q\@ hB[B,ki B@JB@x@AAJjEJek='|l ={% m@R@ c Enb  o B@aB@x@A$ApEЀt ^bq =jKՀ=jj%r@Ӏ@,sJJA#t B@aRB,@x@A ARuE$aRv =R̓=R%w@,@ 11 %aVBxbb jy B@jB| 5n@x@A$AjzEGjaj{ =j7K=j |@J@ }BIB~ B@JB@x@AAJE2Je=:у* = {% @k@ ! @c hb  B@aBy@x@A$AEb =jXÀ=%@@,J%JRc B@aRB@x@A ARE?z aR =R=R%@S}@ #^ -Eb|b  B@jB@x@A$AjE5!jaj =jV9=( @8@ $( @w"AJBB B@JB@x@AAJEM e=U =={%p@@ y c  Ab ^! y B@aBc@x@A$AEӬ"bb =jl#`=^"@Zk@,JjJA# B@aRB@x@A ARE#$a aR =R+=R%@&@ 3^A+^A!BbUb½ B@jB@x@A$AjEh߀ jaj =j=(%p(C@D@~Bဃ J$ B B@JB@x@AAJE%e=oF =۠{% "@%@ ! @c !bb b, B@aBc@x@A$AEuV&a b =j'`=j @@,J`JA# B@aRB@x@A ARE͠@Y F!!aR = +-Հ=R"@Ѐ@ C B%B+j$sDbπb  B@B@x@A$AjE (bj""aj =j="@@ $(n(AJBMB B@JB@x@AAJED)J##e=WFx =J{% @E@, ?EAb,b B@aB 4 L6@x@A$AE*aj^W$'b =jD7,`=^"@5@,JJ ( f=Rh B@aRB @x@A ARE2RA@((aR =@=%@>@ Sm+ T Bbbj B@B@x@A$AjE-b j))aj =j0=j%p(+c@@~BB B@JBL6@x@AAJE?e.J**e=F|@. 8A +k{% "@{f@Dt @c |Ab ! b^c B@ Bc@x@A$AE /aB+,b =j="@U߀@,/JޠJ! B@ B@x@A AREӗ0aR F--aR =Rk=R"@˚@ c1 "yBb7b   B@jB@x@A$AjEZS1j..aj =jV=( @D@ rBU J$  B@JBc@x@AAJE2aJ //e=b!|y"`@% ={% @@@a hv/G?Bb}b B@aB* @x@A$AEgʀ01b =j3a^+c@@,cJZJA# B@aRB,@x@A AREuA4a 22aR =RI=R%@}D@ s!"; a^BbCb@$j B@jB@x@A$AjE 33aj =jt5aj%-`3A@~ B0B B@JBt@x@AAJE  J44e=˄FQ =f{" @@ !%c Abb B@aB@@x@A$AE t6b56b =j:47`=%@2@,JJ F B@aRB@x@A ARE@Y 77aR =R=R% @&@ %1 @B bb@%½ B@jB| @x@A$Aj E8b j88aj =j!=( @|@$BݨBJ B@JBc@x@AAJE$b9J99e=t6`= =h{%p:"@ac@ 5n c b   y B@aB@x@A$AE:ajt ::b = `^"=j @ @,J+JR B@By@x@A ARE1٠@Y R;;aR =R="@1܀@ +\+\ 64, b۠b j! B@jB5n@x@A$Aj"E;b j<?b. =jˀ=j /@\ʀ@,0JɠJA#F1 B@aRB; @x@A AR2Eӂ>aR F@@aR3 =Ry=R(o4@ۅ@ \]% aDf5bGb@%j6 B@jB@x@A$Aj7EZ>?aj2 jAAaj8 =jA=j%p( = {% "?@@ c CA@b|b 륱A B@`B@x@A$ABEg@bCDbC =juA`=jj"D@s@ m!j @FEJ^JA#F B@aRBc@x@A ARGEu,BaFEEaRH =R+4=F!I@/@ ,";]4]Q),Jb.boK B@jBL6@x@A$AjLE瀈 fFFajM =j{=j%pj%N@@~OB;BP B@JB@@x@AAJQECb JGGeR=F; S =@n{% %T@@ ,Ubb! V B@`B@x@A$AWE _Da,HIbX =j<E`="Y@@,,ZJJ R[ B@aRBc@x@A AR\Eր JJaR] =R݀= ^@ـ@ c)6ˀV`D_bؠb #` B@jBy@x@A$AjaEFb jKKajb =@瀃%=H@ c@@~dBB$&5,e B@B@x@AAJfE$MGaJ JLLeg=Fh =S{% i@[N@ ) @ Bjb ! bk B@aBy@x@A$AlEHacMNbm = `Ȁ="n@%ǀ@ !j$coJƠJ p B@B@x@A ARqEIaR OOaRr =R[=R(os@@  , HBtb(b@(u B@jB@x@A$AjvE>;JjPPajw =j>=j%-(+cx@,@yB= B$ z B@JB,@x@AAJ{E QQe|=F |} =}{"~@@ !%NK Ab-b! b B@aBc@x@A$AELKbcRSb =jrL`=%p1@p@,JOJA#F B@aRB @x@A AREY)Ma TTaR = 1=R%@m,@ @``!Bb+b½ B@BB@x@A$AjE jUUA! =jT=(%-%@@ n$( @"@BBB J$B B@JBB@x@AAJEgNVVe=貄Fu =S{% "@@ ) @+c 7Abb b륱 B@aB@x@A$AE[OaWXb =j&P`=^"@@,JJA# B@aRB@x@A ARE FYYaR =Rڀ=R"@ր@ c@``"xBboՠb@1j B@jB@x@A$AjEQb jZZE =j=(%-(%@`@$BB B@JB@x@AAJEJRJ[[e=\Fy = ÀO{% "@EK@ ': @+c iAb  b B@`BB@x@A$AESa\]b =jŀ= c@Ā@,JàJA#Fc B@aRB@x@A ARE|TaR@Y F^^aR =RY=R"@@@``#&XjccE =j)=j @*@ r) @"AJB( B B@JB@x@AAJE dde=ͤF ={% @@ ! @c AAbab b B@aBc@x@A$AELYbefb =!!~]Z`="@[@,JJJ B@aRB@x@A AREY[a ggaR =R=%@i@ #@``%L2Bbb@1 B@jBy@x@A$AjE jhhE =jhӀ=j%p(1@Ҁ@ $( @"@BB$B B@JB@x@AAJEg\b Jiie=F5n =S{% "@@ AbbW! 륱 B@aB@x@A$AEF]ajkb =j ^`="@l@,JJA#Fc B@aRB@x@A ARE llaR =Rŀ= @@ 3@``07Bbsb@1j B@jB@x@A$AjEy_b jmmE =j}=%p(%@b|@~B{B t B@JB,@x@AAJE5`Jnne=GF =:{% %@C6@ >Ab  B@aB@x@A$AEopbjaa^(f@@,JJ F B@aRB`x@9 AR @`Egba FqqaR =Go=R"@j@ C6%3 fBbb@( B@a$B@x@A$Aj E##cjrraj =j&=(%-(% @@  Bg% B$ B@JBc@x@AAJE sse=+Fc ={ @߀@ c +AbFb  B@aB@x@A$AE1dbtub =jhZe`=^%@X@,J3JA#F B@aRB|JeB@x@A ARE>fa vvaR =R=R%@F@ S3D3~%AaBbboc B@jB@x@A$AjÈywwaj =j]Ѐ=(%- @π@ !BB J" B@JB@x@AAJ#EKgxxe$=ͤF% =<{% "&@@F vB'b ! ( B@aB @@x@A$A)EChyyb* =jpH=j c+@F@,,J>J n- B@aRBQ@x@A AR.EY@Y zzaR/ =Ria"0@i@bc21!ů@VB1bb½2 B@jB /@x@A$Aj3E຀2 j{{aj4 =jh= 5@ǽ@~6B(B J$ 7 B@JB@٢o!K$X@x@AAJ8Efvjbw J||e9=nDQ: =@[|{% ;@w@N, c bB<bbe! c= B@`B !F@x@A$A>E1ka* }~b? =j= @@x@ m!j @AJJ B B@aRB@x@A ARCElaRaRD =R̰=!E@@ $F @1# %s@ @yRBFbkb G B@jB @x@A$AjHEdmaj fajI =jh=%-jCJ@mg@ !j @.`@BKBfBBL B@JBc@x@AAJME naJeN=2|O = &{% +cP@B!@ @xAQb b륱R B@aB="@x@A$ASEۀ bT = ``/=^"U@ހ@,VJݠJ W B@B@x@A ARXEob RaRY =R=%pZ@@ an6[bb \ B@jB@x@A$Aj]ERpjaj^ =jV=j%-j%_@uU@n`BTB) ca B@JB@x@AAJbE#qJec=+܃|d = {% ce@^@ ) @ fb ! bcg B@aB @x@A$AhEɀbi =jщra"j@0@,kJJ l B@aRB@x@A ARmE@sa %T63n =RVH= o@C@ \$F @+c  #&),oDpb#b@%,q B@jBB@x@A$AjrE>@Y jajs =j=j%-(%t@#@~!j @(@BuB B$Bv B@JB@x@AAJwEŷtb Jex=FʄF$Xy ={% %z@@ ! @2A{bab! b륱| B@aBB@x@A$A}EKsua,:$^~ =j3v`="@1@,JJJ Rc B@aRB@x@A AREY@Y aR =R=R"@Y@!~" 258;>ADGJ@WBbbb B@jB5n@x@A$AjEߥwb jaj =jp=j%-(%@ͨ@~!j @ťB,BB B@JB@x@AAJEfaxJe=F =Rg{"@b@ c ]Abb  B@aB,@x@A$AEyacb =j݀=$K@|ۀ@,JڠJA#(> B@aRB* @x@A AREzaR FaR =R=R%@ @ c   a Bbvb@$j B@jBc@x@A$AjEO{jaj =jR=(%-%@W@ nBQ J$  B@JB* @x@AAJE |Je=|* ={*"@D @ ! @c tAb ^! b B@aB@x@A$AEƀb =j}a^K@@,JJA#F B@aRB$X@x@A ARE=~a aR =R FaR =@=!@F@a u¹`pBbb@$ B@B@x@A$AjEĢb jaj =jH=%-j%@@) @(@BBBB)B B@JB@x@AAJEK^Je=̤Fz* =/d{% %@_@-I! @9  Ab  b륱 B@aB@x@A$AEacb =jـ=j^"@Y؀@,FJנJA#F B@aRB@x@A AREߐaR FaR =R="@@ ¸uҒ" u 0BbcbA;j B@jB]L@x@A$AjEfLjaj =jO=%-(%@I@ r$( @"@BBN J B@JB@x@AAJEJe=r|v = {% %@* @ ) @+c Abb b륱 B@aB@x@A$AEs ^b =jȀ=^"@xƀ@,JŀJ R B@aRB@x@A ARE~aR =R="@@ y8"¯uuam4Bbnb j B@jBy@x@A$AjE:jaj =j >=j%p(%@e=@ B<B B@JB@x@AAJE} e=ă| ={% "@B@2B! @+c Ab c B@aB*@x@A$AEbb =jq`="@%p@,JoJA# B@aRB{@x@A ARP`E(a aR =RZ0= @+@ @C BC2 b½ @a$B B@x` =Aj @`E" jaj = ?`== @@~$( @wK x%Bw怃(B B@B,@x@AAJ Ee =.F ={%p .`@3e @ 䠀@4f c BAbEb ! c B@`B "B@x@A$AE0[ab =)_`=$ .`@3kc @ `@,J+J@p B@B@x@A ARE=Ҡ@Y FaR =ـ=R(o@FՀ@ !$F!0 5 @BbԀbf B@jB @x@A$AjEčb jaj =jL=(%p .`@3A @ @~!j @ťBB$B B@Bc@x@AAJEKIJe =̤F* ! =G?O{% .`@3B" @ J@ ! @[A#b ! b륱$ B@`B@x@A$A%Ea b& =)x =^"'@@,(JFJ (Rc) B@aRB@x@A AR*EX@Y RaR+ =R!Ȁ=R%,@pÀ@! #D@-b€bj. B@jB@x@A$Aj/E{b jaj0 =jg=(%- .`@3C1 @ ~@<$( @"@B2B'BB$B3 B@B@oB&$X@x@AAJ4Ef7Je5=nw *A6 = )b={% .`@3B7 @ 8@c  A8bb 륱9 B@`B !!c@x@A$A:Ecb; =)aj$ .`@3e< @ `@ m, @,=J밠J@p4` > B@B$X@x@A AR?Eia FaR@ =q="A@m@ 3Tү0uBBbrlbjC B@jB@x@A$AjDE%jajE =j )=%- .`@3AF @ d(@$GB'B JH B@Bc@x@AAJIE eJ=F,K =G{% .`@3EL @ E@ ': @c AMb ! b N B@`Bc@x@A$AOEbbP =)\`=%p .`@3eQ @ `[@,RJZJ@peRS B@B@x@A ARTEa aRU =]=R+cV@@ cC% SDPaWbb jX B@jB@x@A$AjYE"π jajZ =jҀ= [@@$( @ūc\BrрB$Bc] B@JB@x@AAJ^Eb* e_=*F* ` ={% .`@3ba @ ㋀@ c IpEbbIb cc B@`B@x@A$AdE0Fabe =)Y`=j^"f@@,,gJ'J h B@aRB@x@A ARiE= FaRj =RĀ=R%k@I@ o!oS0cppr!dlbbA;/fm B@jBQ@x@A$AjnExb jajo =jT|=j%- .`@3Cp @ {@ rqBBJr B@B@x@AAJsEK4aJ Jet=̤F{u =G3:{% .`@3Bv @ 5@ @-oAwb b x B@`BB@x@A$AyEcbz =)a%{@\@,c|JȭJA#Fc} B@aRB@x@A AR~Efa aR =Rn=%p .`@3b @ i@c +eS,7bKbf B@Bc@x@A$AjEf"ajfaj =)%=j @A@ B$J B@JB C5 @'@x@AAJE݀ e=mF ={% .`@3b @ @'߀@ 5\ @ @ bހb b B@`B !@x@A$AEsbb =)Y`="@X@ m!j$JrWJ B@aRB@x@A AREa aR =R.=! .`@3b @ @ s01 PP0_"Hobb f`[ B@B ,@x@A$AjÈjaj =){π=j @΀@~ `@(AJB;B B B@JB@!K@x@AAJEe=F, =@~{% .`@3b @ @Ȉ@ , Ab*b !  B@`B @x@A$AECab =)?`="@@ mJ J c B@aRB@x@A ARE"@Y aR =R= @@B-'QZ` q0@`Bbbĩ B@jB; @x@A$AjEub jaj =j-y=j @x@~BwB$  B@JB@x@AAJE01aJCe=F = 7{% .` e @ j2@ $F @c "BbС ! bXF B@`B@x@A$AEt b =)P="@@,JJA#(> B@aRB@x@A ARE=b RaR =R=R6@M@ E*arBbb j B@jB$X@x@A$AjEcjaj =j B@aRB@x@A AREa(aR =RE`="@~ $F!oE T{S KDapDb b  B@jB@x@A$AjE, faj ==%- .`@3A @ 김@ r!j @"@BBKB B@B@x@AAJErbw Je=F =Gzx{% .`@3E @ s@ ! @MAb*b b륱 B@`B@x@A$AE.acb =)A=j$ .`@3e @ `@,JJ@p B@Bz$X@x@A ARE"aR aR =¬=R+c@@ y;SrSqSq䐂aBbb½ROjBB@x@A$AjE`aj2 jaj =j1d=j%p `@3A@c@~$( @ťBbB Jc B@JB@y@x@AAJE/aJ Je=Fw =@$"{% " @m@ B c ]A b ! 륱 B@`B @x@A$A E׀b =j˗a @-@ m!j @,JJ  B@aRB@x@A ARENa aR =RlV=R"@Q@!Ro3t?Sq5n,!db,b½ B@jBB@x@ =Aj @`EJ aj jaj = ?`= =j%p(C@-@~B B$  B@Bc@x@AAJE Je=R؄F ˀ{% "@ǀ@ ! @'Lbmƀb b B@aB@x@A$A!EXbb" =A`=$j(f#@?@,B$JOJA#% B@aRB@x@A AR&Ee aR' =R6aRR"(@y~ t"aD)bbĩ* B@jB@x@A$Aj+E쳁, jaj, =j|=j%-%-@׶@~$( @"@B.B8B/ B@JB@x@AAJ0Esobw> Je1=F2 ={u{% "3@p@ ) @ [A4bb! b륱5 B@aB - @x@A$A6E*acb7 =j+="8@@,c9JJ : B@aRBv@x@A AR;EaR aR< =R= =@@ c,Ki,aB>bkb½? B@jBB@x@A$Aj@E]ajF jajA =ja=%p(%B@i`@ CB_BJ$ cD B@JB5n@x@AAJEEaJ JeF=+|G ={% %H@N@ ! @K )cAIb  bXFJ B@aB@x@A$AKEԀbL =j8ـ=^(fM@׀@,NJJ cO B@aRB|@x@A ARPE"aRQ =Rٗ=R"R@6@y% .-P"a]LSbb jT B@jB@@x@A$AjUEKjajV =j5O=j%-(%W@N@ n$( @"@BXBMB JY B@JBc@x@AAJZE/Je[=7Ճ@\ = {"]@k@ 2]L^b _ B@aBc@x@A$A`E€ba =jXǀ=j b@ŀ@,cJ&J d B@aRB@x@A AReE=~b aRf =R=FR%g@E@ $F @o{aDfhbb ji B@jB @x@A$AjjE9ajajk =jS==%pl@<@!j @ mBB Jn B@JB@x@AAJoEJJep=VÃw!^|5nq = )N{*"r@@c ?aBsb ct B@aB "@x@A$AuEѰb 5j^Jobv =jp`=j$j(fw@\o@,xJnJ >yy B@aRB@x@A ARzE'aRA@ A{ =@/=R"|@*@ #+bp+e" ZsB}bNb@&4j~ B@By @x@A$AjEe@Y jaj =j=j%p+c@P@~B倃 BuƁJB@x@AAJ @E@==qFw, =ؤ{% "@&@ `@+c Abb B@abB@x@A$AjErZab =j`=G@1² @@,cJYJ  B@aRB@x@A AREѠ@Y F E =R5ـ="@Ԁ@ $F @%3 "7|@BbӀb B@jB@x@A$AjEb jaj =j=j @揀@ !j @(AJBKBJ B@JB C&$X@x@AAJEHaJ Je=[F* =N{F% @I@, 7Ab)b c B@aB,@x@A$AEa b =j2Ā=j$j"@€@ m' @JJ (R B@aRB@x@A ARE!{aR   aR =Rς=F!R%@*~@ C 5Bb}b f B@jBc@x@A$AjE6j  G =j0:=j%pj+c@9@rB8B B@JBc@x@AAJE/   e=Fy ={% "@i@ $F @+c MAb ! b B@aB@x@A$AEb b =jm`="@Hl@,JkJA# B@aRB* @x@A ARE$a aR =Ri,=R"@'@  SP _b n"~FިBb7bA;j B@jB@x@A$AjEJ@Y jaj =j=( @2@~B  B$ , B@JB@x@AAJEћb Je=RF{ ={% @ @ ! @+c zZBbmb! b, B@aB@x@A$AEWWacb =j`=^+c@@,JVJA#Rc B@aRB@x@A AREeΠ@Y aR =Rր=R%@iр@ c89:QZp!u8@ybРb@%j B@jB@x@A$AjEb jaj =j|=j%-(+c@،@ $( @"@BB8B$B B@JB@x@AAJErEaJye=Fc =bK{"@F@ c Nmbbj! B@aB@x@A$AEacb =j ="@@,J쾠J F B@aRB@x@A ARExaR FaR ==R%@{@ sLu9TG!%䅻 Dfb~zb@&j B@jBz@x@A$AjE3jaj =j 7=(%-@j6@$B5B J$ ic B@JB@@x@AAJE e=| =@{% "@O@ ': @c fBb  B@`B@x@A$AEbb =!bj`=^%@!i@ m'%JhJ  B@aRB @x@A ARE!a aR =R?)=R"@$@ qTB9r abb½ B@jB @x@A$AjE/ݠ@Y jaj =j=(%-(+c@@$%{߀ J B@JB@U@x@AAJE  eI7F {@={%p"@@ , h!bYb .` `BV@x@A$AE! B@aRB| @x@A AR"Eta F((aR# =R|="$@w@ 䅯9 B%bcb@&'& B@jB{@x@A$Aj'Er0j))aj( =j3=%p(+c)@T@ r*B2 J+ B@JB@x@AAJ,E **e-=zF. ={%/@5@ ) @ hv/G?3A0bb b .`1aB@x@A$A2Ebc+,b3 =jg`=j 4@ f@,5JveJA7F6 B@aRB* @x@A AR7Ea --aR8 =R<&=R"9@!@ -09",B:bbo; B@jBJ@x@A$Aj<Eڀ2 j..aj= =j|݀=j >@܀@ ?B@B@ B@JB @x@AAJAE//eB=F*C =@{% :"D@ז@ ! @+c $FBEb6b ! b .`F`B@x@A$AGE!Qa01bH =jQ`=j I@@,JJ JA7K B@aRB@x@A ARLE/ȀF22aRM = π=FR"N@7ˀ@ cÿ,38c16ObʀbP B@Bc@x@A$AjQEb 33ajR =j==j S@@~$( @ .`CűT B$ByU B@JB@U@x@AAJVE 99el=_Fm ={% (n@@]L Aobzb! .`a paB@x@A$AqEdbc:;br =jd`="s@b@ '$ ! !% ARtJ_J u B@aRB@x@A ARvEra <>e=F = 5k{"@@ cA1Abb ! B@aB@x@A$AENa?@b =j/`=%p.@ @,J JA#Fc B@aRB@x@A ARE FAAaR =R̀=R%@ Ȁ@L6P|1Np!ɐaBbǀb j B@jBL6@x@A$AjEb jBBaj = "=(%-%@}@$B₀B$ .`B@@x@AAJE!<JCCe=Fn, =@B{% "@^=@; ?Ab  .`ac`B$X@x@A$AEDEb =jշa^%@6@ mcJJA7 B@aRB$X@x@A AREna FFFaR =R^v=R"@q@ o)'E (/<TBbb½ B@jB@x@A$AjE<*jGGaj =j-=(%-(%@#@$B, J B@JB@@x@AAJE HHe=HFy =@{% "@@ $F @ SAb_b ! b .``B@x@A$AEI`cIJb =!!na`=j$j%@_@ m!j @J=`=,? =@{% %@@Q@ ! @` Q.W AAb ! bB B@`B,@x@A$ACEV`hibD =j`="E@%@,FJJ G B@aRB@x@A ARHÈjjaRI =R<Հ= J@Ѐ@ c1 9u:)"taBKbb½L B@jB} ]L@x@A$AjME.b fkkajN =j=j%-(%O@@~$( @4@BPBr B$BQ B@JB@x@AAJREDaJ> JlleS=6WFT =J{% %U@E@ y) @` E !\AVbQb! b륱W B@aB@x@A$AXE;`cmnbY =jm="Z@ξ@ !j$c[J:JA#\ B@aRB@x@A AR]EIwaR ooaR^ =R~=R"_@Mz@ p` 8*  `byb½a B@jB@x@A$AjbE2ajF jppajc =jX6=(%-(%d@5@ eBBJ$ cf B@JB@x@AAJgEV Jqqeh=ۤFbi =B{% "j@@ y! @b& E+c  kb  bcl B@aB@x@A$AmEݩ`t rrbnj=^(fo@鬀@,pJUJA#q B@aRBy@x@A ARrEdeRssaRs =m=R"t@|h@ :"!_maDubgb jv B@jBy@x@A$AjwE jttajx =js$=j%-(%y@#@ n$( @"@BzB/B{ B@JB@,@x@AAJ|Eq܀ uue}=yy~ =@]{"@݀@ Ab b B@`B@x@A$AE!bvwb =j3X"`=j+""@V@,JUJA# B@aRB@x@A ARE#a xxaR =R=FR%@@ 19t@VBbib½ B@jB@x@A$AjEʀ jyyaj =@݀΀=%p%@v̀@$B̀BJ B@Bc@x@AAJE$zze=F@ ={*"@O@ ': @` c }Ab  bc B@aB 'Z @x@A$AEA%`{:#A& =j&`=j^%@0@,J  B@aRB@x@A ARE@Y: F}}aR =Rc="@@ +d -LtBb'b½ B@jB@x@A$AjE.t'b~~aj =jw= @ @$Brv JFJB@@x@AAJ @E/(Je=6B|ژ =5{% @0@ 5\ @` E6 >{BbTb b B@abB@x@A$AE;b =jc)a  @Ʃ@,J2J (F B@aRB@x@A AREIb*a aR =R j=R(o@ae@ * 7{|laeBbdb j B@jB oy@x@A$AjE+aj j&(o =jS!=j @ @~r) @(AJBB B@JBc@x@AAJEV Je=פFB =N߀{% @ڀ@t Ab ! c B@aB* @x@A$AEݔ,bcb =j U-`= @pS@,JRJ(R B@aRB@@x@A ARE .a $$F =R=R%@@ @` Ho"? n@|ybVbj B@jBژ@x@A$AjEqǀ jaj =jʀ=j%p(1@W@~Bɀ B$ y B@JB@x@AAJE/b Je=yF =숀{% "@1@  c |ybb! y B@aBc@x@A$AE~>0b =j.C="@A@,J@J c B@aRB,@x@A ARE aR =R1aR"@~ ?D%bDb}b½ B@jBx@x@A$AjE, j&' =j=(%-(%@p@ rBзBJ$  B@JB@x@AAJEq2bw Je=?w!^| = ) w{% "@Mr@ ! @` >Ab  b B@aBc@x@A$AE,3`b =j=^.@,@,cJJA#4` c B@aRBnb@x@A ARE4aR aR =RU=R"@@ D w 5 U&J27Bbbj B@jB3k@x@A$AjE-_5jaj =jb=j%-(%@ @$( @"@BBja B B@JB,@x@AAJE6Je`5-||@ = {"@@ AbPb ! B@aB,@x@A$A  E;ր ^b = >`=ڀ=j/"@?ـ@,JؠJ  B@B@x` =AR @`E‘7aR =Rb=FR%@”@ o @` o  ) 7 _ + C!,V-Bb.b@$g! B@a$BL6@x@A$Aj EHM8` aj =jP=j%p% @#@ n BOJ$ c B@JBc@x@AAJE9Je=פF ={F% "@ @ 8Abk b c B@aB#6(,@x@A$AEVĀ&.W =j:aj$j%@킀@,JYJ Fc B@aRB@x@A AREc;;a FaR =R C=FR"@g>@  #"% @<pba2zb=bf B@jBB@x@A$AjE jaj =j=%-%!@!@$"B J# B@JB@x@AAJ$EqRaR0 =!  1= 1@z,@ ) @` c3<eP @D2b+b4 3 B@jB o@x@A$Aj4E aj5 = =j 6@@ !j @"AJ7BMB8 B@B@x@AAJ9E?be:=n|; =|{% <@ơ@ ! @` DA=b,b ! bc> B@aB*" @'@x@A$A?E\@` b@ \`="A@_@@Sf'BJ^J JC B@A*Bc@x@A ARDEARaRE =@M=R(oF@@Ce#` ژGb b jH B@B @x@A$AjIE Ӏ ajJ =jր=(%p(+cK@Հ@ $$( @ťLB\B$BM B@JB@C!K@x@AAJNEBb JeO=FP =@{% "Q@㏀@ y$F @` E+c "ARbCb b륱S B@`B !@x@A$ATE-JC`ybU =jV D`=^"V@@ m!jWJ$J X B@aRB@x@A ARYE;@YA aRZ =RȀ=R"[@?Ā@ Sep8@ @B\bÀb½] B@jB@x@A$Aj^E|Eb jaj_ =jR=j%-(%`@@ aBBb B@JBy@x@AAJcEH8FJed=ɤFe =4>{"f@9@ B!%N` E4 Agb ! b h B@aBc@x@A$AiEbj =jGa j%p%k@^@,lJʱJA#(Rm B@aRB@x@A ARnEjHa FaRo =Rr=FR%p@m@! @` c+_EQ@[&BqbHbjr B@jB oc@x@A$AjsEc&I` jajt =j)= u@J@$vB(J$ w B@JB@x@AAJxE Jey=kFz ={% F"{@'@ W) @b& B+c B|bb by} B@aB "c@x@A$A~EqJ`b =j]K`=j$jK@[@,JcJ  B@aRBz9>Bh @x@A ARE~La !8 =R;="@@ s6 pBbbf B@jB @x@ =Aj @`E jaj =jӀ=%-+c@Ҁ@$BMB J B@aB@!K@x@AAJEMbye= Fvy =@{% %@͌@ b+b B@`B0 @x@A$AEGNa bjK=^%@J@ m'%5nJ~INFc B@aRB @x@A AREO RaR =G =!@@ y zu{luadDb b4j B@jBy@x@A$AjE 2 jaj =j=j @@ / @"AJBd B B@JBc@x@AAJEyPe=F/ ={F% @z@ W`@` c ;AbBb c B@aB< Z@x@A$AE-5Q`b =jP=j^"@@,JJ! B@aRB@x@A ARE;RaRFaR =Rݳ=FR(o@?@ |{|"\4alZBbb B@jB5n@x@A$AjEgSaj aj =jIk=j%p(+c@j@~BB B@JB@x@AAJEH#TJe=ɤF}c =4){% "@$@W @` E+c ȨAb ! b B@aB@x@A$AEހt b =jy="@@,JGJ  B@aRB@x@A AREUUb RaR =R=R"@^@ cld?p_ n a#Bbʜb$ B@jB o@x@A$AjEUVjaj =jdY=( @X@ B B, F B@JB@x@AAJEcWaJe=k߃, = À[{% @@ c yBbb  B@`Bc@x@A$AÈb =jXa^+c@x@,J䊠J  B@aRB@x@A ARECYa aR =RK=R%@F@$X ?p Wh0aBbGbf B@jB@x@A$AjE~ jaj =jZa(%-(+c@a@$BBJ)  B@JB@x@AAJE Je=̈́Fy ={% "@B@ * ': @a c Ab  b B@aB@x@A$AEv[`b =j6\`=j%@5@,J~4JA# B@aRB@x@A ARE aR =RJ="@@ c h03t t]zBbb j B@jB@x@A$AjE]b j] =j=j%-(%@@$( @"@BBt B B@JB@y@x@AAJEd^aJce='wF{ =@j{F% %@e@  AbFbj! 륱 B@`B !@x@A$AE- _acb =jB=j @ހ@,JJ aK aRB@x@A AR@> @:`aR FaR 6R=FR"@J@ _P1n`63t@: @Rajaj 6jIV=%p(%@U@ n BB J$ c B@@Bc@x@AAJ @> @HbJe @6 @ɤF 64{% "@@ ! @` c Ab ! bc B@@6ǠB@x@A$A@> @6ɀb 6jca j^(f@Y@,JŇJ@j B@@By@x@A AR@> @5\@da aR 6RH=R"@C@ yN`5тx\|zBbPb@j B@@By o@x@A$Aj@> @c@ jaj 6j=j%-(%@J@~$( @"@BB B$B B@@B@x@AAJ @> @ee!@6 @kʄFwc" 6ҽ{% "#@$@ c A$bb 륱% B@@B* @x@A$A&@> @psfb' 6jx=j (@xv@,)JuJ@ܣ>* B@@BQ@x@A AR+@> @.gRaR, 6R6=R"-@1@ }arQ@ho.bgb@%j/ B@@B,@x@A$Aj0@> @6 aj1 6j="2@k@ 3BB4 B@@B@x@AAJ5@> @he6@6 @ t|; 7 6{% 8@@@ , inW9b ^! : B@@Bc@x@A$A;@> @aib< 6 >  :f=j = 9@d@,>JJ F? B@@B@x@A AR@@> @jRaRA 6$=R%B@ @ |tk@)SHoCbb jD B@@B|c@x@A$AjE@> @ ajF 6j!܀=j*(+cG@|ۀ@0HBB$ I B@@B@x@AAJJ@> @keK@6 @'bL 6{:% "M@U@ m c ANb ! XFO B@@Bc@x@A$AP@> @OlaybQ 6jm`=j R@1@,SJ J@T B@@B@x@A ARU@> @ FaRV 6RY΀=FR"W@ɀ@ !$F @a   k@xXb'b jY B@@B@x@A$AjZ@> @82n`.aj[ 6jʅ=%-(%\@&@$]B J$ ^ B@@Bc@x@AAJ_@> @=oJe`@6 @BPFa 6C{% "b@>@ " @` wAcbab bd B@@B@x@A$Ae@> @Hbf 6jypa j$j3g@ڷ@,hJFJ@i B@@B@x@A ARj@> @Upqa aRk 6Rw="l@Ys@, #q l@Bmbrbon B@@By@x@A$Ajo@> @82+rjajp 6jT/=%-%q@.@$rBB Js B@@B@8@x@AAJt@> @b eu@6 @Fv 6@  S{% %w 9@@, j Axb ! y B@@B W!,@x@A$Az@> @sbcb{ 6)ct`=j |@pa@ m, @}J`J@c~ B@@B@x@A AR@> @6ua aR 6R!=R"@@ 3 nEhqB"Q}Bbsb B@@B@x@A$Aj@> @} jaj 6jـ= @b؀@ ) @(AJB׀B J$Bc B@@B@$@x@AAJ@> @ve@6 @F|c 6@  {%  9@?@ O! @` c Ab ! bc B@@6ǠB@x@A$A@> @Lw`cb 6 >   x`=%pj" 9@ @ mJ J  `R-_ B@@B@x@A AR@> @5\ FaR 6Nˀ=R%@ƀ@ cC`76Ô6@@xbb jc B@@B$X@x@A$Aj@> @yb jaj 6j=j%-+c@@~$( @r"@BBWB B B@@B@x@AAJ@> @:zJe@6 @'MF 6@{% "@;@ c uxbBb ! 륱 B@@By@x@A$A@> @,cb 6j_{a"@@,J+J@g B@@Bc@x@A AR@> @5\m|a FaR 6Rt= @Np@ $F @` oS9P~0~ۏ @Dfbobĩ B@@B !@x@A$Aj@> @(}` jaj 6j=,=j%p(%@+@ !j @ťB*B$B B@@B@x@AAJ@> @G Je@6 @ȤF$X 6D{F% %@@ @! @b& (Ab ! b륱 B@@B@x@A$A@> @Ο~`t b 6jd=j$@j @3kc@Ƣ@,J2J@n B@@B$X@x@A AR@> @6[RaR 6A  c=R" 9@M^@ !d"!` c`ү"v?@4b]b j B@@B@x@A$Aj@> @6`aj 6)d="@@~!jnB B$B B@@B@x@AAJ@> @bҀe@6 @j$X 6 >  b؀{% F" 9@Ӏ@ / @b& B6 14Ebb ! b B@@B@x@A$A@> @6`  b 6)N`=^"@tL@,JKJ >c B@@B@x@A AR@> @aaR 6 >   =R" 9@@ cs*? WybBb{b  B@@B@x@A$Aj@> @6jaj 6)Ā=(%-(+c@`À@ B€B $  B@@B@x@AAJ@> @|e@6 @F$X 6 >  {% " 9@E}@$X  Ab , B@@B@x@A$A@> @7ab 6)=j)j%@@,J}J@ܦ{ B@@BzFB@@x@A AR@> @6aRA@ A 6@  I=" 9@@ o$F!` Ho"QёaBb bj B@@B@x@A$Aj@> @6j` jaj 6 >  m=%-% 9@@$BclJ B@@B@x@AAJ@> @%aJ J@=@6 @+8|vy 6G+{% %@&@ dAbBb B@@B 4  @'@x@A$Aj@ @6b 6jQaj$j%@@,JJ@nc B@@B@x@A AR@> @6Xa aR 6R_="@:[@ , @&QBZb½ B@ B* @x@A$AjEj G =jM=j @@ ' @"AJB B B@JBB@x@AAJEGπ e=ȤF$X =7Հ{F% F% @Ѐ@ @b& A b ! bc B@aB,@x@A$A EΊ`b =jz= @ڍ@,JFJA# B@aRBy@x@A AREUFaR   aR =RM=R"@MI@ c a K_Ea bHb j B@jB,@x@A$AjEaj j  aj =jc=j%p(+c@@~BB$  B@JBc@x@AAJEb J  e=j = ÀVÀ{% "@@ v b ! ! B@`Bc@x@A$A"Exb  b# =j 9`="$@7@,%J6J(Rc& B@aRB@x@A AR'E aR( = = )@@$X * $X*bfb@&+ B@B]L@x@A$Aj,E}b jaj- =j=j%-(%.@Z@~r/B B$ 0 B@JB@x@AAJ1EgJ >2=yF,3 =l{% %4@?h@$X G$X5b ! 6 B@aB@x@A$Aj7E"ab8 = `="9@ @,:JyJ F; B@B* @x@A AR<EaR FaR= =R?=R">@@ c _EasD?bb½@ B@jBc@x@A$AjAEUaj jajB =jX=(%-(%C@W@ DBOB$ E B@JB@x@AAJFEaJ JeG=*#|yH ={% "I@@ c AJbAb! K B@aBc@x@A$ALE,̀ bM =jЀ=j3N@<π@,OJΠJ P B@aRB@x@A ARQEbaRR =RP=R"S@@ \_ |aBTbb jU B@jB@x@A$AjVE:CajajW =jF=j%-(%X@@~YBzE B$ Z B@JB@x@AAJ[E e\=ȤF] = Àa:% "^@ y! @`_ A_b\b! b` B@`B@x@A$AaEG,cbb =jpza j c@x@,dJ>J e B@aRB@x@A ARfET1a aRg =R9=FR"h@]4@ yֿK_EavBib3b½j B@jB@x@A$AjkE jajl =jW=%-(%m@@ n$( @(@BnBB J$Bo B@JB@@x@AAJpEbeq=Fyr =@N{% "s@@ y ^Atb ! 륱u B@`B@x@A$AvEca bw =j$`=j^"x@s"@,yJ!JA#cz B@aRB@x@A AR{E F!!aR| =R="}@ހ@ ; AajB~br݀b j B@jB@x@A$AjE}b j""aj =j=%-(%@a@$BŘB c B@JB@@x@AAJERJ##e=dFs =@W{%@>S@ ': @` c tAb  B@`B,@x@A$AE `c$%b = `̀=j @ ̀@ m' @* JyˠJ  B@B@x@A AREaR F&&aR =RE=R"@@ /*a@Bb bf B@jB@x@A$AjE@j''aj = C=%-@B@ $( @n(AJB^B$B B@B@@x@AAJE ((e=&|| =@a%p"@ nb$F @`_ E AbAb ! bc B@`B@x@A$AE,,c)*b =^wa %pj"@u@ m!j @J+J  B@aRB@x@A ARE9.a ++aR =R5=!R"@91@, hqB"\}hJBb0bA;# B@jBF@x@A$AjE j,,aj =jP=j%-j+c@@ B B$ c B@JB@x@AAJEG--e=ȤF =+{% "@}@, uAb ȥ!  B@aB |- B@x@A$AE`ac./b =j `="@L@,JJ F B@aRBc@x@A ARE F00aR =R߀= @ڀ@ c#9Q/>ttaKBbOb j B@jB,@x@A$AjEbb j11aj =jږ=j%-(%@6@~B B$  B@JB@x@AAJENJ22e=jaF =T{F% %@#P@, ;AbOb  B@aBy@x@A$AEo a34b =jʀ=j^+c@ɀ@,JnȠJ  B@aRB@x@A ARE}aR F55aR =R/=R"@@o!` N!(o3t\9<@Bbbĩ B@jB /@x@A$AjE=` j66aj =j@="@?@~BCB B@JCB !Ky@x@AAJE J77e= |x =@{% @@ y! @b& _YBb&b ! b B@`B@x@A$AE`88b =j=^%@ @ mJyJ  B@aRB* @x@A AREoaR 99aR =RDw=R%@r@ cCl@KӐ:Bbb$ B@jBt@x@A$AjE+j::aj =j.=(*(+c@-@ $( @"@BB^B $Bc B@JBc@x@AAJE ;;e=F ={% "@@ $F @b& E cAbAbǝ! bc B@aB 'Z@x@A$AE,`<=b =j\b`=j)j"@`@,J*J  B@aRB@x@A ARE9a>>aR =R ="@I@ SK` sP<0y-Bbb jc B@jB* @x@A$AjEԀj??aj =jL؀=%-%@׀@$B B J$ y B@JB@$c@x@AAJEGb @@e=ȤFzc =@[{% %@@ y': @` E.W wb  B@`Bc@x 9A$A @EK`ABb = ?`= `=j @T @ m' @y J J  B@B@x@A ARE€FCCaR = ʀ="@ŀ@ cې;`&6s &5nb_b j B@B o@x@A$AjEa~b fDDaj =j⁀=j%-(%@A@$( @n(@BB B B@JB@@x@AAJE9aJEEe=iLF{ =@?{F%p%@*;@ c 5nb:bj! c B@`Bc@x@A$AEocFGb =aj%pj" @@,!JbJ " B@aRB@x@A AR#E|la FHHaR$ =R1t=R"%@o@ s6sޚDf&bnb½' B@jB@x@A$Aj(E(jIIaj) =jw+=j%p%*@*@ +B3B$ c, B@JB@x@AAJ-E JJe.= F/ =z{% "0@@ c zhA1b&b ! y2 B@aB @x@A$A3EbKLb4 = `2_`= 5@]@,6J\J 7 B@B@x@A AR8Ea MMaR9 =R=R":@*@@  =@Հ=j%-(%?@tԀ@ @BB$ A B@B@x@AAJBE+OOeC=FD = {% "E@e@ y/ @` Q6 _5nFb ! bG B@aB .X@x@A$AHEH`PQbI = ```="J@A@,KJJ L B@B@x@A ARME FRRaRN = iǀ= O@€@ L1,lL6Pb0b jcQ B@BB@x@A$AjREF{b jSSajS =j~=j%-(%T@"@~UB} B$ V B@JB@\$@x@AAJWE6JTTeX=NIF,Y =@<{% %Z@8@ ! @` E( A[bi7b b\ B@`Bc@x@A$A]ET UUb^ =j="_@X@ m'$`JJ a B@aRBژ@x@A ARbEۭbVVaRc =R=R"d@װ@ cL6q ebCbĩf B@jBW@x@A$AjgEaiaj WWajh =jl=(%-(%i@;@ $( @4@BjBkJk B@JBc@x@AAJlE$JXXem=F; n =*{% "o@$&@ W$F @` E+c qSApb%b b륱q B@aBc@x@A$ArEoYZbs =ja ^"t@@@Sf!juJZJA#Jv B@aRB@x@A ARwE|Wa F[[aRx =@(_=R"y@Z@$X L60tBzbYbf{ B@B y@x@A$Aj|Ej\\aj} =js=(%p(%~@@ rB7B J B@JB@!Kc@x@AAJE ]]e= Fuy =@zԀ{% "@π@ SAb&b ! B@`Bc@x@A$AE^^b =j=j%pj%@@@SmJ|JA#J B@aRBB@x@ =AR @`EEaRu__aR =@`=PM=R"@H@ c 0Ӕ_P91$`̠Bbb j B@B@x@A$AjEaj f``aj =j=j @ @ Bj$  B@JBc@x@AAJE Jaae=F =€{% F"@߽@ $F @b& c BbAb b B@aB@x@A$AE+x`bcb =jY8`=%@6@,J&JA# B@aRB@x@A ARE9@Y ddaR =R="@E@ co`'$/+an`,ƱBbb½ B@jB@x@A$AjEb jeeaj =jL=%-(+c@@~BB B@JB@x@AAJEFfJffe=ǤF|c =6l{% "@g@ ! @` E.W bCAb ! b B@aBc@x@A$AE!`ghb =j=^%@X@,JߠJA#(Rc B@aRB@x@A AREژaR FiiaR =R=R"@⛀@ ,$?o`kpepa :BbNbj B@jB$X@x@A$AjEaTajjjaj =jW=j @I@ $( @"AJBV B$Bc B@JB@x@AAJEaJ kke=i"| ={% @"@ W c Abb! c B@aB@x@A$AEnˀclmb =ja"@@,JaJA# B@aRB@x@A ARE|Ba nnaR =R&J= @E@ e`P Kf$XbDb½ B@jB~@x@A$AjE jooaj =jaj%-(+c@@ BKB$  B@JB@x@AAJE Jppe=̄F, =z{F% (@ĺ@ ! @a c V!b%b ! b B@aB@x@A$AEu`qrb =j+5`=j^K@3@,J2JA# B@aRB@x@A ARE쀈 ssaR =R=R"@.@ |`%qbb j B@jB}@x@A$AjEb jttaj =j0="@@ƹ$(n"EB쩀BB$B B@JB@x@AAJE+cJuue=F =i{% @fd@ c qb  B@aB@x@A$AEavwb =jހ=^"@5݀@,,JܠJA# B@aRB@x@A AREaR FxxaR =Rr=R%@Ϙ@ `l Q`Nb;b½ B@jBc@x@A$AjEFQjyyaj =jT=(%-(+c@3@ rBS J B@JB@x@AAJE Jzze  N| ={% "@@ l6bi b  B@a$B@x` =A @ESȀc{|b =ja^%@ކ@@Sf'+> ! $ C>JJJ J B@a B]L@x@A AR Ea?a }}aR =@ G=R" @iB@B #Fhqa+Aj bAb B@B@x@A$AjEc~~aj =jt=( @@$B0B B@JB@x@AAJEnbe=F =c{% @@$X Bbb !  B@aB@x@A$AEqab =j2`=%pj%@x0@,J/JA# B@aRB@x@A ARE aR =R=R%!@@ 3B"K^d?` n@"b{b c# B@jBy@x@A$Aj$Eb jaj% =j= &@w@ c'BզB$ ( B@JB@x@AAJ)E`Je*=rFq+ =f{% F",@La@ ! @` E-b  b. B@aB @x@A$A/E`b0 =jۀ=j^%1@ ڀ@,2Jy٠J 3 B@aRB; @x@A AR4EaR FaR5 =RL="6@@ C`zqBE %s)B7bb½8 B@jBB@x@A$Aj9E+Njaj: =jQ=%-(1;@ @$<BgP J= B@JB@x@AAJ>E aJ e?=3|}@ ={% %A@ @ / @` E+c ABbNb! b C B@aBc@x@A$ADE8ŀcbE =j`a j F@Ã@,GJ/J cH B@aRB@x@A ARIEFb½M B@B o@x@A$AjNE jAO =jQ= P@@ ) @(AJQBBBcR B@JB@!K@x@AAJSESeT=ԤF; U =@G{% V@@ c AWb X B@`B !* @x@A$AYEnacbZ =j/`= [@e-@,\J,J ] B@aRB@x@A AR^E FaR_ =R=R%`@@ @a Ho%cn+\?g@]ab_b jb B@jB @x@A$AjcEn` jajd =j=j%-(+ce@L@~fB B$ g B@JBc@x@AAJhE\Jei=voFj =b{ k@1^@c lb]b m B@aB@x@A$AnE|abo =j؀="p@׀@,qJr֠JA#jr B@aRBc@x@A ARsEaR FaRt =RI=%pF%u@@ sEqBaDvbbĩw B@jBژ@x@A$AjxEKjajy =jN=j%-j%z@M@ {B\B| B@JB@x@AAJ}EJe~=| = À {F% "@@ ! @` Ab2b ! b B@`B* @x@A$AE€@b =jFa j^.@@,JJ  B@aRB@x@A > E+9a aR =R@=R"@3<@ y1N`3da,b;b j B@jBQ@x@A$AjEaj =j=="@@ƹ$(%"DBB J$Bc B@JB@x@AAJE8b e=„F~ =,{% @u@ 5n 2b ! c B@aB@x@A$$^Ekab =j+`=^"@F*@,J)J >c B@aRB@x@A ARE aR =Ra=R%@@h `䐃, a7VDfb,b  B@jBɂ@x@A$AjESb faj = ߡ=(%-(+c@:@ rB , B@B@x@AAJEYJe=[lFc =_{% "@[@ @` c AbvZb b B@aB 4 @x@A$AE``c9 =jՀ=^%@Ӏ@,JWJ F B@aRB$X@x@A AREnaR FaR =R=R"@v@ c-l`aӋBb⎀bf B@jB*@x@A$AjEG2 2 jaj =jqK=(%-(%@J@~B-B J ` B@JB@x@AAJE{aJ Je=FF =p {% "@@ y c wyAbb!  B@aB@x@A$AEb =ja @}@,J|J  B@aRB@x@A ARE6a aR =R==R"@9@ $F @fO o%|Np]Lybp8b½ B@jBy@x@A$.!E jaj =j"= @~@ !j @(DBBJ$B B@JB@x@AAJEb Je=F ={% `3b@W@ 5n! @%yb  b륱 B@aBy@x@A$AEhayb =j(`=j$j"@/'@ ' @J&JrR B@aRB{ @x@A ARE aR =Rg="@@ zy `Dfb%b j B@jB; @x@A$AjE8b jaj =jĞ=%-+c@ @$Bµ B@JB@x@AAJEVaJ Je=@iF = À\{% (@W@ $F @ 9Ab[b b B@`B@x@A$AEE ab =joҀ=j%pj%@Ѐ@,cJAb 'Z bc  aB@x@A$AE绀b =j | a @jz@,JyJA" B@aRB@x@A ARE2a aR =R:=R"@5@ y,Kea BB bhbA;j B@jB*@x@A$Aj E{@Y jaj =j=j%-(+c @W@~$( @ťB B$B B@JBc@x@AAJEe=F*  =ꯀ{% "@=@ c  rAb ! 륱 B@aBV@x@A$AEeab =j%`="@$@,J#JA#R B@aRBc@x@A ARE FaR =R<= @߀@ c] ^U_a@bb j B@jB* @x@A$Aj Ebcaj! =j=j%-(%"@@ #B]B$ y$ B@JB@x@AAJ%ESaJ e&=%fFc' =Y{% %(@T@ ! @c ?@)b?b^! bXF* B@aBc@x@A$A+E*acb, =jMπ="-@̀@,.JJA#/ B@aRB@x@A AR0E8aR aR1 =Rꍀ=R"2@D@,%%` "xED3bb½4 B@jB@x@A$Aj5EAjaj6 =j?E=j%-(%7@D@ $( @ūc8BCB$B9 B@JB@x@AAJ:EE e;=ƤF@< ==a"=@h >b ! ? B@aB@x@A$A@E̸,cbA =xaj"B@[w@,CJvJ cD B@aRB@x@A AREE/aaRF =R7=R%G@2@o!oqBqB}|l?"l1$HbQb I B@jB o Ǝ@x@A$AjJE` fajK =j=(%-L@E@ rMB퀃 N B@JB@x@AAJOEb JeP=hFQ =笀{% "R@"@ ! @BSbb bcT B@aB " @x@A$AUEmbacbV =j"`=^%W@ @,XJXJ cY B@aRB5n@x@A ARZE{٠@Y aR[ =R&=R"\@܀@ c#pA17@B]bۀb½^ B@jB @x@A$Aj_Eb; aj` =j=(%-(&a@뗀@$bBJB J) c B@JB@x@AAJdEPaJ ee= cFf =yV{% "g@Q@ =Ahb$b! i B@aBy@x@A$AjE abk =jJ̀=)j%l@ʀ@,mJJA#(Rcn B@aRB@x@A >oE aR aRp =RЊ=R"q@-@3\D}a8Brbbjs B@jB@x@A$AjtE>!aj jaju =j+B=%-%v@A@ ) @"@BwB@BJ$Bx B@JB@x@AAJyE* Jez=F5n{ ="a% "|@fc A}b  륱~ B@aB@x@A$AE,1 b =jS=j^"@@,J!J  B@aRB,@x@A ARE7q#b RaR =Rx=R"@Ht@ C"ET%"x\|eFBbsb  B@jB@x@A$AjE,$jaj =jJ0=j%-(%@/@BB B@JB@x@AAJEE e=Mh =-{% "@{@ c Ab ! B@aB W.X@x@A$AẸ%bb =jd&`=%@bb@,JaJ B@aRB@x@A ARE'a aR =R"="@@BS}-~abYb½ B@jBB@x@A$AjE`ր jaj =jـ=j @C@~B؀ B$  B@JB@x@AAJE(b Je=hF{ =ۗ{% @!@ B! @ qbb! b B@aB@x@A$AEmM)aBb =j *`="@ @,JXJ c B@aRB@x@A ARE{Ġ@Y aR =R̀= @sǀ@ ! @ c4+m;  RHobƀb½ B@jB,@x@A$AjE+baj =j=%-(+c@ႀ@ $( @(@BBFBB B@JB@٢o)B@x@AAJE;,aJ e= NFy =@xA{% c@<@ Ab$be B@`B@x@A$AEcb =j5-a$j"@@,JJ  B@aRB@x@A AREn.a aR =Ru=R"@$q@ cs1Ӑ5v",?Bbpb½ B@jBc@x@A$AjE)/jaj =j#-=(%-%@,@ B+B$  B@JBc@x@AAJE*倈e=Fc ={ @h@ ! @ 5Abʡ ! bc B@aB@x@A$AE0bb =j`1`=^%@C_@,J^JA# B@aRB@x@A ARE2a aR =Rh=R%@@ c {"E1nb5Bb.b B@jBc@x@A$AjEEӀ jaj =jր=(%-@%@ $( @"AJBՀJ$B B@JB@x@AAJEˎ3e=MF ={% "@@ Abgb 륱 B@aB@x@A$AERJ4a,b =} 5`=j c@@,JIJ B@aRB@x@A ARE` FaR =Rɀ=R"@dĀ@ yN"45:sBbÀb jc B@jBnb@x@A$AjE|6b jaj =jv="@@nB2BB B@JB@x@AAJEm87Je=F =a>{% @9@ c Jb b B@aB@x@A$AEcb =j"8aj @@@S= @/ @7aﱠJ J B@B@x@A AREk9a FaR@r=" ~@n@ E6AEbmbf B@jB@x@A$AjE&:jaj =)*=*(1 @m)@ r B(B J B@JB@C@x@AAJ E e =F =@{% (@J@ $F @ ;Ab ! b  B@`B@x@A$AE;bcb =j]<`=j%pj.@(\@ m!j @ .` nb [J ( B@aRB @x@A ARE=a aR =j="@@Q7$>8Vg3$b'b½ B@jB@x@A$AjE*Ѐ2 jaj =jӀ= @@~BnҀ J$ , B@JBc@x@AAJ!E>e"=1F # ={% F%$@쌀@; B%bLb & B@aBQ@x@A$A'E7G?a,b( =jr@`=%pj%)@@,*J>JA#j+ B@aRB@x@A AR,EDaR- =Rŀ=R".@I@ $9%aeB/bb 0 B@jB@x@A$Aj1EyAbjaj2 =jS}=j%-&3@|@ 4BB 5 B@JB@x@AAJ6ER5BaJ @=7=פF8 =J;{% "9@6@F A:b ǝ! ; B@aBL6@x@A$Aj<EA= =jCa >@W@,?JîJA#@ B@aRB@x@A ARAEgDa aRB =Ro=R"C@j@ K["u4ј:%aBDbZb½E B@jBW@x@A$AjFEm#EjajG =j&=j H@R@ IB% B$ cJ B@JB@x@AAJKEހ} eL=uFM ={% N@0@ ! @+c BOb߀b! bcP B@aB @x@A$AQEzFbbR =jZG`="S@X@,TJiJ U B@aRBh@x@A ARVEHaaRW =R;= X@@ ;% <  a BYbb jZ B@jB@x@W =Aj[ @`È f  aj\ = {=Ѐ=%-(+c]@π@~$( @.`@B^BKBB_ B@aB@@x@AAJ`EIb J  ea=F`=vBb =@{% (c@щ@ y5\ @+c (Adb1be B@`B@x@A$AfEDJajc  bg =jDK`=^"h@@,iJJ j B@aRB@x@A ARkE)  aRl =R€=R"m@9@ E=% %> X2jnbb jo B@jB@x@A$AjpEvLbjajq =jDz=(%-(%r@y@ sBB$ t B@JB@@x@AAJuE72MaJ ev=Fzw =@/8{%p"x@s3@ ! @+c yb z B@`B5n@x@A$A{Eb| =jڭNa^%}@<@ m'% .`DFy~ J@/ B@aRBb@x@A AREdOa aR =l=R"@g@BE?% %@  DbGb½ B@jB@x@A$AjER Pjaj =j#=(%-(%@<@@r$( @n"@BB" J B@JB@x@AAJE e=ZMay ={%p"@݀@ $F @ nAbt܀b b B@aB@x@A$AE_Qajb =jWR`=^"@U@@S!jJbJA#J B@aRB@x@A AREmSa aR =@=R"@u@cEA%%B `Bbb j B@B@x@A$AjE jaj =jẁ=(%p @3A@̀@ƹB3B J B@JB@x@AAJEzTb Je=Fz =ATn{% "@@ ! @  "Abb! b B@`B@x@A$AEAUacb =j&V`=^%@~,JJ > B@aRB@x@A ARE aR =R=R"@@ #EC%@D z`bBbzb½ B@jBژ@x@A$AjEsWb jaj =jw=( @tv@ r$( @J "AJBuBJ$B B@JB@@x@AAJE/XJ@==F =@5{% @Y0@ ژb  c B@`B@x@A$AjEc b =j۪Yaj+"j"@=@ mcJJ  B@aRB$X@x@A AREaZa\!!aR =Rei="@d@ 3EE%F p5Dfb(b j B@jB@x@ =Aj @`E7[aj@ ""aj =j =%-1@@$B J B@aB@١K@x@AAJE J##e=BF =@ހ{% (@ـ@ ': @c AbYb b B@`B@x@A$AED\b$%b =juT]`= @R@ mJCJ  B@aRB@x@A ARER ^a &&aR =R =R"@^@BC% GS"S""1aBb b# B@jBnb@x@A$AjEƀ''aj =jhʀ= @ɀ@ $( @(AJB$B  B@JB@@x@AAJE__b ((e=F =@S{% @@c BxAb ! c B@`B@x@A$AE=`a)*b =j=j^"@y@@SmJJ J B@aRB@x@A AREaaR++aR =@=R%@緀@ cS,"Q"BbSb½ B@B* @x@A$AjEzpbj,,aj =j t=j%p`3A@es@ BrB$  B@JB@x@AAJE,caJ> --e=>| =1{% "@;-@ c eAb !  B@aB@x@A$AEc./b =jda%@@,cJfJA# B@aRB@x@A ARE^ea 00aR =RVf="@a@ ,c}|n"@?" Rbbb½ B@jB5n@x@A$AjEfajf11aj =j=%-(1@@ B`BJ$  B@JB c@x@AAJE 22e =#F$X =@ۀ{% " @ր@ , coA b>b !  B@`B@x@A$AE)gb34b =jSQh`=^%@O@,J JA#c B@aRB@x@A ARE6ia 55aR = =R"@C @ su6+g" 6]Bb b f B@B@x@A$AjEÀj66aj =jIǀ=j%-(%@ƀ@~nBB$  B@JBc@x@AAJEDj77e=ŤF/ =<{% " @~@ ! @ A!b ! b" B@aB@x 9A$A# @E:ka89b$ = ?`=="%@A@,&JJ ' B@B/@x@A AR(EرlaR ::aR) =R=R"*@䴀@ 7]F"qB\l+bPb½, B@jB@x@A$Aj-E_mmj;;aj. =jp=(%-(%/@?@ $( @(@B0Bo J$B1 B@JB@x@AAJ2E(nJ<b9 =joa^":@뢀@,;JWJA#c< B@aRB@x@A AR=Ez[pa@Y ??aR> =R(c=R"?@^@y 8"8%\bDf@b]b A B@jBy 7b@x@A$AjBEqaj j@@ajC =j=j%-(%D@@ EB@BJ$ cF B@JB !KL6@x@C =AJG @EҀ JAAeH=FcI =@{s؀{"J@Ӏ@%N *^AKb#b bcL B@`B@x@A$AMErBBbN =j=j%O@ @,PJvJA#Q B@aRB P 5@A ARR @`EIsaR CCaRS =RMQ=FR%T@L@ y"1Ӫ-t`̠QBUbb jcV B@a$BB@x@A$AjWEtaj jDDajX =j=%-Y@@ZB_BB[ B@JB@x@AAJ\E JEEe]=F]L^ =ƀ{% "_@@, ]B`b>b a B@aB@x@A$AbE)|ubFGbc =jYE@YA WWaR =R=%p@'@ c"T333TB9"3@pbbbĩ B@jBW@x@A$AjEb jXXaj =j&=j%pj%@@~$( @ťBB$By B@JB@x@AAJE)gaJYYe=F =m{% %@bh@ $F @+c hbɡ ! b륱 B@aBt@x@A$AE"acZ[b =j=G@² "@:@,JJ  B@aRB@x@A AREaR,\\aR =Rz=R"@՜@ `ӔPaDbAb j B@jB@x@A$AjECUaj ]]aj =jX=j%-(%@'@ BW B$ , B@JB@),@x@AAJEJ^^e=O#| =@{"@@ !%N.W Abfbj! b, B@`By@x@A$AEQ̀c_`b =ja%@䊀@,JPJA# B@aRB@x@A ARE^Ca FaaaR =RK=R%@bF@ @<aNbEb@$j B@jB@x@A$AjE jbbaj =!bia(%-@@ n$( @"DB)B J$B B@JB@@x@AAJEl Jcce=Fo =@T{% "@@ m c >6bb B@`Bc@x@A$AEubdeb =j6`=^"@e4@ m!j%J3J  B@aRB{ B @x@A ARE ffaR =R=R"@@o!RoÔ%"0}@*[bdb j B@jB@x@A$AjEb jggA =j=(%-(!@g@$BǪB  B@JB@@x@AAJE dJhhe=vF =@j{ @He@ * ': @/Ab  bc B@`B,@x@A$AEaijb =j߀=$%@#ހ@ mJݠJA# B@aRB@x@A AREaR FkkaR =RL=R%@@ " @#aҐq0C#"a.Bbb j B@jBc@x@A$AjE(Raj jllaj U=%-%@@!j @"@BBpTBc B@B`x@9 AJ @E Jmme=0 |B ={% "@@ $F @+c AbKb b륱 B@abB@x@A$A E6ɀcnob =jXaj$j" @@, J%J > B@aRB@x@A AREC@appaR =RG="@OC@ c 3"0"@"z`BbBb  B@jBh@x@A$AjE qqaj =jZa%p%@@ rBB JaIJB@x@AAJEQa  Jrre=ҤF =M{% %@@ c Ab Z 6! B@bBh@x@A$AEracstb =j2`=j !@^1@,"J0J c# B@aRBb@x@A AR$E逈uuaR% =R=R"&@@ cC0G1 `HB'b]b j( B@jBt@x@A$Aj)Elbvvaj* =j=j +@T@ ,B B- B@JB@@x@AAJ.E`aJ wwe/=wsFQ0 =@f{% 1@.b@ c iB2bab3 B@`B @x@A$A4Eyaxyb5 =j܀=j 6@ۀ@ m, @7JpڠJA#c8 B@aRBc@x@A AR9EaRy zzaR: =RA=F!;@@ $F @!6S}}B<bb½= B@jB $X@x@A$Aj>E Oaj j{{aj? =jR=j @@Q@~!j @w.`AJABYBB B@JB@!K,@x@AAJCE J||eD=`=hE =@{ F@ @ ?iAGb0b ! cH B@`Bc@x@A$AIEƀ }~bJ =jZa"K@@@SmLJ&JA#JM B@aRB@x@A ARNE(=acaRO =@D=%pP@0@@Ex$F @c+[ Q0aBQb?b R B@B$X@x@A$AjSEjajT =j?=j%pj1U@@ !j @ťVBB$ByW B@JB@x@AAJXE6b> eY=F,Z ="{% .W[@m@ 6$F @ 7A\b ǝ! b륱] B@aB@x@A$A^Eoab_ =j/`="`@K.@ !j$^caJ-J b B@aRB@x@A ARcE aRd =R=R"e@@ s} +d ulum&BfbJb jg B@jB~c@x@A$AjhEPbaji =jݥ=j(%j@:@kB B$  l B@JB @x@AAJmE]Jen=XpFo =c{"p@_@ !%N+c ~Aqbw^b ! b,r B@aB - @x@A$AsE^abt =j~ـ=%p(fu@׀@,vJMJ w B@aRBx @xu 9A ARx @`EkaR aRy =R'=R%z@@c unuoupu}l{ `̠_B{b뒀bĩ| B@a$Bc@x@A$Aj}EKjaj~ = jO=(%-%@N@ n$( @"@BB.B J$B B@B@$ @'@x@AAJEyJe=Fuc =@@i {% "@@ m) @+c 8Abb b륱 B@`B@x@A$AEÀ,b =j,a^"@@,JJA#c B@aRB$X@x@A ARE :a aR =RA=R"@=@ BDTݐpD{a Bb e=FB =m{% "@@  c 5Abb ! B@aBc@x@A$AEbb =jn`="@~l@,cJkJ  B@aRBc@x@A ARE %a aR =R,= @(@ 9Ґ"+cpc@Bb'b B@jB @x@A$AjEfaj =j=j @x@ BBJ$  B@JB@x@AAJEe=F ={% @U@ ! @W Zb  b B@aBc@x@A$AEWab =j`="@0@,JJA# B@aRB@x@A ARE aR =R]ր=R(o@р@ ]}3aZEbb fc B@jBc@x@A$AjE5b jaj =j=(%-(+c@@ $( @.`@BByB B@JB@y@x@AAJ  EEJe==XFh =@{K{% "@F@ B c yAbXb 륱 B@`BB@x@A$AECaBb =j~=^"@ݿ@ m!j*Qy JIJA# `JR- B@aRB @x@A AR EPxaR FaR =R=R" @X{@ U>%+i-lBbzbf B@jB @x@A$AjE3aj.aj =j_7=(%-(%@6@$BB Jc B@JB @x@AAJE^ e=F =@N{% "@@ 7Ab ! ^ B@`B,@x@A$AEbBb =jk`=^%@wi@ mJhJA# B@aRB@x@A AR E!a aR! =R)=R""@$@c ґ0}<1/*#bbb½$ B@jB@x@A$Aj%Ex݀ jaj& =j=j '@^@$(BB$ g) B@JBB@x@AAJ*Ee+=F, = À{"-@7@, .bbj! / B@`B WB@x@A$A0ETb1 =j$Y=j+"%2@W@,3JVJ 4 B@aRBy@x@A AR5E aR FaR6 =R=R%7@@* .1}}?a?w*[8bb j9 B@jB@x@A$Aj:E jaj; =jπ=j%-!<@w΀@=B̀B J$ > B@JB@x@AAJ?Eb J@=@="U|,A = {% "B@X@ y! @1#  ACb ! bD B@aBc@x@A$AjEEBa,bF =j`=j G@(@,HJJ >cI B@aRB@x@A ARJEaRK =Rg=R"L@@ #‘0u *uaBMb&b½N B@jB@x@A$AjOE5ubjajP =jx=j%-(%Q@$@ $( @(@BRBw B$BcS B@JB@x@AAJTE0aJ eU==CFV =6{% "W@1@ c Y2AXbXb! 륱Y B@aB@x@A$AZEByb[ =jhaW \@ɪ@,]J5JA#^ B@aRB@x@A AR_EPca aR` =Rj=H  S;"a@Xf@3, 0}r1}D@z$bbeb@%c B@jB@@x@A$AjdEaj jaje =jg"=j%-(!f@!@ gB#B$ h B@JB@x@AAJiE] Jej=Fk =n{F% "l@ۀ@ @c  Amb!b ! bcn B@aBL6@x@A$AoEbbp =jV`=j q@gT@,rJSJA#cs B@aRB@x@A ARtE a aRu =R=FR"v@@ ! @C+\ 0TґUajBwbjb x B@jBx@x@A$AjyExȠ@Y jajz =jˀ=j%-(%{@T@r|Bʀ B$ } B@JB@x@AAJ~Ee=F| ={% "@9@ W; @6 Abb b B@aBc@x@A$AE?a,b =j="@@@S(!j$^,JJ R `JR, B@aRB@x@A AREaR FaR = E=R"@@ S1tF,Ô [PBb b B@B@x@A$AjErajaj =ju=(%-(%@@ Bbt J B@JB@x@AAJE-aJBe="@| =3{% "@.@ AbAb ! ^ B@aB @x@A$AE'cb =jVa^3@@,cJ"JA# B@aRB@x@A ARE5`a aR =Rg=R"@=c@ c!@UQ bIBbbb j B@jB@x@ =Aj @`Ejaj =j@=j @@ BB$ c B@aB,@x@AAJEB׀e=äFc = À*݀{"@}؀@ )%Nc Bb ! bc B@`B,@x@A$AEɒbb =jR`=+"%@XQ@,JPJA#F B@aRBw5n@x@A ARE aaR =R}=R%@ @  sҐ‘+gґa@*BbFb j B@jB @x@A$AjE]ŀ aj =jȀ=(%-+c@>@$Bǀ̮$  B@JBc@x@AAJEe=eF =Ԇ{% "@#@ @+c Abb b B@aB@@x@A$AEk B@aRB@x@A AREaaR =Rz=R(o@ @!5mHHcb/b f B@jB@lc@x@A$AjEB€jaj =jŀ=j @3@ $( @"DBĀ Bc B@JB@x@AAJE}e=RF =Ƀ{% F"@@ ) @ i~b b B@aB$X@x@A$AEO9ab =j=$j"@@,JNJA# B@aRBL6@x@A ARE]aRFaR =R=R" @q@ +䐃/ aDf bݲb j B@jB@x@A$Aj Ekajaj =jto=j%p1@n@ B0B B@JB@x@AAJEj'aJe=F~c =[-{F% "@(@ ! @6 @{@ c q?bNb ! ^@ B@aB@x@A$AAE46acbB =jY=^(fC@@,cDJ'JA#E B@aRBy@x@A ARFEBaRFaRG =R=R"H@V@ 0ӔPR}@QavDIb¯b jJ B@jB{ o@x@A$AjKEhajfajL =jUl=j M@k@ NBB$ O B@JB @x@AAJPEO$aJeQ=ԤFQR =?*{"S@%@ c BTb ! U B@aB@x@A$AVE߀bW =ja%X@U@,YJJA#Z B@aRB@x@A AR[EVaaR\ =R^=R%]@Y@  I.p %a(lB^bXb _ B@jB@x@A$Aj`Ejajl caja =j=(%-+cb@]@ cBB $ d B@JBc@x@AAJeÈef=vFg =Ӏ{% "h@2π@ ! @1a0/ Aib΀b b j B@aB@x@A$AkExbnbbl =jI`=j m@G@,nJjJA#co B@aRB$X@x@A ARpEaFaRq =R:="r@@c$@t$U}$Qa4Bsbb jt B@jB@x@A$AjuE  @Av =j=%-(%w@۾@$xB@Bµy B@JB ,@x@AAJzEwb J!`={=Fny| =@}{% %}@x@, VA~b/b ! !n@* B@`B@x@A$AE3a "EB =j>=j @@ m, @ lJ J@0 B@aRB@x@A ARE' "_$F = Ա="@/@ 1z %K`%fjcnbbb" at B@B@x@A$AjEej1|!j =j2i=j @h@ ) @.`DBgB J$B B@JBc@x@AAJE4!J`==F{ =$'{F% @r"@#Q! @c nbb ! bc B@aB@x@A$AE܀B =jaj%pj"@B@,JJA#d<R B@aRB@x@A ARESa  AR = }[=R(o@V@,#V }ÔP"0DfbDb½ B@B* @x@A$AjEOj Aj =j=j%-+c@:@ $( @"@BB B$B B@JB@x@AAJE );@==W݄F =Ѐ{% "@ ̀@ J) @+c Abrˀb b륱 B@aB@x@A$AjE\bc B =jnF`= @D@,J;JA# B@aRB@x@A AREj@Y AR =RaRR"@r@ c3_~/D-0@VBb  B@jB@x@A$AjEj#+c =ju=j%- 5`@3A@л@~B1B B@JB@x@AAJEwt bw 2c@==F =ATdz{F% "@u@ y! @K {Abb! b B@`B@x@A$AjE/ aB =j$=j^(f@@,JJ (Rc B@aRB@x@A ARE aR+ AR =R=FR"@@ C} D}8,bb jc B@jB@x@A$AjEb aj j@u% =jf=j @^e@~r$( @"DBdB$Bc B@JB@@x@AAJE J`==0|$X =@ ${% @S@ c >b ! c B@`B@x@A$AEـB =jʙa"@+@, JJA# B@aRB@x@A AREPa FAR =R[X=R%@S@ S%  ȏ`Dfb!b B@jB@x@A$AjE4 j9% =j=(%-(1@ @ rB J$  B@JBc@x@AAJEǀ `==<ڄFc =̀{% "@Ȁ@! @ӟQ AbWb b, B@aB; @x@A$AEAbcB =jtC`=^(f@A@ '*Q#j` yJ@J@/ B@aRB; @x@A AREO@Y  6$F  +$R"@K~ 8,$F!Rc2o Bbb B@B@x@A$AjEֵ,fAj =jZ=(%-(%@@~!j @"@BBB B@JB@٢oc@x@AAJE\qbw`==ݤF|y =@Tw{% "@r@ $F @6 /Ab ! b륱 B@`B? @x@A$AE,a ^ B =j1=j$jB#;@/@,JSJ!c B@aRB @x@A AREj $ R!!AR =="@z@ s`26T ^Bbb@&#a B@jB @x@A$AjE""Aj =j}=j%p% @צ@$ B9B$ Jc B@JBB@x@AAJ Ew_J#*@==-]L =ge{F% "'@`@, Ubb ! c B@aB@x@A$AjEa$%B =jۀ=j @ـ@,JؠJA#F B@aRBy@x@A ARE aR &&AR =R=FR"@@ d`CqSq\aDbb@$j B@jB| o@x@A$AjEMj''Aj =jQ=%-(%@mP@$ BOB J$ ! B@JBc@x@AAJ"E J((`=#=|$ ={% "%@R @ B c aA&b ! ' B@aBF@x@A$A(EĀ)*B) =jaj^+c*@@,+JzJA#F, B@aRB@x@A AR-E;a i A@++AR. =@]C=R"/@>@ "‘ґ"F$* =:B0b!b½ac1 B@Bh@x@A$Aj2E4 j,,Aj3 =j=j%-(%4@@~5B B$ J6 B@JB@x@AAJ7E--`=8=<ńF9 = À{% ":@@ ! @.W A;bVb b< B@`B@x@A$A=EAna./B> =jf. `=j ?@,@,@J4J A B@aRBc@x@A ARBEOy F00 C =R=FR"D@_@ `S`npaX$`aaBEbb jF B@jB@x@A$AjGEՠ!b j1#!jH =ja=j%-(%I@@~JBBK B@JB@x@AAJLE\\"J22`=M=ݤFyN =Hb{% "O@]@ c  APb ! Q B@aB@x@A$ARE#ac34BS =j؀="T@bր@,UJՀJ(RcV B@aRB@x@A ARWE$aR F55ARX =!J= Y@@ ~(}`TF BZbdbj[ B@jB*@x@A$Aj\EwJ%j66Aj] =jN=j ^@^M@ ) @.`AJ_BLB$Bc` B@JB@x@AAJaE&J77`=b=|c = {% d@;@ 5n! @'`, Aebb ! bcf B@aB 4  @'@x@A$AgE ^88Bh =jƀ=G r ^"i@}Ā@@S'$,jJàJ Jk B@A*B,@x@A ARlE }'99ARm =@=R(on@@  +Y xI|}{zar=Bobb@$p B@BQ@x@A$AjqE8(j::Ajr =j<=(%-(+cs@{;@ r$( @"@BtB:B J$Bu B@JB@x@AAJvE ;;`=w= ƒ|yx = À {"y@T@ Azb ȥ! 륱{ B@`By@x@A$A|E)b<=B} =jo*`=j%p"~@6n@@SJmJA#J B@aRBL6@x@A ARE&+a >>AR =@D.="@)@ ByacNb b½ B@B]L@x@A$!1E45n??Aj =j=j%-%@@B|䀃 B$ y B@JB )* @x@AAJE,@@`==;F =@{F%@ @, Wbjb !  B@`B@x@A$AEAY-aABB =jt.`=j @@,J@JA# B@aRB@x@A ARENР@Y CD5\ = +؀=FRc@cӀ@ %  R"a ; bҀb f B@B@x@A$AjEՋ/bjDDAj =je=%-@Î@ B!B$  B@JBc@x@AAJE\G0JEE`==ݤF =LM{% "@H@ ) @ ; b  b B@aB@x@A$AE1aFDB$^ =j€=j^+c@Y@,JJA#(R B@aRB@x@A AREy2aR HA6!R =R=R"@|@ $F!?7RNaxV6albhbj B@jB @x@A$AjEw53jIIAj =j8=j%-(+c@U@$B7 J B@JB@x@AAJE JJ`==| ={% "@:@ *" @tAbb ! b B@aB@x@A$AE4bcKLB =jl5`=%@ k@,JwjJA# B@aRBL6@x@A ARE#6a MMAR =RA+=%p@&@cjXXAj =j5=(%-(%@:@ $( @(@BB4 B$B B@JB c@x@AAJE YY`==d|W =@{% "@@ ) @+c @b~b b륱 B@`B@x@A$AEi?bZ[B =jvi@`=j"@g@,JDJA# B@aRB@x@A AREw Aa \\AR {'(=R"@#@ 3$paQp[SEDfb"b B@jB`x@9 Aj @`Eۀ j]]Aj =j߀="@ހ@ BEBJ B@aB@x@AAJ EBb J^^@= =?`=c =p{%  @@ ! @( }B b b b  B@aB@x@A$AjE SCaj_`B = `0D`=^%@@, JJ  B@B@x@A AREʀ aaAR =Rр=R%@(̀@ CJqKHWBb̀b½ B@jB@x@A$AjEEb jbbAj =j/=(*(+c@@ r$( @"@BB뇀BJ B@JB@x@AAJE&AFaJ Jc"q@==Fh =G{% "!@cB@  c >A"b¡ c# B@aB@x@A$Aj$EcdeB% =jռGaj c&@7@,c'JJ c( B@aRB$X@x@A AR)EsHa ffAR* =Rg{="+@v@ cSH@B:EÔP@B,b2b@&j- B@jB* @x@A$Aj.EA/IajfggAj/ =@݀2=%p(%0@@~n1B}1 B2 B@B@x@AAJ3Eꀈ hh`=4=HF5 ={% %6@@ y! @c 'FA7bcb! b 8 B@aBc@x@A$A9ENJbijB: =jkfK`=j ;@d@,<J9JA#F= B@aRB@x@A AR>E[La kkAR? =R %="@@d @ ccPQ" (RBAbb fB B@jBc@x@A$AjCE؀jllAjD =jf܀= E@ۀ@ $( @ūcFB"BBG B@JB@x@AAJHEiMmm`=I=FJ =Q{% K@@ B c DBLbb iXFM B@aB m8p @'@x@A$ANEONanoBO =jO`=j P@~@,QJ J R B@A*B@x@A ARSE ppART =R΀=R(oU@ɀ@ cs`#G7Ft"*K.BVbib@'W B@jBy  @x@A$AjXEPb jqqAjY =j=j%-(!Z@l@$[B̄B\ B@JB@x@AAJ]E >QaJ Jrr`=^=PF_ =C{% "`@E?@ c $Aab  b B@aB@x@A$AcEcstBd =jRa(fe@@,fJJ Fcg B@aRBc@x@A ARhEpSa uuARi = Xx="j@s@* " R URT.Bkbb½l B@BF@x@A$AjmE%,TjvvAjn =j/= o@ @ cpBj.(J/l q B@JB@x@AAJrE瀈 ww`=s=-FFt ={% u@@ 5n c BvbHb cw B@aB@x@A$AxE3UbcxyBy =jecV`=^%z@a@,{J2JA#| B@aRB@x@A AR}E@Wa zzAR~ =R!=R%@L@ c+] "+Q/tFBbb j B@jB* @x@A$AjE j{{Aj =jGـ=j%-(+c@؀@ BB B@JBc@x@AAJENX||`==ϤF =>{% "@@ y! @ $"Ab  B@aB@x@A$AELYa*}~B =j Z`="@k @,J JA#F d* B@aRB@x@A AREÀ@Y FAR =Rˀ=R"@ƀ@ c01zU@ BbVb j B@jBc@x@A$AjEi[b jAj =j=( @Q@~$( @r(AJB B B@JB@x@AAJE:\J`==qMY`= =@{%p@&<@ 5n c oAb;b c B@aBy@x@A$AEv#A =j]aj"@@,JqJA#(> B@aRB@x@A AREm^a FAR =R.u=R%@p@ y-`UÐ-A HBbob j B@@]B}@x@A$AjE )_aj jAj =j,="@+@rBNBB B@JB@x@AAJE J`==Fc =}_a% @@ c +Bb-b B@aB@x@A$AE`a,@% =jC`a`=^%@^@@Sf'%JJA#J B@aRB@x@A ARE%ba AR =@=R%@-@ %|p1Ua)0 bb@$j B@B@x@A$AjE jAj =j(ր=(+"(!@Հ@ rBԀB J B@JB@=$X@x@AAJE3c`==F =@{% "@n@ B$F @ Ab  B@`B@x@A$AEIdacB =j e`=j%pj%@8@ m!j @JJA# B@aRB5n@x@A ARE FAR =RrȀ="@À@ cQ/.daBb;b j B@jB5n@x@A$AjEN|fb2 jAj =j= @;@~B~ J `y B@JBc@x@AAJE7gaJ J`==UJF/ =={%pF%@9@ ! @?m :Bbp8b! by B@aB@x@A$AE[B =j~ha%pj%@ޱ@,JJJA# B@aRB@x 9A AR @`Ehjia AR =Rr=R"@}m@ c "% `̠UBblb  B@a$Bc@x@A$AjE%jjAj =j{)= @(@ $( @"AJB7B,B B@JB 5@AAJ @Ev `==F =Z{% F"@@ ) @+c Abb b륱 B@abB -  @'@x@A$AEkbB =j]l`=j^"@k[@,JZJ B@A*Byb@x@A ARE ma AR =R=R"@@ y1 .p}0ykBbrb½ B@jBV@x@A$AjN`E jAj =j!Ӏ=j%-(1@Ҁ@$BрB J) c B@aB@x` =AJ @Enb J`==F ={% "@T@c QAH ! c @abB@x@A$A EFoacB =p`=% @9@,JJA#c B@aRB5n@x@A ARE AR =Rcŀ="@@.` 0taBb,b j B@jB; @x@A$AjE2yqb jAj = |=%-(%@@~cBw{(B$  B@B@)@x@AAJE4raJ`==:GF$X =@:{% "@5@c 1 AbYb !  B@`B@x@A$A E@ B! =j=^%"@<@,#JJ $ B@aRB @x@A AR%Eǫsb RAR& =Rp=R"'@ˮ@ o!!% 0䐃H60PB(b7b j) B@jB@x@A$Aj*EMgtaj jAj+ =jj=(%-(%,@!@n-BiB$ . B@JBc@x@AAJ/E"uJ`=0=ܤFW1 =({% "2@$@ @A3bp#b b4 B@aB@x@A$A5E[ހB6 =jva^%7@@,8JZJ >9 B@aRB@x@A AR:EhUwa FAR; =R]=R"<@pX@ #ßPa"Q` B=bWbf> B@jB`@x@A$Aj?ExjAj@ =jo=(%-(%A@@ rBB+B JC B@JB@xA 9AAJD @Ev̀ `=E=F F =fҀ{% "G@̀@ X1!Hbb! I B@abB@x@A$AJEybAK =j#Hz`=^%L@F@,MJEJA#cN B@aRB@x@A AROE ARP =R{$R"Q@ @3-"8$p$a FRbvb jS B@jBB@x@A$AjTE2 jAjU =j!=( V@}@~WBݼB J `cX B@JB@x@AAJYEv|bw J`=Z=F[ =|{F% \@Rw@ @c F]b ! bc^ B@aB@x@A$A_E1}aB` =j=)j%a@1@,bJJ c B@aRB@x@A ARdE~aR ARe =RR=R%f@@ C`9`p%A Hogbb½h B@@]BB@x@A$AjiE2daj jAjj =jg= k@f@ lB^BJ$ m B@JB@x@AAJnEJ`=o=:2|p =%{% F"q@ @ c RBrbUb s B@aB@x@A$AtE@ۀ Bu =j߀=j^%v@<ހ@,wJݠJA#x B@aRB,@x@A ARyEƖARz =Rn=R"{@ϙ@ S%$e:puvaMB|b;b } B@jBF@x@A$Aj~EMRjAj =jU=j%-(/)@#@ rBT B B@JB@x@AAJE J`==ܤF ={% "@@c Abpb B@aBc@x@A$AE[ɀB =ja%@@,JaJA# B@aRBy@x@A AREh@a AR =R$H="@xC@ cuw~TT0a`hBbBb B@jB  @x@A$AjE jAj =j=j @@ B;B B@JB@x@AAJEvb J`==FL6 =n{% @@ c ĚBbb! B@aBb@x@A$AEraB =j 3`="@k1@,J0J  B@aRB@x@A ARE AR =R= @@ cs:uv%eBbb j B@jB,@x@A$AjEbAj =j!= @{@ BݧB F B@JB5n@x@AAJEaaJ `==sF = g{% @Xb@ ! @ sBb  B@aBc@x@A$AEacB =j܀=^+c@-ۀ@,JڠJA# B@aRByc@x@A AREaR AR =R`=R+c@@ !8%; ʇBb'b½ B@jB@x@A$AjE2OjAj =R=(%-(1@@ n$( @n"@BBzQ J)B B@JBc@x@AAJE J`==:|c ={%p"@ @ c nuAbUb  B@aB@x@A$AE@ƀB =jea^"@Ƅ@,J2JA# B@aRB@x@A AREM=a AR =RD=R"@E@@ 1 D!:dpX[xBb?b B@jB@x@A$AjE jAj =j\=(%-(%@@$BB J B@JB@x@AAJEZ`==ܤF =O{% "@@ ': @c Ab ! b B@aB 4 @x@A$AEoaB =j0`=j c@t.@,J-J  B@aRB@x@A ARE怈 FAR = =R"@@ o"!w6$b_b jc B@B @x@A$AjEub jAj = ="@]@!j%(AJBBB$Bc B@B@x@AAJE]J`==}pF{* =c{% @6_@  c Ab^b c B@aB@x@A$AEacB =jـ=j$j"@؀@,5nJnנJA# B@aRB@x@A AREaR FAR = V="@@o! ZS":6 b bf B@B@x@A$AjELjAj = O=%-&@N@ rBWB J!  B@x@AAJEJ`==| = {% (@@ ! @b:b b  B@aB@x@A$AE$ÀcB =jVaj$j% @@,c J#JA# B@aRB @x@A AR E2:a AR =RA="@2=@ o"!D"T:aBq bB@B? B@JB@x@AAJ@EaJ `=A=xB =o {% "C@@ c ADbb! 륱E B@aBc@x@A$AFE cBG =j8a"H@~@,IJJA#J B@aRB@x@A ARKE7a ARL =R>= M@:@ :9a";/"aHyNb9b½O B@jB@x@A$AjPE jAjQ =j*=%p(%R@@ SBB cT B@JB @x@AAJUE$`=V=F; W ={% %X@_@ ! @c mYb Z B@aB@x@A$A[EiacB\ = `)`=^(f]@2(@,^J'J _ B@B@x@A AR`E FARa =Rk=R"b@@5nI~(}q"ulDcb0b jd B@jB o,@x@A$AjeE?b jAjf =jϟ=(%-(%g@,@ n$( @n"@BhBBi B@JBc@x@AAJjEWJ`=k=GjFl =]{%p"m@Y@ m c AnbbXb co B@aB "@x@A$ApEMaBq =j|Ӏ=^"r@р@,sJGJ t B@aRBL6@x@A ARuEZaR FARv =R =R"w@f@c$4"䐃(a9BxbҌbfy B@jBc@x@A$AjzEEjAj{ =jaI=(%-(%|@H@$}BB J) c~ B@JB@x@AAJEgJ`==F =X{% "@@c 0Abb  B@aB@x@A$AEB =j}aj c@y{@,JzJA# B@aRB@x@A ARE3a AR =R;=R"@6@,#)Pn-0d"BbdbA;j B@jBQ@x@A$AjE@Y jAj =j="@p@ƹcBBB B@JB@x@AAJE b J`==F ={% @A@ c ?Bb  B@aB@x@A$AEfacB =j&`=j @%@,J$J >@ B@aRBL6@x@A ARE݀AR =RQ="@@3GcB!b½ B@jB o@x@A$AjE$b fAj =j=*(+c@@ rBpJ B@JB@x@AAJETaJ%`==,gF =Z{% (@U@ ! @ [AbKb b B@aB@x@A$AE1a  B =jYЀ=j @΀@,J(J  B@aRBy@B.Q @x@A ARE?aRAR =R="@_@ CmpL6$Ea=Bbˉb j B@jB@x@A$AjEBaj2 !_Aj =jNF= @E@~/$( @4AJBB J B@JB@&Q@x@AAJEL J'N@==ѤFv, =@=a% @ c %Ab !  B@`B@x@A$AjEӹ,b =jzaj @fx@ m, @ JwJ@0 B@aRB@x@A ARE0a aR =R8=R(o@3@!RoSV np3]LBbAb½ B@jB@x@A$AjEg j r =j=j%p(+c@E@~B B$  B@JBc@x@AAJEb Je=oF$X =歀{% "@+@c R5Abb!  B@aB @x@A$AEucab =j#`=$j(f@!@,J_J R B@aRB@x@A AREڀ   aR =RB=R"@݀@ c('LU1KoBbb½ B@jB@x@A$AjE b j  aj =j=j%-%@瘀@~BIB$  B@JB@x@AAJEQaJ J  e=dFzc =W{% "@R@; Ab,b!  B@aB@x@A$AE ac  b =jC̀="@ˀ@,cJJ c B@aRB@x@A ARE$aR aR =R؋= @0@  s U+ccJbb½ B@jB@x@A$AjE?jaj =j3C=%-(%@B@ BAB ; B@JB@@x@AAJE1  >=F$X =@a% %"@nW @W R Ab  B@`By@x@A$AjE,b =jvajG b,ژ@/u@,JtJ c B@aRB@x@A ARE-a aR =Rz5=R" @0@ !%($""D,DaB bAb½ B@jB@x@A$Aj EL j r =j=(%-(%@'@ nB뀃J$  B@JB@@x@AAJEӤ@==TF =@ê{%p"@@ 5\ @+c EAbob bc B@`B@x@A$AjEZ`ab =jw `=^K@@ m!j$^JDJA# B@aRBzy@x@A AREgנ@Y FaR =R ߀=R"@{ڀ@ y) (dpK@p'B bـbf! B@jB@x@A$Aj"Eb jaj# =v=(%-(C$@ѕ@ R%B2BB& B@JB@x@AAJ'EtNJe(=`F) =iT{% "*@O@ B! @K A+bb ! b , B@aB@x@A$A-E b. =j=j%pj%/@ @,0Js J (1 B@aRB @x@A AR2E FaR3 =R1̀="4@Ȁ@ - %aB5bǀb j6 B@jB~c@x@A$Aj7E aj8 =j= 9@@ $( @"AJ:BUB J$B; B@JB@x@AAJ<E<Je== > =B{% F%?@=@ W) @+c ;AA@b+b bcA B@aBc@x@A$ABE bC = `Aa D@@,EJ J F B@B@x@A ARGE$oa !!OH =Rv=R"I@ r@ B%K]10#azBJbqbK B@jBz@x@A$AjLE*aj j""ajM = B.=j%-(+cN@-@ OB,BJP B@B@x@AAJQE1 J##eR=FɂS = À{% "T@m@ S! @+c BAUb  b V B@`B 8p@x@A$AWEb$%bX =ja`= Y@G`@@Sj' @ZJ_J Jc[ B@aRB$X@x@A AR\Ea &&aR] =@| =!^@@ " @%aB_b9b½` B@B @x@A$AjaELԀ j''ajb =j׀=j c@9@~!j @ūcdBր Be B@JB@x@AAJfEӏb> J((eg=TFBh =˕{% i@ @ 5n$F @+c o2Bjbob bck B@aB "@x@A$AlEYKac)*bm =j `="n@ @,coJ\J p B@aRB@x@A ARqEg @Y ++aRr =Rʀ=%ps@sŀ@ ӝ@%1@8BtbĀbĩu B@jB @x@A$AjvE}bf,,Lw =jv=j%pj+cx@Ӏ@ yB2BJz B@JB@x@AAJ{Et9aJ --e|=F~3:  K >} =`?{% +c~@:@ @+c Abb b B@aB,@x@A$AE./b = `#a"@@,JJ 4b4c B@B@x@A AREla 00aR =Rs=R"@o@ 6t"+fW1Bb}nb f B@jB@x@A$AjE'j11aj =j+=( @u*@rB)B ` B@JB@b& @'@x@AAJE 22e=Fy =@@{% @R@F c Bb ! , B@`B@x@A$AEb34b =j^`=^.@/]@ m!j*Q`# ! !% ARJ\J  `JR- B@aRB@x@A AREa 55aR =Rb=R%@@ cw OanAjb*b½ B@jBc@x@A$AjE1р j66aj =jԀ=( @Ӏ@ BaBJ$  B@JBc@x@AAJEb J77e=9F ={% @@ c ]BbTb  B@aB W'Z@x@A$AE>Hac89L =jg`=^%@@,J5J B@aRB@x@A AREL@Y: ::aR =R ǀ=R%@\€@'!(T:@T>Bbb½ B@jB@x@A$AjEzb j;;aj =jW~=j%-(1@}@ `@"@BBB B@JBB@x@AAJEY6J<<$5=ڤF =M<{"@7@c Ab ! B@aB@x@A$AjEc=>b =jaj$"@_@,J˯J (Rc B@aRB@x@A AREha* ??aR =Rp=FR%@l@c%TJE /a,kcbmkb j B@jB o@x@A$AjEt$aj @@Ho =j'= @W@$B&µ$ c B@JBc@x@AAJE JAAe=|F ={% F"@8@/ kcbb c B@aB "c@x@A$AEbBCb =j[`=j^%@Z@,JtYJ B@aRBB@x@A AREa DDaR =R<="@@#kYEkeaHobbf B@jB @x@A$AjE jEEaj =jр=%-(+c@Ѐ@$BZB J B@JB@!K@x@AAJEFFe=F =@{% %@ڊ@ `@W+c ZAb8b B@`B@x@A$AE#EaGHb =jD`= @@ m!j @JJ c B@aRB@x@A ARE1 FIIaR =RÀ=R"@=@ c3%Se%aaBbb j B@jBc@x@A$AjEwb jJJKc =j?{=j @z@ƹByBB B@JB@@x@AAJE>3JKKe=EF$X =@.9{% @|4@ ! @( #Bb  b B@`B@x@A$AEcLMb#ja%pj+c@P@, JJ  B@aRB`x@9 AR @`Eea FNNaR ={m=R%@h@ cCTWT.tT`̠BbBb½ B@a$Bc@x@A$Aj EY!jOOaj =j$=j @@@ $( @"AJ B# B B@JB@x@AAJE PPe=aF = À{% F"@ހ@ ) @ mAb|݀b b B@`BB@x@A$AEfbcQRH =jX`="@V@,cJUJA#j B@aRBv B@@x@A AREta SSaR =R)= @@S%t+_Kk0 bb!&' B@jBy@x@A$AjEʀ jTTaj =j΀=j%p(! @̀@ !BCB" B@JB@x@AAJ#EUUe$=FQ% =n{F% %&@@m @ q'bb ! b ( B@aB@x@A$A)EBVVE* =jF=j^(f+@ E@,,JxDJA#n- B@aRB@x@A AR.E FWWaR/ =RVaR"0@@ ccvEqa‰D1bb j2 B@jB]L@x@A$Aj3E jXXaj4 =j=j 5@@0k6BZB$  7 B@JB,@x@AAJ8EtbwJYYe9=F$X: =z{:% ;@u@  c f{B<b8b! y= B@aB@x@A$A>E#0ZZb? =j4=j @@73@,AJ2J B B@aRB@x@A ARCE F[[aRD =RG=FR%E@@ cs%Td%@ 1BFbb@(jG B@jBxc@x@A$AjHE0\\ajI =j=j%-(+cJ@@$KBt J$ L B@JBc@xJ 9AAJM @EbJ]]eN=FlO =h{F% "P@c@$X nAQbSb R B@abBc@x@A$ASE>^^bT =j"=^+cU@>!@,VJ JA#FcW B@aRB$X@x@A ARXEـ@Y __aRY =R=R"Z@܀@ ckYE @-B[bIb \ B@jBc@x@A$Aj]EK``aj^ =jӘ=j%-(%_@0@ rc`B Ba B@JB@x@AAJbEPS aa$5c=ڤFcd =V{% "e@ R@ c AfbnQbcg B@aB >"@x@A$AjhEY aybcbi =j̀="j@ʀ@,ykJ\J (Rl B@aRB@x@A ARmEfaR ddaRn =R= o@z@ ,%EqKe,dBpb慀bjq B@jB{ @x@A$AjrE>jeeajs =jB=j t@A@ uBABv B@JB@x@AAJwEt> ffex=F* y =Xa z@ ! @ B{bb ! b c| B@aB "@x@A$A}E,ygh"~ =j&vaj"@t@,cJsJ F B@aRB@x@A ARE-a iiaR =R4=R(o@ 0@ T+Y%E$cVBbx/bj B@jB; @x 9A$Aj @`E耈fjjaj =j=( @t@~$( @.`AJBB$B B@aB@x@AAJEkke=F ={% c@Q@ y Ab !  B@aB@x@A$AE_almb =j `=^"@#@,JJA# B@aRB* @x@A ARE nnaR = =ހ=R%@ـ@ SN|QtBb b j B@B* @x@A$AjE0 b jooaj =j=(%-(1@ @ Bp  B@JB@)B@x@AAJEM Jppe=8`Fu* =@S{% "@N@ c 1AbSb  B@`B@x@A$AE> aqrb =jjɀ=^%@ǀ@,J8JA#c B@aRB @x@A AREK aR FssaR =R=R"@S@ (}O[}@aBbbf B@jB !@x@A$AjE;jttaj =jJ?=(%-(%@>@$B B J)  B@JB@!K@x@AAJEY uu$5=ڤFy =@M{% "@@  >ɂb !  B@`B@x@A$AjE߲bcvwb =js`=jt%@rq@ m, @JpJ  B@aRB@x@A ARE)a xxaR =R1="@,@ N` EDbeb½ B@jB@x@A$AjEs jyyS =j=j%-(%@N@$B瀃 B$  B@JB@x@AAJEzze={F =ꦀ{F% %@7@ , @ Abbj! b B@aB@x@A$AE\ac{|b =j`=j%pj%@@,JJA# B@aRB@x@A ARE F}}aR = Cۀ=FR"@ր@ %Sre$U0D B$  B@JB"Mc@x@AAJEG!Je $`ZF! =@=qM{% "@H@ ! @(B#bb ! b$ B@`B@x@A$A%E"acD^& =j9À="'@@)f(JJ IJ) B@aRB@x@A AR*Ez#aR FaR+ =@=R.!,@}@ #"T"tU/b\B-b|bĩ. B@Bc@x@A$Aj/E5$aj jB0 =j,9=(%-(11@8@~$( @4@B2B7B J$B3 B@JB@x@AAJ4E" Je5=F6 ={% "7@\@ l8b ! 륱9 B@aB@x@A$A:E%b@Y b; =jU="<@@,=J!JR> B@aRBB@x@A AR?E0h&RDF@ =Ro=R"A@4k@o @o34"DD~hoBbjb jC B@jBc@x@A$AjDE#'jajE =G'=j%-(%F@&@ Rc} B@aRB@x@A AR~Ee1a FaR =Rl=R"@)h@ c101n'bgb j B@jB]L 5@A$Aj @`E 2aj jaj =j$=j @q#@~n$( @(DB"B B@aB@)@x@AAJE" Je=FB =@"{% @_݀@ ; @1! @# +c Ab ! bc B@`B@x@A$AE34@Tcb =jW4`="@(V@ m!j%JUJ(R B@aRB$X@x@A ARE5a aR =Rb=!@@ c sÐ-@a$&bj B@jBB$A$Aj @`E=ʀ jaj =j̀=j%p`k3C@@~B̀ B$  B@aB@x@AAJEą6@==EF ={% (@@ ! @4 +b`b b B@aB@x@A$AjEJA7ac[& =8`="@~@SJMJ J B@ Bc 5@A AR @ 5\ FAR =@`== @X@ ccܚDbĺbĩ B@B ox@x@A$Aj$`DEs9b jaj =jow=j%-(1@v@ $( @ @ (@BB+B B@JB@x@AAJEe/:aJ Je=F, =b5{F% %@0@h xbb! 륱 B@aB "@x@A$AED^ =j ;aj^"@k@,JרJ  B@aRB@x@A AREaBbĥb½%  jB@x@A$AjE^Gjaj =jWb=G@ j%-jC %@a@ $( @K f BBBc B@JBc@x@ =AJ @EeHJ@==F;  =] {% % @@ B$F @+c _A bb ! b륱 B@abBy@x@A$Aj EՀcH =jIa%pj"@s@,JߓJA# B@aRB@x@A ARELJa aR =RT=R"@O@ ﵌Uu䐃"}paBb]b B@jBQ@x@A$AjEKjaj =j =j%p%n@m @ B B$  B@JB@x@AAJE e=քFB =ɀ{% "@Bŀ@m @+c 6@Ab ! bc B@aB@x@A$A!ELbcb" = `?M`="#@ >@,$J=J % B@Bc@x@A AR&E G' = J= (@@ }ZT w4B)bb jc* B@BB@x@A$Aj+E"Nb jaj, =j=j%-(%-@ @~.Bj B$ / B@JB@x@AAJ0EmOJe1=*F2 =s{F% %3@n@  c m4bDb 5 B@aBc@x@A$A6E/)PaA7 =jK=j^+c8@@,9JJA#c: B@aRB @x@A AR;E=QaR FaR< =R=R"=@Q@ D"uu ҽy*>bb j? B@jB@x@A$Aj@E[Raj jajA =jC_="B@^@CB]BBD B@JB@@x@AAJE%  EJSJeF=ˤFG =@{>{% H@@ * ': @c #GIbb b J B@`B@x@A$AKE EL =js׀=j M@Հ@@Sm' @NJAJ JO B@aRBz B  @xM 9A ARP @`EWT rQ =@`= ="R@d@u "SPSuS`̠otSbАb T B@B/@x@A$AjUEIUjajV =jbM=*(+cW@L@ $( @(@BXBB Y B@JB@x@AAJZEeVJ@=[=mӃnb\ =U {% (]@@ $F @ {A^bb bc_ B@aB@x@A$Aj`ED^a =jWaj%pj"b@v@,cJ~J nd B@aRB@x@A >eE7Xa aRf =R?="g@:@q$S"S#S#vahbibi B@jB*@x@A$AjjE jajk =j=%p%l@\@$mBBJn B@JB c@x@AAJo%  EYb Jep=Fw,q =@{{% %r@A@ m @ 8Asb  b t B@`B@x@A$AuEjZa!v =j*[`=j w@ )@ m' @cxJ(JA#y B@aRB@x@A ARzE aR{ = H=R"|@@ #wu’u*u@B}bb j~ B@B@x@A$AjE!\b@Y jaj =@݀= @@ `@(AJBn B B B@B@١%` AJ @EX]aJ Je=)kF =@{^{% @Y@ $F @+c !6AbDbe `bc B@`B@x@A$AE/^acb =j]Ԁ=j%pj"@Ҁ@,J*JA# `R- B@aRB@x@A ARE<_aR aR =R֒=R%@8@ 3Ғ"6 u "a8Bbb½j B@jBz@x@A$AjEF`jaj =jGJ=j @I@  `@r"AJBB$ B B@JB@x@AAJEJaJe=ˤF =:{%pF"@@c yAb ! y B@aB@x@A$AEѽKc =j~ba @c|@,J{J  B@aRB@x@A ARE4ca aR =Rx<=R"@7@ CS6r N&BbBb½ B@jBt@x@A$AjEe jaj =j=j%-(1@Q@~B B$ g B@JB@x@AAJEd@==mF =ܱ{% "@&@ `@c Abb  B@aB $X@x@A$Aj%  Ergeab =j'f`="@&@,Jm%J@ B@a B@x@A AREހ FG =R2= @@ o @3S"X t aBbb@$j B@jBz =@'@x@A$Aj%`DEgb jaj = {==j%-(%@㜀@~BFB B@A"B@@x@AAJ%`EUhJe=hFB =@{y[{% %@V@6 @`Ab)b ! b B@`B@x@A$AEiacb =j;р="@π@ m'$^JJ(> B@aRB@x@A ARE!jaR FaR =R=R"@@ ccp %ucC%a bbj B@jBc@x@A$AjECkjG =j$G=( @F@ rcBEB J$ c B@JBc@x@AAJE/ e=Fc = À#la @j@ $F @6 b ! bc B@`B c@x@A$A%  E1 B =j_=j%p3@½@ 5!j @J.J j B@a B/@x@A ARE@)@~?Bڀ B$ c@ B@JB@@x@AAJAEГ}  eB=QF; C =@{% %D@ @c Eblb cF B@`B@x@A$AGEWO~ac bH = ``=^(fI@ @ m2 @yJJZJ K B@B@x@A ARLEdƠ@YA FaRM =R ΀=R"N@lɀ@ @NDObȠb@%ĩcP B@jBF@x@A$AjQE끀b jajR =j{=(%-(%S@ׄ@ wTB7BJU B@JBc@x@AAJVEr=JeW=FcX =ZC{% "Y@>@ $F @ =!Zbb b [ B@aB@x@A$A\Ecb] =j#a^%^@@,_JﶠJA#F` B@aRB@x@A ARaEpa FaRb =Rw=R"c@s@ (2azBdbzrb@$je B@jB@x@A$AjfE+jajg =j/=( h@u.@$iB-B Jj B@JB@x@AAJkE el=Fm ={% n@N@ ': @6 Bob Z b p B@aB@x@A$AqEbbr =jb`=j+"j%s@)a@,tJ`JA#Fu B@aRB@x@A ARvEa aRw =Rf!=R%x@@ o"!﵌aByb$b½z B@jB B@x@A$Aj{E.Հ jaj| =j؀="}@@ !j%"AJ~Br׀J B@JB@x@AAJEb Je=6F ={% F"@@h .AbQb  B@aBh@x@A$AE>e=F = À :{% @]5@ c Bb   B@`B @x@A$AE,?@b =j̯aj%pj%@.@,JJA#F B@aRB@x@A AREfa FAAaR =RMn=R% @i@  cipWuij<j3B!bb j" B@jB@x@A$Aj#E;"4  jBBaj$ =j%="%@@c&Bw$B' B@JB@x@AAJ(E JCCe)=GF** ={% F"+@ހ@ 5n) @ VB,b^b b - B@aB - @x@A$A.EIbcDEb/ =jaY`=j 0@W@, 1J0J 2 B@aRB@x@A AR3EVa FFaR4 =R ="5@f@ s`$ppaCB6bbf7 B@jBb@x@A$Aj8E jGGaj9 =jeπ= c:@΀@ r;B!B J< B@JB@x@AAJ=EdHHe>=Fz8/|; `A? = X{% @@@@a! @.W gBAbb b B B@`B@x@A$ACEBacIJbD = `=j E@q@,cFJJ cG B@aRBz"vB@x@A ARH' / `E FKKaRI =R="J@케@  t䐁@BKbXb jL B@a$B@x@A$AjMEub2 jLLajN =jy= O@jx@~ƹ$( @.`AJPBwB JQ B@JB@x@AAJRE1aJ JMMeS=CFT =6{% U@C2@ c  mCVb ! yW B@aB* @x@A$AXENObY =ja Z@@,[JsJA#g\ B@aRB@x@A AR]Eca PPaR^ =R6k=Rc_@f@ D<T B@aRBwc@x@A AREc]a FnnaR = e="@_`@ $F!opTq0 uBb_ B@Bnb 5@A$Aj @`E jooaj =j=%-(%@@ r!j @(@BB>B,J B@aB@)$X@x@AAJEqԀ Jppe=F =@]ڀ{% %@Հ@ ! @pAb b b륱 B@`B@x@A$AEbcqrb =jP`=j$j"@~N@,JMJA# B@aRB|@x@A AREa ssaR =R="@ @C#Srvw]aBbq b½ B@jB@x@A$AjE€2 jttaj =jƀ=%@qŀ@~$( @"@BBĀB J B@JB@@x@AAJE~uue=F =@{% F%@N@ 5\ @ dAb ! b륱 B@`B@x@A$A(  E9av*xA!f =j=j @ @ m!j @JJ@ B@a B@x` =AR @`EaR FxxaR = ?`=M=F!@@y1 p҃aӔ@ .;Bbb½ B@Bx@x@A$Aj E-laj jyyaj =jo=j%pj% @@~ Byn B$  B@JBc@x@AAJE'Jzze=5:|5n =-{% `3E@(@ ! @ AbPb b B@aBy@x@A$AE; {$% =j="@/@,JJA# B@aRB#B @x@A ARE|+!R =Rf=R(o@ơ@ #[`p ]{Bb2b$ B@jB{ y@x@A$AjEHZj}}aj =j]=(%-(%!@@ $( @ūc"B\ # B@JB@x@AAJ$EaJ > ~~e%=פFy& = i{% "'@@ y) @+c A(bob b륱) B@`Bc@x@A$A*EVрb+ =ja^",@䏀@,-JPJA#rc. B@aRB- 5@A AR/ @`EcHa aR0 =RP=R"1@kK@3D"zu `̠B2bJbjc3 B@a$Bژ@x@A$Aj4Ejaj5 =jn=(%p(%6@@$7B*B J8 B@JB@x@AAJ9Ep e:=F* ; =eŀ{% "<@@ 5n': @ 1A=b b ! b > B@aB (,@x@A$A?Ezbb@ =j;`=^%A@~9@,BJ8J C B@aRB@x@A ARDE aRE =R=R"F@@ Ct,4 tZBGbb jH B@jBy@x@A$AjIEb jajJ =j=j K@o@ $( @"AJLBϯB$BM B@JB@x@AAJNEiJeO={F{ P =n{"Q@Hj@ * c /ARb  S B@aBy@x@A$ATE$acbU =j=jt"V@@,WJJA#X B@aRBv@x@A ARYEaR FaRZ =RX=FR%[@@ S.tt/aB\bb½] B@jB o@x@A$Aj^E-Wjaj_ =jZ=%-+c`@@$aBqY Jb B@JB@x@AAJcEJed=5%|e ={% "f@@ ': @c =AgbPb bh B@aB@x@A$AiE:΀cbj =j`aj^%k@@,lJ-JA#m B@aRB7B@x@A ARnEHEa aRo = p M="p@dH@ c+_ "y`a >BqbGbr B@B@x@A$AjsEjajt =jO= u@@$vBB Jw B@JB@&@x@AAJxEU ey=֤Fxcz =@F€{% {@@ c !B|b ! } B@`B@x@A$A~Ewbb =j8`= @o6@ m!j @,J5J  B@aRB@x@A ARE aR =R=R(o@@ sÔ@%U7t-QPuBb^b jc B@jB@x@A$AjEpb jaj =j=j @\@~) @K +BB$B B@JBc@x@AAJEeJe=xxF =!k{% @2g@ c Abfb ! c B@aB@x@A$AE~!aFb =j=%pj"@@,@J}ߠJA# B@aRB@x@A AREaR FaR =R9=R%@@ , bUqqt 4^BbbA;j B@jB@x@A$AjETjaj =jW=j%-%n@V@ B^B$  B@JB@x@AAJEaJ> e="| ={% "@@ , Ab5b ! 5n B@aB@x@A$AEˀcb =jVa"@@,cJ"JA#Fc B@aRBc@x@A ARE-Ba(aR =RI= @9E@ 텱``$aBbDb@$j B@jB@x@A$AjEfaj =j8aj%-(%@@ B  B@JB@x@AAJE: e=F =&{% %@u@ * ! @ vAb  b B@aB@x@A$AEtbb =j4`="@H3@,J2J F B@aRB@x@A ARE aR =Ru=R"@@ Vqt'+aA Bb?b(½ B@@]B$X@x@A$AjEUb jaj =jժ=( @2@ $( @.`AJBJ)Bc B@JB@@x@AAJEbJe=]uF =@h{% @d@ 5\ @ Abxcb bc B@`B@x@A$AEcat b =j"=j"@W!@ m!j @J JA# B@aRBB@x@A ARE RaR =R="@܀@ %6% Eqa BbYb j B@jBF@x@A$AjEpb ]aj =j=%-(+c@_@JtJA#c? B@aRB@x@A AR@Ena aRA =R2v=R"B@q@y3Y+]qBCbpbD B@jB; @x@A$AjEE*jajF =j-=j%-(%G@,@ $( @"@BHBVBI B@JBW@x@AAJJE eK=FL ={"M@@ ;TANb4b! O B@aB@x@A$APEbbQ =jOa`="R@_@,SJJA#T B@aRBxJeBc@x@A ARUE,a aRV =R=R%W@1@ 7!oDa+BXbb½Y B@jB5n@x@A$AjZE jaj[ =jC׀=(%p\@ր@$]BՀB J$ c^ B@JBc@x@AAJ_E:e`=Fa =&{% "b@v@ Bcb  `cd B@aB@x@A$AeEJabf =j `=j$j%g@S @,hJJA#ni B@aRBy@x@A ARjE FaRk =Rɀ="l@Ā@ o)!#3a|[BmbBb jn B@jB <@x@A$AjoEU} b jajp =jŀ=%-+cq@#@$rB s B@JB@!K$X@x@AAJtE8 Jeu=]KFuyv =@>{ w@:@ ةAxbw9b y B@`B !@x@A$AzEbcb{ =j aj$%|@@,}JaJ ~ B@aRB@x@A AREpk a FaR =Rs="@`n@ 3!:6[qbmbf B@jB @x@A$AjE& jaj =*=j%-%@)@ Rr' @"@BBRB J)B B@JBc@x@AAJE} e=Fx =m{F% +c@@$X qbb! 륱 B@aB@x@A$AEb =j= @@,JpJA#j B@aRB@x@A AREYaR aR =R0a=R"@\@C3D Je=F =*{% "@t{@, ?Ab֡ !  B@aBc@x@A$AE5ab =j=^.@S@,cJJA#c B@aRB @x@A AREάaR aR =Rt=R"@֯@ cckXQ@@ c Zv++aNY@>B?bqb½@ B@jB@@x@A$AjAE,b jajB =j =(%-(%C@{@~DBܨB J$ E B@JB@x@AAJFEb-aJ,eG=FH = À h{% "I@Xc@ , AJb K B@`B @x@A$ALE.a* bM =j݀=G@² .N@8܀@,OJ۠J P B@aRB@x@A ARQE/aRaRR =Rh=R"S@@ N$F+!3 FUEat2BTb'b U B@jBc@x@A$AjVE9P0aj  AW =jS="X@@ !jn"AJYB}RAZ B@JB@x@AAJ[E 1J@=\=E|w3; ] = À{% ^@ @ A_b\b ` B@`Bc@x@A$AjaEGǀbb =jx2aj$j"c@م@,dJEJ 4` e B@aRB@x@A ARfET>3a FaRg =R F="h@\A@ ! elBib@bjj B@jB`@x@A$AjkE jajl =j_=%p+cm@@$nBB Jo B@JB@b2a,@x@AAJpEb4b Jeq=Fcr =@Z{% (s@@ J 5Atb ! u B@`B !,@x@A$AvEp5abw =j 16`=j$j%x@k/@ m!j @ @ yJ.J@.z B@aRB@x@A AR{E   aR| =R="}@@ e ÔPaJB~bnb j B@jB@x@A$AjE|7b j  aj =j =j @i@cBɥB$  B@JB,@x@AAJE_8J  e=qF|c =d{F% F%@>`@ ! @ @Bb ! b B@aB,@x@A$AE9ac  b =jڀ=j%pj%@ـ@,JؠJA# B@aRB@x@A ARE:aR FaR =RI=R"@@c1 ,$ a@ aBbb½ B@jB @x@A$AjEM;jaj =jP=j$+c@@$BfO J$  B@JB@x@AAJE<J >=&| ={% "@ @/ BAbAb h B@aBc@x@A$AjE,Āb =jR=a @@,JJ  B@aRB@x@ =AR @`E9;>a aR =RB=R"@I>@ Qke`BBb=b B@a$B ,@x@A$AjE jaj =jP=j%-(%@@ ) @(@BB B B@JB@x@AAJEF?e=ĄF =;{% "@@ ! @c WHAb ! b륱 B@aB "@x@A$AEm@ab =j-A`="@X,@,J+J B@aRB@x@A ARE䀈y FaR =R= @@#*t*Qb1aBbSb jc B@jBc@x@A$AjEaBb jaj =j٣=j%p(%@6@~ `@ťB B$ Bc B@JB@$/@'@x@AAJE[CJe=inF =@@+"a{% %@#]@ 5\ @+c G Ab\b bc B@`Bc@x@A$AEoDacb =j׀="@Հ@ m!j$JbJ(> B@aRB@x@A ARE|EaR FaR =R/=R"@@3*

=j=j%-(%?@@~@Bw B$ A B@JB@x@AAJBEUYJ88eC=3hFD =[{% "E@V@ ; @W GAFbNb bG B@aB 'Zc@x@A$AHE9Za9:bI =jmр= J@π@,KJ;J L B@aRB@x@A ARMEF[aR F;;aRN =R=R"O@R@ "~u$a*ZBPbbĩQ B@jB c@x@A$AjREC\j<?b^ =jz^aj"_@ay@,`JxJ ca B@aRB@x@A ARbE1_a @@aRc =R9= d@4@ 4"eaBebXbf B@jB/@x@A$AjgEn jAAajh =j= i@Q@~jB B$ ck B@JB@$@x@AAJlE`BBem=vF* n =@宀{% o@2@ c @#Bpbb cq B@`B@x@A$ArE|daacCDbs =j$b`=^6t@#@ m!j @ uJ{"J v B@aRB@x@A ARwEۀ FEEaRx =R>=R(oy@ހ@ $F!RoEeaBzb݀bĩc{ B@jB o@x@A$Aj|Ecb jFFaj} =j=(%-(+c~@@ r!j @"@BBPBJ B@JBc@x@AAJERdJGGe=eFc =X{% "@S@ c Ab3b 륱 B@aBc@x@A$AEeaHIb =jS΀=^"@̀@,J JA#j B@aRB5n@x@A ARE+faR FJJaR = Ȍ=R"@'@ c+WE"䐃)} Bbbf B@B@x@A$AjE@gaj2 jKKaj =j:D=(%p(%@C@~BBB J B@JB@x@AAJE8 JLLe=F/ =)ha% "@v c \*Ab ! B@aBc@x@A$AE,MNb =jwij)j%@Nv@,JuJA# B@aRB@x@A ARE.ja OOaR =Rz6=R"@1@ y~`paHBb9b½ B@jB; @x@A$AjES jPPaj =j="@7@ B쀃J$&5 B@JB@x@AAJEڥkb JQQe=[F =Ϋ{% F"@@ y! @W 'Lbvb b B@aBy@x@A$AEaalaRSb =j!m`=j^%@@ JXJ  B@aRB@x@A AREn؀ TTaR =R="@vۀ@ !d`%Kc}daEbڠb@$j B@jBb@x@A$AjEnb jUUaj =jy=%-(+c@Ֆ@ r$( @"@BB5BB B@JB@x@AAJE|OoaJ JVVe=F =dU{% %@P@ b$F @ Abb b륱 B@aBF@x@A$AE pacWXb =j0ˀ=j$j"@ɀ@,cJȠJA#F B@aRB{ B\ @x@A AREqaR YYaR =R="@@ p&r0!g {Bbb½ B@jB; @x@A$AjE=rajF jZZaj =jA=j%-%@s@@~B?Bc B@JB; @x@AAJE J[[e=F$X = {F% %@X@ hv/G?Ab ! B@aB@x@A$AEsb\]b =jtt`=j @/s@,JrJA#n B@aRB@x@A ARE+ua ^^aR =R[3=R"@.@+_ьYKoBb"b  B@jB@x@A$AjE8(__aj =j=j @(@B逃 B$  B@JBc@x@AAJEv``e=@F@ =㨀{% @.@ c KBbb  B@aB@x@A$AEF^waabb =jlx`= @@,J8JA# B@aRB{c@x@A ARESՠ@Y ccaR =R܀=R%@[؀@EKpd}Bbנb@%ĩ B@jB@x@A$AjEڐyb jd1A =jb=j%-(+c@@~BB B@JB@x@AAJEaLzaJ Jeee,  Fc =MR{% "@M@ @ UAb ! b  B@a$B* @x` =A @E{acfgb =jȀ="@vƀ@,JŠJ@Fc B@a B@x@A AR E~|aR hhaR =R= @@ @#+^+kFɂ bqb½ B@jB@@x@A$AjE{:}jiiaj =j>= @d=@ BEEIJtte?=ǤF@ =6O{% A@J@ 6 cCBBb  C B@aB@x@A$ADEauvbE =jĀ= cF@SÀ@,GJ J (RH B@aRB@x@A ARIE{aR FwwaRJ =Ry=R%K@~@ cS}ÔPz )a+BLbFb@$jM B@jBc@x@A$AjNE`7aj jxxajO =j:= P@J@rcQB9BR B@JB@x@AAJSE JyyeT=h|U ={% V@@ ! @c  BWbb b X B@aB $X@x@A$AYEnbz{bZ =jn`=j^+c[@l@@S' @\JeJ J] B@aRB; @x@A AR^E{%a ||aR_ =@3-="`@(@ c c0#~FP bhƀb ! c? B@aB/@x@A$A@ERbcbA =jA`=^"B@?@,CJQJ FcD B@aRB@x@A AREE`@Y aRF =R$R"G@p~LpRtZ)pKv@=4HbbjI B@jB@x@A$AjJE況, jajK =jo=%-(+cL@ʶ@ MB*BJ$ N B@JB@x@AAJOEmobw JeP=FQ =Uu{"R@p@, ASb b T B@aBL6@x@A$AUE*acbV =j%=j)%W@@,XJJA#(RY B@ B@x@A ARZEaR aR[ =R=FR%\@ @ #d`9n` t.Q! *@B]bubj^ B@jB @x@A$Aj_E]jaj` =ja=%-%a@l`@$bB_B Jc B@JB@x@AAJdEJee=+|f ={H yg@I@ Ahb ! i B@aB@x@A$AjEԀcbk =jÔaj^%l@$@,mJJA#n B@aRBB@x@A ARoEKa aRp =ReS="q@N@!3bKf aFBrb#Nb½s B@jB@x@A$AjtE*jaju =j = v@@$wBf J$ cx B@JB@8 @x@AAJyE ez=2ՄFwL6{ =@Ȁ{% :(|@À@c B}bLb ~ B@`B@x@A$AE7~btb =je>`=$j%@<@ m' @ J2J  B@aRB@x@A AREE aR =R=R"@M@yC@䐃(yEBbb B@jBy@x@A$AjE˰b jaj =jS=j%-+c@@~BB B@JBc@x@AAJERlJe=ӤF| =:r{% "@m@ 5n$F @+c  Ab ! b B@aB@x@A$AE'ab =j=%pj%@h@, JJA# B@aRB@x@A AREaR FaR =R=R"@@ S%`uvuw+haCaBb^b@$jc B@jBz@x@A$AjEmZjaj =j]=j @Q@ B\ B$  B@JB@x@AAJEaJ> e=u(| ={% F"@*@W @(SBbb bc B@aB; @x 9A$A @Ezрb =ja"@@,cJiJ@ @c B@a Bc@x@A AREHa aR =R&P= @K@ cG\uvdpEbbJbA;j B@jB@x@A$AjEajfaj =j=j%-(+c@@ B[B  B@JB@x@AAJE e=҄F; =ŀ{% %@@ c bb1b 'Z  B@aB@x@A$AE{bb =j7;`="@9@,JJ F B@aRB@x@A ARE) aR =R=R"@2@5ns~ }{zy5@;Dbb f B@jBy@x@A$AjEbjaj =j4=(%-(%@@ BB B@JB@٢oB@x@AAJE7iJe=Fx =@+o{% "@rj@ * ! @c  Ab e B@`B W!B@x@A$AE$ab =j=^1@D@ m'*QJJ  B@aRBL6@x@A ARE˛aR aR =R^=R"@@ c T7` cBb+bA;# B@jBc@x@A$AjERWjaj =jZ=( @?@$BY J$ c B@JBc@x@AAJEaJ e=Z%| ={%p@@ c nBbub B@aBc@x@A$AE_΀cb =ja^%@@,J^JA#F B@aRB@x@A AREmEa aR =RM=R%@qH@ cvwd`Xa8BbGb½ B@jBW@x@A$AjEjaj =j=j%-(+c@@ `@n"@BB<B B@JB@x@AAJEz e=F = Àf€{"@@$X  Abb!&U B@`B@x@A$AExbcb =j,8`=j+""@6@,.5J   B@aRB@x@A ARE aR =R=FR%@@ D %zNbrb j B@jB/@x@A$AjEb@Y jaj =j!= @@$ BݬB J$ c B@JBc@x@AAJ EfaJ Je =F = l{% F"@Xg@ / @1a0 6b  B@aB$X@x@A$AE!ab =j=j^%@5@,JߠJA#Rc B@aRB$X@x@A AREaR aR =RX="@@ c &v$p? Ba Hobbj B@jB $X@x@A$AjE7Tjaj =jW=%-(+c@ @$BoV J B@JB@x@AAJ!EJe"=?"`=# ={%p%$@@ 5A%bYb Zy& B@aB @x@A$A'EDˀb( =jta )@׉@,*JCJA#+ B@aRB@x@A AR,ERBa aR- =RI=R".@FE@ EG$1SF`xb/bDb j0 B@jB@x@A$Aj1E jaj2 =j`aj 3@@ 4B B5 B@JB &B@x@AAJ6E_ Je7=Fzc8 = O{ 9@@ c h:b ȥ! ; B@`Bc@x@A$A<Etbcb= =j5`= >@y3@, ?J2JA#c@ B@aRB; @x@A ARAE뀈 aRB =R=R%C@@ G`vwxez`4a^CHoDbkb½E B@jB@x@A$AjFEzb jajG =j=j H@X@~IB B$ J B@JB@x@AAJKEcJeL=uFM =h{% cN@9d@ , BOb ! cP B@aB@x@A$AQEabR =jހ="S@݀@ 2$,TJܠJA#U B@aRBc@x@A ARVEaR\aRW =RA=R%X@@ , -Q8ayYb b@$jZ B@jB{@x@A$Aj[EQaj?aj\ =jT=(%-(C]@ @ ^BlS g$ _ B@JB@x@AAJ`E aJea='|b ={% "c@ @ %mdbBb ! e B@aB@x@A$AfE)ȀAg =jVaj%pj6h@@,iJ$JA#Fcj B@aRB@x@A ARkE6?aaRl =RF=R"m@GB@ |}Qxua!DnbAb fo B@jB@x@A$AjpEjajq =j=="r@@ sBB $ t B@JB@@x@AAJuEDev=ɤFvw =@4{% F"x@@ ! @yK }Byb b z B@`B@x@A$A{Eqa ZW b| =j1`=^%}@U0@ mc~J/J ̶ B@aRB@x@A ARE耈FaR =R=R"@@$qGQ@l.Bb\b j B@jB@x@A$AjE_bjaj =j맀=(%-(+c@F@$B J B@JBc@x@AAJE_aJe=krFc =e{% "@'a@ >$F @  Ab`b ! b B@aB@x@A$AElayKc =jۀ=j c@ڀ@,Jo٠JA#{ B@aRB@x@A AREzaRA@aR =@3="@@ (o!%xү !tސBbbj B@B@x@A$AjENjaj =jQ=j @P@ !j @(AJBIB$B B@JB @x@AAJE J@== |/ ={F% @ @ ! @zbAb#b ! b B@aB@@x@A$AjEŀyb =j/aj$j"@@,JJA# B@aRB@x@A AREb B@jB@x@A$AjE jaj =j2=%-+c@@$BB J$  B@JBc@x@AAJE)e=F; ={% c@c@ Ab !  B@aB@x@A$AEna  b =j.`=j^%@B-@@SW`@yJ,JA#J B@aRB$X@x@A ARE F  aR =@f=R"@@ 3`GFcyvb-b jc B@B@x@A$AjEDb  aj =jԤ=j%-(%@/@ ) @"@BB B$B B@JB@x@AAJE\aJ   e=LoF =b{% "@^@ ! @c Abf]bĩ! b륱 B@aB@x@A$AEQb =j=j @Y@,JJA# B@aRB@x@A ARE aR =Rۀ=FR"@ր@ CGS0v"FadBbLb j B@jB@x@A$AjE_b jaj = ے=j(%@8@ $( @ťB B$B B@B@x@AAJEJaJ Je=Fnb =P{F% @!L@ ) @+c 7AbKb B@aB@x@A$AElayb =jƀ=j^"@Ā@,JgJ  B@aRB @x@A AREz}aRFaR =R)=R%@~@7!1S% w"$`%$abb½ B@jB@x@A$AjE9aj faj =jx<="@;@ B =R+=R"?@'@ C#6 uvuwa?B@bp&bA B@jB@x@A$>BE j))ajC =j =j%-%D@f@$EBB JF B@JB@x@AAJGE **eH=FI ={% "J@K@ W': @9 ]AKb ! b L B@aB@x@A$AMEV ac+,bN =j `=%O@@,PJJA#cQ B@aRBc@x@A ARRE F--aRS =RbՀ= T@Ѐ@ %$ E4a&BUb&b jcV B@jB@x@A$AjWE( b j..ajX =j= Y@@~$( @"AJZBp B$Bc[ B@JB@x@AAJ\EDJ//e]=0WF^ =J{% _@E@ @ c A`bKb ca B@aB@x@A$AbE600bc =j=^"d@B@,eJJ f B@aRB @x@A ARgEy F11aRh =RkÀ=R(oi@ɾ@ c0 Qb/Bjb5bĩk B@jB} o; @x@A$AjlECw"  j22ajm =jz=(%-(+cn@@ oB{yJp B@JB@!K5n@x@AAJqE2J33er=ҤFs =@8{% "t@4@ ! @c pAubf3b b v B@`B@x@A$AwEQ 44bx =j=j y@U@ m' @yzJJA#{ B@aRBc@x@A AR|Eש55aR} =R="~@଀@ 5a XBbLb  B@jB,@x@A$AjE^ej66aj = h= @E@ $( @(AJBg  B@Bc@x@AAJE J77e=F =&{% @""@ $F @6 Ab!b bc B@aB@x@A$AEl܀89b =jaj%pj"@Ꚁ@,JVJA# B@aRB@x@A AREySa ::aR =R.[="@V@ $F!3@zT˵zuy"av,BbUb@$j B@jB; @x@A$AjEj;;aj =j=%p+c@@$BHB J B@JB@c@x@AAJE <b =j:F`=j$j%@D@ m' @cJJA#c B@aRB@x@A AREu??aR =R$R"@'@zzÔ "(t]LBb j B@jB|@x@A$AjE@Y f@@aj =j2= @@ ' @"DBB$B B@JB@x@AAJE(tbwJAAe=F =z{F% F"@fu@ $F @+c Bb  bc B@aB@x@A$AE/acBCb =j=%pj"@B@,JJA#R B@aRB@x@A AREaR FDDaR = U=R"@@ 䐃NaZThްDfb$b j B@By@x@A$AjECbjEEaj =je=j%-+c@@ Bsd B B@JB@x@AAJEJFFe=K0| =#{% "@@ ! @.W zBAbfb b B@aB@x@A$AEQـGHb =jf a"@Ǘ@,J3JA# B@aRBc@x@A ARE^P!a IIaR =RW= @bS@ Fzxy}a0mBbRb@$j B@jB@x@A$AjE "jJJaj =jm=j @@ $( @(AJB)B B@JB@x@AAJEk KKe=F =\̀{F% @Ȁ@ Abb ! c B@aB@x@A$AE#bLMb =j C$`=j^"@A@,J@J Fc B@aRBz B@x@A ARE+ NNaR = p%$R(o@~ ~Y`vBblb j B@B @x@A$AjE, jOOaj =!!="@Z@BB$ B@JB@x@AAJE q&bw JPPe=Fw =w{% @Gr@$X Bb  B@aB$X@x@A$AE,'acQRb =j="@'@@S#2%JJA#J B@aRB@x@A ARE(aRSSaR =@[=R%@@!R! # mbbb½ B@B@x@ =Aj @`E(_)jTTaj0 `=b)`=(%-(1@ @ rBla J B@B`x@9 AJ @E*a  UUe=0-|c = {% "@@ $F @+c hbKb! b B@abB >"$X@x@A$A E5րcVWb =j`+aG r%dj+c @@,c J,J  B@aRB{c@x@A ARECM,a XXaR = U=R"@SP@ $F 3SSSS ADbOb½ B@B  @x@A$AjE-aj2 jYYaj =jR =( @ @~!j @"AJBB J$Bc B@JB@x@AAJEPĀ JZZe=ѤFy =Yʀ{% F"@ŀ@ ! @( xAb ! b B@aB@x@A$AE.b[\b =j@/`=$j"!@f>@,"J=J c# B@aRB@x@A AR$E ]]aR% =R=R"&@@ cCSStZ/Q'b]b ( B@jBc@x@A$Aj)Ek0b^^aj* =j=%-+c+@X@ $( @"@B,B $B- B@JB@x@AAJ.Em1J__e/=sF0 =s{% "1@-o1` c aA2bnb 륱3 B@aBc@x@A$A4Ey)2``ab5 =j=j^"6@ @,7JwJ Rc8 B@aRB@@x6 9A AR9 @`E3aR bbaR: =RA=G@Qx ";@@!oSTQTSu@z,B<bbo= B@a$B oc@x@A$Aj>E \4jccaj? =j_=%-`3A@@@$ABa^ JB B@JB@x@AAJCE5aJ ddeD=*|tE ={% "F@@t AGb0b! H B@aB@x@A$AIEӀcefbJ =jI6aj$j%K@@,cLJJA#M B@aRB@x@A ARNE(J7a ggaRO =RQ=R"P@0M@ o)!cSuSuSu"tc/]L3 QbLb½R B@jB@@x@A$AjSE8jhhajT =j7 = U@@ !j @"DVBBBi2rW B@JB @x@AAJXE5 iieY=F*Z =-ǀ{% F"[@q€@ c  \b ] B@aB@x@A$A^E|9bcjkb_ =j<:`=$j"`@;;@,aJ:J b B@aRB@x@A ARcE llaRd =R|=R"e@@ ,s4"md`& fbAb jg B@jB; @x@A$AjhEP;b jmmaji =j貀=j%-1j@E@~ `@ kB B$ Bl B@JBc@x@AAJmEj<Jnnen=X}Fo =p{ p@l@ ! @  qbskb b5nr B@aB@x@A$AsE^&=aopbt =j="u@@,vJTJA#w B@aRBc@x@A ARxEk>aR FqqaRy =R= z@w@  $cpttc.paD{b㟠b@$j| B@jBnb@x@A$Aj}EX?jrraj~ =jv\=j%-@[@ $( @(AJB2B B@JB@x@AAJEx@Jsse=F =]{F% (@@ W c lAbb ! 륱 B@aBV@x@A$AEπtub =j#Aaj^"@@,JJA#F B@aRBL6@x@A ARE GBa vvaR =RN=R"@ J@ d`eaBbyIb@$j B@jBz@x@A$AjECajywwaj =j'="@@cBB J$c B@JB@x@AAJE xxe=ЄF =Ā{% @V@ ': @c _Bb ! b B@aB@x@A$AEyDbcyzb =j9E`=^%@08@,J7J > B@aRB@x@A ARE {{aR =R^=R%@@ "*t aJVb*b@$ B@jBc@x@A$AjE5Fb j||aj =j=(%-(1@@ r$( @"@BBiB B@JBW@x@AAJEgGJ}}e==zFW =m{% "@h@ c AbXb c B@aB@x@A$AEB#Ha@Y| ~~b =j'=j c@W&@@S~°!j @BJ%JJ B@aRBB@x@A AREހRaR =@{="@@   ! !!2a(BbIb@$c B@B@x@A$AjEPIb aj =jĝ=%-(%@ @ rBµ) y B@JBc@x@AAJEUJaJye=Fb = À[{% %@W@$X lAbwVb !  B@`B WB@x@A$AE]Kab =jр=j%pjK@π@,cJ`J F B@aRBy@x@A AREkLaR FaR =  =R"@@ !E!Q![!`!o Bbb@& B@B@x@A$AjECMajF jaj = G=%-%@F@ B>B B@B,@x@AAJEx Je=FB =`Na% "@@ ) @ AVAbb  B@aB@x@A$AE$A = `!{Oaj @y@,JxJ F B@Bc@x@A ARE 2Pa aR =R9=R"@5@@ !!e!JK!aBb4bfc B@jB o @'@x@A$AjE jaj =j#=j @@ BB$ a5 ic B@A"Bc@x@AAJEQe=F = {%p@T@ @ Vvb ! bc B@aB,@x@A$AEdRab =j$S`="@7#@,J"JA# B@aRBc@x@A ARE FaR =R\= @ހ@'a$F @ !Qi  U`Eb*b aj B@jBy@x@ =Aj @`E5Tb jaj =j=j%-(+c@@~!j @.`@BB} B$B B@aB@x@AAJERUJe==eF =X{% (B ÀS@ hv/G?RAXb 륱 B@`B,@x@A$AEBVacb =)e΀="@̀@, J1JA# B@aRB@x@A AR EPWaR F-, =R=R" @T@ I!aaBbb@$j B@jByc@x@A$AjE@Xj#!j = cD=j%-(%@C@ BB J B@B@x@AAJE] e=ޤF =IYa"@!!%N .`# +c gA 3 ǝ! b  B@aBy@x@ =A @E䷁,b ==j)(f@@,J\J@Fc B@a B@@x@A AR EksZb aR! =R{=FR%"@ov@!+V?ve+i|B#bub j$ B@jBQ@x@A$Aj%E.[aj j//%& =jq2= '@1@ `@"AJ(B-BB$ Bc) B@JB@x@AAJ*Ex Je+=Q, = Àd{% F"-@@ cA.bb / B@`B@x@A$A0E\bb1 =jf]`=j^"2@rd@,,3JcJA#4 B@aRB@x@A AR5E ^a aR6 =R$="7@ @c!  B@JB@x@AAJ?E_e@=Fz$XA ={% %B@W@.! @ .`c u6C 3 D B@aB@x@A$AEEO`abF =a`=j G@+@,cHJ JA#FcI B@aRBy@x@A ARJE FaRK =RV΀=R"L@ɀ@ #+VŴJo!a}cDMb"b@$jN B@jB@x@A$AjOE5bb2 jajP =j=j Q@@~$( @w(AJRBy BS B@JB C=b@x@AAJTE=caJ JeU=@PFwV = C{%pW@>@ c ّAXbWb! cY B@`B@x@A$AZEBb[ =jgda"\@ɷ@ m!j%` ! !% AR]J5J F^ B@aRBc@x@A AR_EOpea aR` =Rw=!a@\s@ 3 {Ajbbrb fc B@jB@x@A$AjdE+fjaje =jV/=j%pjCf@.@gBB$ ,h B@JBc@x@AAJiE]Fej=ޤF{k =M{% (l@@ TAmb ! n B@aB@x@A$AoEgbbp =jch`="q@za@,rJ`JA#s B@aRBc@x@A ARtEia aRu =R!= v@@ C+V % !aywbab@$jx B@jBy@x@A$AjyExՠ@Y jajz =j؀=j%-(%{@S@~|B׀ B$ } B@JB@x@AAJ~Ejb i A8e=F =㖀{% %@4@ ) @ .`Q6 m 3b! b B@aB,@x@A$AELkacb = l`="@ @,J J Rc B@aRB@x@A ARE aR = @ˀ=R"@ƀ@ SYr0|uJ@hDbb j B@Bx@x@A$AjEmb jaj = =j%-(%@@ cB^B$  B@BB@x@AAJE:nJe=!MF = À@{"@;@ !%N .`E+c UA 3zaj^%@@, J JA# B@aRB@x@A AREj{a FaR =Rq="@)m@ cTD䐁Xa8Hoblbf B@jB~c@x@A$AjE%|jaj =j()= @(@ r5> @"AJB'B Jc B@JB@x@AAJE' e=F ={% @b@c Ab ! c B@aBc@x@A$AE}bcb =j\~`=j @8[@,cJZJA# B@aRB|@x@A AREa aR =RY=R(o@@ A%7ԣ@b'b@%j B@jBz@x@A$AjEBπ2 jaj =jҀ=j( B@aRBc@x@A AREfaaR =Rn= @j@ < E䐃a Bb~ib@$ @j B@jBW@x@A$Aj!E"aj aj" =j&=j #@b%@~r$B$B$ c% B@JB@x@AAJ&E ހ Je'=F( ={% )@C߀@ ) @+` $XB*b ! bc+ B@aBc@x@A$A,Ebcb- =jY`=".@X@,/JWJA#F0 B@aRB@x@A AR1Ea aR2 =RO=R(o3@@ *fV$ÔPOa[B4bb@$j5 B@jB@x@A$Aj6E&̠@Y jaj7 =jπ=j%-(+c8@@9B_΀ B$ : B@JB @x@AAJ;Ee<=.Fc= =!?{">@鈀@c A?bIbj! @ B@aB@x@A$AAE4CbB =jG=j9|C@8F@,DJEJA#RE B@aRBz@x@A ARFE FaRG =RdaFR%H@@ yTp +tt5BIb/b jJ B@jB@x@A$AjKEA jajL =jѽ=%-M@-@rNBB$ O B@JBc@x@AAJPEubw JeQ=ФFw!^|    AR = ){{% "S@v@ c BTbdb cU B@aB@x@A$AVEO1aɂbW =jx=j^%X@@,YJFJ >Z B@aRB@x@A AR[E\aR aR\ =R ="]@d@ ӔPŵaB^bЪb½_ B@jB@x@A$Aj`Ecjaja =jkg=%-(+cb@f@ rcB'B Jd B@JB@x@AAJeEjJef=F g =V%{% %h@ @ ! @K  Aibb b j B@aB@x@A$AkEڀbl =jaj m@s@,nJߘJA#Fo B@aRB{c@x@A ARpEQa aRq =RY=R"r@U@"t c,iBsb~Tbt B@jB@x@A$AjuE aj2 jajv =j=j w@`@ $( @(AJxBBy B@JB B@x@AAJzE Je{=ۄFxy| =@΀{% }@Fʀ@ c ]A~b ! c B@`B@x} 9A$A @Ebb =jD`=j @%C@ m!j @,JBJ@ B@a Bc@x@A AREFaR =RAaRF!@~ o @o"~$%UxBbb½c B@jB !@x@A$AjE&, faj = {=j%pj+c@@~Bf B$  B@JBc@x@AAJErbw Je=.F| =x{% (@s@ @0AbIb! b B@aB ",@x@A$AE4.b =j2="@81@,J0J B@aRBxc@x@A ARE aR =Rv=R"@@"#%&L$a+Bb?b$ B@jBB@x@A$AjEAaj =j=(%-(%@@ Bu $  B@JBh@x@AAJE`Je=ФFw!^. = )f{% "@b@ y) @+c fAbdab b B@aBc@x@A$AEOat ^b =j!=j)j.@c@,JJA#4` c B@aRBc@x@A ARE RaR =R߀="@ڀ@,"3`<}d`@5nܭBbQbA;a`oc B@jB* @x@A$AjE\b jaj =j䖀=%-%@@@@ c Bb=b B@aBy@x@A$AEb =ja"@@,JJA# B@aRB@x@A AREoaBaR =RYw= @r@ yS"}x~u$aTBbb j B@jB @x@A$AjE+aj+uaj =j.=j @-@ BUB B@JB@x@AAJEe=$F~ ={F% @@ B! @.W  Bb?b ! b B@aB "@x@A$AE&bA =jVb`=j^+c@`@,J%J  B@aRB@x@A ARE3a aR =R =R+c@<@ c4"܌Bbb  B@jB@x@A$AjEԀjaj =j:؀="@׀@~cBB$&5 B@JB@x@AAJEA@==ƤFq =9{% @}@ y c x~Bb !  B@aBy@x@A$AjEKa b =j `=^%3@Z @,J J c  B@aRBQ@x@A ARE aR =Ryʀ=R%@ŀ@ (o'Eos "Qk0S]LBb5b j B@jB oc@x@A$AjE\~b jaj =j聀=(%-(6 @B@ !j @B B BB B@JBc@x@AAJ E9aJ Je=dLF*  =?{% "@;@ ! @CAb:b b륱 B@aB@x@A$AEic  b =ja^"@@,J`JA#gc B@aRB@x@A AREwla   aR = 3t=R"@o@ cC!E ?kBbnb½ B@B@x@A$AjE'j  aj =j~+=j%-(%n@*@ $( @"@B B:B)B! B@JB@x@AAJ"E   e#=Fb$ =p{"%@@; +uA&b b! ' B@aB@x@A$A(E bcb) = `;_`=j)"*@]@,+J J , B@B@x@A AR-Ea aR. =R=FR%/@0@ E%0C! x$ʒB0bb½1 B@jB@x@A$Aj2E jaj3 = +Հ=%-%4@Ԁ@$5BӀB J$ 6 B@Bc@x@AAJ7E&e8=F9 ={% ":@c@ ': @c n`A;b ! b< B@aB .X@x@A$A=EHab> =j`=j^%?@7@,@JJ cA B@aRB@x@A ARBE FaRC =Roǀ="D@€@ % 0 r0QaLBEb:b@$jF B@jB$X@x@A$AjGEA{b.ajH =j~=%-(%I@@$JB} J$ K B@JB@$L6@x@AAJLE6aJ eM=IIFzN =@<{% %O@8@  VAPbc7bQ B@`Bc@x@A$ARENbS =jwa T@ٰ@ m!j @UJEJA#V B@aRB@x@A ARWE\ia aRX =R q=R"Y@`l@ (o!RoDъ0C""v 8BZbkb j[ B@jB o@x@A$Aj\E$aj jaj] = ^(=j%-(%^@'@~!j @n(@B_BB` B@B@!K@x@AAJaEi Jeb=F]Lc =@]{ d@@ c \'Aebb ! cf B@`Bc@x@A$AgEbcbh =j\`=$"i@sZ@ mjJYJ(>k B@aRB@x@A ARlEaaRm =R=R%n@ @ t"/4\~$ÔaBobyb p B@jB@x@A$AjqE f  ajr =jҀ=j%p%s@[р@ tBB$ cu B@JB@x@AAJvE b J!!ew=Fx =!{% "y@@@ m$F @6 Azb ^! b @ { B@aB 'Z@x@A$A|EE""b} = ``>J="~@H@,QJ J j B@BB@x@A ARER##aR =R=R"@ @ c @Pŀtt Ia Bbb½ B@jB c@x@A$AjE f$$aj = '=(%-(%@@ rB羀B J$  @d B@B@c@x@AAJE&xb J%%e=-FB =@~{% "@ay@ , :Ab !  B@`B,@x@A$AE3a&'b =j=^+c@7@ m'*QJJA# B@aRB@@x@A AREaR ((aR =R}=R"@έ@ o$F!RoK "$ %Uf) aBb:b½ B@jBɂ@x@A$AjEAfajf))aj =ji=j%-(%@*@~!j @"@BBh B$B B@JB,@x@AAJE!aJ **e=H4|@ ='{"@"@ $F%N+c Abcb! b륱 B@aB@x@A$AEN݀+,b =jqaj$"@ћ@,J=J  B@aRB@x@A ARE[Ta --aR =R\=FR%@`W@ *%+ , - ac B@aRB@x@A >!0E[?aRA@@@aR4 G=R%@oB@B#3C L䐃,PQ BbAb@&4j B@B; `x@9 Aj @`E jAAaj =A|`=^=(*+c@@ rBB J B@B@@x@AAJ EiBBe =F =@Q{% " @@ @ !#A bb b  B@`B@x@A$AEqaCDb =j"2`=^%@0@ m'+,J/JA# B@aRB@x@A ARE FEEaR =R=R"@@ cC0:Tu @a6Bbqb j B@jB@x@A$AjEb2 jFFaj =j=( @`@~ƹBB B@JB@x@AAJE `aJ JGGe=rF|c =e{% !@Aa@ c 1B"b ! # B@aB@x@A$A$EHHb% =j: =j%pj%&@@,'J J ( B@aRBy@x@A AR)Eנ@Y IIaR* =Rހ="+@,ڀ@ c Su L|h@[B,b٠b@%½- B@jB@@x@A$Aj.EJJaj/ =j/=j 0@@$1BB$ F2 B@JB@c@x@AAJ3E%NJKKe4=-5 =@T{F% F(6@bO@ ': @c B7b ! by8 B@`B@x@A$A9E a,LMb: =jɀ=j ;@3Ȁ@,<JǠJA#c= B@aRB@x@A AR>EaR NNaR? =Rq=R"@@Ƀ@ c cP_Q0U+fJBAb5b½B B@jB* @x@A$AjCE@<jOOajD =j?=j%-(1E@&@ $( @(@BFB> B$BG B@JBc@x@AAJHE PPeI=H |$XJ ={% "K@@ / @ K!Lbcb b륱M B@aB@x@A$ANENbQRbO =!!rs`= P@q@,QJ@J R B@aRB@x@A ARSE[*a SSaRT = 2=R"U@c-@ csu Au I$ 4 BVb,b@&W B@B* @x@A$AjXE jTTajY =jf=j%-(#Z@@ [B"B\ B@JB@x@AAJ]EhUUe^=F_ = ÀY{F% "`@@ @6 ]Aabb ! b b B@`By@x@A$AcE\VVbd =ja=j^(fe@_@,fJgJ Fcg B@aRB@x@A ARhEvRWWaRi =R( =R"j@@ T tZ/`C /OBkbbA;jl B@jBy@x@A$AjmEӀ XXajn =j׀="o@ր@~kpBIB J$&5q B@JB@x@AAJrEYYes=]t =h{% u@@ y c Bvbb w B@aB@x@A$AxE KZZby =jO= z@N@,{JMJA#F| B@aRBc@x@A AR}ER[[aR~ =R==R%@ @ `C ,UagBb b j B@jB@x@A$AjE€2 \\aj =jŀ=j%-(+c@Ā@~BXB B@JB@@x@AAJE}]]e=F =@{F% "@~@ b:b ! B@`B,@x@A$AE%9^^b =j==^+c@1<@,J;JA# B@aRB@x@A ARE/__aR =RQ=R"@@ W0% r0 VWDb bA;j B@jBc@x@A$AjE2``aj = = @@ cBv B$ c B@Bc@x@AAJEkJaae=Fc =q{% @l@ GBbUb c B@aB@x@A$AE@'abcb =jr=^%@@,J?JA#F B@aRB@x@A AREMaR ddaR =R=R%@]@ IAA R|Bbɠb@(j B@jB@x@A$AjEYjeeaj =jL]=j%-(+c@\@ BB B@JB@x@AAJE[Jffe=ܤF =C{% "@@ ! @ "Ab O! b B@aBc@x@A$AEЀghb =ja"@t@,JJA#F B@aRB@x@A AREGa iiaR = O=R"@J@ ,P)Q 7vbgb½ B@B @x@A$AjEvjjjaj =j=( @B@$B J$ c B@JB@x@AAJE kke=~фF{ =Ā{% @3@ vbb c B@aB,@x@A$AEzb Zlmb =j:`=j+c@ 9@,Jv8J F B@aRBw@ Bl@x@A ARERA@nnaR =@?=R%@@@#T?0:TQ[` b b j B@B}$X@x@A$AjEb jooaj =j="@@/)n"IB[BB B@JB@x@AAJEhJppe={Fc =n{% @i@ , ib:b B@aB@x@A$AE%$aqrb =jL=^"@@ =%JJA#n B@aRBc@x@A ARE2aR FssaR =Rݢ=R%@2@!!R!\p ~Aq"aODfbbf B@jB@x@A$AjEVjttaj =jAZ=(%p(1@Y@ rBB J B@JB@y@x@AAJE@Juue=F = 8{% "@{@ / Ab ! B@`B/@x@A$AÈvwb =jaj$j%@Y@ mJŋJA# B@aRB|c@x@A AREDa xxaR =RL="@G@ c|ӐZ0XTuaBbLb½ B@jB~@x@A$Aj5  `E[7@ 2 jy<A = 0`== @H@~B B$  B@Bc@x` =AJ @EỀ Jzze=b΄F;  ={% F%@@ ! @ aB b}b! b B@abBy@x@A$A Ehwb{|b =j7`=j @5@,JkJA# B@aRB@x@A AREu@Y }0$F =R="@n@ $G J@l|Bbb f B@jBt@x@A$AjEb~&!j =j=%-(+c@欀@ $( @(@BBDB,B B@JB@x@AAJEeJe=xF =sk{% %@f@, ȎAb#b 륱 B@aB@x@A$A E !a:#"! =j5=j "@߀@,#JJ ($ B@aRB}c@x@A AR%EaR $!R& = {Ο=R"'@+@c $JT +f D FB(bbj) B@jB@x@A$Aj*ESjaj+ =j"W=j%-(%,@V@ -BUB) c. B@JB@x@AAJ/E%aJ} e0=Fc1 ={% "2@a@c $A3b ! c4 B@aBc@x@A$A5Eʀc4q$^6 =jۊ a(f7@>@,8JJA#9 B@aRBx@x@A AR:EA a aR; =RTI="<@D@ $#@ du`$+jL$B=b!bA;j> B@jBB@x@A$Aj?E?@Y jaj@ =j a%-(%A@ ~BBdB(B$ C B@JB B@x@AAJDEƸ JeE=G˄FvcF =@{% "G@@ y5\ @+c AHbbbe! bI B@`B@x@A$AJEMt bcbK =jq4 `=^%L@2@,MJ@JA#cN B@aRB@x@A AROEZ@Y FaRP = + =R"Q@f@ c34u$ bBRbb½S B@B@@x@A$AjTEb jajU =jU=j%-(%V@@~WBB$ X B@JB@٢o@x@AAJYEhbJeZ=F$X[ =@Xh{% "\@c@ ! @( 9A]bb ! b^ B@`B@x@A$A_Eab` =jހ="a@y܀@ m'$,bJ۠J c B@aRB@x@A ARdEaR FaRe =R=R"f@@ CŲ c4Bgblb#h B@jBc@x@A$AjiEPjajj =!! T=(%-(%k@eS@ $( @(@BlBRB J$Bm B@JB@x@AAJnE Jeo=|ycp ={% "q@B @ tArb ! 륱s B@aB@x@A$AtEǀbu =jaj%pj"v@#@,wJJA#x B@aRB@x@A ARyE>a aRz =RFF=R"{@A@ S RC-t B|bb j} B@jB,@x@A$Aj~E$ jaj =j="@@BpB$ B@JB@x@AAJEb Je=,ȄFc ={% F"@趀@ c wBbGb B@aBc@x@A$AE2qacb =jV1`=j @/@, J%JA# B@aRB@x@A ARE?aR =R="@C@!1`@.!cT?0PT~ WBbb  B@jB2W@x@A$AjEƣb f#%9 =jB=%-(+c@@ rBB  B@JB@!KQ@x@AAJEM_Je=ΤFvc =@Ee{% %@`@ [Ab   B@`B @x@A$AEab =jڀ=j$j+c@Jـ@ mJؠJ  B@aRB$X@x@A AREaR FaR =R="@ᔀ@ c sA"|kk=BbMb½ B@jB@x@A$AjEhMaj2 jaj =jP=%-%@S@~BO Jc B@JBc@x@AAJEaJ Je=o| ={% %@, @ ! @ (b b! b B@aB#'Zh 5@A$A @EuĀ&( =ja @@,JtJ@ B@a B@x@A ARE; a aR =R+C=R"@>@ PQ 0+ia:n!b=b  B@jB| c@x@A$AjE jaj =j=j @@ $( @(EBABBc B@JB@x@AAJE!e=ńF ={% @γ@ ) @+c t b,b bc B@aB-"@x@A$AEn"ab = ``<.#`= @,@,J J c B@B@x@A ARE$@Y: aR =R=R%@$@ T+aq0BDfbbf B@jB @x@A$AjE$b jaj =j7=j%-(+c@@~BB) Q B@JB@x@AAJE2\%aJ} Je=F =b{% "@k]@ @4 2Ab ! b B@aBy@x@A$AE&acb =j׀="@?ր@,JՠJ (R B@aRB@x@A AREƎ'aR aR =R= @֑@ @ ,Sq}6FvbBbj B@jBɂ@x@A$AjELJ(jaj =jM=%-(%@0@ BL(J$  B@JB@&@x@AAJE)Je=T|* =@ {% %@ @x Ovbob !  B@`B0 c@x@A$AEZcb =j*a$j.@@,JMJ! B@aRB@x@A AREg8+a aR = @=R"@k;@* $6 #0/S# MDb:bf B@B@x@A$AjE jaj =jv=(%-%@@ nB2B J$ &JBc@x@AAJEu,e=Fwy =m{% "@@ ! @ Abb b B@bB@x@A$AEj-ab =j2+.`=^% @)@, J(JA#j B@aRB/@x@A AR E FaR =R=R"@ @ $Xp! S b aBbub j B@jB@x@A$AjE/b jaj =j=(%-(%@x@$B؟B_  B@JB@x@AAJEY0Je=kF =_{% "@QZ@ GJAb  XF B@aB@x@A$AE1ab =jԀ=j c@$Ӏ@,JҠJA# B@aRB@x@A AR!E2aR@Y FaR" =RQ=R"#@@ c @B$bb j% B@jB !@x@A$Aj&E1G3aj Iaj' =jJ="(@@)n(AJ)B}I Jc* B@JB@x@AAJ+E4aJ e,=9|c- ={% .@@ ! @c .A/bTb! b 06`aB "@x@A$A1E? b2 =j€=j 3@K@,4JJ (Rc5 B@aRB @x@A AR6Ey5b RaR7 =Ra=R%8@|@ $Xl1 "0TaqB9b.bj: B@jB@x@A$Aj;EL56aj jaj< =j8=j%p(+c=@.@~$( @ť>B7 B$Bc? B@JB@x@AAJ@E JeA=ۤFWB ={% "C@@, ADbob cE B@aBL6@x@A$AFEZ7bG =j ="H@j@,IJ֮JA#>J B@aRB@x@A ARKEg8RaRL =Ro="M@j@ prS"arBNbMb$O B@jB@x@A$AjPEg#9jajQ =j&=j%-(%R@O@ rSB% BT B@JB@x@AAJUE eV=FW ={% "X@(@ ! @c AYb߀b b Z B@aB@x@A$A[Eu:bb\ =jZ;`="]@Y@,^JoXJA#_ B@aRB@x@A AR`Eabq = `A?`=^"r@@,sJ J t B@B@x@A ARuE$@Y: aRv =R€=R%w@(@ +\ qSq"#0@,Dfxbb½y B@jB@x@A$AjzEv@b jaj{ = 3z=j%p(+c|@y@ }BxBJ$ ~ B@B@x@AAJE12AJe=F =%8{"@l3@ !%Nc Ab  by B@aB@x@A$AE1 b =je=j%@@,J4J (R B@aRB@x@A ARE?Bb RaR =R簀=FR%@?@ #S#u aovCbb j B@jB y@x@A$AjEdCaj jaj =jIh=%-@g@r$( @"AJBBB B@JB@x@AAJEL DJeT =<&{% "@!@  c#˄Ab  륱 B@aBc@x@A$A0Eۀb jEaj^"@f@,* JҙJ ݡ B@x@A AR @RFa FaR =RZ=R"@U@ %3 +b6`7HBbPb½ B@a$B$X@x@A$AjؠEgGjaj j=j%p(&@U@ B B}B@x@AAJ}E e @o܄F/ =π{% "@+ˀ@ y! @c3Abʀb b á$B@x@A$ASEtHbbEI`=%@C@,cJkJ c B@x@A ARc  aR2JaR"@~ cCS#Kb  |lbb$Bc@x@A$Aj˱E ,aj=j @@ $( @"DBYB gƹB@x@AAJIEsKbw )e @F =y{F% @t@  c lb/b ! c B@a$B@x@A$At$B@@x@A$Aj=ΠE#[  jaj# -=j%-(%$@@~%Bc B4ڡB@x@AAJ7EL\  Je6%=F) kR{% "*@M@, hv/G?A+bFb j! 0RkB@x@A$A- @1]`*b. -jnȀ="/@ƀ@@Sf0J^ uaR3 -@a놀= 4@F@ cT% Gu!YtɂB5bb !BB@x@A$Aj E:_ jaj8 -jY>=j 9@=@ :BB$ ݡB@x@AAJELwee=ѤFy>D{% ?@@ +B@b ^! /$Bc@x@A$AEұ` QbC -qa #D 0@Up@,cEJoJ B$X@x@A AR E(b #A  aRH -0=(oI@+@o%+ctc B@x@A ARE aRLe;ڀ=R%J@Հ@ B t 䐃R +l |BHbb fҡ$BB@x@A$AjEfb jajEx=(%-%C@Ԑ@ CoB4Bµ$ Bc@x@AAJEIgJ @=-=\@] ch kOM% "i@J@ / @ }Ajb+b bck B@o>B@x@A$AjlE@,bm =j?ŀ=j n@À@,oJ J p B@aRB@x@A ARqE#|An  F  aRr = *у="s@3@ <}YE7 *Btb~b@&u B@Byc@x@A$AjvE7B  j  ajw =j2;=%-(%x@:@$yB9Bz B@JB@x@AAJ{E0 J  e|=F} ={% %~@k@ , iAb͡ 'Z B@aB5n@x@A$AE  b =jnj @>m@,JlJA#Fc B@aRB@x@A ARE%E  aR =Ro-="@(@ 9KXo`-%$Z Bb=b@&j B@jB@x@A$AjEK@Y jaj =j=j @(@ cB〃 B@JB@x@AAJEҜH J >=Sk` -¢{F% @ @  c $Bbnb B@aBc@x@A$AjEYXJ0cb =jwjj1@@@Sr°!j @ JDJ J B@aRB@x@A AREfϠ@Y aR =@ր=R(o@ZҀ@ p#-0QD<@{BbѠb  B@B @x@A$AjE튌 jaj =ju=j @ҍ@$B1BJ)  B@JB@x@AAJEtFL Je=Fx =XL{% @G@ c DBbb  B@aB W9@x@A$AENs b =j=%pj%@@,,J_J F B@aRB*@x@A AREyaR =Rŀ=R%@u@,&,Q[`QD>Bb῀b  B@jB@x@A$AjEyQ5 aj =j|=j%-1@{@ cBHB B@JB@x@AAJE4 Je= =:{% "@5@, Ab+bZ B@aBc@x@A$AEb =j6W"@@,cJJ  B@aRB@x@A ARE#gT)  aR =Rn=R"@'j@Q&1 Qz|tI/*-Bbib½ B@jB o,@x@A$AjE"U jaj =j2&=( @%@ $B$B B@JB@x@AAJE0ހ Je=F/ =${% `3b@i߀@, -Bb ! B@aB "c@x@A$AEX b =jY^+c@>X@,JWJ (R B@aRB@x@A ARE !!aR =Re=R%@@ #4tɂrژb%b  B@jB @x@A$AjEK̀j""aj =jπ=( @2@ B΀µ$  B@JB@x@AAJE҇K ##e=WFx =ʍ{% @@ b5\ @, KEbnb b B@aB@x@A$AEYC\$%b =j\j%@@,JWJ B@aRBz  @' @x@A AREf DE &&aR =R€="@n@&3RFt"Q bڼb½ B@ABB@x@A$AjEu` j''aj -j}y=(%-(1@x@$B9BJ B@JB@x@AAJEt1 J((e=Fc =d7{% (@2@ y': @ Abb b B@aB@x@A$AE1 ))b8j=j @@,JfJ (Rc B@aRB$X`x@9 AR @`E R**aR =?=R"@@ cCk0SC!Qk0`̠Ǝbbj B@a$Bc@x@A$Aj Edb j++aj =jg=j @f@~$( @(D BLB B@JB@x@AAJEJ,,e= =%{ @ @ c ,vb*b ! c B@aBc@x@A$AEۀ --b =j߀=j @%ހ@,JݠJA#  B@aRB@x@A ARE..aR =RH=FR%@@ S ?kE%0aDfbb j B@jB@x@A$AjE#R  //aj =jU=j%p+c @ @ !BoT B$ " B@JB@x@AAJ#E  J00e$=FL6% ={F% "&@@ ! @c @aF33aR/ =RG=R"0@FC@ &cC! 0 0aGB1bBb½2 B@jBh@x@A$>3E f44aj4 =jP="5@@ $(n"AJ6B BJ$B7 B@JB@x@AAJ8EKb J55e9=̤F: =7{% ;@@ c 8A<b  = B@aB 9t@x@A$A>Era67b? =j3^"@@e1@,AJ0J B B@aRB@x@? =ARC @`E逈88aRD =R=R%E@@ s r0QDъ0`̠~BFbGb½G B@a$BF@x@A$AjHEfb f99ajI =jꨀ=(%-(+cJ@E@ rKBJL B@JB@x@AAJME`aJ J::eN=nsFO =f{% "P@*b@ ! @c AQbab b R B@aB@x@A$ASEsac;>aj^ =jR=j _@Q@ $( @(AJ`BPBa B@JB* @x@AAJbE J??ec=Qd ={F% e@ @ c Afb.b ! g B@aB@x@A$AhEƀ@Abi =j:ej j@@,kJJA#l B@aRB@x@A /mE"=a BBaRn =RD=FR(oo@3@@ o @o4"䐃()@CVBpb?bq B@jB5n@x@A$AjrEfCCajs =j9=%p(+ct@@$uBB J$ v B@JBc@x@AAJwE0DDex=Fy ={% "z@f@ ': @ژ{b ! b| B@aB$X@x@A$A}EoEFb~ =j/j$j(f@5.@,J-J  B@aRB@x@A ARE GGaR =Ri=R"@@ PGtZ/Ô@7JFDb0b jc B@jB@x@A$AjEKfHHaj =jӥ=j%-%@.@ $( @"@BB B$B B@JB@x@AAJE]JIIe=WpF5n =c{% "@ _@F Abm^b 륱 B@aB@x@A$AEXacJKb =jzـ="@׀@,JGJA# B@aRBc@x@A AREf$J oA@LLaR =@="@j@ 3$U00*vqBb֒bo B@B@x@A$AjEKb jMMaj =jmO=%-(%@N@~B,B B@JB@:W@x@AAJEsJNNe=F* =@c {% "@@ 5n! @c  rAbb ! b B@`B@x@A$AE€cOPb =j$a^%@@ m2 @* JJ  B@aRB@x@A ARE:a QQaR =RA=!@=@ , 1$"QD@ a&Bb B@aRBB@x@A AR?EefrraR@ =Rn=R"A@qi@, '3> "Kc$"rBBbhb4½C B@jBy@x@A$AjDE!jssajE =j`%=( F@$@ rGB B J$ ,H B@JB @x@AAJIEs݀ tteJ={|*K =@c{% L@ހ@, tBMbb! !n@ cN B@`By@x@A$AOEbuvbP =j(YNsj%pj+cQ@W@ mRJVJA#S B@aRB; @x@A ARTEOB wwaRU =R="V@@!!!C4eu*zBWb{b½X B@jB; @x@A$AjYEˀ2 jxxajZ =jπ=%-+c[@{΀@~\B̀B J$ ] B@JB@x@AAJ^EQ Jyye_=Fx` = {% (a@P@ !Abb ! c B@aB5n@x@A$AdEBz{be =j`=$j%f@*@,gJJ h B@aRB@x@A ARiE ||aRj =R`=R"k@@  St-/4%~Ozalb%b m B@jB@x@A$AjnE/ub j}}ajo = x=%-%p@@ qBsw r B@B@x@AAJsE0aJ~~et=7CF}]Lu =6{% "v@1@ ! @ $wbVb bx B@aB@x@A$AyE=bz =jhWj^%{@Ǫ@,|J3JA#} B@aRB} BL6@x@A AR~EJcb FaR =Rj=R"@Zf@ ycRYdp%QYpn!beb@(' B@jB; @x@A$AjEjaj =ja"=j%-(%@!@ $( @"@BBB)B B@JB@x@AAJEXڀ@Y e=ݤFy =D{% "@ۀ@ b/ @6 t b Z b륱 B@aB@x@A$AEޕbb =jV\"@qT@,JSJA#rR B@aRB@x@A ARE ]\ aR =R="@@ csUVSBa[Dfb`bj B@jB @x@A$AjErȀ jaj = ˀ=%-(%@H@~Bʀ(B B@B@@x@AAJEd Je=zFW =@퉀{% "@5@ y! @6 Abb b B@`By@x@A$AE?acb =j=^%@ @,JwJ  B@aRB@x@A AREaR aR =R9=R"@@ yx|?C!Bbb½ B@jB; @x@A$AjErcT jaj =ju=j @t@~$( @"AJB@B B@JB @x@AAJE-e=@| =@3{% @.@ 8b c VhAb7b ! c B@`By@x@A$AE"b =jJa"@@ m!j$,JJA# B@aRB@x@A ARE/`a FaR =Rg=R%@#c@  ttps"\x$aBbbb j B@jB@x@A$AjEjaj =j>=(%p(+c@@ BB J$  B@JB@x@AAJE< e=F =!݀{% "@u؀@m @c ZAb ǝ! b|y B@aB 'Z@x@A$AEÒbb =jR`=j%pj(f@RQ@,JPJ F B@aRB@x@A ARE k~ aR =Ry=R"@ @ \v@$uaTBb=b j B@jB@x@A$AjEWŀ jaj =jȀ="@2@BǀB$ B@JB@x@AAJEހc Je=_`=c =҆{% F"@@ ) @6 Bbzb b B@aB@x@A$AEe B@aRB@x@A AREraRuaR = ="@v@  "u " u Bbⵀb  B@B@x@A$AjEnqv faj =j}r=%-(+c@q@ rB=B c B@JB@)@x@AAJE*r{e== = t0{% %@+@ ! @6 #Ab b bc B@`B@x@A$AEcb = `'dj @@ m' @JJ  B@B$X@x@A ARE]aaR =Rd="@$`@ u JE~%u Ib_b j:  jB@x@A$AjEaj2 aj =j#=%-(%@~@~n$( @.`@BBB Jc B@JBc@x@AAJE! Je=ʤFS, =ڀ{% % @_Հ@ $F @+c f b ! b륱 B@aB@x@A$A Exb =jOx%pj"@?N@,JMJA#j B@aRB@x@A AREdF aR =R^=R"@ @ s<C""t!/a}Dfb.b  B@jBx ! u@x@A$AjE< @Y jaj =jŀ=j%p%@(@ BĀ c B@JB@x@AAJE}e=DF$X ={% "@@ ! @+c \Ab_~b bc B@aB@x@A$A!EJ9ab" =js= #@@@Sr°' @c$J@J R% B@aRB@x@A AR&EW~c FaR' = =!(@c@ cv "P0 nb6ɂ)bϲb* B@B@x@A$Aj+Ek jaj, =jRo=j%-j%-@n@~$( @(@B.BB)B/ B@JB@x@A>0Ee'd} Je1=F2 =Q-{% %3@(@ , ɂ4bb! 륱5 B@aB@x@A$A6Ecb7 =j!a"8@@,c9JJA#: B@aRB@x@A AR;EYa aR< =Ra= =@]@ y (SP"("CaMDf>bm\b½? B@jB@x@A$Aj@E5 jajA =j=%-(%B@c@~CBB cD B@JBb@x@AAJEEр JeF=FL6G =ր{%H@@Ҁ@t AIb J B@aB@x@A$AKEbL = `L^(fM@K@,NJJJ O B@B@x@A ARPEe@Y: aRQ = +D =R"R@@ $F!!(C[CgB0hBSb b jT B@B@x@A$AjUE! jajV =j€=(%-W@@ n!j @`" "AJXBeBY B@JB@٢oB2ay@x@AAJZEze[=)Fc\ =@{ ]@{@c #4^bHb c_ B@`B@x@A$A`E/6aba =j]=^"b@@,cJ)J cd B@aRB/@x@A AReEc B@aRBw* @x@A AREa FaR =R.="@@ 3($)St).SnbDfbbf B@jBy@x@A$AjE jaj =j=%-%@뾀@ rBJB J B@JB@x@AAJEwe=F =y}{% %@x@ ! @( Zhb)b b B@aB@x@A$AE3cb =j2=j @@,JJ c B@aRB|@x@A ARE! FaR =Rñ=R"@!@ Ct .?1 ֐)Dbb B@jB@@x@A$AjEedfaj =j,i=j @h@$BgB J B@JB@@x@AAJE.!aJ e=F} =@'{G e @j"@ c }Bb ! B@`B !@x@A$AE܀b =jaj @H@ m!j @JJ c B@aRB@x@A ARESD aR =Rm[=F!@V@ Sp;/*`aBb7b½c B@jB@x@A$AjEIi jaj =j=j @&@~) @w.`AJB B$Bi B@JBc@x@AAJEʀe=Qd =Ѐ{% @̀@c ^JAbpˀb  B@aB@x@A$AEWb =jFa"@D@, JRJA#j B@aRB@x@A AREd FaR =RaR @h@ c%?)e p`Bb ĩ B@jB* @x@A$AjE븀jaj =jo=j%-(1@̻@~B+B B@JB@),@x@AAJErtbw> e=F =@^z{% .W@u@ y) @6  Abb! b B@`B@x@A$AE/acb =j,="@@,cJJ  B@aRB@x@A ARE aR =R=R"@@(sR`<|Bb~b@(j B@jBy@x@A$AjEbd jaj =jf=j @ne@~BdB c B@JB @x@AAJE( Je=0| =#{"@O@/ zBb  B@aB@x@A$AEـb =jʙc1.@-@,JJA#F B@aRB; @x@A AREPa aR =RSX=R%@S@ e#a\iBbb@$j B@jBc@x@A$AjE.  jaj =j=(%-+c@@ n;f  B@JB c@x@AAJE Je=6ڄFu =@̀{*c@Ȁ@ c AbQb  B@`B@x@A$AE<d^b =jpC`=^% @A@, J>JA#F-ȯj`'F ;` >A8 y  `  @'  5  > @@IE@`;    A =@`=`G "=  @@3c@I~ %~@ `@1 @# K (R`<[+` !C bbb`bB aj B@B j@x@A$AjEе, DE jaj =A6T=H <=!jj!@@ ?@!j @K $ BBB J BiJ B@B@J!K@x@AAJEVqbw J@==؃`=}3#:  B " =@Cw{"@r@@at! @ hv/G? Ab ,! biX$^ B@`B !@x@A$AjE, aj 5!b =j=j^"@h@ m`@> ! @ AR JJ R `JR-! B@aRB@x@A AR"E aRRA@aR# =@=G "$FR"$@@ @pS%"ϥ yAj%b_b@&j& B@B{ @x@A$Aj'Eq_ aj jaj(; ] c=%p%n)@\b@r$( @r"@B*BaBB$B+ B@B@!K@x@AAJ,E aJe-=y-|z. =@ {% "/@5@ $F @ =A0bb b륱1 B@`B !@x@A$A2Eրb3 = `` aj$j"4@@@Sm!j @5JzJ J6 B@B@x@A AR7EMa FaR8 =@=U="9@P@?ㅲaxB:bbf; B@B @x@A$Aj<E jaj= = { =%-%>@ @ r?BSB J@ B@JB@x@AAJAEĀ eB=ׄFC =ʀ{% %D@ŀ@ @.W AEb6b! b F B@aB "@x@A$AGE bcbH =jI@`=j%pj%I@>@,cJJJ K B@aRBzLW?@x@A ARLE.@YE aRM =R=R"N@&@ cŲ&䐃(@BObb@%½P B@jB| @x@A$AjQEb2 jajR =jA=j S@@ TBBJ$ U B@JB C!Kc@x@AAJVE;naJ JeW=FwcX =+t{% F"Y@yo@ ) @+c BZb  b[ B@aB@x@A$A\E)ab] =j=%^@M@ m!j%c_JJA#Fc` B@aRBc@x@A ARaEϠ8@T aRb =R|=!c@أ@ 1P)t/`%@BdbDb fe B@jB@x@A$AjfEV\jajg =j_=jj+ch@9@iB^ Bj B@JB@@x@AAJkEJel=^*|{m =@{% n@@c Aobyb p B@`B@x@A$AqEdӀbr =ja"s@@ mtJZJA#u B@aRBc@x@A ARvEqJa aRw =R*R=R(ox@yM@ %o.!3$4ǏacBybLbĩz B@jB@x@A$Aj{Ejaj| =j =( }@@ ~B<B B@JB@x@AAJE~ e=ԄF = 5wǀ{% @€@ $F @+c aBbb ! b B@aB 'Z@x@A$AE}bb =j;=`=^+c@;@,JJ B@aRB@x@A ARE@Y: aR =R=R%@@ 1 $1 "@Bbb@% B@jBx ,@x@A$AjEb.aj =j"=j @}@ BݱB J$  B@JB@x@AAJE kaJ @==Fc = Àq{"@fl@ !%N( #yBb ! b B@`B "@x@A$AjE&acA%b \ ``=)%@2@,JJ >c B@B@x@A ARE aRaR =Rf=R%@@ !)E"e",/Bb,b½c B@jB @x@A$AjE;Y!jaj = \=(%-1@@ r$( @"@BB[ J$B B@B@?!K  @x@AAJE"Je=C'| =@{% "@@ W c LAb^b 륱 B@`B@x@A$AEHЀb =jn#aj$j"@ώ@ m!j @` J;J , B@aRB{y@x@A AREVG$aaR =RO="@jJ@)7$/pAu$`A aq@BbIb j B@jB@x@A$AjE%aj2   aj =j]=%-%@@~ƹBB J B@JB@@x@AAJEc J  e=F| =@TĀ{% %@@ @ ղAb ! b B@`B@x@A$AEy&b  b =j:'`=%pj%@i8@ mJ7JA# B@aRB@x@A ARE  aR =R=R"@@ #Aq8ӔP8d`aBbtb  B@jByc@x@A$AjE~(bjaj =j = @g@ BƮB $  B@JB@x@AAJEh)aJ e=zF =m{% F"@E-aJ} e=($| ={%p"@@!! @ AbCb B@aB@x@A$AE-̀yb =jd.a%@ċ@,J0JA#c B@aRBc@x@A ARE;D/a aR =RK="@GG@ cC A8ÔPAm`OBbFb½ B@jB~@x@A$AjE jaj =j60` @@ $( @ "AJBBBc B@JB@&@x@AAJEH Je=ɤFy< 4{%p@@ y c OAb什b'Z  B@`B`x@9 A @Ev1bcb =j62`=^"@Z5@,J4J@ B@a B@x@A AR E aR =R{=R% @@ cSӔ@%O8TAsB bHbA;j B@jB@x@A$AjEc3b jaj =j笀=j%-(+c@H@~B B$  B@JB@@x@AAJEd4Je=kwF$X =@j{% "@%f@ ! @c Abeb b, B@`B@x@A$AEp 5ac b =j="@ހ@ m'$yJgJA# B@aRB@x@A ARE~6aR\!!aR =R1=R" @@!Rc(T<9T`zYB!bb j" B@jBc@x@A$Aj#ES7j""aj$ =jV=(%-(%%@U@ $( @(@B&BQB J' B@JB@x@AAJ(E8aJ ##e)=!* ={bxe "+@@ $F%N6 fA,b'bǝ! b륱- B@aB 'Z@x@A$A.Eʀ$%b/ = ``69aj$j"0@@,1JJ 2 B@B@x@A AR3E A:a &&aR4 =RH=R"5@(D@!3 s:T%; a76bCb½7 B@jB @x@A$Aj8E''aj9 =j6;a":@~ ;BB $c< B@JB@x@AAJ=E-  ((e>=Fc? =%{% F"@@i@ ! @Y Ab ! b B B@aBB@x@A$ACEsb f,,ajN =jȩ=%-+cO@&@ r$( @"@BPBJ$BQ B@JB@&@x@AAJREa?aJ J--eS=PtFuT =@g?`{% %U@ c@ $F @+c AVbkbb bcW B@`Bc@x@A$AXEU@a,c./bY =j݀=jj"Z@ۀ@,c[J\J \ B@aRB$X@x@A AR]EcAaR 00aR^ =R="_@k@ %=QT>@/axB`bזb½a B@jB@x@A$AjbEOBj11ajc =jrS=j%-(%d@R@ eB2Bf B@JB@@x@AAJgEp CJ22eh=Fi =@l{F% %j@ @ ! @.W /Akb b ! b l B@`B !@x@A$AmEƀ34bn =j'Daj o@@,pJJ q B@aRB@x@A ARrE>Ea 55aRs =RE=R"t@A@ %t_TtaBub|@bv B@jB @x@A$AjwE j66ajx =j=j y@u@ $( @(AJzBB$Bc{ B@JB@x@AAJ|EF77e}=DŽF~ ={% @K@ c 6Ab ! c B@aB "@x@A$AEpGa89b =j0H`= @+/@,J.J B@aRB@x@A ARE F::aR =R^=R%@@ q +i?ab =j_ڀ="@؀@,J-JA# dR- B@aRB@x@A AREHLaR??aR =R= @P@ yS%@QaA%aBbb j B@jB/@x@A$AjELMaj @@aj =!bSP=%-(%@O@~BB$  B@JB@&@x@AAJEUNJAAe=֤F$X =@Q{% %@ @ , _Ab !  B@`B@x@A$AEÀcBCb =jOa^.@c@ m, @yJρJ  B@aRB@x@A ARE:Pa FDDaR =RB=R"@=@ y B@`B@x@A$A?E4faybcb@ =j=^%A@>@ m' @BJJ C B@aRB@x@A ARDEgaR ddaRE =R`=!F@@ cCt+:(tȏ`;nbGb-b½H B@jB@@x@A$AjIEGghaj jeeajJ = j=%-j1K@5@ LBiJ$ M B@Bc@x@AAJNE"iJffeO=O5|* P =({% (Q@$@ @$F @#!8+c ARbj#b bS B@aBc@x@A$ATEUހ@ghbU =jxjaj^%V@ל@,WJCJA#X B@aRB}UBnb@x@A ARYEbUka FiiaRZ =R]=R"[@rX@ SP/ QmaPB\bWb@$'] B@jB{y@x@A$Aj^Eljjjaj_ =jm=j%-(%`@@ aB)Bb B@JB@x@AAJcEp̀} kked=Fe =\Ҁ{"f@̀@ ! @6 kAgb bZ b h B@aB@x@A$AiEmllbj =j=%k@@,lJbJA#Fcm B@aRB@x@A ARnE}CnRmmaRo =R.K=R"p@F@*c` 1 F?BqbEb jr B@jB@x@A$AjsE fnnajt =joa( u@@ $( @`" "AJvB@Bw B@JB@x@AAJxE Jooey=z = À{{% :"{@@  c YA|b'b$} B@`B@x@A$A~Evpbpqb = `G6q`=^"@4@,JJ  B@B@x@A ARE rraR =R=R"@@ *s0Cŀeb{b j B@jB @x@A$AjErbyssaj =j.=j%p(+c@@wB骀B J B@JB@x@AAJE,dsaJ tte=F =j{"@fe@ eb !&U B@aB@x@A$AEtauub =j_$=j @"@,J+JA# B@aRB@x@A ARE:ۀ(vvaR =R=FR%@>ހ@ yL6d`89aҪDb݀b  B@jB@x@A$AjEub fwwaj =jP= @@ B B  B@JB@x@AAJEGRvJxxe=S y =3X{% :"@S@ vZb   B@aB@x@A$AE wayzb =j΀=j^+c@è@,BJˠJA# B@aRB|JeB@x@A AREۄxaR F{{aR =Rz=R"@ۇ@ :C""#0S#Q(EbGbA;' B@jB@x@A$AjEb@yj||aj =jC=j%-(+c@L@ rBB J)  B@JB@x@AAJE }}e=j| =za% "@% ! @ Abb b B@aBc@x@A$AEo,y~b =jw{aj%@v@,cJruJ F B@aRBF@x@A ARE}.|aaR =R46="@1@ (1P_$Z (BbbA;j B@jB@x@A$AjEfaj =j|=j%-(%@@ $( @"@BB@BB B@JBF@x@AAJE}b e=Fr3(BEO A = v{% "@Ǧ@ y ,Ab&b 륱 B@`Bc@x@A$AEa~ab =j9!`="@@,JJA#4`  B@aRB@x@A ARE؀aR =R߀= @+ۀ@   aRB@x@A AREb+a aR =R2=R%@V.@ 33yBb-b½ B@jB@x@A$AjE怈caj =ju=j%-(+c@@  B1B$  B@JB@c@x@AAJ Eoe =F~ =@g{"@@ !%NK FAb b ! bAf@`BF@x@A$@A @E]aBb =j#`=%@@,JJ@c B@a B@x@A ARE aR =R܀=R%@؀@ ]`1k1WBb׀b j B@jB; @x@A$AjEbaj =j=(%@a@$BƒB J$  B@JB@@x@AAJ ELJe!=^F" =@ R{% :"#@RM@ , vA$b % B@`B !$X @x@A$A&Eacb' =jǀ=jj%(@ƀ@ m, @)JŠJ  `JRL6* B@A*B @x@A AR+E~aR laR, =RR="-@@ ːa"[a.bbc/ B@jB@x@A$Aj0E,:jaj1 =j==%-(%2@@$3Bd< J4 B@JB@x@AAJ5E e6=4|7 ={% %8@@ c 39bNb ^: B@aB@x@A$A;E9bb< =jrq`=%pjK=@o@,>J@J j? B@aRB@x@A AR@EG(a aRA =0=R"B@[+@ +y`0 ;BDCb*b jcD B@jBB@x@A$AjEE〈cajF =!bY= G@@ƹ$( @"AJHBB JI B@JB@x@AAJJETb eK=դFL =D{% F"M@@ y) @ ANb ! b륱O B@aB@x@A$APEZaybQ =j`=j^"R@r@, SJJA#T B@aRB@x@A ARUEрaRV =Rـ=R"W@Ԁ@  zzxy"*K0qXbdb½Y B@jB@@x@A$AjZEob faj[ =j=j%p(!\@^@~]BB$ ^ B@JB@x@AAJ_EHJe`=w[Fa =N{% "b@,J@ ! @( qcbIb ! bd B@aBc@x@A$AeE|acbf =jĀ=%g@À@,chJ JA#i B@aRB@x@A ARjE{aR FaRk =RG="l@~@+#r~=}{zy@ Dmbbĩn B@jB@x@A$AjoE7aj_ajp =@݀:=j%-(%q@@ $( @"@BrBa9 g$Bs B@B@x@AAJtEeu=|cv =!?{% "w@@, `Axb7b !륱y B@aBc@x@A$AzEb ^b{ =jӲ="|@2@,}JJA#~ B@aRB|@x@A AREiaRaR =RPq=R"@l@ +30 ;$bb@%j B@jB@x@A$AjE+%aj aj =j(=j%-(!@ @ nBl' B$  B@JB,@x@AAJEJe=F; ={"@@ 0AbNbȥ! B@aB @x@A$AE9bb =jY\`=(f@Z@,J(JA#F B@aRBB@x@A AREFa FaR =R=Rc@R@ CÔP aBbb@$j B@jBB@x@A$AjE jaj =jYҀ=(%-@р@ nBB J$ B@JBc@x@AAJETe=٤F =@{% "@@ uBb  B@aB@x@A$AEEat b =J=j @H@,JSJR B@aRB@x@A AREaaR RaR =R =R"@i@ S@Kc a!dbbj B@jB@x@A$AjE jaj =jx=j%-(+c@Կ@ rB4B J B@JB@x@AAJEoxe=wF5n =c~{ @y@]L G'Lb b Z B@aB@x@A$AE3a b =j=+c@@,JJ  B@aRB@x@A AREaRaR = =%@@ ccpbt"iuDb{b j B@B@x@A$AjEfaj2 aj =jj=j @ui@ BhB B@JB@x@AAJE"aJe=4|@ ='{F% :"@N#@  , ͇'b ! B@aBy@x@A$AE݀yb =jɝaj^%@*@,JJA#F B@aRB@x@A ARETa@Y FaR =Rf\=FR"@W@ 7 @1@ # (ost%tEc|b-b(c B@jBc@x@A$AjE+aj jaj =j=j @@~Bg B$ , B@JB@x@AAJEˀe=3ބF =р{% @̀@ @lbRb bc B@aB .B@x@A$AE9bb =j֋="@9@,JJ  B@aRB@x@A AREBaR FaR =RWJ=R%@E@  Ӫ)tRawHob b$ B@jBW@x@A$AjEF@Y jaj = +a(%-()w@ @ B~, B@B@x@AAJE͹ Je=٤F; = À{% "@ @ Ix c Abib B@`B,@x@A$AETubt b =jy=j)j+c@\x@,JwJA#/ B@aRBc@x@A ARE0aRFaR =R|8="@3@ % kpepB?Bb j B@jBc@x@A$AjEa aj =j= @M@̀=j $@ˀ@ m!j @`# %J J (& B@aRBc@x@A AR'EaRaR( =Rϋ=F!)@*@ c`$ aɠHo*bb j+ B@jBc@x@A$Aj,E?ajaj- =j$C=j .@B@ /BAB$ 0 B@JBc@x@AAJ1E+ e2=F3 = Àa% 4@e ! @ mRB5b ǝ! b6 B@`B@x@A$A7E,b8?j[="9@@,:J*JA#j; B@aRB@x@A AR@iu@ y U%% l1B?btb @ B@jB  ,@x@A$AjAE-jajB =j71=(%-(6C@0@ $( @4@BDB/B,BE B@JBF@x@AAJFEF逈eG=RH =>{% "I@@  AJb 륱K B@aB "@x@A$ALEͤbcbM =jd`=^"N@Oc@,OJbJ P B@aRBy@x@A ARQEaaRR =R#=R"S@@ 1 I1KfJsBTbVb jU B@jB; @x@A$AjVEa׀ ajW =jڀ=(%-(%X@?@$YBـZ B@JB@$@x@AAJ[E蒿be\=iFB] =@{% "^@(@/ .!_bb c` B@`B@x@A$AaEnNabb =`=j%c@ @ mdJiJ  `5ne B@aRB@x@A ARfE|ŀ ףA FaRg =R4̀="h@Ȁ@ TD@V7#Bibǀb jj B@jB@x@A$AjkEbajl =j=j m@郀@ cnBKB$ co B@JB@٢o@x@AAJpE<Jeq= OF@r =@}B{F s@=@ $F @ Btb)b ! bu B@`B@x@A$AvEcbw =jDaj x@@,yJJA#z B@aRB@x@A AR{EoaFaR| =Rv=FR(o}@-r@ TupD{1aTB~bqb j B@jB; @x@A$AjE*jaj =j8.=%-)w@-@$B,B J$  B@JB@x@AAJE+怈e=F; =#{% "@l@ ': @+c$Abˡ b B@aBc@x@A$AEb b =ji=^+c@ʤ@,J6J > B@aRBy@x@A ARE8]aRaR =Rd= @<`@,a\Bb_b  B@jB@x@A$AjEjaj =jG=j%-(%@@ $( @"@BBB B@JB@x@AAJEFԀe=R =:ڀ{% %@Հ@ GAb ! 륱 B@aBc@x@A$AȄbb =jP`="@cN@,JMJ c B@aRB@x@A AREaaR =R=R"@ @ pE`Ô@a]BbFb j B@jB,@x@A$AjEa€oaj = ŀ=(%p(%@I@ BĀ B$ c B@B@x@AAJE}e=lF| =䃀{% "@&@ Ab~b c B@aB@x@A$AEn9ab =j=j(f@@,JqJA# B@aRB@x@A ARE|aRFaR =R2=R"@@ ,#Ӕ@uEa-Bbb  B@jB @x@A$AjElajaj = {o="@n@ BJB  B@JB@x@AAJE'Je=:| =y-{% @(@$X "Bb)b B@aBB@x 9A$A @Eb =j=j @@,JtJ@ B@a B@x@A AREaR =RC="@@ 3ǐE}2Bbb  B@jB5n@x@A$AjEZjaj =j]=*(+c@ @ Bm\  B@JB@x@AAJEJe=F ={% (@@ 5n! @ EAbDb b B@aB@x@A$AE+рyb =jOaj @@,JJ  B@aRB@x@A ARE8Had ,aR =RO=R"@TK@ C%% BbJb  B@jB|  @x@A$AjEajoaj = K=j @@$BB J B@B@x@AAJEF,e=ˤFv =:ŀ{% @@ , vBb ! B@aB@x 9A$A @Ezbb =j;`=1@c9@,J8J@Fy B@a Bc@x@A ARE `xA =Rv=%@@ S%% BbBb@j B@jB@x@A$AjE`b j"Aj = 鰀= 7@C@~ƹ) @"AJX&B B$B @JB@x@AAJEhJ`==p{Fs =n{% @%j@ ! @c =Fbib b B@aB@x@A$A En$B =j )=^" @j'@, J&JA#F B@aRB@x@A ARE߀ F60% =R=R%@@ c%% v2zbmbA;j B@jB@x@A$AjE{+!j =j=(%-(1@\@B J B@JB@x@AAJEWJ`== % =\{% "@=X@ 8bb !  B@aB@x@A$AEB =j2=j @@,!JJ F" B@aRBc@x@A AR#EΠ AR$ =RՀ="%@ р@&~Z(o!oss($t&bxЀb ' B@jB%J@x@A$Aj(E Aj) =j= *@y@ !j @(E+BڋB,$Bc, B@JB@x@AAJ-EEJ `=.=%/ =K{% 0@ZF@ eA1b  c2 B@aB @x@A$A3Eat ^ B4 =jC=j$j"5@@,6JJ (R7 B@aRBc@x@A AR8E*@Y R AR9 =RÀ=R(o:@.@ o$F! 4t/ @;bbj< B@jB @x@A$Aj=Ewb j Aj> =j9{=j%-+c?@z@~!j @"@B@ByBA B@JB@x@AAJBE83J`=C=@D = À,9{% "E@o4@ L6 3!Fb ! 륱G B@`B@x@A$AHEW5w.WI =ja"J@E@,KJJ (RL B@aRB@x@I =ARM @`Eea F!!RN =Rm`=%pO@h@ c1 I$tFBPbLbjQ B@a$B@@x@A$AjRES!a, jAjS = $=j%pj#T@7@~UB# B$ "$`4cV B@B@x@AAJWE J`=X=[FY ={% %Z@ހ@ B! @ ;"A[bu݀b b \ B@aB W.X* @x@A$A]E`@u$^^ =j="_@p@,`JܚJ a B@aRB@x@A ARbESRARc =R[=R"d@V@ B  eebOb jf B@jB$X@x@A$AjgEnaj@Y fAjh =j=(%-(%i@P@~jB Jk B@JB@x@AAJlE J`=m=Fn =Ѐ{% "o@-̀@ B c #epbˀb q B@aBc@x@A$ArE{b Bs =j&=+ct@@,uJJ >cv B@aRBc@x@A ARwEBRARx =RI=R"y@E@ %%% ,?Dzb~Db j{ B@jB o@x@A$Aj|E2 Aj} = a ~@u@~r) @"AJB B B@B@x@AAJE J`==| ={% @J@ ! @c Ab  bic B@aB@x@A$AEtb/B =j4`=j^"@!3@,J2JA# B@aRB@x@A ARE AR = J="@@ ,% Bbb  B@B,@x@A$AjE*b Aj =j=%p(+c@@ $( @"@BBn  B@JB@x@AAJEbaJ  `=8`2uFt =h{% (@c@ m c aAbMb B@a$B,@x@A$AE8a!"B =j^ހ=j @܀@,J*JA# B@aRB|; @x@A AREEaR ##AR =R=R"@Y@ ctt  Bbŗb½ B@jBc@x@A$AjEPj$$Aj =jLT=j%p(%@S@ BB B@JB@x@AAJES aJ} %%`==ԤF =O{ @ @ ! @c 4Ab ! bc B@aB .X@x@A$AEǀc&'B =ja(f@d@,JЅJ B@aRBc@x@A ARE>a ((AR =RF=%@A@ c+c+[ݟ1a:Bb[b@$ B@jBy@x@A$AjEm@Y j))Aj =j= @N@~$( @"AJB(B$By B@JB@١B$@@x@AAJE**`==uȄFyB =@ເ{% :"@/@ c  Abb ! 륱 B@`Bc@x@A$AE{qac+,B = `1`=^"@0@,J~/J  B@B@x@A ARE F--AR =R7=R"@@ yPt1 aqbb j B@jB@x@A$AjEb j..Aj =j=(%-(+c@@~+BWB$ / B@JB@@x@AAJE_J//`==rFc =@e{% "@`@ ,  qb2b !  B@`By@x@A$AEac0,WA =jLۀ=^%@ـ@ m'%;` WJJ ( B@aRB@x@A ARE*aR F22AR =Rř=R"@&@c-됂T/bb@(# B@jBc@x@A$AjEMj33Aj =j9Q=(%-(%@P@ BOB J$  B@JB@x@AAJE7 9@T 44`==F = {% "@s @c Ab ǝ!  B@aB@x@A$AEĀ55B = `hɀ=%pj%@ǀ@,J6J F B@Bz@x@A AREE66AR =R=R"@U@c-`D~7a fBbb j B@jBF@x@A$AjE;aj2 f7 (o =j@?=%-`3A@>@~BB$  B@JB C@x@AAJER J88`=AN@ZŃB! =G{% "@@ Ab !  B@a$Bc@x` =A @Eٲbc9:A =jr`=^%@Xq@ mcJpJ@ B@a B@x@A AR E)a ;;AR =R1= @,@` @--`<K -#6 E` Akn bWb  B@jBژ@x@ =Aj @`Emj<<Aj =j=%-(+c@Y@ B瀃  B@aBc@x@AAJE==`==uF =즀{% %@*@ y$F @+c qVbb b B@aBc@x@A$AE{\a5n>?B =j`=^%@@,JJA# B@aRBzc@x@A !E @@AR =R=ۀ= !@ր@ c39aq#D"bb j# B@jBF@x@A$Aj$E b jAAg 9% j=jj%&@@~n'BOB) ( B@JB@x@AAJ)EJ aJ} JBB`=*=]F+ =P{%,@K@ c W-b2b! . B@aBL6@x@A$A/E acCDB0 =jFƀ="1@Ā@,2JJA#3 B@aRB@x@A AR4E*} aR EEAR5 =R߄= 6@:@ Ctb"TC""aD7bb½8 B@jB@x@A$Aj9E8 jFFAj: =j5<=%-%;@;@ <B:B = B@JB@,@x@AAJ>E7 G!.@=?=Fx3(  K 9@ @'{% %A@q@ W c [VABb C B@`B@x@A$AjDEb,HI FE jo`=^+cF@Mn@,GJmJ *RH B@aRB@x@A ARIE&2C  JJARJ =Rm.=R"K@)@ S4"t@TUBLb3b½M B@jB@x@A$AjNER jKBy 9O j=(%-(%P@6@ nQB䀃J$ R B@JBc@x@AAJSEٝLL`=T=ZFcU =ѣ{ V@@ ! @4 AWbub bcX B@aB@x@A$AYE`YaMNBZ =j`=^%[@@,\JbJA#] B@aRB@x@A AR^EmР@Y FOOAR_ =R؀=R%`@yӀ@ c8/"7$M`3$pS+QTBabҀbfb B@jB@x@A$AjcEb jPPAjd =jx=(%-e@Ԏ@$fB4BJg B@JB@x@AAJhEzGJQQ`=i=YFj =kM{% "k@H@ `@6 Blbb m B@aBc@x@A$AnERRBo =j= cp@@,qJqJA#(cr B@aRBy-Bx[ @x@A ARsE FSSARt =R@ƀ=R"u@@ sӔP$8 Np Q`xvbb jw B@jB* @x@A$AjxEzb2 jTTAjy = }= z@|@~r `@(D{BKB J| B@B@@x@AAJ}E5aJ JUU`=~=F*  =@;{% @6@ 0xb1b! c B@`B,@x@A$AEL6VWB =jLa^"@@ m' @> JJ  B@aRBy@x@A ARE*ha XXAR =Ro=R%@k@ {x8|}aIDfbjb½ B@jBW@x@A$AjE#aj jYYAj =j@'=j @&@ B%BJ$  B@JBc@x@AAJE7 JZZ`==Fnb = À{% @t@ L6$F @c Jb  b B@`B @x@A$AEb[\B =jZ`=%pj%@EY@ 5!j @JXJA# B@aRB*@x@A AREa ]]AR =R=!R%@@ $F @3a!&~aEb;b½ B@jB @x@A$AjER̀ j^^Aj =jЀ=j%-j6@,@~!j @"@BBπ B B@JB@x@AAJEوb@Y> J__`==ZF =Վ{% "@@\۠ @O5Abyb ^! b륱 B@aB@x@A$AE_D ac`aB =j|!`="@@,cJJJA#c B@aRBc@x@A AREm@Y bbAR =RÀ=%p@y@@-}{zy8U@ϾBb彀b  B@jB4@x@A$AjEv"b jcC 9 jtz=%pj%@y@~B0B c B@JBx@x@AAJEz2#Jdd`==F =j8{% %@3@ ) @ kLAbb  B@aB@x@A$AEefB =j&$a^(f@@,JJA#(> B@aRB@x@A AREe%a FggAR =Rl=R"@ h@ L`C"`C"HzBbvgbj B@jB@x@A$AjE &jhhAj =j%$=(%-(%@#@ nB"B J$ B@JBc@x@AAJE ii`==Fc = À {%p"@Y݀@ ! @( JAb ! b B@`B@x@A$AE'bjkB =jW(`=^%@5V@,JUJA# B@aRB@x@A ARE)a@Y llAR =RU=R"@@Ex~Z"'E"6$` $`$@Bbbb`b B@jB@x@A$AjE7ʀ jmmAj =j̀=(%-(%@"@$B̀J$ Jc B@JB@x@AAJE*nn`==?F ={% "@@  c cAbZb !  B@aB@x@A$AEDA+acopB =jv,`=^%@~,JCJA#c B@aRB@x@A ARER FqqAR =R=R"@^@ ypKˀ;S"CB(Bbʺb j B@jBx@x@A$AjEs-b jrrAj =j]w=j%-(%@v@n' @"@BBBB$B B@JB@x@AAJE_/.Jss`==F = ÀC5{"@0@ y!%N vb  b륱B  `B 9; @x@A$AEctuB =j/9 mj)K@q@,JݨJ > B@aRB@x@A AREa0a FvvAR =Ri=FR%@d@ "L" $zDf bgb½ B@jB @x@A$Aj Ez1jwwAj =j =(%-! @Z@ r$( @K BB J B@JB@x@AAJE xx`==F =ހ{% "@;ڀ@ W`@6 yAb ! 륱 B@aB; @x@A$AE2bcy:B =jT3`=j^"@S@,J~RJA# B@aRBB@x@A ARE 4a {;AR =R:=R"@@ c"pQ"0aknb b@$j B@jBy o,@x@A$Aj Eǀ2 j||Aj! =jʀ=j%p(%n"@@~#Bdɀ J$ `$ B@JB !K @x@AAJ%E5}}`=&=#F' =@{% "(@݃@ c qV)b>b * B@`B@x@A$A+E)>6a ,&, =jW=j -@@ m' @.J$JA#F/ B@aRBc@x@A AR0E77aR FAR1 =R伀=F!2@7@ @oK .S"q0aD3bbĩ4 B@jBW@x@A$Aj5Ep8aj jAj6 =j=t=j%-j%7@s@~8BrB9 B@JB@@x@AAJ:ED,9J`=;=ɤF< =@<2{% %=@-@ L6$F @ 4+A>b ! b ? B@`B@x@A$A@EBA =:a"B@^@, CJʥJ  dR-D B@aRB@x@A AREE^;a F BF =R~f=%pG@a@.L aBHbDb½I B@jBF@x@A$AjJE_<jAjK =j=j L@7@ MB B$ cN B@JB@x@AAJOEՀ> !@=P=gF@Q =ۀ{% R@׀@ y! @ LBSbրb! bcT B@aB W'Z@x@A$AjUEl=bBV =jQ>`="W@O@ '$cXJkJ Y B@aRB{Je@x@A ARZEz?a AR[ =R =R(o\@~ @.#Yeda]b b½^ B@jB} @x@A$Aj_E?ajF jAj` =ǀ=j%-(+ca@ƀ@~$( @4@BbB=B$Bc B@JB@!K@x@AAJdE@aJ J`=e=Ff =@w{"g@€@ W$F%N+c  hb#b! b륱i B@`B@x@A$AjE;AaBk =j==%p"l@@,mJ JA#cn B@aRB@x@A ARoEBaR ARp =Rʹ=R%q@(@ 3`6 x4|{zyarbb½s B@jB~@x@A$AjtEmCjAju =j*q=(%-%v@p@$wBoB J$ x B@JB@@x@AAJyE))DJ`=z=F{ =@/{% "|@d*@ y': @K hv/G?}b ! bc~ B@`Bc@x@A$AEB =jEa^%@B@ m'%cJJ  B@aRBQ@x@A ARE[Fa AR =Rlc=R"@^@ C+b u6@Db1b½ B@jB@x@A$AjEDGjAj =j=(%-(%@)@$B J$  B@JB@x@AAJE `==LFc =؀{% "@Ԁ@ * $F @+c $AbgӀb ! b B@aB@x@A$AEQHbcB =jNI`=j%pj%@L@,JPJ  B@aRB@x@A ARE_Ja AR =R ="@o@,.SӔ@dup^ abbb@$j B@jBvc@x@A$AjE jAj =jrĀ=j%- @3C@À@ ) @"@BB-B J$B B@JB@x@AAJEl|K`==F}@ =ATT{F% %@}@, hbb 륱 B@`B,@x@A$AE7LacB =j=j @v@,JJA#Fc B@aRB@x@A AREMaR FAR =R=R"@@ c% `$Y` ZaBDfbdb@$j B@jB/@x@A$AjEjNajt= =jn=j%-(+c@em@$BlB J B@JB@x@AAJE&OaJ `==8| =+{% "@J'@ c BAb W! B@aB @x@A$AEcB =jPa @@,J{J F B@aRB/@x@A AREXQa AR =RM`=R"@[@ s0D0Ayp97ôBbb@(j B@jB@x@A$AjE)Raj2 jAj =j=j @@  `@ūcBu B$ Bc B@JB@x@AAJE J`==0Fɂ =Հ{F% @Ѐ@ ! @+c WBbKb b B@aB@x@A$AE6SbB =jVKT`=j^"@I@,J%JA#F B@aRB@x@A AREDUaFAR =R =FR%@H@   a[Bbbo B@jB@x@A$AjEʽ fAj =jJ=j%-(+c@@~$( @"@BB B B@JB@y@x@AAJEQyVb J`==ҤF$X =@I{% "@z@  c EA.] ! 륱 B@`B @x@A$AE4WaB =j="@_@, JJA# B@aRB@x@A AREXaRAR =R=R"@鮀@ c\w 'U2$anbUb@$j B@jBc@x@A$AjElgYjAj =jj=(%p(%@J@ rBi J$ y B@JBc@x@AAJE"ZaJ `==t5|y =({% "@/$@, @c  b#b B@aB@x@A$AEyހcB =j[a^(f@@ '*Q,CB BlJ F#@aRB5n@x@A AREU\a AR =/]=R"@X@ @zT˵zuya@bWb@$ B@jB@x@A$AjE]ajF jAj =j=(%-( < @@~ BNB B@JB@x@AAJ È J`= =߄Fc =GxҀ{%p"@̀@ $F @ jAb0b! bZ B@aB W- B@x@A$AE^bB =jDH_`=^%@F@,JJ F B@aRBy B@x@A ARE( DE AR =R`$R"@9@ $F 3 1  S YsBbb c B@jB B@x@A$AjEjAj =j+=( @@ !j @"AJB缀BBc B@JB@x@AAJ!E6vabw `="=F# =2|{% $@sw@ ! @ A%b  b륱& B@aB@x@A$A'E1ba ZDB( =j=j$j")@C@,*JJ R+ B@aRB@x@A AR,EʨcaRRA@!sA- =@{=%.@ګ@ c""zu$t5@/bFb j0 B@B@x@A$Aj1EQddjAj2 =jg=%- <3 @(@$4Bf J) 5 B@JB@&@x@AAJ6EeaJ @=7=Y2|8 =@%{% "9@!@ B c :bt be! c; B@ B !c@x@A$Aj<E^ۀ$=B= =jfaj >@陀@ m!j @?JUJ R@ B@aRB@x@A ARAElRgaRA@ARB =@Z=R"C@tU@ y}~" DDbTbjE B@B c@x@A$AjFE hjAjG = o=%-( <H @@ ) @(@BIB.B J$BJ B@B@@x@AAJKEyɀ `=L=FwM =@qπ{% "N@ʀ@Q _AObb! 륱P B@`By@x@A$AQEibcBR =j)Ej`=%pj"S@C@ mTJBJA#U B@aRB@x@A ARVE ARW =RkaRR"X@~  (" S"/aBYb}b jZ B@jB@x@A$Aj[E, jAj\ =j$=j%- <] @@~^BB$ c_ B@JB@x@AAJ`Eslbw J`=a=F; b = y{% "c@Qt@ $F @6 Nldb ! bce B@aBc@x@A$AfE.maBg =j="h@4@,iJJA# @Rj B@aRBc@x@A ARkEnaR ARl = h= m@è@ cL"x4| Dnb/b½`L6o B@B@@x@A$AjpE6aojAjq =jd=j%-( <r @@ sBzc B$ Jt B@JB@x@AAJuEpJ`=v=>/|w =G"{F% %x@@ $X %AybXb z B@aB@x@A$A{EC؀B| =jmqaj^+c}@Ζ@,~J:JA# B@aRB@x@A AREQOra+ AR =RW=R"@aR@/}"6$~p!Lu'bQb j B@jBc@x@A$AjE saj jAj =jW="@ @ƹBBB B@JB@2a@x@AAJE^ƀ J`==ߤF =@Ǹ{% @ǀ@ c Eb  B@`B@x@A$AEtbcB =jBu`=^%@t@@@Sm!j%J?JA#Jc B@aRB@x@A AREAR = v$R%@~ vw"x|}V Bbjb½ B@Bc@x@A$AjEy, fAj =j=(*( < @a@ rBBJ ` B@JBc@x@AAJEpwbw J`==Fc = su{% "@:q@ 5n! @( VYAb bc B@aB@x@A$AE+xacB =j="@ @ JuJA# B@aRB5n@x@A AREyaR AR =RF=R"@@ 7"'#y~1'Bb bf B@jB@x@A$AjE^zajfAj = a=( @@~!j @(DBg` B B@B 5@AAJ @E{aJ `==",|/ ={% @@/ Bb=b! 륱 B@abB@x@A$AE(ՀB =jR|aj$j"@@,JJA# B@aRB@x@A ARE5L}a@Y AR =RS="@FO@; /39ِ.7hDfbNb f B@jB@@x@A$AjE~aj jAj =jD =%p < @ @ BB c B@JB@x@AAJECÀ J`==ĤF = 3ɀ{% (@~Ā@ @ GAb  bc B@aB@x@A$AE~bB =j>`=j @X=@,J=R"@=:@ sґҐ",\Bb9b½ B@B@x@A$AjE jAj =jD=(%-(%@@ rBB J$  B@JB@x@AAJEC`==K|@ = 3{% " @@ , A!b ! " B@aB@x@A$A#EiaB$ =)`=j+c%@T(@,c&J'J ' B@aRB@x@A AR(E FAR) = ="*@@ /t/Ƀ B+bGb j, B@Bc@x@A$Aj-E^b2 jAj. =j=%-(%/@I@~0B J$ 1 B@JB@x@AAJ2EWaJ J`=3=ejF4 =]{% %5@"Y@/ !A6bXb! XF7 B@aB@x@A$A8EkB9 = `= :@g@,;JJ < B@By@x@A AR=E AR> =Rր=R"?@Ҁ@ te]LB@brрb jA B@jB@x@A$AjBExb@YW j C =j=(%-(%D@a@ EBB $ F B@JB@x@AAJGEEJ`=H=w!^ `AI = )K{H =`=e "J@?G@ !%N, DxAKbFb ! bL B@aB@x@A$AMEa* AjN =j= O@@,PJJA#a!Q B@aRB@x@A ARRExaR F pARS =RN=R"T@{@  @ 9~a;UbbjV B@jB5n@x@A$AjWE4j AjX =j7=j%-`3CY@6@  `@.`@BZB^B$ B[ B@JBc@x@AAJ\E @=]=&|y* ^ ={% "_@@F `b=b ! a B@aB@x@A$AjbE(byBc =jOk`="d@i@,eJJA#f B@aRBc@x@A ARgE5"a aRh =R)=%pi@)%@ }"6a=Dfjb$bk B@jB@x@A$AjlE jajm =j<=j%-j+cn@@ oBB$ cp B@JB@x@AAJqEBer=ĤFys =7{% %t@z@ ! @ Aub ! bv B@aB W?n@x@A$AwETa bx =j`="y@<@,zJJ { B@aRBx @x@A AR|Eˀ F  aR} =RӀ=R"~@΀@%t  a BbKb jc B@jB + @'@x@A$AjE]b j  aj =j劀=(%-(%@C@$( @ūcBB$B B@A"B@x@AAJEBJ  @==eUF =H{% "@ D@ W`@+c {AbCb 륱 B@aB "@x@A$AjEkc Kc = ``a^"@@,JnJ > B@B@x@A ARExua FaR =R0}=R"@x@ Q "$h\{"$aBbwbf B@jBW@x@A$AjE0jaj =j4=(%-(%@3@ rBCB J B@JB@\$@x@AAJE e=F2(EO A =@z{% "@@ ! @?m 8Ab"b! b B@`B@x@A$AE bcb =j   @==F~, =W{% "@@ ) @#!8 AbbZ b B@aB@x@A$AjEbc!"b =je`=%@|c@,cJbJ Fc B@aRB@x@A AREa ##aR =R#="@@ $F @%)Lp+MTp 8Bb{b½`bF B@jB y@x@A$AjE׀F j$$N! =jۀ= @\ڀ@ !j @"AJBـBJ B@JB@!K@x@AAJE %%e=F@ =@{% @I@, JAb  c B@`B@x@A$AENa&'b =j`=$j"@* @,J JA# B@aRB@x@A ARE F((aR =RM̀=R%@Ȁ@0#KYM0TerBbb j B@jB; @x@A$AjE'b j))ajEj=j%p+c@ @~Bk B B@JBBD`x@9 AJ @E<J**e=/OF =@{B{% "@=@  c `AbJb B@`B@x@A$A E5+,b =jVa" @@, J#JA# B@aRB@x@A AREBoa F--aR =Rv=R"@Rr@,03PMN1~aakɂbqbĩ B@jB$X@x@A$AjE*j..aj =jY.=( @-@ rBB J B@JB@x@AAJEO //e=ѤF =D{% @@, LEb !  B@aB,@x@A$AE֡bc01b =ja`=^+c!@U`@,"J_J ># B@aRB@x@A AR$Ea 22O% =y =R%&@@ C%Ǵt"Q@ u+B'bHb@&j( B@jB@x@A$Aj)EjԠ@Y j33aj* =j׀=j +@N@ `@"AJ,Bր$ By- B@JB@x@AAJ.E44e/=rFc0 =ٕ{"1@+@nE c 2bb 3 B@aB - @x@A$A4ExKac56b5 =j `=j"6@ @,7Js J >8 B@aRB@x@A AR9E€ F77aR: =R3ʀ=FR%;@ŀ@ SӔP Qy ^Df<bb@$ = B@jBy @x@A$Aj>E ~b j88G? =j=%-1@@쀀@ rABLBkB B@JB@x@AAJCE9J99eD=LFE ={?{% "F@:@ y! @ ;AGb/b bZ,H B@aB@x@A$AIEc:;bJ =j+aj^%K@@,LJJA#FM B@aRB$X@x@A ARNE'la F<>eY=FFZ =%{% [@o@F  A\b ! 륱] B@aB@x@A$A^Eb?@b_ =j^`= `@2]@,aJ\J b B@aRB@x@A ARcEa AAaRd =Rr=R(oe@@ $F!osu$4ǏBfb1b½g B@jB@x@A$AjhEOр jBBaji =jԀ=j%p(+cj@7@~!j @ťkBӀ B$Bl B@JB@x@AAJmE֌b JCCen=[Fo =Β{% "p@@/ f-Aqbrb! 륱r B@ B,@x@A$AsE]HaDEbt =j`=$j"u@@ 2 @ @ ! !% ARvJ\J w B@aRB@x@A ARxEj FFaRy =Rǀ=!R"z@r€@ c"+YpǬDx,{bb½| B@jB@x@A$Aj}Ezb jGGaj~ =je~=j%-j%@}@~B!B$ B B@JB@x@AAJEx6aJ> JHHe=F =l<{% "@7@ $F @+c ,bb! b B@aB 4 @x@A$AEcIJT =j!a"@@,cJJ B@aRBw&BW@x@A ARE ia KKAR =Rp= @l@ Eǭ cqbkb@& B@jBQ@x@A$AjE$ajF jLLaj =j(=%-(%@{'@ B&B  B@JB; @x@AAJE JMM@==a* ={% %@T@ y! @+c qb  b B@aBB@x@A$AjEajNOb =j[`=^+c@7Z@,JYJ F B@aRB{@x@A AREa PPaR =RL=R"@@ E"\T &abb f B@jBy@x@A$AjE4Π@Y jQQaj =jр=(%-(%@@ $( @"@BB|ЀB B@JB@١B)* @x@AAJERRe=H@ m!j @JGJA# B@aRBB@x@A AREaR RTTaR =R="@@ +c 13OafDfbDb# B@jB@x@A$AjEO jUUL =jϿ=%-(%@*@<BB/l c B@JB@x@AAJEwVVe=ޤFF =}{% %@y@ y! @c Abrxb bc B@aB@x@A$AE\3acWXb =j=j%pj(f@@,JOJ  B@aRB@x@A AREjaR FYYDF =R#="@z@ ЂЃQyT1aBb欀bf B@jB@x@A$AjEejZZaj =jyi=%-%@h@$B9B J B@JB@c@x@AAJEw!J[[e=F@ =@h'{% %@"@ ) @6 Abb b B@`B,@x@A$AE܀\]b =j#a @@ m!j @cJJA#c B@aRB@x@A ARE Ta ^^aR =R[=R"@ W@ $ "<|6+mazBbxVb j B@jB@x@A$AjEaj* __aj =j=j @y@  `@(AJBB B@JBc@x@AAJE ``@==݄F* = р{% @Ẁ@ c kAb ȥ! c B@aBc@x@A$AjEb,abb =jF`=%pj"@7E@,,JDJ  B@aRB@x@A ARE ccaR =RVaRR%@@ $XmaBb!b½ B@jB} !B@x@A$AjE4 jddL =j=j @@~Bd B$  B@JB@x@AAJF  Etbw> Jeee= B@JBc@x@AAJ?Eqbw Jtte@=!FA =w{% "B@r@ ': @( WACb@,rJdJ s B@aRBnb@x@A ARtEw@Y: aRu =R=R"v@{@ cCA1P1 @wbb@%x B@jB@x@A$AjyEb jajz =j=j {@굀@~c|BJB} B@JB@x@AAJ~EnJ@== F =qt{% @o@ c Eb b ! B@aB@x@A$AjE *ayb =.=j @@,JJ Fc B@aRBc@x@A AREaRy FaR =RǨ=FR%@)@ SŰE%a&UBbb@$ B@jB@x@A$AjE\aj jaj =j/`=j @_@~B^B$ y B@JB@x@AAJE&Je=F$X ={% @a@ ': @+c Bb ! by B@aB@x@A$AEӀcNW =ja"@@@#P2$yJJ IF B@aRB@x@A AREJa F4y2h =@iR=!@M@ c"Q p KJ}Bb6b@) B@Bb@x@A$AjEAj$!j =j =j%-j1@&@ $( @.`@BB B$B B@JB ,@x@AAJE e=IԄF =@ǀ{% (@À@ $F @6 (Abd€b b륱 B@`B@x@A$AEN}bcb =jz=`="@;@,cJEJA#F B@aRB@x@A ARE\@Y aR =R=R"@d@ , s@%K`R11P@Bbbo B@jBc@x@A$AjEb jaj =js=(%-(%@в@~B/B J B@JB@x@AAJEik:@T Je=Fc =Vq{% "@l@ , |Abb! B@aBc@x@A$AE&aH =j=j(f@w@,JJ (R B@aRBx@x@A AREaR aR =R=R"@@ o$F!o.! $1uP aSBbnb  B@jB@x@A$AjEYjaj =j ]="@j\@ !j%"AJB[B $Bc B@JB@x@AAJE Je='| ={% @G@$X Ab ^! c B@aBx@x@A$AEЀb =jaj$j"@ @,JJA# B@aRB@x@A AREGa aR = [O="@J@ puT}uU} tT/,5Bb'b j B@B@x@A$AjE&jaj =j=%-+c@@$Bj J$  B@JB@@x@AAJE e=.фFu$X =@Ā{% (@鿀@ y': @ AbIb B@`Bc@x@A$AE3zbcb =jS: `=j @8@,J"JA#c B@aRB@x@A AREA(aR =R="@U@ tU%C$)YBbb j B@jB*@x@A$AjEǬ b fN! =jT=j%-(!@@ $( @n(@BBB B@JB@@x@AAJENh Je=ϤFz =@Bn{F%p%@i@  vB bZB@x@A$AE# acb ==j @`@,JJ  B@9B@x@A ARE aR FaR = =R" @杀@ !$F!o1AӔP&FLDf bRb½ B@B/@x@A$Aj EiVjaj =jY=j%p(%@?@ !j @ BX B B@JB@x@AAJEJe=q$| ={ @)@Q Abb  B@aB@x@A$AEẁH =ja %d(f +@@,JqJ  B@aRB@x@A AREDa aR =8L=%pR%@G@ $@6|{a-BbFb B@jB o/@x@A$Aj!E jaj" =j=j%pj%#@@ $BWB% B@JB@x@AAJ&E e'=΄F( ={ $F% ") +@μ@Q Z*b-b ! + B@aB "B@x@A$A,Ewbb- =)97`=  j^%. +@5@,/JJ 0 B@aRB@x@A AR1E&+ aR2 == "R"3 +@6@  P $Bs%u,]D4bb jc5 B@jB@x@A$Aj6Eb jaj7 =),="8@@~ƹ9BB$&50: B@JB@\$* @x@AAJ;E3eJe<=F@= =@#k{% >@pf@ , ZB?b !  @ B@`B$X@x@A$AAE acbB =j= , ^%C +@A߀@ m2$ DJހJ(RE B@aRB@x@A ARFEǗaR F!G =x=  R%H +@Ӛ@ CudǴt"* Ib?bjJ B@jB/@x@A$AjKENSjajL =)V=(%-(+cM@1@ rNBU J$ O B@JBc@x@AAJPEJeQ=V!|cR ={% "S@@ $F @ +c * Tbqb bU B@aB@x@A$AVE[ʀcbW =ja ^%X +@@,YJ^J Z B@aRBz@x@A AR[EiAa aR\ =I= ] +@yD@ c6%At"Q@$`#C^bCb_ B@jB@x@A$Aj`E2 jaja =)xa(%-(%b@ ~cB4B Jd B@JB@x@AAJeEv  Jef=F{yg =k{ %"% %h +@@ y! @6 Ixibb! b j B@aB@x@A$AkEsbbl =)*4`=+"j%m@2@,nJ1J o B@aRB@x@A ARpE aRq =R= "R"r +@@2]F  Qy` yRDsbb(½ct B@jBx @x@A$AjuE b jajv =)= w@q@ $( @"AJxBѨBJ$Bcy B@JB@x@AAJzEb!aJe{=tF| =h{% F"}@Vc@  c A~b c B@aB@x@A$AE"ab =j݀=j^"@"܀@![ !j @ nbJۀJ R B@aRB@x@A ARE#aR FaR =@N= a +@@2p`yu yBbbf B@B; @x@A$AjE3P$jaj =)S=%-j+c@@$BR J B@JB@x@AAJE %aJ e=o|Gc ={% %@ @  @c 'AbVb! b B@aB@x@A$AE@ǀcb =jj&aj%pj%@˅@,cJ7JA# B@aRB@x@A AREN>'a aR =RE=R"@ZA@2#$"TpGӔyQqb@b½ B@jB@x@A$AjE jaj =je= 1' +@@ cB!B  B@JB ,y@x@AAJE[(e=ܤF$X =@K{% F"@@ ) @+c qb  `b B@`B@x@A$AEp)ac[& =j1*`= ," +@i/@,J.J  B@aRB@x@A ARE FaR ==R"@@ c 3 Q %ctHobcb j B@jB; @x@A$AjEv+b jaj =j=j%-(+c@V@~B B$  B@JBc@x@AAJE^,Je=~qF =d{%p"@7`@ y! @( [Ab_b b B@aB@x@A$AE-ab =jڀ= % +@ـ@,J~ؠJ B@aRBc@x@A ARE.aR FaR =7=  R" +@@ C$yD@ yS$p_KdEJpWI@K[Bb=b@& B@B@x@A$AjE jaj =@݀A="@@ƹBB J$c B@B@x@AAJE@3b Je=Fc =0{% @{@ ! @c 1Bb ! b B@aBc@x@A$AEm4acQ =j-5`=  ^% +@R,@,J+J > B@aRB@x@A ARE䀈aR == R% +@@ ccSXKCXFLpD y*bXb½ B@jB@x@A$AjE[6b faj =)㣀=(%-(+c@@@ r$( @"@BBJ$B B@JB ?@x@AAJE[7Je=cnFx3ɂ =@a{% "@]@ y c 9b~\b c B@`B@x@A$AEh8a Z! 8b =j׀=jtB +@Հ@ m!j @,J_J  B@aRB; @x@A AREv9aRR@aR =@1=!g X"@@ sK+\>Idpq yhobbj B@B@x@A$AjEI:aj2 jaj =jyM=  j%-(% +@L@~ B9B J B@JB@1@x@AAJ E;aJ J@==} =@t {% "@@, nWbb!  B@`B@x@A$AjE b =j=b J@=#=F$ =G{ !% % +@]@ $F @ B&b  by' B@aB@x@A$Aj(Ej?aQ) =)*@`=  j^+c* +@?)@, +J(JrR, B@aRB}LW% @x@A AR-E aR. =d=  R(o/ +@@ PMEyB0b1b '1 B@jB; @x@A$Aj2E@Ab jaj3 =)Ƞ= !j%-(+c4 +@%@~r5B B6 B@JB@x@AAJ7EXBaJ} Je8=Hk?`=9 =G^{  % ": +@Z@ B! @K A;bcYb! b < B@aB@x@A$A=EMCajcb> =)iԀ=%?@Ҁ@,c@J8J nA B@aRBF@ 5@A ARB @`E[DaR GC =R= $F"D +@S@ c+ZQ@ %MQ ycKBEbb½F B@a$Bc@x@A$AjGEFEjajH =)bJ= I@I@ $( @"AJJB&BBcK B@JB@@x@AAJLEhFJeM=F* N =@X{ "% O +@@ y c ǹAPbb Q B@`B@x@A$ARE`bS =)~Ga^"T@v|@,UJ{JA# `>-_V B@aRB@x@A ARWE4Ha aRX =R<=R%Y@7@ B&!%|T5nTZbhb[ B@jB/@x@A$Aj\E jaj] =j= 1$(%-(+c^ +@a@~ `@r"@B_BB B` B@JB@@x@AAJaE Ieb=Fc =@{  d +@F@x Zeb !&Uf B@`B !5n@x@A$AgEgJayJh =)'K`=^"i@#&@ mefyjJ%J k B@aRB/@x@A ARlEހ!ARm =R>=R%n@@  "ML aBDfobb@$#a p B@jBw $X@x@A$AjqE%Lbjajr =j= $( s +@ @ tBm J$ Ju B@JB@x@AAJvEUMJ@=w=-hFx =G[{  % :"y + -V@ c BzbKb { B@`B "@x@A$Aj|E2Na,b} =)[р=^%~@π@,J)J F B@aRB@x@A ARE@OaR@Y aR =R쏀=R"@L@ dpKEJpQPHhBbbo B@jB@x@A$AjECPaj@A =jNG=  +@F@$B B J B@JB@x@AAJEM !!@==ҤF5n =G]Qa  %  +@@ Bbb,! B@aB@x@A$AjEԺyB =)zRj @Oy@,JxJ > B@aRB@x@A ARE1Sa aR =R9="@4@ 7)! 0 Op M3!aBb]b½E c B@jB oc@x@A$AjEh jaj =j=  (*(1 +@O@ r!j @(@BBJ$Bc B@JB@x@AAJETe=pF =G㮀{  :% ( +@,@ , ]gAbb c B@aB@x@A$AEudUab =)$V`=  j#j" +@"@,JXJ  B@aRBz,@x@A ARE۠@YcaR =$="@{ހ@ 6+\ P0M@8Bb݀bf B@jB@x@A$AjE Wb2   aj =j= c +@홀@~@BRB J B@JB@o&* @x@AAJERXaJ J  e=eF =@X{% F%@S@ ! @ Bb,be! b B@`B@x@A$AEYa  b =j0΀=j @̀@ mJˠJ  B@aRBc@x@A ARE%ZaR   aR =Rٌ= $FR" +@5@,3pJTJU`\}Bbb½ B@jB@@x@A$AjE@[aj jaj =)7D= 1!j*(+c +@C@~$( @(@BBBB$Bc B@JBc@x@AAJE2 Je=F{3"<| =G"\a =`G!% " +@p W$F @ Ab ! bc B@aB,@x@A$AE,b =)w]aj"@Dv@, JuJ > B@aRBc@x@A ARE.^a aR =Rk6=  +@1@ %efN`NuOnbhb6b B@jB}c@x@A$AjEM jaj =)=  j%-(% +@4@~B쀃 B$  B@JB@x@AAJEԥ_b Je=UF =G{  % % +@ @ y! @( `hbpb! by B@aB - y@x@A$AEZa`acb =)!a`="@@,cJQJ  B@aRB@x@A AREhؠ@Yh' aR =R =R"@pۀ@y3#PE@ud yDbڠb@&½ B@jBF@x@A$AjEbb faj =j{=j%-(%@֖@~$( @ūcB7BB B@JB@$@x@AAJEuOcJe=F =@]U{ c +@P@c aAbb  B@`B@x@A$AE dab =)*ˀ="@ɀ@@Sm, @JȠJA#J B@aRB@x@A ARE eaR FaRIR=R%@@ c3udǵfef VBb}bĩ B@jB oy`x@9 Aj @`E=fjaj =Bi`=A=a1$(%-@t@@ nB?B J ` B@B@!K@x@AAJ E e = | =@{*c @Q@ c $B b ! c B@`B@x@A$AEgb b =jth`=^%@,s@ mJrJA# B@aRB/@x@A ARE+ia !!aR =Ra3=R"@.@ C"F =@{% !@@ $F @6 B"bTb b# B@`TB !@x@A$A$E?^kac$%b% =jel`=j+"j%&@@,'J2J ( B@aRB@x@A AR)EMՀ F&&aR* =R܀=G@)R%+@U؀@,3ST~%HT@zl@,I׀b j- B@jB,IA$Aj. @`EӐmb j''aj/ =jT=j%-C0@@nc1BBB2 B@aB@x@AAJ3EZLnJ((e4=ۤF; 5 =JR{H@ % "6@M@, @7b  8 B@aBc@x@A$A9Eoac)*b: =jȀ=j^K;@pƀ@,<JŀJ >= B@aRB@x@A AR>E~paR F++aR? =R=R"@@@ $F!o"c+gKg cDAbZb½B B@jB@x@A$AjCEu:qj,,ajD =j>=j E@^=@ r!j @"AJFBb =jn~`=^+c@l@,cJZJA#F B@aRBF@x@A AREu%a(??aR =R0-=R"@(@ , %6Kԣab'b j B@jB~ @x@A$AjEF f@@aj =j=j%-(%@@~B@B B@JB J!K@x@AAJEb JAAe=Fc =@n{"@@ c  bb!&Z, B@`B@@x@A$AE XaBCb =j-`=+"%@@,JJA# B@aRBx B\ @x@A ARE DDaR =Rր=R%@'Ҁ@ Jd`=Mp? ]WDbрb j B@jB@@x@A$AjEb jEEaj =j=( @w@$BՌB c B@JBc@x@AAJE$FJFFe=F =L{F"@`G@ b   B@aB 'Z@x@A$AEaGHb = ``=j @=@,JJ n B@B$X@x@A ARExaR FIIaR =Rh="@{@  (MdpR%@Eb4bA; B@jB5n@x@A$AjE?4jJJaj =j7=%-o+c@@$Bw6 J)  B@JB@$c@x@AAJE KKe=G|V =@{% %@@ 'Abbb !  B@`Bc@x@A$AELbcLMb =jpk`=j @i@,J?JA# B@aRB@x@A AREZ"a NNaR =R*=R"@f%@ KMa9Bb$b@$j B@jB@x@A$AjE jOOaj =ja=%-(%@@ B B J$  B@JB @x@AAJEgPPe=F5n =@S{% "@@ ! @ :Abb b B@`B@x@A$AETacQRb =j`= @}@ myJJA# B@aRB@x@ =AR @`Eˀ FSSaR =RӀ=R"@΀@ K R`~[M`̠ BbWb! B@a$B5n@x@A$AjEb jTTaj =j =j%-(%@d@@r$( @4@BBƉB B@JB@x 9AAJ @E CJUUe=U`= =H{% "@BD@ $F @ EAb ! b륱 B@abB@x@A$AEcVWb =ja"@@,JJA# B@aRBc@x@A AREua FXXaR =R=}= @x@ KWK~a' Bbb½ B@jB@x@A$AjJ  `E$1aj@ jYYaj =j4=j%p(%@ @ Bl3 B$ c B@aB@x` =AJ @E JZZe=+F*  ={F% %@@Q A bFb c B@abB@x@A$A E1b[\b =jVh`=j^(f @f@,J$J  B@aRB@x@A ARE?aF]]aR =R&=R"@O"@y4G Kea/Bb!bj B@jB ,@x@A$AjEڀ f^^aj =jAހ="@݀@ BBJ B@JB@!K@x@AAJELb 4E J__e=ͤF]L =@<{% @@  c xBb  B@`Bc@x@A$A EQa`ab! =j`=^%"@b@, #JJ $ B@aRB@x@A AR%EȀ bbaR& =!JЀ=R%'@ˀ@ $F'E!%KW3<}p/S`+ B(bDbf) B@jB@x@A$Aj*Egb jccaj+ =j燀=(*(+c,@B@ r!j @"@B-BJ. B@JBc@x@AAJ/E?aJ Jdde0=RFV@1 =E{% "2@+A@c ,MA3b@b c4 B@aBc@x@A$A5Etcefb6 =jaj$j"7@@ ' @ ! !% AR8JoJ 9 B@aRB5n@x@A AR:Era ggaR; =R3z="<@u@4#+\%Kdpa=btb½> B@jBF@x@A$Aj?E .ajF jhhaj@ =j1=j%p%A@0@~BBQBC B@JB @x@AAJDE JiieE=FF ={F% %G@@ Hb+b! I B@aB@x@A$AJEbjkbK =jCe`=j%pj%L@c@,MJJ N B@aRB@x@A AROE#a llaRP =R#=FR"Q@@ 3|}J ,IDRbb S B@jB@x@A$AjTE׀jmmajU =j:ۀ= V@ڀ@ WBـB X B@JBc@x@AAJYE1nneZ=F[ =%{% F"\@k@ 7B]b  ^ B@aB@x@A$A_ENaopb` =j`=j^%a@. @,bJ J c B@aRB@x@A ARdE qqaRe =Rr̀=R"f@Ȁ@ 4CMp!BgbAb@(ja]Lh B@jBy@x@A$AjiELb jrrajj =j܄=j%-(+ck@8@$lB Jm B@JB@@x@AAJnE<Jsseo=TOFp =@B{% "q@ >@ / @ +c OArbo=b cs B@`B@x@A$AtEYctubu =jwa%v@ض@,wJDJA#x B@aRBc@x@A ARyEgoa FvvaRz =R w="{@{r@ cS~"efa9|bqbf} B@jB; @x@A$Aj~E*jwwaj = z.=%-(%@-@ cB9B$ B@B@@x@AAJEt xxe=F$X =@d{%p"@@ WAbb ! XF , B@`B* @x@A$AEbcy$A =jb`=^K@v`@ m' @J_JA# B@aRB B@x@A AREa {+!R =R =!@@ ccabQ HBb|b@&j B@jB* @x@A$AjE j||aj =j؀=j%-j%@{׀@ BB$  B@JBc@x@AAJE}}e=F ={% %@P@ m$F @c iAb ȥ! b B@aBc@x@A$AEKa Z|D~b =j `="@3 @,J J R B@aRB%IB@x@A ARE RA@aR =@Pʀ=R"@ŀ@ sdud:ȀǴ pBbb@&j B@B@x@A$AjE1~b jaj =j=(%-(%@@~rBq J$  B@JB@x@AAJE9aJ Je=b =jyaj+c@ٳ@,JEJA#F B@aRB@x@A ARELla aR =Rs=R"@Po@ 2 "fe"NaBbnb½ B@jB@x@A$AjE'aj jaj =jb+="@*@ $(n"AJBBJ$B B@JB@x@AAJEY Je=ڤFc =E{% @@ c EAb  B@aB @x@A$AEbb =j_`=j @o]@, J\JA# B@aRB@x@A AREaaR =R="@@ $F!o|%O>faBbqb½ B@jBy@x@A$AjEt faj =jԀ=%-(+c@Y@ r!j @ťBӀ J B@JB@@x@AAJEb Je=|Fc =@{% (@6@ @*!bb! bc B@`B@x@ =A @EHacb =j`=j$j"@@ m' @JdJ c B@a B4B@x@A ARE D aR =RFǀ="@€@ !Re"{zǑ +Bb b½ B@jBL6@x@A$AjE{bF jaj =j~=j%p#@}@~BZB$  B@JB@@x@AAJE6aJ Je=IF5n =@<{F% %@7@ TAb8b! X\y B@`B ! O*@x@A$AE#b =jBaj$j%@@,JJ  B@aRB@x@A ARE0ia aR =Rp=R"@5l@ c A@ a.Bbkb  B@jBc@x@A$AjE$jaj =j?(=j%-%@'@B&B$ CG@JB@x@AAJ#@E> e=F =2{% "@v@ c 6Ab !  B@abB@x@A$AEśbb =j[`= @[Z@, JYJ j B@aRB@x@A AR Ea aR =Ry=R"@@ $X A D7a*BbBb½ B@jB $X@x@A$AjEY΀ jaj =jр=j%-(%@F@~BЀ B$  B@JB@x@AAJEb Je=aF = ÀЏ{% "@@ / @W Ab|b! b B@`B@x@A$AEfEacb =j`="@@,JUJA# B@aRBx@x@ =AR! @`Et@ aR" =RĀ= #@l@ +c,o%Cx@ B$bؾb½% B@a$B@x@A$Aj&Ewb@Yjaj' =j{=%-(%(@z@ )BFB$ * B@JB@x@AAJ+E3aJ e,=FF$X- =u9{% %.@4@ A/bb! 0 B@aBc@x. 9A$A1 @Ecb2 =j(a^ <3 @@,4JJ@ݣRc5 B@a Bx@x@A AR6Efa aR7 =m=R"8@i@ ΢QagB9bhbj: B@jB@x@A$Aj;E!jaj< =j$%=(%-(%=@$@ w>B#B J$ ? B@JB@,/@x@AAJ@E# eA=FVB =@{% "C@_ހ@ c nADb ! E B@`B@x@A$AFEbcAG =jX`=^ <H @4W@ m!j% * IJVJ@0J B@aRBy@x@A ARKEa aRL = o=R"M@@ $F!R!K 4"S!t$XqBNb/b½O B@B@x@A$AjPE>ˀ i AXajQ =@΀=(%-(%R@ @$SB̀J$ T B@Bc@x@AAJUEĆeV=FFW = À{% "X@@ m @AYb`b bZ B@`Bh@x@A$A[EKBab\ = `w`=$j <] @@,^JFJ _ B@B@x@A AR`EY FaRa = =R"b@i@c5"hBcbջb jd B@jBc@x@A$AjeEtb jajf =jgx=%-%g@w@n' @ :@Bh #BBi B@JB@x@AAJjEf0Jek=Fz3(.@l =R6{% "m@1@ ) @ Anbb b륱o B@aB @x@A$ApEbq =jaj^ <r @x@ !j @csJ䩠JA#4` ct B@aRB@x@A ARuEba FaRv =j="w@e@ $F!R% ͣalBxbbbjy B@jBc@x@A$AjzEjaj{ =j"=%p(%|@\!@ r!j @ :@B}  B J~ B@JB@x@AAJEڀ e=F ={% %@Eۀ@ ! @'Ab b륱 B@aB @x@A$AEbcb =jU`=j$j < @T@,cJSJA#eF B@aRBz((Bb@x@A ARE a aR =P=R"@@ c#\s,-/7 Bbb B@jB5n@x@A$AjE#Ȁfaj =jˀ=j%p%@@ $( @ :@B gʀJ B@JB C@x@AAJEe=*F ={% "@焀@ ) @+c 5@AbEb ! b륱 B@aB,@x@A$AE0?ab =ja= < @@ m!j%cJ/JA# B@aRBc@x@A ARE=aR aR ==!@J@ 3%-.9RBbb fc B@jB@x@A$AjEqjaj =jPu=j%pj%@t@nBB$  B@JB@@x@AAJEK-Je=̤F{ =@;3{% %@.@W @.W Ab ! b B@`B@x@A$AEb =ja"@X@ mJĦJA#c B@aRBc@x@A ARE_a aR =Rg=H@@b@ o$F%Cx-@zhobKb½ B@jB5n@x@A$AjEfjaj =j=j%-(%@A@ !j @ :@B  B B B@JB@x@AAJEր e=rFQ =܀{% %@"؀@, nWb׀b! 륱 B@aB@x@A$AEsbcb =jR`="@ Q@,JvPJ  B@aRB@x@A ARE a aR =R:=R"@ @ S$:$ ad Dfbb½ B@jBc@x@A$AjEŀ ,aj =jȀ=j%p(%@ǀ@ BLB$ c B@JBL6@x@AAJEe=Fc =~{"@ȁ@ !%N Ab*bj! bc B@aBc@x@A$AE e(=9|) =-{% "*@P(@ ! @A+b ! b륱, B@aBc@x@A$A-Ecb. =ja"/@@,c0JJA#1 B@aRB@x@A AR2EYa(aR3 =Rca=%p4@\@ y4h15b)b j6 B@jB /@x@A$Aj7E0ajfaj8 =j=j%-j%9@ @ $( @"@B:Bl$B; B@JB@x@AAJ<EЀ e==7F}> =ր{% %?@р@ y) @+c @bRb b륱A B@aB "@x@A$ABE=b bC =jߐ="D@A@,EJJ F B@aRB @x@A ARGEGRaRH =R\O=R"I@J@L65"AaEDfJb(b@$K B@jB{ @x@A$AjLEJjajM =j=j%-(%N@5@ nOB BP B@JB,@x@AAJQEѾ eR=٤Fw!^P/ AS = )Ā{"T@@ W%N AAUbmbV B@aB@x@A$AWEXzbbX =j:`=(fY@8@,ZJSJA#4[ B@aRB@x@A AR\Ee@Y aR] =R=R%^@e@ % BV @@0B_bb@%jaoy` B@jB|@x@A$AjaEb jajb =jx=( c@ӯ@ ndB4BJe B@JBc@x@AAJfEshJeg=Fzch =_n{%p:"i@i@ c +Bjbb ck B@aB@x@A$AlE#abm =j=j n@x@,oJJA#Fp B@aRB@x@A ARqEaR FaRr =R="s@@ 5uŃ%Ńs5ahBtb{bfu B@jB @x@A$AjvEVjajw =jZ= x@qY@$yBXB Jz B@JB@x@AAJ{E;@T e|=$|} ={% ~@R@ ': @c qVb ! b B@aB@x@A$AÈb =j̍a @.@,JJA# B@aRB@x@A AREDa aR =R]L=R(o@G@ 666L6a6naLEb%b j B@jB@x@A$AjE/aj jaj =j=j @@$( @.`AJBsB$B B@JB@x@AAJE Je=7΄F{c ={% @@ c |AbRb c B@aB@x@A$AE=wbcb =jj7`= @5@,,J8JA# B@aRB@x@A AREJ aR =R=R%@N@ e6ѻ6L6ͥBbbA;j B@jBy@x@A$AjEѩb jaj =j]=j%-(6@@~nBB B@JB@x@AAJEXeJe=٤F =a aR =F=FR"@vA@ c Cswoѻkq^Bb@bĩ B@a$B~ B@x@A$Aj E jaj =jy= @@ n$( @"AJ B5B J$B B@JB@x@AAJEe=ȄF = Àp{% F"@@ ) @+c fAbb b B@`B "y@x@A$AEqab =j-1`=j^"@/@,J.J  B@aRB|/@x@A ARE FaR =R=R"@ @ Scq vuVA|abb j B@jB@x@A$AjEb jaj = '=j%-(+c @@~ƹ!BB" B@B@x@AAJ#E!_Je$=Fx% =e{% "&@]`@ ! @+c Q 'b ! b ( B@aB@x@A$A)Eab* =jڀ=j +@/ـ@,,JؠJA#c- B@aRBc@x@A AR.EaRy FaR/ =RX=FR"0@@$X6c}4%aD1bb j2 B@jB oc@x@A$Aj3EEJĀcb? =jy"a"@@ق@,AJEJ(>B B@aRB@x@A ARCEW;#a(aRD =R C= E@k>@ s+]\t@8BFb=b@(G B@jB{ @x@A$AjHE   ajI =jn=j%-(+cJ@@ KB*BL B@JB@x@AAJMEe$b J!!eN=ĄFO =M{% (P@@ @c eAQbb^! b R B@aB "@x@A$ASEm%ac"#bT = `` .&`="U@j,@,VJ+J FW B@B@x@A ARXE $$aRY =R=R"Z@@ \r2\r-wA|[bb j\ B@jB~ @x@A$Aj]E'b j%%aj^ =j=( _@a@~`BB J$ Fa B@JB@x@AAJbE\(aJ J&&ec=nFd = Àa{% e@>]@ , lfb ! g B@`B "@x@A$AhE)a'(bi =j׀=j.j@ր@,kJՠJ l B@aRBy@x@A ARmE*aR ))aRn =RN=R%o@@ d p |} _Hopbb q B@jB@x@A$AjrE!J+j**ajs =jM=H@*e-(+ct@@ uBeL, v B@JB@x@AAJwE,J++ex=)|y = {% "z@@ ! @c A{bDb b | B@aB@x@A$A}E/,-b~ =jV-aj @@,J%J Rc B@aRByy@x@A ARE<8.a ..aR =R?="@D;@!!~%Q 1raBb:bf B@jB oc@x@A$AjE j//aj =j;=%-(%@@$BB J) c B@JB@x@AAJEJ/b J00e=ˤF =B{% %@@, wAb ! c B@aB "c@x@A$AEj0ac12b =j+1`=j$j+c@c)@,cJ(J 1 B@aRB@x@A ARE 33aR =!J="@@ OV"udǴt MBbRb@& B@jB@x@A$AjEd2b j44aj =j=j%-%@K@) @"@BB B$B B@JB@$@x@AAJEX3J55e=lkF/ =@^{F% %@(Z@ ! @ AbYbj! b륱 B@`B,@x@A$AEr4a67b =jԀ=j @ Ӏ@,JuҠJA# B@aRB@x@A ARE5aR F88aR =R+=R"@@ c"Ô"pWUBbb½ B@jB oc@x@A$AjEG6j99aj =jJ=j%-(%@I@ $( @ťBJB$B B@JB@x@AAJE7J::e=| ={% "@@ L6 {Ab)b ! 륱 B@a5 "c@x@A$AEE;>aj =j8=j%-(%@@ BB$  B@JB@x@AAJE.:b??e=F ='{% "@o@ ! @c b AbΡ ! b B@aB@x@A$AEg;ac@Ab =j'<`="@@&@,J%JA#c B@aRB@x@A AREހ FBBaR = o= @@ " Bb3b j`F B@B@x@A$AjEI=b jCCaj =jɝ=H@1y@$@~ƹ$(ncB B$B B@JB@)@x@AAJEU>JDDe=QhFh =@[{% @ W@ c =`BblVb `Bc@x@A$A @EW?acEFb =jр="@π@ m!j$$XJRJ(> `JR- B@a B@x@A AREd@aR FGGaR =R=R(o@p@  kkaaBb܊bj B@jB o@x@A$AjECAjHHaj =jsG=(%-(+c@F@ rB/B J B@JBc@x@AAJEr IIe=Fz/ =nBa% "@@ Abb! ^ B@aB "@x@A$AEBa,cJKb =j&{C`=^(f@y@,JxJ j B@aRBz,@x@A AR`E2Da LLaR =R9=R"@5@ '1 @# K 7 "֨ &VBbr4b½ B@a$B @x` =Aj @`E퀈2 jMMaj =j=( @x@~BB J$ g B@aB@x@AAJ EENNe =F/ ={%  @U@ ) @ Bb ! b B@aB,@x@A$AEdFaOPb =j$G`=$j%@-#@,J"JA# B@aRB@x@A AREۀ FQQaR =R]=R%@ހ@ $F @%L"d"b$b½ B@jB@x@A$AjE.Hb jRRaj =j=%-+c@@ !j @"@BBnJ$B B@JB@x@AAJERIJSSe =6eF! =X{% ""@S@ @ #bQb b륱$ B@aB (c@x@A$A%E<JaTUb& =jm΀=j$j"'@̀@@Sf' @(J;J J) B@aRB@x@A AR*EIKaR FVVaR+ =@=",@e@ !R#dtTM,` -bчbf. B@B c@x@A$Aj/E@LjWWaj0 =j`D=%-C1@C@ r2BB J3 B@JB@x@AAJ4EW XXe5=ؤF6 = ÀSMa% %7@ $F @+c ee8b ! b 9 B@`B@x@A$A:Eݷ,cYZb; =jwNj$j%<@Xv@,c=JuJA#> B@aRB$X@x@A AR?E.Oa [[aR@ =R6=R"A@1@ $F @+c3$"% Th:FDBb_b½C B@jB@x@A$AjDEq j\\ajE =j= F@Q@~!j @"AJGB쀃 $BcH B@JB@&y@x@AAJIEP]]eJ=yF/K =@諀{% F"L@3@ @AMbb ! bcN B@`B !c@x@A$AOEaQaJ^_bP =j!R`=$j"Q@ @,RJJ S B@aRBc@x@A ARTE F``aRU =R2=R"V@ۀ@ C"VÔQx"aeWbڀb jX B@jB/@x@A$AjYESb jaaajZ =j=j%-+c[@@~\B_B$ ] B@JBc@x@AAJ^EOTJbbe_=bQ`=|y` =U{% "a@P@ c L0Abb6b ! c B@aB@x@A$AdE! UajcdAe =jKˀ="f@ɀ@,gJJ jh B@aRBc@x@A ARiE.VaR FeeaRj =RЉ=R"k@*@ )%oSt&t6C!~!dlbbĩm B@jBc@x@A$AjnE=Wjffajo =jAA=(%-(%p@@@ !j @(@BqB?B$Br B@JB@x@AAJsE; gget=Fu =0{% "v@r@ y! @2_Awb ! b륱x B@aBc@x@A$AyE´Xbhibz =jtY`=^"{@Ms@,|JrJA#} B@aRB@x@A AR~E+Za jjaR =Rr3=R"@.@ yctEBb8b j B@jB@x@A$AjEV jkkaj =j=(%-(%@7@$( @"@BB逃B$B B@JB@x@AAJEݢ[b Jlle=^Fc =Ѩ{% "@@ c Abyb 륱 B@aB@x@A$AEd^\acmnb =j]`=^"@@,J_J >c B@aRB@x@A AREqՠ@Y: ooaR =R,݀=R"@؀@ cs"$Yp9y@Bb׀b½ B@jB y@x@A$AjE^b jppaj =jt=(%-(%@ѓ@ rB4BJ B@JB@٢oB!K @'@x@AAJEL_Jqqe=_F = 5sR{% "@M@ , ^Abb B@AB@x@A$AE`acrsb =j8Ȁ=j/j%@ƀ@ m`@,JJ  B@aRB; @x@A AREaaR FttaR =Rʆ="@#@ cp5ô. aBbb# B@jB@x@A$AjE:baj2 juuaj =j*>= @=@~B e=F, =PO{% +c@J@ $F @+c NAbb! b B@aBB@x@A$AEkacb =  ŀ="@mÀ@,cJ J F B@aRBF@x@A ARE{laR aR =R=%p@ @ c˵zuy"4,IBbx~b½ B@jBc@x@A$AjE~7mjaj =j ;= @h:@ B9B c B@JBh@x@AAJE e=|~ ={ @A@ ! @+c Bb  B@aBc@x@A$AEnbb =jno`=^+c@m@@S' @JlJA#J B@aRB@x@A >E%pa aR =@I-=R(o@(@ o"!RS"",aBb b½O  B@x@A$AjE  jaj =j=(%-+c@@ n!j @n"@BBd〃J$B B@JB@y@x@AAJEqe=(Fy =@{%p" @㝀@ $F @+c q5A bCb b B@`B$X@x@A$A E.Xrab =jVs`=^"@@ m!j$^J$JA# B@aRB/@x@A ARE;Ϡ@Y FaR =Rր=R"@3Ҁ@ $F!R(o""Hh*Bbрbf B@jB@x@A$AjEŠtb jaj =j>=(%-(%@@$BBJ B@JB@x@AAJEHFuJe=ʤF =IL{% "@G@ @Ab ! b B@aB 'Z@x@A$A!Evacb" =j€=^%#@b@,$JοJ (% B@aRB@x@A AR&ExwaR FaR' =!J=R"(@{@ pKJP P  =B)bYb@&j* B@jB@x@A$Aj+Ec4xaj jaj, =j7=j(%-@F@' @"@B.B6B$Bc/ B@JB@x@AAJ0E Je1=k|5n2 ={"3@#@ A4bb 5 B@aBy@x@A$A6Eqybcb7 =jkz`=j)"8@j@,9JpiJ >: B@aRB@x@A AR;E~"{a aR< =R*=FR%=@r%@ 0uP "uPKa>b$bA;? B@jBV@x@A$Aj@E jajA =j=%-%B@@ rCBIB JD B@JB@x@AAJEE|eF= FG =|{% "H@ɚ@c ?dAIb(b J B@aB@x@A$AKEU}acbL =j?~`=j^%M@@,NJ JA#FO B@aRB$X@x@A ARPE ̠@Y FaRQ =RӀ=R"R@0π@y8MJ$``$`@BSb΀baFT B@jB5n@x@A$AjUEb2 jajV =j=j W@z@~XB߉B JY B@JB@٢o/lB@x@AAJZE-CaJ Je[=Fw\ =@I{% ]@kD@ `@ kB^b e! _ B@`B@x@A$A`Eba =jݾaj b@?@ m!j @cJJ d B@aRBc@x@A AReEua aRf =Rv}=F!g@x@ |}N$ `TT'W%qhb>b½i B@jB@x@A$AjjEH1aj jajk =j4=j l@/@~mB3 B$ ,n B@JB@ `@x@AAJoE Jep=TFq =@{H e r@ @, Esbkb t B@`B@x@A$AuEVbbv =j{h`="w@f@@SmxJIJA#Jy B@aRB@x@A ARzEca aR{ =@'= |@c"@ #``$`$pq|a;&B}b!b#`fc~ B@B} @x@A$AjE jaj =jzހ=j%-(1@݀@ B6B B@JB@x@AAJEqb> Je=F* =Y{% .W@@ $F @c Ab b! bc B@aB "y@x@A$AEQat b =jV="@T@ !j$cJcJ B@aRB@x@A ARE~ RaR =R9=R"@@83}<|}4kcbb j B@jB@x@A$AjE aj =j̀=( @ˀ@ BMB J$ c B@JB@$@x@A>Eb Je=R =@{% @Dž@ ;kcb(b B@`B@x@A$AE@ab =1`=j%pj/o@~ mJJ c B@aRB@x@A ARE  aR =RϾ="@(@ C},|}$aHobb½ B@jB@x@A$AjErb jaj =j3v=j%-+c@u@ BtBJ B@JBc@x@AAJE-.Je=F =4{bxs@i/@ $F%c CAb  bZ B@aB@x@A$AEb =j멏aj @K@,JJA# B@aRB@x@A ARE`a FaR =Rmh=FR+c@c@,8STdpI2PDJ!aSBb9b@$j B@jB{ o@x@A$AjEHjaj =j`= @6@$B J B@ B@x@AAJE e=PF =݀{% :"@ ـ@ ': @ GBbk؀b b B@aB@x@A$AEUbcb =jaS`=j^+c@Q@,J0JA#F B@aRB@x@A AREc a aR =R =R"@g @ cMu$r4]L]Bb bo B@jB@x@A$AjE jaj =jfɀ=j @Ȁ@ $( @"AJB"B B@JB@x@AAJEpe=Fu, =a{% @@c Ab b ! c B@aBc@x@A$AE e=5F =ڀ{% %@Հ@ , AbPb 륱 B@aBc@x@A$AE:bcb =jgP`=" @N@ 82$, J5JA# B@aRBynb@x@A AR EHa aR =R=R"@H @ %e4Z@Bb b B@jB@x@A$AjE€faj =jWƀ=(%-(%@ŀ@~BB B@JB@x@AAJEU~e=֤F =A{% "@@ ! @c uAb ! b  B@aB@x@A$AE9ab =j=^(f@[@, JJ ! B@aRB@x@A AR"E鰢aR aR# =R=R"$@@'%t"ta9?B%b^b c& B@jB* @x@A$Aj'Epljaj( =jo=( )@K@ $( @"AJ*Bn,Bc+ B@JB@x@AAJ,E'Je-=x:|. =-{% /@4)@ A0b(b c1 B@aBh@x@A$A2E~〈 Z^iqb3 =jaj$j"4@@,5J|J 6 B@aRBz@ B @x@A AR7EZaRA@aR8 =@8b="9@]@ ,"VHT`$`%$ |y:bb@&'; B@B$X@x@A$Aj<Ejaj= =j=%-+c>@@$?BFB J) V@ B@JB@@x@AAJAE eB=FvyC =@׀{% (D@Ҁ@ , &|yEb5b ! F B@`Bc@x@A$AGEbH =j=^%I@@ mJJJA#K B@aRBw@x@A ARLEHRaRM =R@P="N@K@ ypSITpMIakcObb jP B@jB @x@A$AjQE-jajR = =j%-(%S@ @  `@"@BTBm B$ BU B@Bc@x@AAJVE eW=FBX =ŀ{F% "Y@@c kcZbOb [ B@aB@x@A$A\E:{bb] = `];`=j^"^@9@,_J)J ` B@BL6@x@A ARaEH aRb =R=FR"c@\@ HTop?I%$VaDfdbb je B@jB@x@A$AjfEέb jajg =jV=j%-(%h@@~͓iBBj B@JB@c@x@AAJkEUiJel=֤Fym =@Eo{% "n@j@ TAob ! p B@`By@x@A$AqE$abr =j="s@g@@SmctJJA#Jcu B@aRB@x@A ARvE雰aR FaRw =@=R"x@@ *kd,+dpxBybeb½z B@B@x@A$Aj{EpWjaj| =jZ=( }@I@ r~PY J$ q B@JB@@x@AAJEJe=x%|h =@{% @2@ $F @ mBbb bc B@`B@x@A$AE}΀cb =ja^+c@@ m!j*Q,JtJA# B@aRB@x@A AREEa aR =R>M=R%@H@ 6 uabb B@jB@x@A$AjEaj2 jaj =j=(%-(+c@@~BZB J B@JB@x@AAJE Je=τF =€{% "@н@m @K `Ab4b! b B@aB@x@A$AExbb =jR8`=%pj%@6@,JJA# B@aRB@x@A ARE, aR =R=R"@=@y9I$P4@Bbb c B@jBz@x@A$AjEbjaj =jC= @@ BB c B@JB@x@AAJE:fJe=xF =&l{% F"@vg@ y) @ /Bb  bc B@aB@x@A$AE!a,b =j=j^%@;@,JߠJA#(Rc B@aRB@x@A AREΘaR aR =R~="@ޛ@ %aYJBbJb@$j B@jB$X@x@A$AjEUTajaj =jW=%-(+c@3@$BV J)  B@JB@x@AAJEaJ@Y e=]"|y, ={% %@@ y': @( hv/G?Ab|b ! b B@aB@x@A$AEbˀb =jaj @@,JiJA#r B@aRB@x@A AREpBaFaR =RJ=R"@|E@9#Sua+BbDb j B@jBB@x@A$AjEjaj =ja%-(%@@ $( @(@BBCB$B B@JB@@x@AAJE}Je=̄F =@q{% "@@ c )!Tbb ! 륱 B@`B@x@A$AEubyb =j45`= @3@,JJA#c B@aRB@x@A AREaR =R=R"@!@ c3zBbb j B@jBx@x@A$AjEbjaj =j(=j%-(#@@ BB$ c B@JB@x@AAJEcJe=uF = i{% "@_d@l @c DAb ! bc B@aB 'Z @'@x@A$AEa b =jM#="@!@,JJ  B@A*BB@x@A ARE,ڀFaR =R=R"@D݀@ CǨ999alBbܠb@$ B@jBy 5n@x@A$AjEbjaj =jC=(%-(%@@ rBB J$  B@JB@x@AAJE:QJe=F@Q&W{% "@xR@ c Abڡ  B@aB`x@9 A @E ayA =̀=^.@Sˀ@,JʠJ@F B@a B@x@A AR E΃aR aR =Rp=R" @҆@ S9 :::3:T :aNB b>b@$<c B@jB@x@A$AjEU?aj2 jaj =jB=(%-(%@A@~ӈBA J B@JB@x@AAJE J @==d |t =a% "@ ! @cS$Abwb b  B@aB@x@A$AjEb,b =jvaj%@t@,J]JA#F B@aRB@x@A AREp-a aR =R5=R" @`0@ cq$:T(:q,:T0:q4:TկB!b/bĩ" B@jBQ@x@A$Aj#E耈 jaj$ == %@@ $( @"AJ&B>BJ' B@JB@x@AAJ(E}b J  e)=F * =i{% +@@ , yq]A,bb c- B@aB,@x@A$A.E`a,  b/ =j `=j^"0@{@ 5, @ 1JJ R2 B@aRB|@x@A AR3E׀  aR4 =Rހ="5@%ڀ@ cs8:q<:T@:qD:aӡB6b٠b@$7 B@jB@x@A$Aj8Eb f  aj9 =j =%p(C0;@}@$;BܔB B< B@JB@x@AAJ=ENaJ Je>=F? = À T{% (@@ZO@ ': @c wIxAb  bB B@`B@x@A$ACE acbD =jɀ=j%pj%E@0Ȁ@,cFJǠJ FG B@aRB@x@A ARHEaR aRI =RY=R"J@@ c HI K Jao>DKb#b½L B@jB@x@A$AjME9<jajN =j?=%-%O@@ $( @"@BPB~>(JcQ B@JB@8W@x@AAJRE eS=A | T = {% "U@@$X AVb\b 륱W B@`B !y@x@A$AXEGbY =jٷ= Z@;@,[JJ \ B@aRB@x@A AR]EnRaR^ =Rv=R"_@q@ %M L O NaB`bJb ja B@jB@x@A$AjbET*jajc =j-=j%p(%d@3@ eB, Bf B@JBc@x@AAJgE eh=Fyi ={"j@@ !%Nc `Akbwb b l B@aB@x@A$AmEbbbn =ja`= o@_@,pJ]JA#jq B@aRB@x@A ARrEoa aRs =R$ =R%t@{@ 9udǩt >`Bubbov B@jBژ@x@A$AjwE jajx =j׀=( y@ր@ $( @ūczBBB J{ B@JB@)c@x@AAJ|E}e}=F~ =@q{% :"@@ 5\ @+c .OBbb bc B@`Bc@x@A$AEKab =j5 `=^"@ @ m!j% ! $ ARJJ  B@aRB@x@A ARE€aR =Rɀ=R"@-ŀ@7!R% QTSPA6tNZWAjbĀb j B@jB @x@A$AjE}b2   aj =j(=(%p(+c@@~ƹBB J B@JBc@x@AAJE9aJ J!!e=Fnb =?{% "@\:@B! @\Ab ! b B@aBQ@x@A$AE"#b =jδa$j%@0@,JJA# `RJ B@aRB@x@A AREka $$aR =RPs=R"@n@ yP 0; Bbb½ B@jBB@x@A$AjE9'aj%%aj =j*= @)@ $( @r"AJB) $By B@JB@x@AAJE &&e=AF = À{% F"@@ y) @+c CvAb`b bc B@`B@x@A$AEGb'(b = `l^`=j^"@\@ 5!j @cJ:J B@B@x@A ARETa ))aR =R =R"@h@  t^t aBbb B@jB _c@x@A$AjE j**aj =jkԀ=j%-(+c@Ӏ@ rB'B J B@JB@x@AAJEbb J++e=Fc =N{% "@@c LAb ! B@aB,@x@A$AEGac,-b =j`=%@@,cJJA#c B@aRB@x@A ARE ..aR =Rƀ=&@@ cK[ 0 ucr aJ,bfb@$jc B@jBB@x@A$AjE}zbf//aj =j}= @@@ B|  B@JB &@x@AAJE6aJ 00e=HF =@;{% @=7@ ) @c ,b  b B@`BB@x@A$AE12b =ja^%@@,J}JA# B@aRB@x@A AREha 33aR =RIp=R(o@k@ cCSPCPCPQDak}Hobb f B@jBc@x@A$AjE$j44aj =j'=j%-(+c@@Bf& B)  B@JB@@x@AAJE 55e=&F =@{% "@@h ϏAbAb  B@`B@x@A$AE,b/67b =j^[`="@Y@ m'$J*JA# B@aRB@x@A ARE9a 88aR =R=R"@E@:C PaBbbĩ B@jB@x@A$AjE j99aj =jLр=(%-(%@Ѐ@ BB J B@JB@x@AAJEF::e=ȤF =7{% "@@, (%Ab ! B@aB@x@A$AR  EDac;>aj =jz=j @F@  By$ c B@JB@x@AAJE2aJ??e=iEFc =8{"@'4@ VBb3b  B@aB@x@A$AEoc@Ab =jaj+"%@@,JnJA# B@aRB@x@A ARE|ea FBBaR =R+m=FR%@h@:#(QȀd +gYaBbgb@$j B@jB@x@A$AjE!jCCaj =j$=%-+c!@#@$"BOB J# B@JB@x@AAJ$E܀ DDe%= F& =v{% "'@݀@ y/ @ m4(b&bZ bZ) B@aBy@x@& =A* @EbcEFb+ =jCX`=j^%,@V@,-JJ@F. B@a B@x@A AR/Ea GGaR0 =R="1@.@ c3Ǫtkb`p a@D2bb½3 B@jB@x@A$Aj4E jHHaj5 =j5΀= 6@̀@$7B̀B J8 B@JB@x@AAJ9E+IIe:=F; ={% <@g@ , @( lB=b ! ba${ > B@aBc@x@A$A?EAaJKb@ =j`= A@=@,BJ C B@aRB@x@A ARDE FLLaRE =Rf=R(oF@Ȼ@ c C6E5@+g0GBGb4b½H B@jBc@x@A$AjIEFt<@T jMMajJ =jw=j K@+@~$( @(AJLBv B$BM B@JB@x@AAJNE/JNNeO=NB|P =5{% `3bQ@ 1@ c xARbi0b 륱S B@aB,@x@A$ATET뀈yOPbU =ja V@㩀@ , @yWJOJA#cX B@aRB@x@A ARYEaba FQQaRZ =Rj=![@ie@ S8Ǩ$QaxB\bdb@$j] B@jBQ@x@A$Aj^EjRRaj_ =jp!=j%-j1`@ @ aB,Bb B@JB@x@AAJcEoـ> SSed=Fe =[߀{% cf@ڀ@ Agb bǝ! h B@aB@x@A$AiEbcTUbj =j!U`="k@S@,clJRJA#Fcm B@aRBc@x@A ARnE a VVaRo = = p@@  cQ3<5nBqbb½r B@B* @x@A$AjsEǀF jWWajt =jˀ= u@oʀ@ vBɀBJ$ yw B@JB@x@AAJxEXXey=Fz ={% {@L@ ) @6 CnW|b  b} B@aB@x@A$A~E> aYZb =!b=^.@@,JJ @ B@aRBQ@x@A ARE aR F[[aR =RH=R(o@@ s+``%IoEbb f B@jB@x@A$AjE+q j\\aj =jt=(%-(+c@@ Bgs,  B@JB]L@x@AAJE, J]]e=3?| =2{% "@-@ ! @6 AbNb b B@aB@x@A$AE9W^_b =je a^%@Ǧ@,J3JA# B@aRB/@x@A AREF_a ``aR =Rf=R"@Rb@ `aBbabf B@jB@x@A$AjEjaaaj =jQ=(%-(%@@$BB Jc B@JB@B@x@AAJET bbe=٤F =@D܀{% "@׀@ c OuAb ! B@`B@x@A$AEڑbccdb =jR`=j c@eP@ m!j @JOJA# B@aRB@x@A AREa eeaR =R="@ @ ВЄ(Bb\bA;j B@jB@x@A$AjEnĠ@Y jffaj =jǀ=j @Q@$Bƀ F B@JB@x@AAJEgge=vF5n =݅{F% @2@ y c fBbb c B@aBy@x@A$AE|;hhb =j'@=j%pj+c@>@,J=J  B@aRBy@x@A ARE FiiaR =R=R(o@@ ЂЃ2taqBbgb j B@jB@x@A$AjEjjaj =  =j%-+c@i@ $( @"@BBɴB)B B@B@c@x@AAJEnJkke= e!='|F" ={% #@@4 b$b7b ! % B@aBc@x@A$A&EЀcb' =jX&aj0j%(@@@S')J$J J* B@aRB@x@A AR+E+G'a aR, =@N="-@/J@ cpeΐǵ%a_Ho.bIb/ B@B @x@A$Aj0E(jaj1 =j*=j 2@@ ) @"AJ3BB$Bi,4 B@JBB@x@AAJ5E8 e6=դFa7 = Ā{F% F(8@t@ , 4A9b ! : B@aB,@x@A$A;Ey)bcb< = `9*`=j =@J8@,>J7J ? B@B@x@A AR@E aRA =R=R"B@@;Eepd`ud"HtBCbLb D B@ B@x@A$AjEES+b j! AF = ׯ=j%-(6G@5@$HB I B@Bc@x@AAJJEg,JeK=[zFL =m{% "M@i@ ) @  8ANbvhb bO B@aBQ@x@A$APEa#-abQ =j= R@@,SJ[JA#FcT B@aRB@x@A ARUEn.aR F+$FV =R=R"W@r@$) @%pP0txBXbޜb@%jY B@jB@x@A$AjZEU/jaj[ =jY=H@e-(%\@X@ !jnc]BAB)B^ B@JB@x@AAJ_E{0Je`=Fa =h{F% "b@@ @"Acbb ! b d B@aB$X@x@A$AeÈ,5$^f =j&1aj$j"g@@,hJJA#i B@aRB@x@A ARjED2ay aRk =RK=FR"l@G@!$F @#~3%!0 8_|BmbFb jn B@jB@x@A$AjoE jajp =  3aj%-%q@h@ !j @"@BrBB$Bs B@B@x@AAJtE Jeu=Fv ={% "w@Y@, Axb  cy B@aB@x@A$AzEv4bcb{ =j65`="|@75@, }J4J ~ B@aRB@x@A ARE퀈 aR =Ra=R"@@ 3S!q'SBߘBb%b½ B@jB@x@A$AjE86b jaj =j=(%-(%@@ rB|J B@JB@?) @x@AAJEd7Je=@wF = @j{% "@e@ ! @ {jAb[b b B@`B@x@A$AEE 8acb =jv=^(f@ހ@ m2* JDJ c B@aRB@x@A ARES9aR F>, =R=R"@W@ C ! T` axbÙb@$j B@jB@x@A$AjER:aj2 j#!j =jfV=( @U@~n$( @"DB"B B@JB@x@AAJE`;aJ Je=F =E{% @@ $F @+c 4`b ! bc B@aB@x@A$AEɀ,b =ja%p+c@^~ !j @"@BBBB B@JB@x@AAJE  e=ʄF ={% "@?@$! @eb  b륱 B@aB@x@A$AEs?bb =j3@`=j$j"@ 2@,Jw1JA# B@aRBz[{B@x@A ARE aR =RK="@@ c${Dfbb j B@jB@x@A$AjEAb jaj =j=%-%@@$Be , B@JB &@x@A>EaBaJ Je=%tF =@g{% %@b@. c cAb@b , B@`B@x@A$AE*Cab =S݀=j @ۀ@ m!j @J!J c B@aRB@x@A ARE8DaR aR =Rܛ=R"@8@ (o!Roszy1U"a}QBbb½ B@jB@x@A$AjEOEjaj =j?S=%-(%@R@ !j @(@BBQBB B@JB @x@AAJEE FJe=ʤFw =5{% "@ @ @٣Ab  B@aB@x@A$AEƀcb =jGa$j"@W@,JÄJ   B@aRB@x@A ARE=Ha aR =RE=R"@@@ c% ~}{%q.BbIb½ B@jIBc@x@A$AjE` jaj =j=j%-%@C@~B B$  B@JB@x@AAJEIe=hDŽFh =ۺ{%p"@$@8) @6 Abb bc B@aBc@x@A$AEnpJab =j0K`="@.@,J`J  B@aRBc@x@A ARE{@Y FaR = +4= @@!d @6y!$q 21BTbĩ B@B@x@A$AjELb jaj =j=j%-(%@@~BNB B@JB@x@AAJE^MJe= qF =}d{F% % @_@5 J! @A b$b ! b B@aB@x@A$A ENab =j9ڀ=j$j+c@؀@,JJ c B@aRB 5@A AR @`EOaR FaR =RΘ=R"@)@ c+\\y%`̠PBbb j B@a$B@x@A$AjELPaj jaj =j#P="@O@BNBB$&5 B@JB@x@AAJE*QJe=Fc ={% F"@d @ c &B b  c! B@aB@x@A$A"EÀcb# =jRa^%$@H@, %JJA#& B@aRB@x@A AR'E:Sa FaR( =RdB=R")@=@ zy` a)B*b2b@$j+ B@jByc@x@A$Aj,EE* aj- =j=(%-(+c.@-@ r) @"@B/B J0 B@JB@y@x@AAJ1E̱Te2=MĄF3 =@{% "4@ @c SA5blb 륱6 B@`B$X@x@A$A7ERmUacb8 =j|-V`=j c9@+@ m2 @y:JIJA#c; B@aRB{,@x@A AR<E`@Y aR= =R=">@p@ yVy4 WB?bbo@ B@jB@x@A$AjAEWb2 jajB =jo=(%C@Ϣ@~DB/B JE B@JB@٢o@x@AAJFEm[XaJ JeG=F|yH =@Va{% I@\@ $F @6  AJb be! b K B@`B@x@A$ALEYabM =j׀=%pj(fN@Հ@ m!j @OJԠJA#P B@aRB@x@A ARQEZaR aRR =R=!R(oS@@ o @6%Q % ~aVBTbjb U B@jB@x@A$AjVEI[jajW =jM= X@qL@ YBKB, Z B@JB@x@AAJ[E\Je\=|] = {% ^@F@ @B_b dh` B@aB$X@x@A$AaEbb =jĀ]aj$j%c@$@,dJ~JA#aHRe B@aRB/@x@A ARfE7^a aRg =RU?=R%h@:@ Bq%a5nibb½j B@jB@x@A$AjkE* jajl =j=j%-+cm@@~nBn B$ o B@JB@x@AAJpE_b} Jeq=2Fr ={%p"s@쯀@ B) @ ,5ntbMb! bu B@aBB@x@A$AvE7j`acbw =jZ*a`=%x@(@,yJ&JA#z B@aRBc@x@A AR{EE@Y aR| =R="}@Y@ ct/t /Q@~bb½ B@jB~@x@A$AjE˜bbaj =jT=%-(%@@ BB c B@JB@٢o@x@AAJERXcaJ e=ӤF/ =@F^{% "@Y@ y! @.W b(b e B@`B !L6@x@A$AEdacb =jӀ=^%@\Ҁ@,JѠJ c B@aRB@x@A AREeaR aR =R=R"@捀@,<"+Y~+h@ aCDbRb½ B@jBF@x@A$AjEmFfjaj =jI=(%-(%@N@ n$( @n"@BBH J$B B@JBc@x@AAJEgJe=u|c ={%p"@/@ c  Abb c B@aB@x@A$AE{b =j}ha^"@ |@,Jy{J j B@aRB@x@A ARE4ia aR =R/<=R"@|7@ $F'Eo<%}" %8,b6b B@jB o$X@x@A$AjE jaj =j=(%-(%@@$BOB J B@JB@x@AAJEje=F ={% "@լ@ < {>b5b B@aB@x@A$AEgkab =jH'l`=j$j%@%@,JJA# B@aRB@x@A ARE*ހ FaR =R=R"@2@<#!0S!zy@Dbb jc B@jB@x@A$AjEmb jaj =@݀@="@@ƹ'%"AJBBB B@B@x@AAJE7UnJe=Fy, =#[{% F"@oV@ S c _Ab  c B@aBy@x@A$AEoacb =jЀ=j @Eπ@ !j @,JΠJA#c B@aRB; @x@A AREˇpaR FaR =R{="@ϊ@ 3% ~ƑDa?Bb;b½ B@jB/@x@A$AjERCqjaj =jF=%p(+c@@@ rBE J B@JB@x@AAJE e=Z| = Àra% %@@ * ! @W bu ! b B@`B@x@A$AE_cb =jzsj%pj(f@x@,cJVJ  B@aRB$X@x@A AREm1ta aR =R9=R"@q4@ C"S!tkcb3b½ B@jB@x@A$AjE쀈2 jaj =jl=j @@~$( @"EB0B J$B B@JBF@x@AAJEzue=F/ =o{% F"@@ ) @6 tkcbb bc B@aB@x@A$AEdvab =j1$w`=j^"@"@,JJ  B@aRBc@x@A ARE۠@Y FaR = {=FR"@ހ@ S% ""0S" Dfb{݀b  B@jB@x@A$AjExbjaj =j!=j%-(+cU@@~BB B@JB@٢o85n@x@AAJERyJe=Fz =@X{% "@XS@ @4 YBAb e! b  B@`B@x@A$A E zab =j̀=" @%̀@ m'$ JˠJ@0 B@aRBc@x@A ARE{aR aR =R`=!@@}@~B;bsڀb j< B@jBc@x@A$Aj=Ezb  A> =@݀=(%p%?@U@$@B A B@B@@x@AAJBEOJ@=C=aFrD =@T{% "E@>P@  c AFb  G B@`B !B@x@A$AjHE abI =jʀ=j J@ɀ@ m!j @KJȠJ cL B@aRB/@x@A ARMEaR FaRN =RN="O@@<"KX S!t$wBPbb½Q B@jB5n@x@A$AjRE=j ES =j@=%-(%T@@$UBh? J) V B@JB@x@AAJWE eX=$ |zY ={% %Z@@c yA[b>b \ B@aB5n@x@A$A]E)bb^ = `Jt`=%pj+c_@r@,`JJ ja B@B@x@A ARbE7+a   aRc =R2=R"d@3.@ c "~$`/0N$eb-b jf B@jBQ@x@A$AjgE j  ajh =jE=%-!i@@ƹ/ @"@BjBB Jk B@JB@x@AAJlEDb J  em=ŤF5nn =<{% "o@@$X _Apb ! 륱q B@aB@x@A$ArE]ac  bs = ``=j^"t@^@,uJJ >v B@B@x@A ARwEԀaRx =R܀=R"y@׀@ yy"!0 S!ߑB'zbPbA;{ B@jB/@x@A$Aj|E_b faj} =j=j%p(%~@J@~B B$ c B@JB@x@AAJEKJ >=g^F =Q{% "@ M@ 5n! @ S,bLb bc B@aB5n@x@A$AjElacb = `ǀ=%@ŀ@,JgJ F B@B@x@A AREz~aR FaR =R+="@~@ cÿBBBDbꀀbĩ B@jBL6@x@A$AjE:aj jaj =j==j%-(%@<@ $( @"@BBEB B@JB@x@AAJE Je= =x{F% "@@ \eAb#b ! 륱 B@aB@x@A$AEbb =j8q`=j^"@o@,JJA# B@aRB@x@A ARE(a aR =R/=R"@ +@ * q x|aYBb*b( B@jB@x@A$AjE〈jaj =*="@@~BB$c B@JB@: @x@AAJE)e=Fs =@!{% @c@ , Bb ! B@`B@x@A$AEZab = ``=^%@B@ myJJ  B@B/@x@A ARE aR =Rـ=R%@Ԁ@ o$F'E! C!"$_xaMBb9b jc B@jB o* @x@A$AjEDb jaj =j̐=(%-(+c@(@ !j @"@BBB B@JBc@x@AAJEHaJ~v Je=L[F =N{% "@ J@ y$F @6 CAbkIb  B@aB ",@x@A$AEQac !b =jĀ=^"@€@,JLJ r B@aRB@x@A ARE_{aR ""aR = =R"@g~@ 8|}{zy"r0 2FBb}b@&j B@B@x@A$AjE6j##aj =jj:=j%-(%@9@ B&B$  B@JB @x@AAJEl $$e=d3`A =P{"@@@a!K Abb! b B@aB@x@A$AEbc%&b =j%n`=j)%@l@,JkJA# B@aRB@x@A ARE%a ''aR =R,=FR%@(@= sC#"pBDBb|'b@&j B@jBژ@x@A$AjE j((aj =j=%-%@l@$BB J$  B@JBc@x@AAJE))e=F ={% "@I@ c FAb  B@aB/@x@A$AEWa*+b =j`=jj%@@,JJA#F B@aRB5n@x@A ARE F,,aR =RYր="@р@Ex(o!!%~ Ӕ~P~ a:|bb j B@jB o@x@A$AjE)b j--aj =j=%-(%@@$Bq B@JB@!K@x@AAJEEJ..eV  1XF =@=K{ @F@ " @lbKb bc B@`B@x` =A @E6a/0b =je=j$%@ſ@ m' @BJ1J@ B@a Bc@x@A AR EDxaR F11aR =R=F!R(o @D{@y =#"7ː7Vdp8a9D bzb j B@jBF@x@A$AjE3aj j22aj =jR7=j%-j%@6@~n$( @K BBBc B@JBc@x@AAJEQ J33e=ҤF} =E{% "@@/ hAb ! 륱 B@aB 'Z@x@A$AEتbc45b =j k`="@ki@,JhJ(R B@aRB@x@A ARE!a 66aR =R)= !@$@c3ѡt!Ѯљt8/mB"bYbj# B@jB@x@A$Aj$El݀ j77aj% =j=j%p(%n&@Q@~'B߀ B$ ( B@JB@x@AAJ)E88e*=t`=+ =㞀{% %,@.@w @1a0" ( -A-bb bc. B@aB@x@A$A/EyTajc9:b0 =j`="1@@,2JtJA#c3 B@aRB@x@A AR4E F;;aR5 =R.Ӏ=R"6@΀@%C4$3a 7b̀b j8 B@jB o@x@A$Aj9Eb j<EBaJ J==e?=UF@ =H{% "A@C@ L6/ @+c   Bb0b! b C B@aB "c@x@A$ADE >>bE =ja$j.F@ @,GJwJ H B@aRBz>B@x@A ARIE DE R??aRJ =RK=R"K@@ S,-<]L"2DLbb jM B@jB @x@A$AjNE(ub j@@ajO =jx=j P@ @$QBmw B$ cR B@JB,@x@AAJSE0JAAeT=FU =6{F% F"V@1@ BWbKbjX B@aB@x@A$AYE6cBCbZ =j_aj^%[@@,\J-JA#] B@aRB@x@A AR^ECca/DDaR_ =Rj=FR"`@Pf@  c "1 Qy@abeb jb B@jB4@x@A$AjcEaj EEajd =j:"=%-(+ce@!@ nfB B g B@JBc@x@AAJhEQ JFFei=ҤF j =={ k@ۀ@ c @lb  m B@aB,@x@A$AnEؕb5nGHbo =jU`=j^%p@^T@,qJSJA#r B@aRB@x@A ARsE a IIaRt =R=R%u@@ csљх$ lbDvbYbq w B@jB@x@A$AjxElȀ jJJajy =jˀ=j%-z@W@~{Bʀ Bc| B@JB@x@AAJ}EKKe~=tF =㉀{% "@-@ y! @6 wbb b B@aB@x@A$AEy?acLMb =j=%@@,J|J  B@aRBc@x@A AREaRy FNNaR =RH="@@ ;౟B$ iSEbb j B@jB$X@x@A$AjE raj jOOaj =ju= @t@~BIB B@JB@5@x@AAJE-JPPe=@| =@3{% @.@  c ͡Bb0.b ! B@`B@x@A$AE逈cQRb =j1a^%@@ m!j @JJ(>, B@aRB@x@A ARE(`a FSSaR =Rg=!@0c@ yCE"% $Xbbbj B@jBy@x@A$AjEjTTaj =j7=j @@ ) @"DBB$B B@JBc@x@AAJE6 UUe=F =.݀{% @p؀@ y! @c c$Xb ! b B@aB@x@A$AEbcVWb =jR`="@GQ@,JPJA#j B@aRB@x@A ARE a XXaR =Rx=R+c@ @ cb½ B@jB@x@A$AjEQŀ jYYaj =jȀ=(%-(6@1@~$( @ťBǀA$B B@JB@x@AAJE׀ZZe=XF =̆{% "@@ c bsb 륱 B@aB @x@A$AE^E a'Bb_bf B@jB@x@A$AjEjccaj =j=*(+c@u@ rBB J B@JB@@x@AAJEԀ dde=F =@ڀ{% (@VՀ@ 5\ @ Ab ! b B@`B@x@ =A @Ebcefb =jO`=j @ N@ m!j @JMJ@ c B@a BB@x@A AREa ggaR = j="@ @ $F!R?7?E;Bb'b½ B@B@x@A$AjE5€ jhhaj =jŀ=j @#@!j @.`AJBĀ B$B B@JB @x@AAJE}iie==FB ={F% @~@ @SAbXbj! bW  aBB@x@A$AEC9ajkb =j^=j$j"@@,J*JA" B@aRB@x@A AREPaR FllaR =R =R(o@]@ @E aUB bȲb½ B@jB @x@A$Aj Ekajmmaj =jko=j%-+c @n@ B'B$ / B@JB@x@AAJE^'aJ nne=ߤF$X =V-{% "@(@ c \Ab !   B@aBc@x@A$AEopb =ja @w@,J㠠JA# B@aRB@x@A AREYa qqaR =Ra=R"@\@ AE` bfb½ B@jBh@x 9A$Aj @`Eyjrraj! =j=j%-(%"@Z@ #B B$ $ B@aB@x@AAJ%E sse&=Fc' =ր{% "(@;Ҁ@ y! @c e)bрb b* B@aB (@x@A$A+Ebctub, =jL`="-@ K@,.JuJJ / B@aRBy@x@A AR0Ea vvaR1 =R; =R"2@@>"tD3bb4 B@jB~ c@x@A$Aj5E jwwaj6 =j€=j%-(%7@@~$( @.`@B8Bb B9 B@JB@x@AAJ:Ezxxe;="F< ={"=@{@ 5\%N V&A>b=b b륱? B@aB "@x@A$A@E(6acyzbA =j\="B@@,CJ+J D B@aRB@x@A AREE5aR F{{aRF =RѴ=R%G@-@ ъtfakBHbbĩcI B@jB @x@A$AjJEhj||ajK =j8l=(%pL@k@ rMBjB JN B@JB@\!KB@x@AAJOEC$J}}eP=ĤFQ =@7*{% "R@%@ ! @( {BSb ! b T B@`B@x@A$AUE߀~#[AV =ja^%W@X@ m'%yXJĝJ Y B@aRBy* @x@A ARZEVa aR[ =Rw^=R"\@Y@F># Bё;TOaCbB]bCb@$j^ B@jB& BJ@x@A$Aj_E^aj2 jaj` =j=( a@D@~$( @ "AJbB J$Bc B@JBc@x@AAJdE Jee=iFvf =Ӏ{% g@!π@F Ahb΀b ci B@aBb@x@A$AjEkbbk = `I`=%pj"l@G@,mJ^J Fn B@B@x@A ARoEya aRp =R)=R%q@@ c3JECE$a*PBrbbĩs B@jB@x@A$AjtE jaju =j=%-1v@⾀@ wBCBJx B@JB@x@AAJyEwb Jez=Fz{ =r}{% "|@x@ ! @c ɂ}b"b b ~ B@aB (@x@A$AE 3ab =j==j^%@@fcJ J I B@aRB@x@A AREaR aR =@α=R"@&@* >C KcD\t@ ENDbb½ B@B(c@x@A$AjEejaj =j1i=j @h@ r$( @"AJBgB J B@JB@x@AAJE(!aJ e=F ='{% @e"@ $F @+c Ab ! bc B@aB "@x@A$AE܀b =ja"@!@,cJJ c B@aRB@x@A ARESa aR =Rx[=%@V@>SEEF@ aQb4b½ B@jB @x@A$AjECajfaj =j=%p(+c@@ BJ$  B@JB@!K@x@AAJEʀ e=J݄Fw34P]L =@Ѐ{% "@̀@ ! @ LQbeˀb b, B@`B @x@A$AEPbb =jF`=^%@D@,JOJA#4`  B@aRB@x@A ARE]@Y`~ 28 =R aRR"@^@ @c6GEEH  DDb j B@jB-$Bc@x@A$AjE一jaj =jd=j%-(%@@~$( @"@BB B B B@JBc@x@AAJEktbw e=F5n = Àgz{% "@u@ c Abb! 륱 B@`B@x@A$AE/a1}$^ =j="@p@,JJ (R B@aRB/@x@A AREaR aR =R=R"@@ s$EIEABbcbj B@jB@x@A$AjEbjaj = f=(%p(%@qe@ BdB J$ c B@B@x@AAJE aJe=0| = ${% `3B@N@ ! @ /Ab ! bc B@aB@x@A$AEـcb =ja^(f@@,J~JA# B@aRB@x@A AREPa aR =RJX=R%@S@ ,"8"TaBbb@$j B@jBxc@x@A$AjE' ajfaj =j=j%-(%@ @ $( @"@BBk J$B B@JB@x@AAJE e=/ڄF =̀{"@ ɀ@ c /CAbnȀb B@aB/Z " .X@x@A$AE5bcb =jRC`=j/"@A@,J J >c B@aRB@x@A AREB@Y aR = +aRFR%@F~ yT"e" ĜBbbz B@B @x@A$AjEɵ, jaj =jQ=%-%@@ r `@ B BJ B@JB@x@AAJEPqbw Je=ѤF =@w{% "@r@ y! @c `nAb  bc B@aB]L@x@A$AE,acb = `$=j^%@a@,XJ (R B@B/@x@A AREaR -2h =!J="@@ y,"~ p$Xbdbj B@jB@x@A$AjEk_aj2 jaj =jb= @C@~$( @"D Ba J B@JB@x@AAJ E=@T Je =r-|5n = {% @,@ * c $Xbb! 륱 B@aB(= c@x@A$AExրb =ja @@,JsJ! B@aRB@x@A AREMa aR =RCU=R(o@P@ c%nc,"aSDfb b½ B@jBc@x@A$AjE aj jaj =j =j%p(+c@ @~BPB$  B@JB@x@AAJ!E Je"=ׄF# =ʀ{% "$@ŀ@ c T%b/b ! XF& B@aBc@x@A$A'Ebb( =j@@`= )@>@ v' @*J J IJ+ B@aRB@x@A AR,E'\aR- =@=!.@3@ S!V@'/bb 0 B@@]B o@x@A$Aj1Eb faj2 =j>=j%-j%3@@~4BB$ 5 B@JB@x@AAJ6E5naJ> Je7=F8 =!t{% %9@ko@ $F @ ,:b ! b; B@aB "@x@A$A<E)acb= =j=">@N@,c?JJ @ B@aRBc@x@A ARAEɠ aR aRB =Rs=R"C@ɣ@ )%K >ъaoDDb5b½E B@jB @x@A$AjFEP\ ajfajG =j_=j%-(%H@0@ !j @űIB^J$BJ B@JB; @x@AAJKE aJ eL=W*|M ={"N@@/ AObrb P B@aB@x@A$AQE]ӀbR =j a$"S@@,TJ`JA#cU B@aRB@x@R =ARV @`EjJ a aRW = ?`=R=R%X@oM@ ъ 6CYbLb fZ B@B}@x@A$Aj[Ejaj\ =jm =(%-%]@@ ^B-B, _ B@JB@&B@x@AAJ`Ex ea=FFb =@hǀ{% "c@€@ c Ixdbb ce B@`B@x@A$AfE|bbg =j=j h@@ m!j @iJsJA#j B@aRBB@x@A ARkE8aR aRl =R>@="m@;@ $F!Rc"daDnb:b½o B@jB@x@A$>pE jajq =j=%-(%r@@$sBXB Jct B@JB@x@AAJuEJev=}|tw ={% %x@а@ @" @J5Ayb/b b z B@aBc@x@A$A{Ekacb| =j:+`=j$j+c}@)@,~JJA# B@aRB@x@A ARE' aR =R=R"@7@ "! ?@"EP@2Bbb B@jBc@x@A$AjEb jaj =j6=j @@$BBJ B@JB@٢oBc@x@AAJE4YJe=F/ =@9_{% F"@rZ@ ) @ Bb e! b B@`B !@x@A$AEa$Xb =jԀ=j$j%@JӀ@ m!j @cJҠJ c B@aRBc@x@A AREɋaR FaR =R=F!R"@Վ@c?""9":albAb½c B@jBc@x@A$AjEOGaj jaj =jJ=j @2@~' @"DBI B$B B@JBc@x@AAJEJe=W| ={% @@  Je=F =t{% (@@ ) @c W.Abb ! b B@aB@x@A$AEga b =jl="@j@,cJjJA# B@aRBQ@x@A ARE#RaR =R0+=R"@&@y?3^BRp 3QBb%b j B@jBL6@x@A$AjE aj =j=( @@ƹBLB J$ / B@JB@x@AAJEb Je=h ={% @Λ@ @ Bb/b! by B@aBy@x@A$AEV ab =jL!`=j.@@,JJA# B@aRB@x@A ARE'͠@Y aR =RԀ="@#Ѐ@ C+]%~ÏBbπb½ B@jB !/@x@A$AjE"b jaj =j6=j%-( =R$=R"?@O @7+o IFEa kB@bbA B@jB !y@x@A$AjBE؀ jajC =jf܀=(%-(%D@ۀ@~EB"B JF B@JB@x@AAJGE\5eH=ݤFcI = ÀQ{% "J@@ ! @AKb ! b L B@`B "@x@A$AMEO6abN =j7`=j$j%O@b@,PJ J Q B@aRB@x@A ARRE FaRS =!J΀=R"T@ɀ@!!I  I"BUbeb cV B@jB @x@A$AjWEw8b jajX =j="Y@R@ $(%"AJZBBc[ B@JB@x@AAJ\E=9aJye]=PF^ =D{% F"_@??@ A`b>b ca B@aB "@x@A$AbE,bc =j:aj$j"d@@,eJJ f B@aRB@x@A ARgEp;aaRh =RKx="i@s@ IC!""Qn}Bjbb jk B@jB@x@A$AjlE,<jajm =j/=%-+cn@.@$oBEB J) p B@JB \$@x@AAJqE(aer=%Fs = {% %t@@ ': @ ʏAub@b ! bv B@`B@x@A$AwY`DE&=bbx ==Sc>`=j y@a@ m2 @ l@ ! ( ARzJ!J { B@aRB@x@A AR|E4?a  A} =R!=R"~@4@ IF"4xBAjbb B@jB oc@x@A$AjE jaj = Cـ=%-(%@؀@ Rr$( @(@BBB$B B@B @x@AAJEA@@==ƤFb =={% "@@ {`b ! 륱 B@aB@x@A$AjELAayb =j B`=%pj"@[ @,J JA# B@aRB@x@A ARE FaR =Rˀ=R"@ƀ@ "}{zy~aDfbEb j B@jB@x@A$AjE\Cb j G =j삀=j%-%@G@~B B$ c B@JB@x@AAJE:DJe=dMF =@{% "@ <@ y! @c VAb;b bc B@aBy@x@A$AEj b = `Ea"@@,J`J B@Bc@x@A AREwmFa F  aR = $u= @wp@ c"0 S"~ű$`>Bbobĩ B@B@x@A$AjE(Gj  aj =j,=j%-(%@+@ $( @(@BBJB B@JB@x@AAJE   e=F =y{F% %@@ / @ Ab b ! b륱 B@aB W.X@x@A$AE H  b = ``=j^"@ @,JwJ B@B@x@A ARE[IRaR =RAc=R"@^@ c"S!aTפb]b j B@jB@x@A$AjEJaj faj =j="@@~ƹBe J$c B@JB@x@AAJE J >=F$X =؀{% @Ӏ@ y! @K ݌b;b b B@aB@x@A$AjE&Kb&b = `ܒ=j%@>@,JJ B@Bc@x@A AREILaR aR =RvQ=R%@L@y@%   aHob-bĩ B@jBy@x@A$AjE4Maj2 jaj =j=j%-(+c@@~$( @"@BBd B B@JB@x@AAJE Je=ƤF* =ƀ{F% "@@, :AbVb! c B@aB@x@A$AEA|Nbb =jvENހ f**aj? ==j%-(+c@@)@~AB BB B@ B@!K@x@AAJCEՙ^++eD=ݤF`E =@ɟ{"F@@ .rAGbqb H B@`B !@x@A$AIE\U_a| ,,bJ =j Z=%K@lX@,LJWJ cM B@aRBh@x@A >NE`aR R--aRO =R=R"P@@ o$F'E!c11E%PaXBQbVbĩR B@jBc@x@A$AjSEì j..ajT =jπ=( U@N@~!j @"AJVB΀ BW B@JB@x@AAJXEa//eY=FZ ={% :"[@+@ A\bb c] B@aBc@x@A$A^EwCbay01b_ = `c`=^"`@ @,aJuJ jb B@B@x@A ARcE F22aRd =R'€=R"e@@s >utBfbb@(jg B@jBz oc@x@A$AjhE vdb j33aji =jy=(%p(+cj@x@kBWBBl B@JB@!Kc@x@AAJmE1eJ44en=DFto =@z7{% "p@2@6 @ qAqb-b b r B@`B ! @x@A$AsE 55bt =j=)j%u@@,vJJ w B@aRB@x@A ARxEf66aRy =R\=R"z@@ c4:"azB{b#b j| B@jB@x@A$Aj}E&dgaj2 77aj~ =jg= @@~ncBff J B@JB@x@AAJEhaJ@Y J88e=F =%{% F"@ @ \BbLb B@aBc@x@A$AE3ۀy9:b =jdia^%@ƙ@,J2JA#r> B@aRB@x@A AREARja ;;aR =RY=R"@QU@   ƣ x BbTbj B@jB@x@A$AjE kaj j<?b =jDm`= @TC@@Sf2 @" /JBJrR B@aRB@x@A ARE @@aR =@naR!@~ c $ $@ aBbZb j B@B @x@A$AjEi, jAAaj =j=j @X@~rB B B@JB@x@AAJErobw} JBBe=uF/ =x{% @)t@ pBbsb! B@aB@x@A$AEv.pacCDb =j=G@p ^+c@ @,cJuJ  B@aRB@x@A AREqaR_EEaR =R9= @@ 1t 5n%Bbb j B@jB@x@A$AjE araj fFFaj = {d= @c@~BWB F B@JB@x@AAJEsJGGe=/|* ="{% @@ OBb-b `B B@aB@x@A$AE؀HIb =jFta^%@@,JJA#= B@aRB@x@A ARE%Oua FJJaR =RV=R1@1R@yV"BbQbĩ B@jB@x@A$AjE vjKKaj =j0=(%-( B@Bc@x@AAJ?ENb Jcce@=ӤFyA =>{% "B@@ ^ACb ! D B@aBc@x@A$AEEZadebF =j `=^%G@k@,HJJA#I B@aRB@x@A ARJE ffaRK =Rـ=R"L@Ԁ@ )'ő_7K A#i1%%"kaBMbRb jN B@jB@x@A$AjOEhb jggajP =j=j Q@M@!j @"AJRBB$BcS B@JB@x@AAJTEHJhheU=p[FV =N{"W@&J@ )%N+c 5AXbIb bcY B@aB @x@A$AZEvaBijb[ =jĀ=j$"\@À@,]Jm JA#^ B@aRB@x@A AR_E{aR FkkaR` =:`=FR%a@~@ 3%&% 5(Bbb}`fc B@jB; @x@A$AjdE 7`llaje =j:=+cf@9@$gBVB Jh B@JB@x@AAJiE mmej=|*k ={% F"l@@ ': @( Amb-b! b n B@aB m2$X@x@A$AoEbcnobp =j>n`=j^%q@l@,rJ J s B@aRB|5n@x@A ARtE%%a ppaRu =R,=R"v@-(@ CkZ'%1ia6wb'b½x B@jB~ ,@x@A$AjyE jqqajz =j =j {@|@ $( @"D|BB$Bc} B@JB !K @'@x@AAJ~E2rre=FB =@@#{% @n@ c 2b ! c B@`B@x@A$AEWastb =j`=j @H@ m, @JJ  B@aRBc@x@A ARE΀@Y FuuaR =R}ր=F!@р@ c S$4% cʖDfbCb½ B@jBc@x@A$AjEMb jvvaj =j͍=j%-j+c@*@~B B$ , B@JBc@x@AAJEEJwwe=UXF@ =K{% (@G@ B! @c ndAbpFb b, B@aB 'Zc@x@A$AE[ayxyb =jv="@ֿ@,$XJBJ (> B@aRB@x@A AREhxaR FzzaR =R= @d{@ ccKc "u"BP=Bbzbj B@jB @x@A$AjE3j{{aj =j7=j%-(%@6@ $( @ūcB;B B@JB@x@AAJEv> ||e=F =f{% %@@ y) @6 Abb ! b륱 B@aBc@x@A$AEby}~b =j(k`="@i@,cJhJA#F B@aRB@x@A ARE "a\aR =R)=R"@%@ s-1aS+b$b j B@jB@x@A$AjE݀faj =j!=(%p(!@~@~rBB$ c B@JB@x@AAJEb e=F ={% "@S@ c O*b ! c B@aB@x@A$AETab =j`=^(f@-@,JJ  B@aRB@@x@A ARE aR =RWӀ=R"@΀@ tBtZ)` a+ZDb$b  B@jB@@x@A$AjE2b jaj =jŠ=(%-(%@ @ B~  B@JB 5@AAJ @EBJe[`<=:UF ==H{% "@C@ c AbUb  B@abB,@x@A$AE@b =jcaj%@Ƽ@@S, @`# !*J2J (Jc B@aRB@x@A AREMua FaR =@}="@ax@ v$F!R!?71  1MaBbwbf B@BQ^@x@A$AjE0jaj =jP4=%-(%@3@$BB J)  B@JB@x@AAJE[ e=ܤFu, =_{% %@@ Ab !  B@aB@x@A$AE᧥bcb =jg`=j$j%@\f@,JeJA# B@aRB@x@A AREa aR =R&="@"@  M+[ M`1]]a66Bbo!b½ B@jB@x@A$AjEu jaj =j݀=j%-%@D@$B܀ J$  B@JBc@x@AAJEe=}`= ={F% %@9@ ) @6 A\b b B@aB*@x@A$AEQajcb =j`=j @@,JzJA# B@aRB@x@A ARE FaR =R@Ѐ=R" @ˀ@ ]`"a`1B bb j B@jB@x@A$Aj Eb jaj = =j%-(%@@~ƹ' @(@BBSB B@B@x@AAJE?Je=RF =E{% "@@@ ! @+c Ab:b ! b륱 B@aB .X,@x@A$AE$cb =jUa @@,J#J  B@aRB@x@A ARE2ra FaR =Ry=R"@Bu@ y%"$4aSBbtbĩ B@jB$_@x@A$Aj!E-jaj" =jE1=j%p(%#@0@ $( @ť$BB$Bc% B@JB@x@AAJ&E?/e'=F( =8{F% ")@@ y c wA*bߡ ! 륱+ B@aB@x@A$A,EƤb,b- =d`=j^".@Uc@,/JbJ 0 B@aRB@x@A AR1Ea+ aR2 =R#=R"3@@ %u$EasB4bHb5 B@jB@x@A$Aj6EZ׀ jaj7 = ڀ="8@=@ 9BـJ$ : B@B@&B@x@AAJ;Eᒳb 4E Je<=bF= =@՘{% >@"@ y! @c /B?bb b @ B@`B,@x@A$AAEhNabB =j`=^%C@ @, DJ_JA#E B@aRB@x@A ARFEuŀ aRG =R*̀=R%H@Ȁ@ BEaS;BIbǀbfcJ B@jB@x@A$AjKEb jajL =j=(%-(+cM@烀@ r$( @"@BNBHBJO B@JBc@x@AAJPE` sb5b t B@Bx @x@A$AjuE?Ԡ@YW jajv =j׀= w@+@ xBր ,y B@JBc@x@AAJzEƏe{=GF| ={% F"}@@ ) @ e~bbb b, B@aB "y@x@A$AEMKab =jv `=j^%@ @,JCJ `R- B@aRB@x@A AREZ @Y FaR =Rʀ=R"@jŀ@cBOdENpuVGMd@ƎbĀbj B@jB5n@x@A$AjE}b jaj =ji=j%-(+c@ŀ@$B%BJ)  B@JB@x@AAJEh9aJ@Ye=F =X?{% "@:@c mAbb !  B@aBB@x@A$AEyb =j a%@m@,JٲJA#r B@aRBc@x@A AREka FaR =Rs="@o@ #p(S`$K %aBbtnbj B@jB@x@A$AjE'jaj =j+=%-(C@b*@ cB)B$ g B@JB@)y@x@AAJE e=F/ =@{% "@C@ y c ,VAb !  B@`B@x@A$AEbcb =j^`=^%@#]@ m!j @J\JA# B@aRB@x@A AREa aR =RS=!@@ 3_+%%aGBbb½ B@jB/@x@A$AjE$р jaj =jԀ=j%-j%@@~BdӀ B$  B@JB@@x@AAJEe=,`=@ =@{% %@區@ ! @+c uAbGb b B@`B@x@A$AE1Hajcb =jp`="@@ mJ ǭ^aD)Dfbb j B@jB@x@A$AjEejaj =jNi=%pj+c@h@  BB $ y! B@JB@c@x@AAJ"EL!Je#=T$ =@@'{% 4 %@"@ hv/G?A&b ' B@`B ! @x@A$A(E܀b) = ``a^%*@j@,+J֚J , B@B@x@A AR-ESa aR. =R[=R"/@V@  Ǭe "aUB0bPb½1 B@jB@x@A$Aj2Egjaj3 =j=(%-(%4@N@ n5B J6 B@JBc@x@AAJ7E e8=o݄Fzc9 =Ѐ{ :@+̀@ pA;bˀb Z,< B@aB@x@A$A=Eubt b> =j=j ?@}@,@J鈀JFA B@aRB@x@A ARBEAaR RaRC =RI="D@D@ c$@"a#BEbgbjF B@jB o,@x@A$AjGE jajH =ja I@K@ rJB JK B@JB@c@x@AAJLE JeM=|w  y`\yN = ){% :cO@D@ b5\ @ +c hBPbb b Q B@aBc@x@A$AREtb,bS =j4`=j T@3@ m!j @UJ2J *RV B@aRB@x@A ARWE뀈@Y FaRX =RT="Y@@ tP. T@oBZbb j[ B@jB@x@A$Aj\E$b2 jaj] =j= ^@ @~_Bh J` B@JBc@x@AAJaEbaJ Jeb=/uFycc =h{% d@c@ ! @6 VBebFb! b f B@aBe 5@A$Ag @E1abh =jTހ=%pj1i@܀@,jJ J@ݥ(Rk B@a B@x@A ARlE>aR aRm = 휀=Rcn@G@ UtQ.v%`J\Bobb p B@B@x@A$AjqEPajajr =jMT=j s@S@r$( @`" "AJtB B$Bu B@JB@x@AAJvEL aJ ew=ͤFx =D{% F"y@ @ y) @+c  Azb ! baai{ B@aBy@x@A$A|Eǀ Z b} =ja ~@]@,JɅJ R B@aRB@x@A ARE>aRA@aR =@F=R"@A@ PPÔPuP BbTb@&4j B@B@x@A$AjEg@Y jaj =j=j%-(6@L@~B B$ y B@JB@x@AAJEb Je=oȄF, =һ{% "@%@ m @+c JnAbb! ba"  B@aBB@x@A$AEtqacb =j1`="@/@,JgJA#R B@aRB]L@x@A ARE@Y aR =R5=R"@@ yuPdq[Ǯt@_Bbbj B@jBb@x@A$AjEb jaj =j=j%-(%@@~BMB  B@JB5n@x@AAJE_Je=rF ={e{"@`@ c rAb+b  B@aB @x@A$AEb =j=.@@,JJA#(> B@aRB$X@x@A AREր FaR =RJހ=R%@ـ@  X.Bbb j B@jB,@x@A$AjE#aj =j=(%-@@rBo J$ B@JBc@x@AAJEMJe=Fy =S{*"@N@ BbFb  B@aB@x@A$AE1 b = ` =j @- @,J J B@B@x@A AREĀ aR =Rj̀=R"@ǀ@ o$F!!C%  t?Nb,bĩ B@jBB@x@A$AjE>aj = ΃=j%-(+c@,@ !j @(@BB  B@B@x@A>E;Je=ͤF =A{% "@=@ c ZAba{% " @9@ ! @(  bFb B@aB@x@A$AE1  b =jaa^%@ò@,J/JA#1R B@aRB@x@A ARE>ka   aR =Rr=R"@Fn@'ECAt.'t 1a^]Lbmb½ B@jB@x@A$AjE&aj  aj =j1*=( @)@$B(B J B@JB@2a @'@x@AAJEK Je=ͤF, =@@({%p!@@  c ]L"b ! c# B@`B !$X@x@A$A$Eҝbcb% =j]`=j$j%&@Y\@ m!j @'J[J ( B@aRB@x@A AR)EaaR* =Rx="+@@ St@% P"u@aJ[,bE aR FaR? =R =R"@@ @ Cc"t! QBAbwb jcB B@jB y@x@A$AjCE jajD =j€=j%-1E@a@ $( @ FBBG B@JB@!Kc@x@AAJHEz b JeI=H|J =@{% "K@C{@c ALb Z 륱M B@`B,@x@A$ANE5 bO =j4:= P@8@ mcQJJA#cR B@aRB@x@A ARSE@Y aRT =R=R"U@@ ,s*% "¯q@4BVbb½W B@jB@x@A$AjXE ajY =j =(%p(%Z@j@ [BЮB,J\ B@JB@x@AAJ]E#hJe^=+6_ =n{% "`@_i@/C  Aab  b B@aB@x@A$AcE#abd =j=^.e@(@,fJJ (Rg B@aRB@x@A ARhE@ aRi =Rk=R"j@@ - L6kb+b jl B@jB@x@A$@mE>Vb|ajn =jY=( o@$@$pBX Jq B@JB@c@x@AAJrEaJ   es=F$|t =@{% u@@ L6vbab^! w B@`B@x@A$AxEK̀F!"by =jaj cz@⋀@ mc{JNJA#| B@aRB@x@A AR}EYDa ##aR~ =RK="@QG@ ,  t+hD"aHobFb j B@jB@x@A$AjE$$aj =jpaj @@ cB,B$  B@JB@x@AAJEf %%e=F =J{F @@ L6! @ Bbb B@aB 'Z"@x@A$AEvb,&'b =j7`=j @t5@,J4J F B@aRB@x@A ARE ((aR = =FRc@ @ ÔPtQ wbvb j B@vB@x@A$AjEb j))aj =j=%-1@l@$BͫB B@JBy@x@AAJEeJ**e=wF =j{%p"@Ef@ b   B@aB@x@A$AE a+,b =j=j^1@߀@,J}ޠJA# B@aRB$X@x@A AREaR F--aR =RL=R"@@ $~01{Dbb½ B@jBL6@x@A$AjE#Sj..aj =jV=j%-(%@ @ ) @"@BBoU Bc B@JB@x@AAJEJ//e=+!| ={% "@@ ! @c &AbEb b륱 B@aBc@x@A$AE0ʀ01b =jQaj @@,JJ  B@aRBc@x@A ARE>Aay 22aR =RH=FR"@ND@ 88$ `a$`q5n6bCbA;j B@jB| ,@x@A$AjE j33aj =jL aj%p(%@ ~ƹ$( @ťBB B@JB@x@AAJEK  J44e=̤F{ =7{% "@@ 5\ @ b ! b륱 B@aBB@x@A$AEs!b55b =jrx="@v@,J>JA#Fc B@aRB@x@A AREX/"R66aR =R7=R"@i2@ !$F%?79: ; ?b =jˀ=j)j%@%ʀ@,cJɠJ R B@aRB@x@A ARE)aRRA@@@aR =@[="@@ !)!oҐ?>rybbj B@B5n@x@A$Aj_  `E">*jAAaj =jA=j @@!j @"DBc@ Bc B@aB,@x` =AJ @E BBe=* | ={F% F%@@  m bEb! c B@abBL6@x@A$A E0+bcCDb =jcu,`=j$j" @s@,J/JA#{R B@aRB@x@A ARE=,-a EEaR =R3=FR"@M/@DA%@r@ Dfb.bA;j B@jB@x@A$AjE jFFaj =jP=%p+c@@ nB BAJ$  B@JBc@x@AAJEK.GGe=̤F =?{% "@@ c >Ab ^! , B@aBy@x@A$A E^/aHIb! =j0`=^%"@X@,#JJ $ B@aRB@x@A AR%E FJJaR& =R݀= '@؀@,DBp}pB(bcb j) B@jB@x@A$Aj*Ef1b jKKaj+ =j=j%-(%,@S@~-B B$ . B@JB@x@AAJ/EL2JLLe0=n_F1 =R{% %2@(N@ @W pA3bMb b4 B@aB@x@1 =A5 @Es3a,MNb6 =jȀ="7@ǀ@,8JrƠJ@9 B@a B@x@A AR:E4aRy FOOaR; =R<= <@@ c#% =ZB=bb j> B@jB@x@A$Aj?E;5aj jPPaj@ =j>=j%-(%A@=@~BBCBC B@JB@x@AAJDE JQQeE= |v,F ={% %G@@ v c AHb*b ! I B@aB@x@A$AJE6RRbK =j="L@@,MJJA#N B@aRBzWB @x@A AROEm7aRSSaRP =REu=R"Q@p@ c3<':%9aBRb bĩS B@jBB@x@A$AjTE")8aj fTTajU =,=( V@@ cWBf+J$ cX B@JBc@x@AAJYE JUUeZ=F$X[ ={% \@@ c {B]bEb c^ B@aBy@x@A$A_E09bVWb` =jU`:`=j1a@^@,,bJ#J nc B@aRB@x@A ARdE=;a XXaRe =R="f@Q@ DCT% p0{Bgbb@(jh B@jBy ! @x@A$AjiEҀYYajj =jHր=%-(+ck@Հ@ rlBB Jm B@JB@!K/@x@AAJnEK`=j v@\@ m!j @; wJJ rȭx B@aRB @x@A ARyE ]]aRz =RȀ="{@À@ S>aa|b[b j} B@jB @x@A$Aj~Ee|?b j^^aj =j=j @N@ B~ B$ c B@JB@@x@AAJE7@aJdE J__e=mJF =@={F% @/9@ y! @  b8bj^! bc B@`B@x@A$AEs`ab =jAaj%pj+c@@,JfJA#rR B@aRB@x@A AREjBa bbaR =Rr=R(o@m@ Dc?U"uvuw"agHoblbj B@jBL6@x 9A$Aj @`E&Cjccaj =j)=j%-+c@(@ $( @"@BBSB$B B@aB@x@AAJE dde='Fd =~{% "@@ |Ab*b ! 륱 B@aB@x@A$AEDbefb =j;]E`= @[@,JJ  B@aRB@x@A ARE"Fa ggaR =R=R"@"@ cs$ >"}l{ * lBbb B@jB @x@A$AjE jhhaj =jӀ=j%-(%@yҀ@ BB$ c B@JB@x 9AAJ @E/Giie=Fc =({% "@j@ y! @c Ab̡ bc B@abBc@x@A$AEFHacjkb =jI`="@9@,JJA# B@aRB@x@A AREĽ FllaR =R~ŀ=R"@@ y1U>2`a[BbDb jc B@jBF@x@A$AjEJyJb jmmaj =j|=j%-(%@'@~ƹ$( @ūcB{ B B@JB@x@AAJE4KJnne=RGF =:{"@ 6@ y5\%N+c JAbm5b b륱 B@aB @x@A$AEX5nopb =jLa"@简@,JSJ  B@aRB@x@A AREegMa FqqaR =Ro=R%@mj@ c 1/EA \?Bbibĩ B@@]Bc@x@A$AjE"Njrraj =jp&=(%p@%@ rB,B J B@JB@x@AAJEsހsse=F =o{% "@߀@ c Bbb B@aBc@x@A$AEObytub =j)ZP`=^%@X@,JWJ c B@aRBB@x@A AREQavvaR =R=R"@@ ґҐ"ґ@bbb j B@jB$X@x@A$AjÈ2 wwaj =jЀ=( @wπ@~ƹB΀B J B@JB@x@AAJERb Jxxe=FB ={% @P@ , eEb ! B@aB,@x@A$AECSayzb =jT`= c@.@,JJA# B@aRB@x 9A AR @`E {{aR =RT€=R%@@ c T<}0ґ`̠MBbb½ B@a$BQ@x@A$AjE/vUb j||aj =jy= @@ B{xJ$ ``JB@x@AAJE1VJ}}e=7DF =7{% `3b@2@ , BbRb  B@aB@x@A$AE=~b =jtWaj^+c @ԫ@ 2 @ J@J  B@aRB@x@A AR EJdXacaR =  l=R%@bg@ CqSqc}]Lbfb  B@B@x@A$AjEYaj aj =ja#=j%-(6@"@~nBB B@JB@x@AAJEXۀ> Je=ݤFy, =T{% "@܀@ $F @ Ab ! b  B@aB@x@A$AEޖZbcb =jW[`=%@iU@,cJTJA#nb B@aRB@x@A AR!E \aaR" =R=&#@@ZX @K DBtZ/va6N$b\b j% B@jB @x@A$Aj&Esɀaj' =j̀= (@D@ )Bˀ( c* B@JB@B@x@AAJ+E]b e,=~F- =@{% .@5@ W! @E/bb bc0 B@`BW@x@A$A1E@^b2 =jE=$j%3@D@,4JpCJA#y5 B@aRB@x@A AR6E aR7 =R_aR(o8@~ ,%UL@pBѹBB? B@JBc@x@AAJ@Es`bw JeA=AB =y{"C@Nt@ y c !D`  E B@aB@x@A$AFE.aa bG =j= H@"@,IJJ J B@aRB@x@A ARKEbaR aRL =RZ=R%M@@ ± e"Nb(b@%jO B@jB@x@A$AjPE/acjajQ =jd=(%-R@c@$SB[B J/l T B@JB@c@x@AAJUEdaJeV=7/|wW =@"{"X@@ y': @c BYbVb bcZ B@`By@x@A$A[E<؀b\ =j&eaj ]@@ m' @^JJA#c_ B@aRB{* @x@A AR`EJOfaaRa =RV="b@JR@,E[p `*BcbQb jd B@jB@x@A$AjeE gaj2 ajf =jY=%-g@ @~w$( @ūchBB Ji B@JBc@x@AAJjEWƀek=٤F$Xl =L̀{% %m@ǀ@ 7Bnb io B@aB@x@l =Ap @Eށhbbq =jBi`=%pj"r@e@@,sJ?J@t B@a B@x@A ARuE FaRv =RzjaRR"w@~ tt3p,cCBxbHbĩy B@jBc@x@A$AjzEr, jaj{ =j=%p,k|@W@ }BJ~ B@JB@x@AAJEokbw J@==~Fxc =u{% "@4q@ ! @ȅ#( :Abpb b B@aB@x@A$AjE+lab =j=j^%@@,,J{JA# B@aRB@x@A AREmaR aR =R/=R"@@ #1x|}䐁aBbb½ B@jB @x@A$AjE^njaj =ja=j @`@ $( @"AJB\B B@JB@x@AAJEoaJe=,|B = À{% @@ / @+c 5Ab;b ^! bic B@`B@x@A$AE!Հcb =jPpa"@@,cJJA# B@aRB@x@A ARE/Lqa aR =RS=%@;O@yE33L@$ IBbNb B@jB @x@A$AjErajF jaj =jB =%p(+c@ @ B BJ `, B@JB@@x@AAJE<À Je=ɤFqc =@0ɀ{% "@wĀ@ ! @ aO*b  b B@`B !5n@x@A$AE~sbb =j?t`=^%@b=@,J=R"@7:@ s0D𐁫6\aqb9b@$j B@jBy@x@A$AjE jaj =j9=j @@ BB B@JB@2aL6@x@AAJE =@{% ?@[@$X A@b ao! 륱A B@`By@x@A$ABEfaxbC =j&`=^"D@F%@ mcEJ$JA#aHRF B@aRB@x@A ARGE݀aRH =Rg=R%I@@ U:U@{BJb%b jK B@jB]L@x@A$AjLE e9=ÄF,: ={% ;@ݱ@ / @+c (A<b>b ! b= B@aB@x@A$A>E la zA? =jG,`="@@*@,AJJ rB B@aRBc@x@A ARCE.  qARD = =%E@N@ s$p#ќ`Su0BFbbjG B@jB@x@A$AjHEb j AjI =j-=%p(+cJ@@~KBB$ L B@JB@٢o/l@x@AAJME;ZJ`=N=ĤFQO =@+`{% "P@v[@ @9 AQb e! bR B@`B@x@A$ASEa* 1|%T =jՀ=^%U@AԀ@ m' @VJӠJA#W B@aRB@x@A ARXEόaR FARY =Rz=R"Z@ۏ@ ,+"HK/}/Na J[bGb@$j\ B@jB,@x@A$Aj]EVHj(p"^ =jK=(%-(%_@;@ `BJ B$ a B@JB@@x@AAJbEJ`=c=^|,d =@ {% "e@@ $F @+c &Afbyb bg B@`Bc@x@A$AhEc ^ Bi =jĀ=^%j@p€@@Sm!jkJJA#Jl B@aRBy@x@A ARmEz ARn =@=R"o@~@ b S "ѣE=pbn}bA;jq B@BF@x@A$AjrEq6j Ajs =j9=(%-(Ct@L@ ruB8 Jv B@JB@@x@AAJwE  `=x=|yy = 5{% "z@5@ ! @+c oA{bb b | B@aB@x@A$A}E~b B~ =jm`=j%pj%@ l@ mJukJ  B@aRB$X@x@A ARE$a !) =RA,="@'@ q $ÔP" aX2zbb! B@jB$X@x@A$AjE2 jAj =j= @@~$( @"DBSB B@JB C@x@AAJE`==F ={% #)`@3e@ל@ B$F @+c 8bb5b ! bc B@aB0!,@x@A$AE WB =A6`[=^"@$Z@ m!j%JYJ  B@B@x@A ARERAR =RI=!@@ c #  0 S`-M#Dfbb@' B@jB@x@A$AjE-Π@Y @u' =jр=%pj+c@@~BzЀ $  B@JB@١$@x@AAJE`==Fc =@{% +c@@ ': @+c ;AbPb ! b B@`Bc@x@A$AE;EaB = `r`=^%@@,J>J  B@B@x@A AREH@YA FAR =RÀ=R"@X@  Ô}@~$@Bbľb# B@jB o@x@A$AjEwb j'% =jK{=j%-(C@z@~$( @"@BB B$B B@JB@٢o!KB@x@AAJEV3J`==EF} =@J9{% "@4@ ) @1! @# +c hv/G?*Ab e! b륱 B@`Bc@x@A$AEB =ja"@w@ m!j$#j`4! !% ARJ㬠J  B@aRBb@x@A AREea FAR =Rm=R"@h@7!R(o~0abbb½ B@jB@x@A$AjEq!jAj =j$=(%-(C@Z@ `@ťB# J$ B B@JB@x@AAJE܀ `==yFy ={% "@7ހ@h b݀b c B@aB5n@x@A$AE~b !B =jX`=j$j"@W@,JmVJA# B@aRB@x@A AREa ";) =R7=R"@@!!Cu"w$`p##ED[Dbb j`b* B@jB@lc@x@A$AjE j#I[!j =j΀="@@ƹBf̀ J B@JB@x@AAJEb J$$`==FFQc ={% F"@Շ@c "'b5b!  B@aB " O@x@A$AE Bac%&B =j?`=j$j%@@ cJJ c B@aRBB@x@A ARE- ''AR =R="@5@ yw"ќ` `vw&HBbb½ B@jB @x@A$AjEtb j((Aj =j8x=*#@w@ rBvBJ$  B@JB@x@AAJE;0J))`==F =+6{% %@w1@ ! @  1Ab  bc B@aB "@x@A$AEc*+B =jaj @P@,cJJ B@aRB@x@A ARBB@`Eba F,,AR"R{j="@e@GYp #`B`̠+BbCb½ B@a$B@x` =Aj @`EVaj2 j--Aj =j!=%-(%@0@~$( @(@BB J B@aB@$@x@AAJ E J..`= =]Fzc =@߀{%  < @ۀ@ ) @ .Abxڀb b륱 B@`B@x@A$AEcb //B =)"=jj"@@ m!j @JJA#c B@aRB@x@A AREPR00AR =RX=F!@S@yG"ӔP`"Q=sBbbb j B@jB$X@x@A$AjEp j1#1 =j=%pj%@T@ B  B@JB@@x@AAJEǀ 22`= =F,! =@̀{%  <" @1ɀ@ y! @!`\y A#bȀbǝ! b $ B@`B@x@A$A%E~bc34B& =)C`=^%'@ B@,(JyAJA# @R) B@aRB@x@A AR*E 55AR+ =RA$R <, @~ c#K]œ ]wB-bb j. B@jB@x@A$Aj/E, j66Aj0 =)=( 1@@ n$( @"AJ2BRBB3 B@JB@x@AAJ4Eqbw J77`=5=F 6 =w{% 7@r@ m) @+c  A8b5b bc9 B@aB@x@A$A:E -a89B; =jN="<@@,=JJA#> B@aRB@x@A AR?E-aR ::AR@ =R׫=R <A @9@ G3uY"ѣKVu6*Bbb@(jC B@jBy @x@A$AjDE_j;; FE =)@,gJZJ >h B@aRB@x@A ARiEp@Yg DDARj =R+="k@@o!oSw 1`w pAlbbfm B@jB@x@j =Ajn @`Eb fEEAjo = ?`==%-(%p@䵀@ rqBCBJ) r B@B@x@AAJsE~nJFF`=t=Fu =vt{%  <v @o@ ! @]Awbb bx B@aB @x@A$AyE*GDB%z =).=^3{@-@,|J},JA#(} B@aRBx B @x@A AR~E倈 FHB!R =R;=%p@@ c"ќ`Su~`n!bbj B@jB !@x@A$AjEIIAj =j=j%-j%@@ $( @"@BB^B B@JB@x@AAJE\aJ> JJ`==Fh = Àb{%  < @]@F t b5b! 륱 B@`B "@x@A$AEaKLB =)P؀="@ր@,cJJ n B@aRB@x@A ARE-aR MMAR =R門=R < @A@  s` ` Yahobb½ B@jB@x@A$AjEJajF jNNAj =)bgb½? B@jB@x@A$Aj@E jttAjA =j+$=j%p(%B@#@$CB"B JD B@JBc@x@AAJEE: uu`=F=FG =.{%p"H@p݀@ @': @K }AIb ! bcJ B@aBc@x@A$AKE bvwBL =jW `= M@KV@,NJUJ O B@aRB@x@A ARPEa xxARQ =R{=R"R@@HÔPB_(+FBSb:b½T B@jB@x@A$AjUEUʀ jyyAjV =j̀=j W@0@~$( @ūcXB̀ B$BcY B@JB@x@AAJZEۅzz`=[=]F\ =̋{F% ]@@, [B^bwb 륱_ B@aB@x@A$A`EbAa{|Ba =jx`=j^"b@~,cJEJ d B@aRB@x@A AReEpy F}}ARf =R=FR%g@x@yHp-Td` yBhb亀b ji B@jBB@x@A$AjjEsb~~Ajk =jw=j%-(+cl@v@ mBBBn B@JB@2ay@x@AAJoE}/J`=p=F$Xq =@q5{% "r@0@ y! @c gAsbb ! b t B@`B@x@A$AuEcBv =j*a"w@@, xJJA#y B@aRB@x@A ARzEba AR{ =Ri=R"|@!e@yH#~aB}bdb> 4~ B@jB@x@A$AjEj=MA =!=( @t @ r$( @(AJBB J Bc B@JB@a@x@AAJE `==Fc =߀{%  +@@3b@Yڀ@ c !'b ! c B@aB@x@A$AEbcB =A6`T`=^"@,S@ m82*Q JRJA# B@B{,@x@A ARE a@Y C$F =RQ=R%@@ 37EV/9xJBbb½ B@jB@x@A$AjE:ǀ2 j@!j =jʀ=(%p(#@@~B~ɀ B$ F B@JB@x@AAJE`==AFc = À{% "@@ Ab\b ! , B@`B 'Z,@x@A$AEG>aB =jm=j%pj%@@,J:J (> B@aRB@x@A ARETaR FO$F =R="@a@ C@%@~?B B@ B@JB C@x@AAJAEπ `=B=NF/C =Հ{% %D@ р@$X "AEbiЀb! F B@aBc@x@A$AGET8b BH =j㏀=^+cI@D@ m=$^BJJJA#jK B@aRB@x@A ARLEF9RARM =RN=!N@I@ c1Kf tE4anBOb[b jcP B@jBB@x@A$AjQEa:jAjR =j= S@5@ TB$U B@JB@@x@AAJVE轀 `=W=|w   AX = )À{% Y@"@ $F @ |Zbb[ B@aB @x@A$A\Eoy;bAj] =j9<`=^%^@8@,_Jn7JA#*R` B@aRB@x@A ARaE| ARb =R.=R(oc@@ Ekfa dbb je B@jB@x@A$AjfE=b jAjg =j=j h@㮀@~iBCB) j B@JB@x@AAJkEg>J`=l= zFm =zm{%pn@h@ ! @+c 8 ob&b ! bp B@aB@x@A$AqE#?aBr =j;="s@@,tJJA#u B@aRB@x@A ARvE@aR FARw =R=R%x@@ 1$t%~acSKcybbĩz B@jBc@x@A$Aj{EUAjAj| = -Y=(%-(1}@X@ $( @(@B~BWB J$B B@B@x@AAJE+BaJ+U`==F = {% "@j@ c ǡAbˡ 륱 B@aB@x@A$AÈB = `ՌCaj"@5@,JJ B@B@x@A ARECDa AR =R^K=R"@F@ 7//9/cwBb(b j B@jB@x@A$AjEF jAj =jEa"@'@ƹBB B@JB@x@AAJEͺ J`==VBaJty ={% `3b@@ ! @c XBbib b B@aB@x@A$AETvFaj B =j{=j @hy@,JxJA#c B@aRBy* @x@A ARE1GRAR =R9=R%@4@ I"t/VBbSb  B@jB{y@x@A$AjEa Aj =j=j*(+c@H@ $( @(@BB B@JB@x@AAJEH`==F =خ{"@%@, Bbb c B@aB@x@A$AEodIaB =j$J`="@6#@ 5,%yJ"J R `JR- B@aRB@x@A ARE| F9 =R,=!F"@ހ@ o @o I"t/ ayb݀b j B@jB@x@A$AjEKb jAj = =jj%@噀@~nBGBc B@B@x@AAJERLaJ} J`== eF, =X{% @S@ mb&b! ^ B@aB@x@A$AEMaB =j9΀="@̀@,cJJA#c B@aRB@x@A ARENaR AR =RŒ= @@I#"6t"uaDbb½ B@jBW@x@A$AjE@OjAj =j-D= @C@ BBB g B@JB$X@x@AAJE+ 0@==F =Pa% @h ) @+c BMBb  B@aB * @x@A$AjE,B =jZ=^+c@@,J&J B@aRB@x@A ARE9sQb AR =Rz=R+c@5v@WI3腌 Bbub@( B@jBy * @x@A$AjE.Raj jAj =jH2=j%-(+c@1@BBB$ B@JBc@x@AAJEF J`==N =2{"@@ W! j+Ab  bXF B@aB@x@A$AEͥSbB =jeT`=j @Td@,JcJ > B@aRB@x@A AREUaAR = $=FR%@@ cC"0tt1{ bVb½ B@B@x@A$AjEa؀ fAj =jۀ=%-@B@ r$( @(DBڀJ B@JB@?&@x@AAJEV`==iF|3 S 4 fܙ{% "@#@@atE c ( bb 륱 B@aB`x@9 A @ nOWAj =B`= T=^"@R@,JQJ  B@Bx"vB k @x@A AR E XRAR = p= @ @ yS1@vv"t  bu b  B@Bc@x@ =Aj @`E| Aj =jɀ=j%p(+c@R@ BȀ B B@aB@x@AAJEYb@Y J`== P| ={% %@@@ ! @+c b ^! b  B@aBy@x@A$AE=ZaB = `="@ @,cJxJ rȭ B@B@x@A ARE[aR AR =RC= @@ ct1{1Pvv"D!b bj" B@jB@x@A$Aj#Ep\ajF jAj$ =js= %@@ $( @(AJ&BjrS3$B' B@JB@٥kBc@x@AAJ(E+]aJ J`=)=%>|* =@1{% +@,@ 'A,b@be! c- B@`B@x@A$A.E+B/ = `X^a^"0@@,1J&J 2 B@B@x@A AR3E8^_a AR4 =Re=R(o5@Aa@ s&6"B6b`b f7 B@jBy@x@A$Aj8E`j=M/9 =jG=(%-(+c:@@ ;BB, y< B@JB@@x@AAJ=EFՀ `=>=ǤFy? =@6ۀ{% "@@ր@ ! @c 4PAAb  bB B@`Bc@x@A$ACE͐abt  D =jl=j E@͓@ m2 @FJ9J G B@aRB@x@A ARHESLbaR RARI =RS="J@[O@ y"땂ddayKbNb@$jL B@jBJ@x@A$AjMEcjAjN =jf =%-(%O@ @<$( @(@BPB"B J)BQ B@JB@x@AAJREaÀ `=S=iyT =Mɀ{% %U@Ā@ y$F @ GyVb ! b륱W B@aBc@x@A$AXE~dbcBY =j?e`=j%pj"Z@r=@,[Jn@Q :kb  cl B@`B  Q@x@A$AmE(haBn =j=$j%o@@ m' @cpJ|J!q B@aRB@x@A ARrEiaR FARs =RA=R"t@@ Ta:Dub b jv B@jB~ @x@A$AjwE[jaj jAjx =j^=j%-%y@]@~' @"@BzB]B)B{ B@JB@ ,@x@AAJ|EkJ`=}=%)|@~ =@{% "@@ $F @+c mAb@b ! b륱 B@`B@x@A$AE+ҀB = `Zla%pj"@@,,J&J  B@B@x@A ARE8Ima FAR =RP=R"@(L@ c|$>0D+ɂbKbĩ B@jB@@x@A$AjEnjAj =jG=j%-%@@ BB$ c B@JB@x@AAJEF,`==ǤF =>ƀ{% "@@  YAb ! c B@aB (c@x@A$AE{ob 5^ B =j;p`="@W:@ '$cJ9J F B@aRBc@x@A ARE-AR =R=R"@@ 1FkbT|aBbNb j B@jB@x@A$AjEaqbAX Aj =@局=(%-(%@B@ Bµ$  B@B@x@AAJEiraJ J-@==l|Fy =o{% "@#k@ $F @c KAbjb b B@aB@x@A$AjEn%sB =j *=j%pj+c@n(@,J'JA#{R B@aRB; @x@A ARE aR =R="@@ B u-5Kea` b]b j B@jB@x@A$AjE{taj =j=j%-%@o@ nBОB B@JB@x@AAJEXuJe= &t =]{F% %@8Y@ aeb ^! B@aBy@x@A$AEvab =jӀ=j @Ҁ@,J|ѠJA# B@aRB@x@A AREwaR aR =RP=FR"@@ @o9D?1aDbb½ B@jB@x@A$AjEFxj  aj =jI= @@$BaH J$ c B@JBc@x@AAJEyJ  @==%| ={% @@ ?GBb@b c B@aBL6@x@A$AjE+  Kc = ``}zaj$j+c@{@,J-J B@B@x@A ARE84{a   AR = ;=R%@P7@ % C!"0 >Bb6b B@B@x@A$AjE jaj =j7=j%-+c@@ cBB B@JB@x@AAJEE|e=ǤFw =>{% "@@ ,Ab ! B@aB@x@A$AEf}a,D^ = `&~`=j @C%@,J$J B@Bc@x@A ARE݀y FaR =Rs=FR"@@JtQ$@v"EaQBb:b jc B@jBF@x@A$AjE`b jaj =j=j @L@~B B$ c B@JB@x@AAJETJe=hgF$X =Z{% @!V@F hv/G?(BbUb c B@aB,@x@A$Ag  EnE =j="@v@,JJ@ B@a B$X@x` =AR @`E FaR =RӀ=R%@π@cJtQ$Pv"&`̠bbm΀bĩ B@a$By@x@A$Aj E{B =j=(%-(+c @]@  B  B@JB@x@AAJECJe= / =H{% "@>D@ ! @ mhb ! b  B@aB@x@A$AE1 ^b =jajK@@,JJA# B@aRBz B* @x@A ARE RDF =R="@@ !#"dd" Zvb{b j B@jBy !j@x@A$AjEub jaj =jy= !@vx@$"BwB c# B@JB@x@AAJ$E1J@=%=%Fy& = 7{% '@W2@ ,J v(b  c) B@aBy@x@A$Aj*Et b+ =jD=^%,@@,-JJA#n,. B@aRB{@x@A AR/E*aR0 =Rկ=%p1@.@ c3t!%~4bYEJ[2bb j3 B@jB @x@A$Aj4Ecaj Iaj5 =j1g=j%-j+c6@f@ ) @"@B7BeB)B8 B@JB@x@AAJ9E8?@T   e:=@c; = n8%{% +c<@{ @ c h=b > B@`B@x@A$A?Eڀ!"b@ =ja"A@U@,BJJ C B@aRB|@x@A ARDEQa ##KcE =RwY= F@T@,JCt'%~"Q`~DfGb4b½H B@jBnb@x@A$AjIES aj@Y j$$AjJ =j=j%-(%K@@@ LB BM B@JB@x@AAJNE J%%@=O=ZۄF~yP = À΀{F Q@ʀ@ NARbuɀb cS B@`B@x@A$AjTE`b&'bU =jD`=j^(fV@B@,WJSJA#FcX B@aRB@x@A ARYEn@Y ((aRZ =R$R(o[@z~JSE%1@:B\bbj] B@jB@x@A$Aj^E, j))aj_ =jx="`@ֹ@ aB4BJb B@JB@x@AAJcE{rbw J**ed=Fe =kx{% :"f@s@ @ lBgbb b h B@aBy@x@A$AiE.a+,bj =j6="k@@@S2%lJJA#Jm B@aRB@x@A ARnEaR --aRo =@Ϭ=R"p@'@ ,c$ V4%,Bqbbr B@B@x@A$AjsE`j..ajt =jd=( cu@pc@ rvBbB Jw B@JB@8C@x@AAJxEaJ //ey=Fz =@"{% {@Y@ B$F @+c T|b ! b } B@`B !@x@A$A~E׀01b =jחaj%pj+c@:@ m!j @JJ  B@aRB; @x@A ARENa 22aR =ReV="@Q@ csC!@e NEb-b½ B@jB; @x@A$AjE8 ajf33Q =j =j @@~ `@"AJBx B$ B B@JB@x@AAJEŀ 44e=?؄F]L =ˀ{F% F(@ƀ@ ! @.W UAbZb! by B@aBc@x@A$AEEb 55b =j؅=%pj"@9@,JJA# B@aRB,@x@ =AR @`E<R66aR =R}D=R"@?@ C"% Kq0 `̠~BbDb j B@a$B @x@A$AjER 77aj =j=%-6@6@~$( @"@BB B$B B@JB@x@AAJEٳ88e=Fy ={% "@@; QAbub 륱 B@aBc@x@A$AE`oac9:H =j/`=^"@-@,J_JA# B@aRB@x@A AREm@Y F;;aR =R#=R"@}@ q4QCq S"":S"@Bbbĩ B@jBW@x@A$AjEb j<?b =j8ـ="@׀@,JJ (> B@aRB@x@A AREaR F@@aR =R=R"@#@FJC"Cq"qVu6u7a%Bbb@$j B@jB @x@A$AjEKjAAHo =jO=( @nN@ BMB J$  B@JB@x@AAJEJBBe=F$X = {% @S@ y`@+c Bb ^! XF B@aB @x 9A$A @E€CDb =jւaj+c@6@,JJ@ @R B@a B@x 9A AR @`E9a EEaR =R[A=R%@<@ c8$``$p%Bb%b½af B@a$Bx@x@A$AjE7 jFFaj =j="@@ BgJ$ B@JB@x@AAJEb JGGe=?ÄFc ={% @@ ! @( a,BbZb b B@aB@x@A$AEElHHb =jp=j @Qo@,JnJA# B@aRBy@x@A ARE'RIIaR =R/="@*@!!L9NaBbLb  B@jB,@x@A$AjER fJJaj = =%-(1@-@ $( @(@BB倃Bc B@B@x@AAJEٞKKe=F =Ť{% (@@ y c Abub 륱 B@aBc@x@A$AE`ZaLMNW =j`=j$j"@@,J^JA#h  aRB@x@A AREmѠ@X FNNaR =R%ـ=R"@Ԁ@ ~$F!9: 9K:Q 8ABbӠb@&b B@jB| @x@A$AjEb jOOaj =j=j%-%@ڏ@~j @"@B B<Bc B@JB@x@AAJ E{HaJ} JPPe =F, = ÀgN{% "@I@ y" @ Abb! b륱 B@`B@x@A$AEaQRb =j"Ā="@€@,JJA#F B@aRBc@x@A ARE{aR SSaR =RÂ=%p@~@  -L\y<a;{Bb}b½ B@jB@@x@A$AjE6jTTaj =j:=%pj%@h9@ $( @"@BB8BBc B@JB@& @x@AAJ E UUe!=F5n" =@{% %#@Y@ / A$b % B@`B ! @x@A$A&EVVb' =j7=^"(@@,)JJ * B@aRB@x@A AR+E*iaR WWaR, =Rp=R"-@.l@ :; < = aaB.bkb j/ B@jB@x@A$Aj0E$aj jXXaj1 =j4(=(%-(%2@'@3B&BB$ 4 B@JBc@x@AAJ5E7 JYYe6=?7 =+{ 8@r@ ! @c A9b  by: B@aB@x@A$A;EbZ[b< =j[`=j =@MZ@ 2 @ ! !% l>JYJ j? B@aRB@x@A AR@Ea \\aRA =R~="B@@K>%? @ A BCbGb½D B@jB@x@A$AjEER΀ j]]ajF =jр=%-G@7@ r$( @(AJHBЀJI B@JB@)c@x@AAJJEى^^@=K=ZFx3#xL =@͏{% (M@@ (ANbub 륱O B@`B@x@A$AjPE_Ea_`bQ =j`=j%pj"R@@ mSJZJ 4` T B@aRB* @x@A ARUEm@Y`~ FaaaRV =RĀ="W@u@ B%C D E  B2BXbᾀbjY B@jB@x@A$AjZEwb2 bbY[ =j|{=%p+c\@z@~]B8B J^ B@JBc@x@[ =AJ_ @Ez3aJ Jcce`=Fa =o9{% %b@4@ ! @c Acbb! b d B@abB@x@A$AeEdebf =j,a g@@,hJJ (Ri B@aRB@x@A ARjEfa ffaRk =Rm=R"l@i@ #F%GC"`QCGaBmb{hb n B@jB@x@A$AjoE!jggajp =j%=j q@z$@r$( @(AJrB#B$Bs B@JB@x@AAJtE hheu=F* v = {% w@Xހ@ ) @+c  Axb ! bcy B@aB@x@A$AzEiib{ =j9= |@@,}JJA#~ B@aRBy@x@A ARE)TRjjaR =R[=R%@)W@ 3"C"4~5BbVb j B@jB ,@x@A$AjEjkkaj =j<=(%-(+c@@ BB$  B@JB@x@AAJE7 lle=? ='р{% "@t̀@ Ab  B@aB@x@A$AEbmnb =jF`=^(f@LE@,JDJA# B@aRB@x@A ARE ooaR =Rx$R"@@/KC6+g7 8 aOBb;b j B@jB@x@A$AjER jppaj =j⼀=(%-(%@=@ kB B@JB@x@AAJEtbw Jqq@==ZF =z{ @v@ y c  Abtub y B@aB (,@x@A$AjE_0rrb =j5=j c@g3@,J2J  B@aRB@x@A ARE ssaR =R=%@@ KS9Keu4G5$X|b^bA; B@jBz c@x@A$AjEmb2 jttaj =j=%-@N@~B Jc B@JB@x@AAJEbaJ Juue=Fc =h{% "@/d@ ;lbcb! B@aB "@x@A$AEzav!A = ``ހ= @݀@,J}ܠJ F B@B@x@A AREaR xxaR =R:=R"@@ c1`p-@}Hobb½ B@jB~ @x@A$AjEQaj jyyaj =jT=j @S@~BNB$ F B@JB@x@AAJE Jzze=| =}{% @ @ c DBb1b ! c B@aB "@x@A$AEȀ{|b =jGaG r% @@,JJ  B@aRB{ ;V/ @x@A ARE)?a F}}aR =RF=%@AB@ s} uvu /$XbAbĩ B@jB @x@A$AjEQ~~! =j8=j%-(1@@ BB$  B@JB@x@AAJE7bxe=F ='{% "@r@  @yK $Xbס ^! b B@aBc@x@A$AEqa* b =j1`="@L0@,cJ/J n B@aRBc@x@A ARE aR =Rv= @@ w"Kf$``$FNb?b j B@jB@x@A$AjERbF jaj =j⧀=%-(%@?@ B$  B@JB@@x@AAJE_aJ Je=YrF~ =e{% %@a@ c_Tbt`b  B@aBy@x 9A$A @E_ab =jۀ=^K@ـ@,JNJ@ B@a BL6@x@A ARElaR ,Y) =R=R"@u@ pKYw"`Dib j B@jB{c@x@A$AjEMj"`!j = sQ=(%-(%@P@ nB7B J ` B@B@,B@x@AAJEz Je=F =@f{% " @ @c 7A bb  B@`Bc@x@A$A Eŀ'" =j9a^%@@#P"J'%JJ IJc B@aRB@x@A AREbo B@B@x@A$AjE jaj =j=( @{@$BB J B@JB@C@x@AAJEe=FB =@{% @X@ ڢB b ! ! B@`B !@x@A$A"Enacb# =j.`=j%pj%$@!-@ m%J,J & B@aRB@x@A AR'E FE( =Rh=")@@o!"[ aIB*b,b j+ B@jB@x@A$Aj,E6b jAj- = =j .@@ c/Br$ c0 B@B'$c@x@AAJ1E\Je2=>oF3 =@b{F% F(4@]@c ,5bYb c6 B@`B@x@A$A7EDacb8 =jl؀=j$j%9@ր@,:J;J >; B@aRB@x@A ><EQaR FaR= =R=FR">@a@ 䐂a"7KaVE?b͑bf@ B@jBB@x@A$AjAEJjEB =j\N=%-1C@M@ r `@"@BDBB JE B@JB@x@AAJFE_JeG=FH = ÀO {% "I@@ ) @ aAJb #! b륱K B@`B@x@A$ALEcbM =ja^"N@p@,OJJA#P B@aRB@x@A ARQE8a aRR =R@= S@;@ LL/LRL^MMa|BTbgb@$jU B@jB| o,@x@A$AjVEz2 jajW =j=j(%Xi@`@ YBB$ cZ B@JB@x@AAJ[Ee\=„F{y] = s{F% ^@=@ ! @K A_b ` B@aB@x@A$AaEkaQHb =j+`=j^%c@*@,dJ)JA#Fe B@aRB@x@A ARfEaFaRg =R9=FR(oh@@ @ FMTMM6NFTKBibb½j B@jB@x@A$AjkEaj ajl =j=j%-(%m@@~$( @n"@BnB[Bo B@JB@x@AAJpEYJeq=#lFr =_{%p"s@Z@ c tb>b ! cu B@aBy@x@A$AvE)abw =jFՀ="x@Ӏ@@Sf!j$^yyJJA#Jz B@aRB@x@A AR{E6aR FaR| =@㓀=R"}@>@ $F!R90CqSq90an6Df~bbĩ B@B@x@A$AjEGjaj =jEK=(%p@3A@J@ r!j @ťBB J$Bc B@JB@x@AAJEDaJ ${=ŤF = À4 {% "@@ c Ab ! 륱 B@`Bc@x@A$AjEʾKc = `~a^"@Y}@,cJ|J B@B$X@x@A ARE5a aR =R==R"@8@cLCr%r% akcb\b@$ B@jBx@x@A$AjE^@Y jaj =j=j%-(+c@B@B B$  B@JB@١2ay@x@AAJE@==fFc =@ɲ`{"@@c kcbbje! B@`B !,@x@A$AjElha, E =jm=j)%@hk@,JjJ c B@aRBB@x@A ARE#RaR =R+=FR%@&@ KSrK90aWFbWb@$j B@jB$X@x@A$AjEyߠ@Y aj =j=j%-%@c@ nBB B@JBc@x@AAJEe=i|$X = s{F% "@<@ W @W Fb  bXF B@aBc@x@A$AEVaE =j`=j^%@@,JnJ > B@aRB@x@A ARÈ FaR =R?Հ=R"@Ѐ@ L#DKT 8 aJDb b½a B@jB{ oy@x@A$AjEb jaj ==j%-(%@ @~Bk B) Jc B@JB@x@AAJEDJe=#WF$X =J{% "@E@ 5\ @+c yb>b b B@aB@x@A$AE(ab =jL= @@,JJA#o> B@aRB@x@A ARE6waR FaR =R~=R"@Bz@ o @%3%q -0avDbybj B@jB @x@A$AjE2aj jaj =jM6=j%-(%@5@ B B B@JB@x@AAJEC J${=ĤF =8{F% "@@ @Ab ! b B@aBB@x@A$AjEʩbb =jj`=j$j+c@eh@,JgJ  B@aRB@x@A ARE a aR =Rs(=R"@#@ c C"D1@;Bb @==fF =ٝ{% F"@%@ y c 7Bbb c B@aB@x@A$AjElSab =j`=^%@@,JjJA#rc B@aRB,@x@A AREyʠ@Y aR =R!Ҁ=R"@ỳ@ c S389Q0*  .Bb̀bj B@jBc@x@A$AjE@@T jE =j=(%-(+cj@∀@$BDB [,J B@JB@٢oB2ay@x@AAJEAaJ Je=0TFQ  =@{G{% "@B@ c Ab#be!  B@`B !y@x@A$A E cb =j)aj c @@ m' @ JJ  B@aRB@x@A AREta aR =R{="@w@ y c 8d` pBVBbvbA;j B@jB@x@A$/E/jaj =j*3=j @2@ cB1B J$ c B@JB@x@AAJE( e=F = {F% @a@ $F @6 VpBb  B@aB,@x@A$AEbcH =jf`=j%pj+c @>e@,!JdJ F" B@aRB@x@A AR#Ea aR$ =Ra%=FR(o%@ @ sÔ@0.:B&b,b@(j' B@jBB@x@A$Aj(EC٠@Y jB) = +܀=%-+c*@@ R~+B{ۀB, B@B@x@AAJ-Eʔe.=KF/ ={%p"0@@ ! @9 A1bfb bZ2 B@aBy@x@A$A3EPP acb4 =jm `=j^%5@@,6J;JA#7 B@aRB @x@A AR8E^Ǡ@Y FaR9 =R΀=R":@Vʀ@ `:t8* B;bɠbj< B@jB@x@A$Aj=E b2 jaj> =j]=j ?@@ $( @"AJ@BBA B@JB@٢o/l@x@AAJBEk> aJ J@=C=FtD =@XD{% E@?@ c rAFbbe! 륱G B@`B@x@A$AjHEbI =j# aj J@@ m!j @KJJA#L B@aRBc@x@A ARMEqa@Y aRN =Rx=F!O@ t@ t @@Pbxsb½Q B@jB@x@A$AjRE,aj jajS =j0=j%pj+cT@m/@~UB.B$ V B@JBc@x@AAJWE JeX=FBY ={% (Z@J@ B! @c I>A[b ! bc\ B@aB@x@A$A]Ebb^ =jc`="_@#b@,`JaJ >a B@aRBc@x@A ARbEa Oc =RF"=R"d@@ , b c8XBebb½f B@jB@x@A$AjgE(ր jajh =jـ=`Ze-(%i@@~@$(ncjBt؀ B$Bk B@JB@x@AAJlEb Jem=0Fn ={% "o@쒀@ y) @6 ApbKb! b q B@aBy@x@A$ArE5MaL6bs =jk `=^"t@ @,cuJ8J v B@aRB@x@A ARwECĠ@Y aRx =Rˀ=R"y@3ǀ@ 11+fK<~@Bzbƀb½{ B@jB$X@x@A$Aj|Eb jaj} =jV=j%-(%~@@ BB$ c B@JB@x@AAJEP;Je=ѤFc =8A{"@<@ c kb ! B@aB,@x@A$AEcb =ja%@N@,JJA#(R B@aRB@x@A AREma FaR =Ru=R%@p@ pC9ӔP9pXADb\bj B@jB @x@A$AjEk)jaj =j,=H@1c@O@$B+ J$ B@JBc@x@AAJE e=sF ={% `3b@,@, Bbb Z B@aB @x@A$AEybb =j``=j @^@,JgJA# B@aRB]L@x@A AREa aR =R4="@@ H9"z9 Ea Bbb B@jB@x@A$AjE jaj =jր=%-(+c@Հ@$BIB J B@JB@x@AAJEe=F ={% (@Ώ@!, @K $Ab/b b B@aB@x@A$AEJayb =jP `= @@,JJA# B@aRB@x@A ARE( FaR =RȀ=R"@0Ā@  D9t!/4aϛBbÀb B@jB@x@A$AjE|!b jaj =j6=j @@ $( @.`AJB~BJ B@JB@x@AAJE58"Je=F|B =%>{% @p9@ kiAb  c B@aB@x@A$AEcb =j#a @C@,yJJA# B@aRB@x@A AREj$a FaR =Rgr=R%@m@ * %Te]|yb-b½ B@jB@x@A$AjEP&%j] =j)=j%p(+c@4@ B( B B@JB@x@AAJEဈ> e=XF ={% "@ @ y! @c |ybsb! b B@aB,@x@A$AE]&byb =j]'`="@[@,cJTJA# B@aRBw Bnb@x@A AREk(a!aR =R= @k@M%3 B@aRB@x@A AR4E񺀈  aR5 =R€="6@@  C0:6aB7kab½8 B@jB oc@x@A$Aj9Exv7b faj: =jy= ;@J@ r$( @"AJ<BxJ$B= B@JB@x@AAJ>E18Je?=DF@ =7{% F%A@;3@ Sf) @+c 2qABb2b bcC B@aB "c@x@A$ADE퀈cQE =j9a^"F@@,GJ|J H B@aRB@@x@A ARIEd:a FaRJ =RJl="K@g@ cSH% `єaBLkbfM B@jB*@x@A$AjNE ;aj2 jajO =j#=j%-(6P@"@ QBRBR B@JB@x@AAJSE JeT=!FFU = À{F% "V@܀@ ! @+c wAWbaFaR_ =R=FR"`@=@ cPP%@H| Ӑ8Babbb B@jB@x@A$>cEɀ fajd =;̀=j e@̀@~$( @"AJfBB$Bcg B@JB@)@x@AAJhEB?b Jei=×F$Xj =@2{% k@~@ W c ,Alb ! cm B@`B@x@A$AnE@@abo =jA`="p@X~, qJJA#cr B@aRB@x@A ARsEַaRt =R=R%u@ں@ $F%os*ps\aBvbFb½cw B@jB@x@A$AjxE]sBb fajy =jv=(%-(+cz@G@ r!j @ť{BuJ$B| B@JBc@x@AAJ}E.CaJ Je~=eA|* =4{% "@ 0@c FAb/b 륱 B@aB@x@A$AEjꀈc b =Da^"@@ '$^yJiJ B@aRB5n@x@A ARExaEa !!aR =R,i=R"@d@5nMt|ExaBbcb@$ B@jB{ @x@A$AjEFj""aj =j =j%-(%@@ B?B B@JB @x@AAJE؀ ##e= Fv =iހ{"@ـ@  $F%N6 NAb!bx B@aBF@x@A$AE Gb$%b =j4TH`=j%p%@R@,JJA#Fc B@aRB@x@A ARE Ia &&aR =RI`=FR%@)@ \|}a(ak I`½ B@jB5n@x@A$AjEI j''aj =j$ʀ= @I`~$BȀB J B@JBc@x@AAJE'J` J((e=F = À{%pF"@d@ @': @( 4b ! b c B@`B,@x@A$AE=Ka)*b =j=j^%@<@,JJA# B@aRB@x@A ARELaR ++aR =R`="@@ $\$R: aHok'b½ B@jB5n@x@A$AjEBpMj,,aj =s= @@$Br J$ 5n B@JB@,@x@AAJE+NJ--e=J>|c =@1{% @-@  c `Bbd,b / B@`B W!,@x@A$AEO瀈c./b =jpOaj @ҥ@ m!j @J>J c B@aRB@x@A ARE]^Pa 00aR =Rf=R(o@ia@ !(o!Ro00acsBk`b j B@jB @x@A$AjEQaj j11aj =js=j%-(1@@~ƹ!j @` (@BB/B B@JBc@x@AAJEj J22e=F/ =bۀ{% "@ր@ B! @ǁAbb ! b륱 B@aB@x@A$AERbc34b =jQS`="@|O@,JNJ(> B@aRB@x@A ARETa 55aR =R=%p@ @ $X8pK$`$`$paBbz bj` B@jB/@x@A$AjE j66aj =jǀ=j%pj%@pƀ@ $( @"@BBB$Bc B@JB@x@AAJE U77e=F ={% %@I@ $X gAb ! 륱 B@aB (c@x@A$AE:Vac89b =!b="@@,JJ c B@aRBc@x@A AREWaR F::aR =RM=R"@@ z Bo 5E qaBbb@$ B@jBx c@x@A$AjE'mXaj j;;aj =jp=(%-(%@@~Bgo J$  B@JB@x@AAJE(YaJ J<b =jbZaj(f@â@,J/JA"Fc B@aRB@x@A AREB[[a@Y ??aR =Rb=R"@N^@ cDրb m]VB b]b  B@jB@x@A$Aj E\aj j@@aj =jD=" @@ BB  B@JB@x@AAJEOҀ JAAe=ФF = ?؀{% @Ӏ@ c VBb   B@aB (c@x@A$AE֍]bBCb =jN^`=j @iL@, JKJrR B@aRB{5n@x@A ARE_a DDaR =R ="@@ cR8I9C :bIBbcbA;j B@jBy c@x@A$Aj Ej jEEaj! =jÀ=%-(C"@N@$#B€J) c$ B@JB@١B!Ky@x@AAJ%E{`b JFFe&=rFb' =@ف{% ((@+}@ , /O*)b|be! c* B@`BQ@x@A$A+Ew7aacGHb, =j=j -@@ my.JbJA#/ B@aRB@x@A AR0EbaR IIaR1 =R+="2@@, NPCA%L%Ta//3bb½4 B@jB@x@A$Aj5E jcjJJaj6 =jm=j%-(%7@l@ c8BPB$ 9 B@JB@@x@AAJ:E%dJKK@=;=8/< =@+{F% %=@&@, />b.b ! ? B@`Bc@x@A$Aj@ELMbA =jKeaj B@@,CJJ D B@aRB@x@A AREE&Xfa NNaRF =R_=R"G@[@c N:Ӕ@@@,1 HbZbA;jI B@jB/@x@A$AjJEgjOOajK =j1=j%-(%L@@ MBB$ N B@JB@x@AAJOE4 PPeP=FQ =Հ{% "R@kЀ@c Sb ȥ! T B@aB@x@A$AUEhbQRbV =jJi`= W@MI@,XJHJA#FY B@aRB@x@A ARZEja SSaR[ =Rj =R"\@@ #:u:%+gX`nD]b8b@"j^ B@jBz@x@A$Aj_EO@Y jTTaj` =j=j%- @3Aa@3@~bB B$ c B@JB@c@x@AAJdExk@  JUUee=WFf =@~{% "g@z@ y/ @y+c IAhbqybe! bi B@`B !@x@A$AjE\4lacVWbk =j="l@@@Sm!j mJKJ Jn B@aRB@x@A ARoEjmaR+ XXaRp =@=R"q@z@ 31 IVTD yXBrb歀b js B@B} @x@A$AjtEfnaj jYYaju =jpj=(%-(+cv@i@~wB0B$ x B@JB@C!K@x@AAJyEw"oJZZez=FF{ =@g({% "|@#@'L @+c A}bb ! b~ B@`B@x@A$AE݀c[\b =j pa^K@m@ mJٛJ(> B@aRB@x@A ARE Uqa F]]aR =R\=R"@X@,NC-L6d`IBbWbj B@jBQ@x@A$AjErj^^aj =j"=(%-(%@@ rBB J$  B@JBc@x@AAJÈM__e=ބFc =Ҁ{% "@X̀@,N zO*b  B@aB 'Zc@x@A$AEsbc`ab =jGt`=^%@*F@,JEJ j B@aRB@@x@A ARE bbaR =RXu$R"@@ c S89:"]I"5nn!b!b j B@jB~ c@x@A$AjE42 jccaj =j=(%-(%@@~ƹBx J B@JB@x@AAJEuvbw Jdde=;F@ ={{F% "@v@ y! @c Bt bVb! b B@aBc@x@A$AEA1waefb =jx=0j%@@,JDJA# B@aRB@x@A ARENxaR ggaR =R=R"@W@! @cTSr"~}aDbêb  B@jBW@x@A$AjEcyjhhaj =jag= @f@ $( @"AJBB,Bc B@JB@x@AAJE\zJiie=ݤF =P%{% F"@ @F 6Ab  c B@aBc@x@A$AEڀjkb =j{aj$j"@v@@SfJᘀJ  B@aRB} @x@A AREQ|a llaR =@Y=R"@T@ cs]A \m\tBbdb½ B@B@@x@A$AjEw }jmmaj =j=j%-+c@d@ BB)  B@JB@x@AAJEȀ} nne=ۄF =΀{% "@:ʀ@ , !Abɀb!  B@aB/@x@A$AE~bcopb =jD`=%@C@,cJBJA# B@ B@@x@A ARE qqaR =R=aR"@~ є% yG ]L$6bb j B@jB@x@A$AjE, jrraj =j=%-(%@김@~BQB  B@JB@2ay@x@AAJErbw Jsse= F/ = x{% "@s@ W) @W+c Ab;b B@`B@x@A$AE&.actub =jV=^%@@,J%JA# `- B@aRB@x@A ARE3aR vvaR =R߬=R"@;@ \x]|}")avfBbb½`j* B@jB@x 9A$Aj @`E`jwwA =jBd=j%-(%@c@  `@"@BBB B B@aB @x@AAJEAJxxe=¤Fz@ =@1"{%p"@}@ ! @?m ҔAb ! bc B@`B@x@A$AE׀yzb =j藆a"@J@ mc5nmJ  B@aRB/@x@A ARENa {{aR =RyV=R"@Q@ Q *$``/`aVBbEb½a B@jBF@x@A$AjE\ j|8% =j =H@e-(% @:@ $(% B J$B B@JB @x@AAJ E }}e =d؄Fy =@ˀ{% "@ǀ@ $F @+c 'Lb~ƀb b륱 B@`B@x@A$AEibt~b =jA`=j"@?@,J\JA# B@aRB@x@A AREw aR =R'$R"@~ B@$pT+_$ ё1 a`2zbb j B@jB@x@A$AjE, jaj =j="@䶀@ƹBEBB B@JB@x@AAJ!Eobw Je"= F# =pu{% $@p@ ĕ'%b b & B@aB@x@A$A'E +acb( = `+=j )@@,*JJ >+ B@B@x@A AR,EaR aR- =Rͩ=%.@$@ y~ :e0au/bb½0 B@jB@x@A$Aj1E]jaj2 =j/a=*(#3@`@ r4B_B J5 B@JB@x@AAJ6E&Je7=F8 ={% "9@c@  c A:b ! ; B@aB - @x@A$A<EԀyb= =j͔aj >@/@,?JJ @ B@aRB2B @' @x@A ARAEKa aRB =R^S=R"C@N@ KWy% &%  BDb"b½E B@ABB@x@A$AjFEAaj2 jajG =j =j H@$@~IB J$ }J B@JB@$y@x@AAJKE JeL=HՄF{M =@Ȁ{% N@Ā@ ! @6 2BObcÀb b,P B@`B@x@A$AQEN~bbR =jk>`=j S@<@ m' @TJ9J U B@aRBc@x@A ARVE[@Y aRW =R=F!X@l@ $@q y%@yBYbb@%ĩZ B@jB@x@W =>[ @`EⰖbjaj\ =jr=j%-j+c]@ͳ@~$( @4@B^B.B_ B@aBc@x@AAJ`EilJea=Fb =]r{H O8P% (c@m@  |Adbb ! 륱e B@aB@x@A$AfE'bg =j,="h@+@,iJp*J j B@aRB<Bc@x@A ARkEv aRl =R)=R"m@@ !$F%o+W$P~ Bnbb jo B@jB@x@A$AjpEajq =jy=(%p(%r@֡@ !j @ťsB9B J$Bct B@JB@c@x@AAJuEZJev=(w   >w = )t`{% "x@[@ y! @iAyb b b륱z B@aBy@x@A$A{E ab| = `Bր=^"}@Ԁ@ mc~J J 4?"  B@B|@x@A AREaR aR =R=R"@@,O "M 1Bbbj B@jB@x@A$AjEHjaj =jL=(%-(%@|K@$BJB J B@JB@b@x@AAJE%Je=F| =@ {% "@a@ $F @ Ab ! b B@`B]L@x@A$AEb =jaj)j%@~@ m!j @J}JA# B@aRB@x@A ARE6a aR =Re>=G@.!!R"@9@cO)1 qKjto!Bb*b j B@jB $X@x@A$AjE@ jaj =j= @@) @K C#BxB$Bc B@JB@x 9AAJ @Eǭ@@@w Je=HF ={H {"% @@ @ Abgb bc B@abB@x@A$Am`ENiacb =ji)`=j^K@'@,J5J > B@a B@x@A ARE[@Y aR =R="@c@ c #zѕng@$Xbba B@jB@x@A$AjE⛤b jaj =jr=%-(%n@О@ rB.BJ B@JB@x@AAJEiWJe=F =Y]{% c@X@ ) @+c hv/G?3$Xbb b B@aB@x@A$Am`DEacb =jӀ=j @rр@,JРJ ( B@aRBy@x@A AREaR FaR =R=R"@@ c3ak\ @c@"n@.Dbabj B@ B@x@A$AjEEaj2 jaj =H=j @Y@ BG B B@JB !,,@x@AAJE aJ D38 J e=| =@O{% @G@ c Bb e! !@Wc B@`B ! @x@A$AEb =j<=j @@,J J  B@aRBz@x@A ARExaR =R=R%@{@ $F!o.!C} " m" 8Bbzb j B@jB 5@A$Aj @`E3ajaj = ?`=#7=j @~6@~!j @.`AJB5B$B B@B@$@x@AAJE% e=-y =@{:% @3b@_@, :Ab ! 륱 B@`Bc@x@A$AEbcb =A6`j`=$jK@?i@,JhJ  B@B@x@A ARE!a aR =Rk)=R%@$@ S"ќ(L'Bb1b½ B@jBW@x@A$AjE@݀ jaj =j=(%-1@@$Bx߀J$  B@JB@x@AAJEǘe=HF]L ={% "@@ ': @1a0# ( Abcb bF B@aB@x@A$AENTat b =jX=j @VW@,JVJA# B@aRB@x@A AREaR RaR =R|="n@@Oc)Ô"u $ RVbHb@&j B@jB@x@A$AjE[ˠ $ jaj =j΀=%-(%@I@ b~b 륱 B@aB@x@A$AEhBacb =j`=j @@,JWJA#F `R/ B@aRBy B@x@A AREv DE FaR =R-=R"@@ ys4p%$ft [Dfbbf B@jBy@x@A$AjEtb jaj =j}x=j%p(%@w@~B9B B@JB@x@AAJE0Je=CFy =x6{% " @1@ A!bb ! ^" B@aB,@x@A$A#E b$ =:aj %@@,&J J (>' B@aRB5n@x@A AR(Ecay FaR) =Rj=H@5 R"*@ f@ y5{"981@z\B+beb,nSjB @x@A$Aj-E@ ?aj. = /""=j /@!@ r0B B$ 1 B@B J!K@x@AAJ2E% e3=FV4 =@{% 5@aۀ@ c  6b ! 7 B@`By@x@A$A8Ebt b9 =jS=":@@ m!j%`# ! !% DF;J J < B@aRB@x@A AR=E2QRaR> = X=R%?@7T@ "1  l5n@bSb$A B@By@x@A$AjBE jajC =j==(%-(CD@@ EBB $ F B@JBc@x@C =AJG @E@ eH=HyI = }{0΀{% "J@zɀ@ ȤAKb L B@`B@x@A$AMEǃb Z%" 8bN =jC`=j%pj3O@UB@,PJAJ RQ B@aRB{@ B@x@A ARRE RA@aRS =@aR"T@~ Tbj B@jBc@x@A$AjE jaj =jI=(%-(%@@ BB$  B@JB@x@AAJE@e=H = À4{% "@|@ ^Ab !  B@`B >"@x@A$AEn@ /b =j.`=^(f@Q-@,J,J c B@aRB@x@A ARE FaR =R=R"@@ cPSr`a9WbPb j B@jB @x@A$AjE[b jaj =j㤀=(%-(%@=@~B J$  B@JB@x@AAJE\aJ Je=boFz/ =b{% "@^@ / Ab}]b!  B@aBc@x@A$AEhab =j؀=j c@׀@@S`@,Jo֠JA#Jc B@aRBy3By 5 A AR @`EuaR-aR =@`=*=R"@@ P$`^`{$`@RBbb  B@B @x@A$AjEJaj faj =jN="@M@ B@Bb$ n`JB@x@AAJEJe=| = Ās {% @@W)a;E! @ |Bbb b B@`By@x@A$AE €b = `"aj @@@SjJJ J B@B@x@A ARE9a FaR =@@="@<@ P+]paa*[b;bf B@B@x@A$AjE jaj =j=%-(!@y@ $( @.`@BBB J B@JB@/l @x@AAJE%b Je=F* =@{% (@b@ $F @ 6Ab ! bc B@`B@x@A$AEkacb =j+`=j @:*@ m!j @cJ)J  B@aRB@x@A ARE aR =Rm=R"@@ %t~a-Bb5b j B@jB@x@A$AjE?b jaj =jġ=%p(%@@~B(B$  B@JB,@x@AAJEYJe=GlF = À_{% "@[@ ! @( 4AbbZb ! b B@`B@x@A$AEMacb =jvՀ=%pj(f@Ӏ@,JDJA# B@aRB@x@A AREZaR FaR =R=R"@j@yP#33a Bb֎bf B@jB @x@A$AjEGjajo ] qK=j%-%@J@ $( @"@BB-B$B B@B@!Kc 5@AAJ @EhJe=F =@{` {% "@@ JAbb ! 륱 B@`B@x@A$A Eタb = `a" @y}@, J|J c B@Bc@x@A ARE5a aR =R== @9@ c3]`"[p aBbp8b B@jBB@x@A$AjE jaj =j =j%-(%@f@ BB$ c B@JB@x@AAJE e=F ={F% %@?@ y! @c 4Ab ! bc B@aB 'Z,@x@A$AEhab =j(`=j^(f!@'@,"Jo&J j# B@aRBv[{By@x@A AR$E߀ FaR% =RS=R"&@@ C[t&A%[B'bb jc( B@jB@x@A$Aj)E$b jaj* =j="+@ @$(n"AJ,BlB$B- B@JB@x@AAJ.EVJe/=,iFc0 =\{% 1@W@ 5\ @+c A2bGb b 3 B@aB,@x@A$A4E2ab5 =jhҀ=^"6@Ѐ@@S#!j%7J5JA#J8 B@aRBc@x@A AR9E?aR,aR: =@퐀=G@a;@G@  S "Cr6U+@z_B<bb = B@Bc@x@A$Aj>EDjaj? =jJH=(%-j+c@@G@ rAB B JB B@JB@1)@x@AAJCEMJeD=ΤFE =@A{% (F@@ RAGb H B@`B@x@A$AIEӻcAJ =j{aj%pj%K@^z@ mLJyJA#M B@aRB@x@A ARNE2a aRO =R:="P@5@ c00%D%auBQbUbR B@jB@x@A$AjSEh2 j BT =j= U@D@~VB JW B@JB@@x@AAJXE@=Y={Fp Z =@߯{% F%[@)@ $F @c 9B\bb b ] B@`B@x@A$Aj^Eueab_ =j%`= `@ $@ m!j @caJx#J b B@aRB@x@A ARcE FaRd =R,=R"e@߀@ $F!Rc B@aRBy@x@A AREǠ@Y FaR = +?π="@ʀ@ c,$Uk"z Dbbf B@B*@x@A$AjE b jaj =j=(%@@ rBQBJ B@JB@x@AAJE>Je=QF =D{% @?@ y! @+c UCAb,b b B@aBc@x@A$AEb =j?aj @@,J J ( B@aRBz@x@A ARE$qaaR =Rx="@0t@ cl`zn{t+:aY1Bbsb joRjB @x@A$AjE,A 2   aj =j+0= @/@~r$( @.`AJB.B J B@JB@,9/@'@x@AAJE1 J!!e=F =@@*{% @o@ nb c Ab ! c B@`B@x@A$AEb"#b =jc`=j @Gb@ m!j @,JaJA# B@aRBc@x@A AREa $$aR =R^"=F!@@ {|`a#JBb&b  B@jB@x@A$AjELրj%%aj =jـ=j%pj+c@7@~B؀ B$  B@JB@@x@AAJEӑ&&e=TF =@×{% 4 @@ y! @c L6bob b B@`By@x@A$AEZM''b =jR="@bP@ mJOJA# B@aRB{c@x@A ARER((aR =R=R"@ @ % "ґ9Ґ61aDbXb j B@jB@x@A$AjEgĀ ))aj =jǀ=(%-(%@<@ $( @ūcBƀ B@JB@@x@AAJp  E**e=F =@{څ{% "@)@ $F @6 )Abb b륱 B@`B@x@A$AEu;a+,b =j=^"@@ m!j$^c JoJA# B@aRB|@x@A AR E aR F--aR =R5=R" @@ Gp% QwBbbA;j B@jBzy@x@A$AjE n j..aj =jq=(%p(%@p@$BEB J B@JB@@x@AAJE) J//e=<| =@|/{% "@*@ ': @6 Ab+b b  B@`BJ@x@A$AE01b =jM ajj%@@ mJJA# B@aRB@x@A AR E$\ a 22aR! =Rc=""@0_@y Q"+d21/3B#b^b j$ B@jB@x@A$Aj%Eaj j33aj& =jB= '@@ $( @"AJ(BBB) B@JB @x@AAJ*E1 J44e+=F, =@ـ{% -@iԀ@ y$F @ 8A.b  bc/ B@`Bc@x@A$A0E55b1 =jf=^"2@ȑ@,3J4JA# f=Rt4 B@aRB@x@A AR5E?JaR 66aR6 =RQ=(o7@?M@QӔ @t ‘aÐaB8bLb½9 B@jB@x@A$Aj:Eaj j77aj; =j= =j%p(+c<@@~=BB> B@JB@@x@AAJ?EL J88e@=ThA =@<ǀ{% "B@€@ ! @ IACb ! b^D B@`B@x@A$AEE|b9:bF =j=`="G@j;@@Sm'$HJ:JA#JI B@aRB@x@A ARJE ;;aRK =@}=!L@@ c#2/ґ"aBMbDb½N B@B$X@x@A$AjOEgb j< J==eU=o}FyV =p{% W@#l@ B$F @+c u7AXbkb! b륱Y B@aBc@x@A$AZEt&a/>?b[ =j="\@@ !j$]JkJA#^ B@aRBz@x@A AR_EaR @@aR` =RC=R(oa@@ $F!R(o3"DTbbbb½c B@jB@x@A$AjdE YajF jAAaje =j}\=j%-(+cf@[@~!j @ťgB9B$Bh B@JB@x@AAJiEaJ JBBej='k ={"l@@c avAmb+b! n B@aB - @x@A$AoEЀCDbp =j<a$"q@@,rJ J s B@aRB@x@A ARtE#Ga EEaRu =RN=R%v@4J@  C҄"1`1aBwbIb x B@jB@x@A$AjyEjFFajz ==(%{@z@ |BB, } B@JBc@x@AAJ~E1 GGe=Fw3(. EO ! =!Ā{"@k@ ) @+c 1(Ab  b B@aB@x@A$AEy!@HIb =j9`=j @B8@,J7J 4b4 B@aRB@x@A ARE JJaR =R{="@@ SґFpcPBbAb j B@jB@x@A$AjELb jKKaj =j̯=%-o%@(@$Bµ) F B@JB@x@AAJEg JLLe=TzFc =m{% %@ i@ B': @.W oAbohb ! b B@aBB@x@A$AEY#!acMNb =j=j @@,JXJA#e B@aRB@x@A AREg"aR FOOaR =R ="@o@Qc"1x|}!Bbۜb@(j B@jB5n@x@A$AjEU#jPPaj =jvY=j%-(%@X@ $( @.`@BB1B J$Bi B@JB@x@AAJEt$JQQe=F =\{F% %@@$X Abb 륱 B@aB5n@x@A$AÈyRSb =j%aj @v@,J⊀J > B@aRB@x@A ARED&a TTaR =RK=R"@ G@NN$F!os11@xү"~aBbxFb B@jB * @x@A$AjE jUUaj =j'aj%-(%@{@ !j @ťBB B@JB@x@AAJE JVVe=̈́F = {% "@M@ c HtAb ! 륱 B@aB$X@x@A$AEv(bcWXb =j6)`=$j"@5@,J4J  B@aRB@x@A ARE YYaR =RP=R"@@ cyxxÔ "ayBbb@$j B@jBB@x@A$AjE1*b jZZaj =j=j%p%@@ Be B$ c B@JB@x@AAJEd+aJ J[[e=8wF =j{F% "@e@ )AbSb B@aB,@x@A$AE> ,a\]b =ji=j^%@ހ@,J5JA#F B@aRB@x@A >EL-aRF^^aR =R=R"@\@ yxu$t5{aBbșb½ B@jB}c@x@A$AjER.aj+u__aj =j^V="@U@ BB  B@JB@,* @x@AAJEY/aJ ``e=ڤFc =@M{ @@ y! @W "Bb ! bZ B@`By@x@A$AEɀabb =j0a^%@g@@Sm'%JӇJA#J B@aRB@x@A ARE@1accaR =@H=R%@C@ "*tGaQBb]b½ B@B$X@x@A$AjEt fddaj =j2a(*+c@a~ r$( @"@BBBJ$Bic B@JBc@x@AAJE  Jeee=|ʄF = À뽀{% "@6@ $F @6 Aqb b륱 B@`B@x@A$AEs3bcfgb =j34`=j%pj"@2@ !j @J1JA# B@aRB@x@A ARE hhaR = :=" @@ op" 4Q`G7  bb j B@B@x@A$Aj E5bF jiiaj =j=j%-%@@~B^B B@JB@c@x@AAJEa6aJ Jjje=tF =@g{F% %@b@ @?m b8b! b  B@`B@x@A$AE#7aklb =jF݀=j%pj%@ۀ@,JJA#c B@aRB| Bh@x@A ARE08aR mmaR =Rܛ=FR"@5@ +EutBfDbb I B@jB@x@A$Aj!EO9jnnaj" = GS= #@R@$$BB J$ c% B@Bc@x@AAJ&E> :Jooe'=F( =*{% F")@v @ $X 4*b ! + B@aB@x@A$A,Eƀpqb- =j;aj^%.@O@,/JJA#n0 B@aRB@x@A AR1E=@@ ! @c NCA?b|b ! b@ B@aB - @x@A$AAEfp>acuvbB =j0?`=%C@.@,DJYJ E B@aRBxc@x@A ARFEt@Y: FwwaRG =R+="H@@ +`Q66*@OBIbbĩJ B@jBQ@x@A$AjKE@b jxxajL =j=%-(%M@ܥ@~$( @"@BNBBB$BO B@JB@٢o$y@x@AAJPE^AJyyeQ=qFvR =@qd{% "S@_@ 8ATbb ! 륱U B@`B@x@A$AVEBacz{bW =j8ڀ=^"X@؀@,YJJ cZ B@aRB@x@A AR[ECaR F||aR\ =RŘ=R"]@@ c jajv =j=(%-(%w@ @~$( @"@BxB J$By B@JB@x@AAJzEıH@={=IĄFc| = À{% "}@@c 8A~b`b 륱 B@`B@x@A$AjEKmIab =x-J`=j c@+@,JFJ B@aRB@x@A AREY FaR =R=R"@]@cRS""~}"IBbbĩc B@jBc@x@A$AjEߟKb jaj =jo="@ʢ@ B+BJ B@JB@x@AAJEf[LJe=F]L =^a{% @\@ `Ebb B@aBc@x@A$AEMb =j=j @@,JaJA#c B@aRB @x@A AREsҠ@Y FaR =R ڀ=R%@hՀ@ #T6U +ndBbԀb  B@jB* @x@A$AjENaj =j=j*(+c@␀@nBBB B@JB@x@AAJEIOJe=Q =qO{% "@J@ y/ @+c 'Lbb ! b B@aB@x@A$AEPab =j:ŀ=.@À@,JJA#(> B@aRB@x@A ARE|QaR aR =R˃="@%@ 3V%%W iDb~bj B@jB$X@x@A$AjE7Rjaj =j,;=j @:@ B9B$  B@JB@x@AAJE# e=FB ={% @]@> @+c ABb ! b B@aB>",@x@A$AESbb =jnT`="@8m@,JlJ  B@aRB@x@A ARE%Ua aR =Re-=R%@(@ !d$F%CX1ZD-KBb'b½ B@jB@x@A$AjE= jaj =j=j%-(+c@*@~!j @(@BB〃 B$B B@JB@x@AAJEĜVe=EF ={"@@ y c Ab`b B@aB@x@A$AEKXWA@Tcb = 0`zX`=$"@@,JFJ B@B@x@A AREXϠ@Y: FaR =R ׀=R%@hҀ@ ySD"-Q@dBbрbĩ B@jB@x@A$AjEߊYb jaj =jg=(%-%@č@B#BB B@JB@x@AAJEfFZJe=F =VL{% "@G@ y! @ Abb bc B@aB@x@A$AE[acb =j€=^%@g@,JӿJA#( B@aRB| @x@A AREx\aR FaR =R=Rc@|@/ Rct𐁷u aCBbz{b@$j B@jB/@x@A$AjE4]aj@Y jaj =j 8=( @f7@$B6B J B@JB@x@AAJE Je=| ={% @C@! c Bb b! B@aB@x@A$AE^bb =jk_`=j%r@)j@,JiJ c B@aRB@x@A ARE"`a aR =RK*=R%@%@ s%v%%wuVBbb½ B@jB@x@A$AjE"ޠ@Y jaj =j= @@ ) @B+ B^J$B B@JB@x@AAJ Eab Je=*F =!?{% @ @ ! @c BbAbEb bc B@aB T@x@A$AE0Ubab =jWc`=j^"@@@Sr' @ @ J#J@.J B@aRB@x@A ARE=̀ aR =@Ӏ=R%@Qπ@ Ӕ@%1aN7Bb΀b B@B@x@A$AjEćdb jaj =jL=j%-(%n@@ r$( @"@B BBJ! B@JB@x@AAJ"EKCeaJ Je#=̤F$ =;I{% "%@D@c A&b  륱' B@aB@x@A$A(Ecb) =jfa"*@X@,c+JļJA#, B@aRB@x@A AR-Euga aR. =R}=&/@x@ yua'B0bcb½1 B@jB@x@A$Aj2Ef1hajfaj3 =j4=%pj%4@7@ 5B3J6 B@JB@)@x@AAJ7E쀈 e8=mFB9 =@{% %:@(@ ! @c  A;bb b < B@`By@x@A$A=Esibb> =jhj`=^%?@f@,@JVJ cA B@aRB@x@A ARBEka aRC =R4'=R"D@"@ tm/4aBEb!b fF B@jBB@x@A$AjGEۀjajH =jހ=j I@݀@~$( @"AJJBKBK B@JB@@x@AAJLEleM=FzN =@{% O@ʗ@ / @ 1lAPb*b ! bcQ B@`B@x@A$ARERma| ^bS =jV="T@U@ m!j$UJTm` RV B@ Bb@x@A ARWE n RaRX =RI=R%Y@@  QQe! HBZbb j[ B@jBB@x@A$Aj\E"ɀ jaj] =j̀=(%p(+c^@ˀ@<_B^BB$ ]L` B@JB@@x@AAJaEoeb=Fw b` gc = ){% "d@ㅀ@ B': @?m !AebEb b f B@aB@x@A$AgE/@p!@cbh =jUq`=j%pj(fi@~ mjJ"J 4b>k B@aRB@x@A ARlE= FaRm =RӾ="n@5@ !! Je=F =r{% "@Ă@ W c 2Ab*b ! 륱 B@aB@x@A$AE={a b =jA="@@@,cJ?JA#Fc B@aRB/@x@A ARE RaR =RO|aR"@~%o""; ]b b j B@jB !h@x@A$AjE", jaj =j=(%p(%@@ BfB$  B@JB@x@AAJEo}bw Je=F =u{% "@p@x AbEb  B@aBx@x@A$AE/+~a,b =j`=^(f@@,J.JA# B@aRB@x@A ARE=aR aR ==R"@U@cS"O 䐃9  -mBbb@&j B@jB; @x@A$AjE]jaj =jPa=j%-(%@`@ B B B@JBW@x@AAJEJJe=ˤF, =6{"@@c Ab  B@aB; @x@A$AEԀb =jaj)%@\@,JȒJA#Fc B@aRB@x@A AREKa aR =RS=FR%@N@ !$F @cSÔ@a~)OQ* bRb½ B@jBc@x@A$AjEejaj =j = @H@$B J B@JBc@x@AAJE e=mՄF =Ȁ{*F"@)Ā@; * bÀb c B@aB @x@A$AEs~bt b =j =^%@k@,J׀JF B@aRB@x@A ARE9aR RaR =RA=%p@<@ S#0+[:+dapHobebj B@jB5n@x@A$AjE jaj =j=j @l@~' @"AJBB B@JB@x@A>Ee=| ={% @>@  Ab !  B@aBc@x@A$AElab =j,`="@+@,J*JA#c B@aRB,@x@A ARE FaRsRI= @@ c3*GE)% GBb b j B@jBc`x@9 Aj @`E"b jaj ==j%p(1@@ Bf B$  B@aB@x@AAJ EZaJ Je =)mF =`{F% +c @[@ B! @W WA bDb B@aBB@x@A$AE/ab =jbր=j^(f@Ԁ@,J.J  B@aRB@x@A ARE {%p!@@ c dVA"b  Zy# B@`B@x@A$A$Eѿb% =ja^"&@S~@ m!j%'J}J ( B@aRB* @x@A AR)E6a aR* =R>=R%+@9@ Sq 3%qea* ,bNb½- B@jB; @x@A$Aj.Ee jaj/ =j=(%p(+c0@N@$1BJ2 B@JBc@x@AAJ3E쭒b Je4=mF|5 =ܳ{% "6@'@ @c /* 7bb b 8 B@aB@x@A$A9Eria1 b: =jn=j%pj%;@rl@,<JkJA#= B@aRBz; @x@A AR>E$RaR? =R,="@@(@ c+qTQ2dUDAbq'b jB B@jB@x@A$AjCE ajD =j= E@S@ rcFB  JG B@JB@c@x@AAJHEeI=j|J =@{% F%K@D@ BLb M B@`B W!L6@x@A$ANEWbO =j5\=^%P@Z@ mcQJJ cR B@aRB@x@A ARSERaRT =R="U@@ s.k[7+gBVbb jW B@jBy@x@A$AjXE΀2 ajY =j#Ҁ=j Z@р@ [BB\ B@JBc@x@AAJ]E!bhe^=)Xy_ ={F `@`@/ ~.Bab ! cb B@aB,@x@A$AcEEabd =`=j^%e@3@,fJJ g B@aRB@x@A ARhEEaRi =RpĀ=R%j@ο@ %1%qkb:b(ol B@jB@x@A$AjmE@ !j @(@BBh  B@JBc@x@AAJE!Je=F ='{% (@#@ B! @ b~"b b륱 B@aB@x@A$AEe݀ ZWUb =jaj$j"@뛀@,JWJ  B@aRB@x@A ARErTaaR =R'\="@W@ caV.%b½) B@Bnb@x@A$Aj*E@Y jaj+ =j^= ,@@ -B!B$ c. B@JBV@x@AAJ/Ed  e0=F; 1 =T{% 2@@ 8B3bb ! c4 B@aBy@x@A$A5Enac!"b6 = /`=^%7@~-@,8J,J ýF `R-9 B@aRB@x@A AR:E F##aR; =R=R%<@@ #6u"Tc)L=bdb j> B@jB@x@A$Aj?Eb j$$aj@ =j=(%-(+cA@U@ wBBµ$ C B@JB@٦B)@x@AAJDE]aJ%%eE=oFVF =@b{% "G@F^@ c 4Hb I B@`B@x@A$AJEa&'bK =j؀=^%L@׀@ m!j%MJ֠JA#N B@aRB@x@A AROEaR F((aRP =RF=R"Q@@ 3le"EfaDRbb#S B@jB@x@A$AjTE!Kj))ajU =jN=(%-`3AV@ @$WBmM JX B@JB@x@AAJYEJ**eZ=)|[ = {% "\@@ ': @, :6A]bCb b ^ B@aB@x@[ =A_ @E.€+,b` =jVa%pj%a@@,bJ%J c B@a B@x@A ARdE<9a --aRe =R@=R"f@4<@ C%EgeBgb;b jh B@jBc@x@A$AjiE j..ajj = J= k@@ƹ$( @"AJlBB Jm B@B@x@AAJnEIb J//eo=ʤFp =5{% F"q@@ B) @6 #Arb ! bcs B@aB@x@A$AtEkA@T00bu =jwp=j^"v@n@,wJDJ@x B@aRB* @x@A ARyEV'R11aRz =R.=R"{@G*@ Sek aiB|b)b } B@jBB@x@A$Aj~E  f22aj =j]=j%p(1@@~BB$  B@JB@x@AAJEd33e=llL6 =T{% "@@! @+c JAbb ! b B@aBc@x@A$AEYa| 44b = ^=%@\@,J_J  B@aRB@x@A AREqaR R55aR =R =R"@e@ c$pBFcBbbĩ B@jBc@x@A$AjE j66aj =jxԀ=(%-(%@Ӏ@ $( @"@BB8B$B B@JB@@x@AAJE77e=Z5n =@o{% "@@  ccAbb ! 륱 B@`B@x@A$AEHa88b =jL=j c@K@ m!j @JzJJF B@aRBB@x@A AREaR F99aR =R: ="@@; TsŮmt̀1Bbbj B@jBc@x@A$AjE j::aj = {€=%-(%@@ rBWBJ$ c B@JB@@x@AAJEz;;e=H|@ =@{% %@{@ * ! @c Ab6b bc B@`B@x@A$AE 6a<=b =jN=j%pj(f@@ mJJA# B@aRB@x@A ARE.aR F>>aR =R="@B@ o"!%  'NZBbbf B@jB @x@A$AjEhaj??aj =j9l=%-%@k@$BjB J B@JB@x@AAJE;$aJ @@e=F =4*{% %@v%@b$F @6 "!b ! b B@aB@@x@A$AE߀ABb =ja$j%@M@,JJA# B@aRB@x@A AREVa CCaR =R^=R"@Y@  % xt ` aABbPb½ B@jB@x@A$AjEVaj jDDaj =j=j @B@~!j @"AJB B$Bc B@JB@x@AAJE JEEe=^FQ =Ӏ{% F"@π@h IAby΀b c B@aB@x@A$AEdbFGb =jI`= @G@@Sf' @J_J J B@aRB@x@A AREqa HHaR =@'=!@@ t%& "aBbbĩ B@B(c@x@A$AjE jIIaj =j=j%-j)w@侀@ BDB B@JB@x@AAJEwb> JJJe=F = 5s}{% %@x@ L6$F @c >Abb! b  B@aB "@x@A$AE3acKLb =j,="@@,cJJ  B@aRBc@x@A AREaR MMaR =R=R"@@P$F%(oEadBbsb½ B@jB @x@A$AjEejNNaj =j*i=j @h@ !j @ūcBgBBcu  JBy@x@AAJE !JOOe=F = €('{"@["@ %NYBb  B@`B "@x@A$AE܀PQb =jڜa$" @:@, JJ  B@aRB@x@A AR ESa RRaR =Rw[=Rc@V@ e$F!e x$4CBb0b½ B@jB @x@A$AjE;jSSaj =j=(%-+c@ @ n!j @ B J$B B@JB !K@x@AAJE TTe=C݄FQ =@Ѐ{%p"@ˀ@ c Ab^b c B@`B !@x@A$AEIbUVb =jtF`=^%@D@ m!j$^J?J  B@aRB/@x@A AR!EV@YA WWaR" =R$R"#@^@ ,|} "l@$b % B@jB@x@A$Aj&EݸjXXaj' =jm=(%-(%(@ʻ@$)B)BJ* B@JB@x@AAJ+Ectbw YYe,=Fc- =Xz{% ".@u@ , /b  0 B@aB@x@A$A1E/acZ[b2 =j=j%pj%3@y@,4JJA#(R5 B@aRB@x@A AR6EaR \\aR7 =R="8@詀@ m n o":abD9bTb jc: B@jB5n@x@A$Aj;E~baj j]]aj< =jf= =@le@rc>BdBB? B@JB@x@AAJ@EaJ$X^^eA=0|/B =#{% F"C@E@c WBDb E B@aB@x@A$AFEـc_`bG =jÙaj H@#@,IJJ >J B@aRB@x@A ARKEPa FaaaRL =R4X=R"M@S@ 5n97867u4u6S"aWsBNbb@$O B@jB$X@x@A$AjPE jbbajQ =j=j R@@ SBd BT B@JB@x@AAJUE cceV=,ڄF$XW =̀{% X@Ȁ@ 5n! @1a0# K BYbCb b Z B@aBc@x@A$A[E-bcdeb\ =jQC`=+c]@A@,^J JA#F_ B@aRBx5n@x@A AR`E; ffaRa = +aR%b@+~c U"++bPBcbbd B@B@x@A$AjeEµ, jggajf =jB=j g@@ $( @"AJhBBi B@JB@x@AAJjEHqbw Jhhek=ɤF~ l =5w{F% m@r@ 5\ @  5Anb ! bo B@aB$X@x@A$ApE,aijbq =j=j^"r@R@,sJJA#(Rt B@aRB@x@A ARuEݣaRFkkaRv =R=R%w@馀@U$4"%aBxbUbjy B@jB@x@A$AjzEc_aj fllaj{ =jb="|@%@~}Ba B$il~ B@JB; @x@AAJEJmme=k-|u = {% @&@ ! @ ~Bbb b B@aB @x@A$AEqրno! =j  ^%@@@Sf'%yJsJ R B@aRB/@x@A ARE~Ma FppaR =@:U="@P@ #T}N"aerBbObĩ B@B@x@A$AjE jqqaj =j =(%-(@ m!jJJ  B@aRB@x@A ARE @YA uuaR =R=G = a@$@ 3zu"‘@z;$bb B@jB@x@A$AjEb jvvaj =j+=j%pj!@@ BB$ c B@JB @x@AAJE-naJ@Yw Jwwe=F5n =t{"@jo@, 0Ab͡j! B@aB@x@A$AE)a xxb =jW.=j%p%@,@,J$JA#rR B@aRB @x@A ARE; RyyaR =R=R(o@S@ 7$F!o" CTD t;aBbb j B@jB* @x@A$AjEzzaj =jJ="@@ !j n"AJB B$B B@JB@c@x@AAJEH\J{{e=P*5n =@8b{% F"@]@ ) @+c )Ab ^! bZ* B@`B,@x@A$AEa|}b =j׀=$j"@Zր@ m!j @JՀJ(R B@aRB@x@A ARE܎B@T~~aR =R=!R"@䑀@ S"u6 @TNBbPb  B@jB@x@A$AjEcJjaj =jM=j%-j+c@S@ BL B$ v B@JBy@x@AAJEaJ ge=k|* = {% "@$@ ! @( Abb^! b B@aB@x@A$AEpV =jaG@ %@@,JcJ dR- B@aRBc@x@A ARE~8a aR =R@@= @;@ 7" @c"& ' (xBb:b½ B@jB @x@A$AjE jaj ==j%-(%@@ !j @r"@BB=B$B B@JB@x@AAJEe=`= ={F% %@ư@ Ab'b ! 륱 B@aB@x@A$AEkaj b =jo=j$j"@&n@,JmJA#= B@aRB@x@A ARE&RaR =R).=R"@)@ cs"t5%hht5gg"`IBb(b j B@jB @x@A$AjE  aj =j=j%-%@@~ƹBh䀃 B$ g B@JB@x@AAJEe=F@ ={:% "v@㞀@ ! @ :AbBb ! bc B@aBc@x@A$AE-Y acb =jY `=j @@,J(J  B@aRB@x@A ARE:Р@Y: %T2 =R׀=FR" @OӀ@ yEYB)"‘ xC v   B   `   @ F B@B `8B @'@x 9 > @@ `@E  @ A =@`=I=H "=  @@3A@@  `@K J!JBB BiJ B@B@B!KJ@x@AAJEHG J@==Y `=z3"<    ! =@ ={F% (?@;@ c 'A@b ! 륱A B@aB "@x@A$ABEbbC = ``Z`=j$j"D@"Y@,EJXJ nF B@B@x@A ARGEaaRH =R3=R"I@@ $F!Ô0" TD"aSBJbb@$K B@jBy @x@A$AjLE͠@Y f//)M =jЀ="N@@!jn"AJOBcπB$BP B@JB@x@AAJQEb JeR='FS ={% F"T@ቀ@ @AUbBb2kT! b V B@aB "@x@A$AWE-DacbX =j``=^"Y@@ `'$^ZJ,J BJ[ B@aRB@x@A AR\E:@Y aR] =@€=R"^@N@1r~Z$F!Rt-%~"d 8B_bb ` B@B @x@A$AjaEvb jajb =jAz=(%-(+cc@y@ r!j @"@BdBB$Be B@JB@٢oB!K@x@AAJfEH2aJ Jeg=ɤFxch =@<8{% "i@3@'$F @6 {4Ajb bck B@`B !@x@A$AlEcbm =jaj$j"n@U@ m!j @oJJ p B@aRB|@x@A ARqEda -)r =Rl="s@g@!R6"t~"+aBtb\b#u B@jB @x@A$8`8صq'!UEdC =@Nַ`=`(f` a&@Հ@@S`6@`@ ^@ݔCJԠJ J `J@ D-F B@B{KwB x  @x@A AREeaR J 8eeAR =@A=R!R@@ `@RK%WARJJ  `JRiR B@B@dR @x@A AREJaRfgAR =RB`=d (r@@ !R"!@BBBBJ B@JBz@-"@'@x@AAJE hheK=Ѐ=`=8>La` 8w  @/`8A =! =ZA`=M!Y!@?@ M @{%BJ'J  ` @ B@a B@x` =B @`E@AR =@`==R#M@C@~#M @!@BB B B@BNB @x@AAJ Eb_Q J NAJ =J3`=J  @@@ >AR JJ J B@RBB$ @x@A AREjabAR =Rm=R"\@l@0 @>JykJJ,2 J B@RB>B%@x@A AREd&RAR =RH)="R@'@@So"!R m+֯BJJ$R B@RBR@x@A ARE AR = {=R,@'@ RR @PK?ALDD B@LB@ 5@AAL @`Erb LAL =@p`=@=L& @@~!L @!BB" B@Bx@x@AAJ#EX`)AJ$ = /b@ J ,%@@U#!J&#A&J+J ' B@B d@x@A AR(EЀ AR) =RҀ=$*@<р@ TAR+J , B@RB R"@x@A AR-E":RAR. =Rm=)6 R/@Ɍ@ R" @1 >ouXAR0J(JR1 B@RB@x@A AR2EGRF3?3 =RI="4@JH@ R%CRK !0WAR5J R6 B@RB@x@A AR7ERAR8 =Rz="R9@@R ";RAR:J6JA#; B@RB@x@A AR<E!j KAR= =R="R>@\@ R   u (4?J @ B@RBR@x@A ARAEy :B =R|="RC@z@ R KPARDJCJA#E B@RB@x@A ARFE.5RARG =R8="RH@k6@K"#Q:ARIJ J B@RB@x@A ARKE ARL =R="RM@@ R  ARNJQJRO B@RBR@x@A ARPE;ARQ =R="DR@y@ R KTGaxgSJؠ%g!K  T B@RB@x@A ARUEgRARV =Rj="W@h@ R "]#KBXJ^J$Y B@RBR@x@A ARZEI# RAR[ =R%=R"\@$@ @SZ5` K |\]F ^ B@NB N@x@AAN_Eހ AN` =@& a!& h-9/(a@@ V!N @ *bBB*c B@B{@*@x@AAJdEU a TAJe =@p8 `=J ,f@@!*%BdAgJJ *h B@B*@x@A ARiÈ ARj = {Kπ=R, 'k@%΀@@S" @  xANlF̀Fm B@NB @x@AANnEq "6ANo =@E`=;#N#p@(@ V!N @ qBD Br B@B@x@AAJsE7AJt =JaJ"q" 7 ,u@A@ "AvJJ Rw B@RB @x@A >xEv  ARy =Rly=# jz@w@ ," @ KUSB fAR{J(J R| B@RB@x@A AR}E2  RAR~ =R4="R@P3@ R  RecbARJ C B@RBR@x@A ARE@Y RAR =R~="R@@  eiv!TAARJ:J$ B@RBR@x@A ARE AR =RL=R<@f@5tZ @\rALD D B@LB@ۢYB* @x@AALEdaL6AL =@p!`='@^@ " B B B@B@x@AAJEۀAJ =J $J ,@k@ "!J\ _/JחJA#Z B@RB+@x@A ARER  =AR =RS= gB@^@~ B B@B@JCI@x@AAIa%E 1I@.A =@UL i j@*T@!V |JSJ NV B@B$BV@x@A AREmaR 8//aR =@I= V0)VaR@@ $ @K #J J F B@B G@x@A AREɠ A@00aR =@̀="R@1ˀ@,JʀJR B@B@x@A AREz 11aR =R=R(@@&DD$ B@LB@x@AALEA L22aL =LB=L'[(@1@ # @ B — B@JB@x@AAJE 34aJ =J a2&@S@ = $ AJJA#R B@RBMmB@x@A AREs a 55aR =Ruv=&O!R@t@ R" @J1J B@RB%@x@A ARE/ R66aR =R1=RD@T0@@Z"!R@  1kBC K B@KB@@x@AAKE 77aK =@pq=%<@@~" <B?B< B@By@J@x@AAJE)bo89aJ =@pWe`=! @c@!%<T|J$JA#< B@B$@x@A ARE7a ::aR =R =R#R@t@ R" @<J < B@RB<@x@A ARE؀ R;;aR =Rۀ="R@ـ@ <R !JZJA#R B@RB @x@A ARED<>aR =R2="R@ @K !J R B@RBR@x@A AREƀH3??aR =Rɀ=<&]`3k@Ȁ@ R  !JxǠJ m K B@RB@x@A ARE_@@aR =R[="@@ R K !JJA# B@RB@x@A ARE=RAAaR =R@="R@!?@K !J>J$R B@RBR@x@A AREmz DBBaR =RM="R@@ R  Ga !J J$R B@RBR@x@A ARECCaR =Rӷ="R@/@ R K !JJ$R B@RBR@x@A AREzpRDDaR =Rr=RFx@q@ @S4 !FF$N B@NB !@x@AANE,NEEaN =@-=N1*@1@ !N @ gB 8* B@B|@*@x@AAJE gFGaJ =@pܥaBq;! 8 @>@ # @ @{'%A JJ * B@By1B '~ @x@A AR E^a HHaR =@րq`="@_@Z" @ B1BB B@B@"9@x@AAJEaJIJaJ =@p؀=J"\@׀@ AJ~֠J  B@B}@x@A ARE)aR KKaR =R=R"\R$@p@@SU7ANF  B@NB N@x@AANELNLLaN =@}N=N#@M@!N @ BLB B@B@x@AAJ!E7aJMNaJ" = ƀ="q! #@Iŀ@$KA$JĠJ % B@B@x@A AR&EDaR OOaR' =R@=<(@@ " @c )JJ* B@RB@x@A AR+E: RPPaR, = {=="R-@J<@ R&R .J;J$R/ B@RB@x@A AR0ER QQaR1 =RN=!"2@@  3J J4 B@RB@x@A AR5Eر!RRaR6 =R$=E7@<@& 8DD$9 B@LB*@x@AAL:E_m"LSSaL; =LRo=''<@n@ " @ =BB> B@JB@x@AAJ?E(#aJTUaJ@ =Jx=J#A@@ %=!JBJDJ oC B@RB@x@A ARDE$aR =VVaRE =Rk=!zF@I@GFF9H B@NB9@x@AANIEz[%NWWaNJ =Nf]=N"`K@\@ LB2BM B@JB[@x@AAJNE&aJXYaJO =JՀ="q" P@Ԁ@$QJoӠJ R B@RB[@x@A ARSE'aR ZZaRT =R= *U@j@ }" @?cVJ W B@RB}@x@A ARXEI(R[[aRY =RL="RZ@J@ R&R[JYJR\ B@RBC@x@A AR]E)R\\aR^ =R=!`3g_@X@ R `J Ra B@RB@x@A ARbE ]]aRc =R€=+d@ @&eDnLf B@LB@x@AALgE)|*^^aLh =L*~=L i@}@ " @ jB Jk B@JB@x@AAJlE7+aJ_`aJm =J=! n@&@$סoxJA#op B@RB@x@A >qE,aR aaaRr =RM==!zs@*@(tFF¡u B@NB,@x@AANvEDj-NbbaNw =Nl=!& /x@|k@ yB Jz B@JB@x@AAJ{E%.aJcdaJ| =Ji= }@@$~J5JA# B@RB&@x@A ARE؜/aR eeaR =R䟀=R1@>@ R" @JJ R B@RB*@x@A ARE_X0RffaR = W[="R@Y@ }JJ$R B@B@x@A ARE1RggaR =R=C"d@5@ R JJ$R B@RB@x@A AREl hhaR =Rр=+@Ѐ@ y`%aDLD$L B@LB@5@x@AALE2iiaL =@pߌ=L'@?@ " @ B B B@B@x@AAJEzF3aJS@sjlaJ =J4`=! @@ " @!JoJ Z B@RB@x@A AREy5aRA@mmaR =@{=="@xz@ " @ B ʁ B@B@@x@AAJE46aJnoA =@p=J"\@w@@S "{HJJR B@B@x@A ARE7aR ppaR =@Ү=R"\R@/@  K JJA# B@B.@x@A ARE)g8RqqaR =R)j="R@h@ R"!R u%rD;J ¥R B@RBR@x@A ARE"9RrraR =R%="R@&$@)*J#J$ B@RB@x@A ARE6 ssaR =R="R@w߀@ R )K@2@ @O@}AJaJ@Z0 B@RB"5B@x@A ARE l~~aR =@Ԁd= j?@Ġ~  B B@B@J50@x@AABba =gC`= @"f@ $VOBVJeJ  V B@NB@x@A AREDaA@,WaR =@"= @ @ $ @O?ARJ@J B@B G@x@A AREۀ RaR = `'ހ="R@܀@R uvARJ R B@B@x@A AREEaR = ="R@ݗ@ R p ^ARJ>J  GF B@>BR@x@A ARE(RFRaR =RU="R@nS@ R%K)$u ARJ  B@RB@x@A ARE GRaR =R="R@@K &q(ARJwJ$ B@RBR@x@A ARE6 KaR =R*̀="R@ʀ@ 0 1TmARJ y  RBR@x@A AREHbz RaR =R="R@@0% 8ARJyJR B@RB@x@A AREC@IaR. R$`: =RSC="R@A@KB 8| JJA# B@RB@x@A AR E@Y RaR =R="R @$@ R  FUBJJ B@RB@x@A AREQJaR =R5="R@@ R +'ARJ R B@RB@x@A ARErKRaR =Ru=&]@3t@K &ARJsJ$ B@RBK@x@A ARE^.LR# %K =Rb1="@/@ R *4ARJJ$R B@RBR@x@A ARE KaR =R="R!@1@ D K #AR"JJ# B@RB@x@A AR$ElMbz RaR% =Rp="R&@ʦ@K u% AR'J,JR( B@RB# ;B6@x@A AR)E`NaR R:#* =Rc="R+@Kb@ u%AR,JaJD- B@RB@x@A AR.EyOR g!R/ =R="R0@@ R K  AR1JIJ$R2 B@RB ~@x@A AR3E؀ aR4 =Rڀ="R5@:ـ@K%I?mAR6J 7 B@RB2! ;R@x@A AR8EPaR9 = pw="D:@ϔ@IC)lAR;J/J$K< B@B$R@x@A AR=E OQRaR> =RuQ=!z?@HP@@S-o)BAN@F A B@NBN@x@AANBE RaN 4EGC =@ǀ=N>D@K@s!N @ EBƀ BF B@B@x@AAJGESaJ*?@saJH =JY.W`=JKI@,@8!Jo~B9טAJJ'J@K B@RB@x@A ARLE@YRA@aRM =@*= R~N@@~ >O B@B I@x@APAPXbaQ =`Y`=$ oR@[_@V "wBVSJ^J VT B@NBq@x@A ARUE^ZaqaRV =R^= V!R W@@@S$ @K<gARXJJ R FY B@RBD @x@A ARZEԀ aR[ =@E؀="R\@ր@ < Wd"AR]JJ$R^ B@B5@x@A AR_Ek[b RaR` =RK="Ra@@   "\bJJG"c B@RBR@x@A ARdEK\RaRe =RN="Rf@1M@ R CYBgJLJ$Rh B@RB@x@A ARiEy]RaRj =R] ="Rk@@ %Fu|IARlJ!J$Rm B@RB5@x@A ARnEà@Y aRo =Rŀ=&]zp@<Ā@5.5 |ARqJ r B@RB5@x@A ARsE~^aRt =R="u@@!NcWARvJFJ$w B@RBK@x@A ARxE :_RaRy =R=="Rz@j;@ # v'{J | B@RBK@x@A AR}E aR~ =R="R@@ KucJ`JR B@RBR@x@A ARE`aR = _="K@@=% l@  A)BA?JJ (R B@B@x@A ARElaRaR =Ro="@m@ ! B EKJ]J$R B@RB@x@A ARE((bRaR =R*=R '@)@'@SpZ`  B&B;AOG G B@OB(@x@A AOENT =@%ca3IA4@@ W%H @ BB B@B@x@AAJEZda A!ʒ@ϙ@ 8AJ =JO Br" = F` 1+! J4@@@ @@̥pAJdJ ~ B@RB{ @x@A AREOWaRA@aR =@I[=D@Z@ c @AKAKCYC B@B@b Ko@x@AAKEKaK =@p=K'#@@ !K @ BVB4 B@B !KJ@x@AAJE\΀E8caJ =Jla&\=@k@ AJjJ  B@RB.@x@A ARE!aRA@aR =@O&=$J@$@k@S" @ }@AK:rAQI7II B@B_ ;@x@A AQE&݀ Q@==|ifj @@ƿ#@F =A;{W@`ހ@ !e~ )g @% @ AГ `AV V$A ViqU^ B@`B E @x@AA E `E % %N@D@$NB  !  vk B@B a! N@x@ABkEc+c =J`=J"BJ)8@@,NJZJ N B@RB@x@A AREAˀ@Y aR =Rπ=R%N@y΀@l@S~Z N )BÌI QN B@QBN@x@A AQEȆbfQaQ = Ӡ=H '#k#@݉@ !Q @"@BB<B B@JB@x@AAJENBaJ (@==T`=- Ex = F{)&"@_E@) @)"qAIDI ! IҦ B@`Bo@g%@x@A AQE8AQ =Q1aQ @@,JJ  B@aRBf@x@A AREta aR = {y=H $-R"@x@""ANeIwI Q B@QB@x@A AQEi0aQ Qd4=c@(A A =@ )3{#4@1@ 4D4)D4IIY4 B@`Bl! @x@A A Ez5&&@4@ B=B! A B@a B@ @x@ABEA,"^ =@pFbJ'@@,AJJA#A B@B@x@A AREbO@TA AR =Rg=R%A@.f@p@S"!0.BIeIaA B@QB` s@x@A AQEaQeA=c A =A;(#{H=f&-!@!@o@S~@! @  AI I $4 I4 B@`Bt !@x@A B E@`E%$A@$@ Y! @$5A B=Mc@A =^{ A@@ @@ [/L@ I2IA B@aB@x@A EA Eb$%A@@ ABz B! A B@a BA@x@AB^EA c =JvaJ"A @u@ b'$/!JltJ IJA" B@RB@x@A AR#EN-a aR$ =@ 2=R%A%@0@!R@~!&I/IA' B@BbA@x@A AQ(E QeA)=dr7A* ={-%-!+@@ " @5!Dw,IqI `I4- B@aBp ,@x@A EA. E$%A/@^@ `@)w@B0BB B1 B@a BA@x@AB2E\cAc3 =Jd`=J#J! 4@c@,A5JbJ RA6 B@RB@x@A AR7Eia aR8 =R% =R#9@@ "!HCMܗB:I IA; B@QB@x@A AQ<Eր QeA==~`> =ۀ{%!?@ـ@ ! @ A@I`IAA B@aB@ 5@A EAB  `E݀$%AC@K@$ADB܀ AE B@B@i &NI@x@ABFEwcA5cG =@pɣ`=J#J%AH@7Ȁ@,IJǠJ AJ B@B|DSRE@x@A ARKEa aRL =RL=R#M@ʃ@! @eANI6I O B@QB@x@A AQPE<QeAQ=N`=R =>{%!S@R=@g@ST AB'@sDwTI AU B@aBh!$4@x@A EAV E@`EXA$%AW@@@ Y&U @$5@BXBBe BY B@BA@x@ABZE c[ =JƷbJ ^\@8@ !J @!]IIQ I^ B@QB$@x@A AQ_EnaD!"aQ` =Q /`=Q$"]a@k-@,bJ,J c B@RB@x@A ARdE ##aRe =R{=R%f@@ @7CgIbI Qh B@QBY@x@A AQiEAbf@Y Q$$fj=*k ={#W!y@@"@T620@bmV n B@aB=V@x@AFo E  & &p@]@ %U @ $B@BqBB ! Br B@a B@x@ABsE\b%&ct =J`=! u@~@,NvJJA#sNw B@RB o@x@A ARxEӀ@Y ''aRy =R؀=#%Nz@ ׀@"N#B{IyրI QN| B@QB o@x@A AQ}E[bf Q((eN~= o ={ N@e@ —$- @% @ K&0 @ >VȑV $A V B@aB N@x@AEN E@`E䗀$%N@A@ @$B@BB B! BN B@B |@x@ABEJbmR A9)AJ =@ڼP@k! @<@,NJJ@N B@B@x@A AREsQ@T AR =R>m`=R%N@x@ N }>IwIQN B@QBN@x@A AQE/a QAQ = Ӡ2=H ck@ @ %"CB1J B@JB !@x@AAJE J`==d-o- A =@]{&"@@ |">I4I ¦ B@`B@x@A AEAQ =Q=H@" @[@ T!Q @6JǨJ  B@aRB@x@A AREaaRAR =R_f=R"@d@"2ß>IFI Q B@QB@x@A AQE-aQAQ =Q =Q%>)o@@@ B B B@JB k@x@AAJE؀@==Fb[ =@wۀ{$"@ـ@ ! @BڿISI I  B@`B>@x@A AQE:b0 @s+ =Q`=G@#@ƀ@ TJSJ  B@aRB1@x@A ARE:aRA@aR =@타=R"@f@ |IҁIɴ B@B@x@A AQE:aQ QaQ =Qi>=Q @=@ # @`AB%BJ B@JB*}@x@AAJEG J@==5R.-  `$- = {H@ -$@@ $- @jI  IҪ B@aB@x@A AQEαaQ[ b =Q=*Q-@ @,JvJA# B@aRB@x@A AREUmRaR =Rr=R%@p@"3ΟIoI Q B@QB\+b@x@A AQE(QaQ =Q,=Q%>*@+@ <BPB B@JB@x@AAJEb e= ={"@t@"II B@aB@x@A AEfL@T71 . "8=֙R u @u7sIg`ud uu(Nu=]U uu7cQu{ q .=nV- \`k2 =g kW7r5=\?[u7_=au7a=\-h$={t kW74=ⲑ] ۀ7ba=hnu70%A[(%KY =ƺ_ b @iĀ@,JàJ ` B@eB@x@A EdE|aRA@,aR =@p=R*@@  IXIQ B@B@x@A AQEC8QaQ =Q;=~ @Y@$B: J B@JB@x@AAJE@==uQ( -].KD-{.{.&@ @!qB\KViV  B@aB E,dr |, `x@9 A^ @EPb0 > B3 =@`=t|`@L^!5^/@@,JCJ@ B@Bd@x@A AR E1}a aR =R͟=:R% @M@+ IIQ B@QB@x@A AQEV~Q;=Gmbs A`DA =[{#$A@W@  ^~$/ @% @dAVTV % V A B@aBA@x@AA  E h]  0@\@ ! @$B@BB$B! Bd B@a B@x@ABE?biN%AJ =J?a@"N@H@,NJJ@N B@RByGB@x@ =AR @`E N&  =R[=R%N@ۼ@+N IGI QN! B@a B[ Q@x@A AQ"E.u@bf # =Qx="$@@@$%Bw B& B@JB@x@AAJ'E0AaJ (=6d-- `D-){6{&*@3@ c% w@F+V,V! Ϻp, B@aB@x@AA-E;Aa)4A. = `[!b ^&/@@,0J*J I1 B@B@x@A AR2Eؠ@Y //AR3 =R܀="4@Lۀ@+5IڀI¤6 B@QB!e@x@A AQ7Ebf Q00`=8=^Bbu9 =㙀{"A:@@ )#AKA;VVA< B@aB@x@AB= E K *Wb*>@@ ! @ $B@B?BB B@ B@a B@x@ABAE*Ob17}B =J?`=J"BJ! C@;>@,NDJ=JA#_NE B@RB@x@A ARFE 88aRG =R="NH@@+NIII Qa>aJ B@QBN@x@A AQKEbf Q99aQL =Qɵ=Q#k#M@(@$NB B$ JO B@JB@@@x@AAJPEmJ::@=Q=L `=R =@q{-&X1uS@n@ $TV;V^9! -NU B@`B@x@AA^VE~{|0W=gJc`@ X7o_0Y=zKu0Z7&)bJx;œ[ =J`u"!J&x\@/@,x]JJAxw>x^ B@b>By T@x@A B>_E &Bœ` =R>Հ=R1Ta@Ӏ@+xbI&I Qxc B@QB0@x@A AQdEbf QCŒe =Q=&xf@@~YhgBq J$ Fh B@JBh@x@AAJiEGaJ JDD@=j=I-Tk =K{%-&xl@H@ x! @%a0qTmV7V! Vxn B@aBx@x@AA^oE"aTEJMPp =^?8Hd@^!5^%q@6@,rJ J@s B@aRB@x@A ARtE@Y KKaRu =R=R%v@+@+wII¤x B@QB@x@A AQyEIbf QLL@=z=ET{ ={#$A|@ū@ A$}V&VA~ B@aB&@x@AD E F  &@@ %b @ $B@BBB! B B@a B@٣Od@x@ABkEfJbMSAJ =@pV e ! @U@ "k"JTJ@ B@BT@x@A AREy a TTaR =R*=!%N@@+NIIaN B@QB@x@A AQEȀ QUUaQ =Q̀=#kQ#@@~Blˀ  B@JB@@x@AAJE VV@==4"Kd- =@戀{ @@ 0! @%! @\0V"V ! VϪ B@`B@x@AA^E @ a W\E = `+u`=^9%@s@ aJrJ  B@B!@x@A ARE+a :]]aR =R0=:R%@*/@+I.IĄ B@QB8T@x@A AQEu Q^^@==  ={#*@@8VV A B@aBs@x@AD E ) @@ %b @ $BG.BB B B@a B@@x@ABkEc_e =@pf@! @ @ NJuJ@N B@B \@x@A AREdJa ffaR =R#O=#%N@M@+NI I QN B@QB@x@A AQEaQ QggaQ =  =Q#kQ*@@~VBZB$ 2 B@B0a@x@AAJEq Jhh =`d- =ǀ{ @}Ā@ !! @VÀV ! VqWT B@aBu@x@AAE3,i"_`w@=={KuOl =WZ`==|ccl&{6 7ib=9`=9$=  @ B.=O`=`A@``@!2@(/ <@ i c @`V <no e> @@@`$ (~ `Q@ @ 2@ @` m!  "@ @ c  !z" "1 W   " @ U<B!`otL ad!jr j@y@Y  @+! !@8`~ @ &T 7 T;`     @] !` mR!c iv   0 V@!s b ` <(`e 'hI`@ASA@E3@Q@@I/A @B@M ; 7@G@1I  @Md @i`D@i"s iYY @(Mu @z i_B@fwupd-1.0.6/plugins/unifying/data/lsusb-U0007-bootloader.txt000066400000000000000000000034761325145456600236440ustar00rootroot00000000000000Bus 001 Device 036: ID 046d:aaaa Logitech, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x046d Logitech, Inc. idProduct 0xaaaa bcdDevice 1.02 iManufacturer 1 iProduct 2 iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 4 bmAttributes 0x80 (Bus Powered) MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 25 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 1 fwupd-1.0.6/plugins/unifying/data/lsusb-U0007.txt000066400000000000000000000101341325145456600215010ustar00rootroot00000000000000Bus 001 Device 049: ID 046d:c52b Logitech, Inc. Unifying Receiver Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x046d Logitech, Inc. idProduct 0xc52b Unifying Receiver bcdDevice 12.07 iManufacturer 1 Logitech iProduct 2 USB Receiver iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 84 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 4 RQR12.07_B0029 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 59 Report Descriptor: (length is 59) Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 2 Mouse iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 148 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 93 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 2 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/unifying/data/lsusb-U0008-bootloader-old.txt000066400000000000000000000057551325145456600244230ustar00rootroot00000000000000 Bus 003 Device 036: ID 046d:aaac Logitech, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x046d Logitech, Inc. idProduct 0xaaac bcdDevice 3.01 iManufacturer 1 Logitech iProduct 2 USB BootLoader iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 4 BOT03.01_B0008 bmAttributes 0x80 (Bus Powered) MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 25 Report Descriptor: (length is 25) Item(Global): Usage Page, data= [ 0xb0 0xff ] 65456 (null) Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x20 ] 32 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 1 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/unifying/data/lsusb-U0008-bootloader.txt000066400000000000000000000057551325145456600236470ustar00rootroot00000000000000 Bus 003 Device 039: ID 046d:aaac Logitech, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x046d Logitech, Inc. idProduct 0xaaac bcdDevice 3.00 iManufacturer 1 Logitech iProduct 2 USB BootLoader iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 34 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 4 BOT03.00_B0006 bmAttributes 0x80 (Bus Powered) MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 25 Report Descriptor: (length is 25) Item(Global): Usage Page, data= [ 0xb0 0xff ] 65456 (null) Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x20 ] 32 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 1 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/unifying/data/lsusb-U0008-old.txt000066400000000000000000000426521325145456600222700ustar00rootroot00000000000000 Bus 003 Device 033: ID 046d:c52b Logitech, Inc. Unifying Receiver Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x046d Logitech, Inc. idProduct 0xc52b Unifying Receiver bcdDevice 24.01 iManufacturer 1 Logitech iProduct 2 USB Receiver iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 84 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 4 RQR24.01_B0023 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 59 Report Descriptor: (length is 59) Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x06 ] 6 Keyboard Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Usage Page, data= [ 0x07 ] 7 Keyboard Item(Local ): Usage Minimum, data= [ 0xe0 ] 224 Control Left Item(Local ): Usage Maximum, data= [ 0xe7 ] 231 GUI Right Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0x01 ] 1 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x08 ] 8 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x05 ] 5 Item(Global): Usage Page, data= [ 0x08 ] 8 LEDs Item(Local ): Usage Minimum, data= [ 0x01 ] 1 NumLock Item(Local ): Usage Maximum, data= [ 0x05 ] 5 Kana Item(Main ): Output, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x01 ] 1 Item(Global): Report Size, data= [ 0x03 ] 3 Item(Main ): Output, data= [ 0x01 ] 1 Constant Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x06 ] 6 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xa4 0x00 ] 164 Item(Global): Usage Page, data= [ 0x07 ] 7 Keyboard Item(Local ): Usage Minimum, data= [ 0x00 ] 0 No Event Item(Local ): Usage Maximum, data= [ 0xa4 0x00 ] 164 ExSel Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 2 Mouse iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 148 Report Descriptor: (length is 148) Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x02 ] 2 Mouse Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x02 ] 2 Item(Local ): Usage, data= [ 0x01 ] 1 Pointer Item(Main ): Collection, data= [ 0x00 ] 0 Physical Item(Global): Usage Page, data= [ 0x09 ] 9 Buttons Item(Local ): Usage Minimum, data= [ 0x01 ] 1 Button 1 (Primary) Item(Local ): Usage Maximum, data= [ 0x10 ] 16 (null) Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x10 ] 16 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Global): Logical Minimum, data= [ 0x01 0xf8 ] 63489 Item(Global): Logical Maximum, data= [ 0xff 0x07 ] 2047 Item(Global): Report Size, data= [ 0x0c ] 12 Item(Global): Report Count, data= [ 0x02 ] 2 Item(Local ): Usage, data= [ 0x30 ] 48 Direction-X Item(Local ): Usage, data= [ 0x31 ] 49 Direction-Y Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Logical Minimum, data= [ 0x81 ] 129 Item(Global): Logical Maximum, data= [ 0x7f ] 127 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Local ): Usage, data= [ 0x38 ] 56 Wheel Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0x0c ] 12 Consumer Item(Local ): Usage, data= [ 0x38 0x02 ] 568 AC Pan Item(Global): Report Count, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x0c ] 12 Consumer Item(Local ): Usage, data= [ 0x01 ] 1 Consumer Control Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x03 ] 3 Item(Global): Report Size, data= [ 0x10 ] 16 Item(Global): Report Count, data= [ 0x02 ] 2 Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0x8c 0x02 ] 652 Item(Local ): Usage Minimum, data= [ 0x01 ] 1 Consumer Control Item(Local ): Usage Maximum, data= [ 0x8c 0x02 ] 652 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x80 ] 128 System Control Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x04 ] 4 Item(Global): Report Size, data= [ 0x02 ] 2 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0x03 ] 3 Item(Local ): Usage, data= [ 0x82 ] 130 System Sleep Item(Local ): Usage, data= [ 0x81 ] 129 System Power Down Item(Local ): Usage, data= [ 0x83 ] 131 System Wake Up Item(Main ): Input, data= [ 0x60 ] 96 Data Array Absolute No_Wrap Linear No_Preferred_State Null_State Non_Volatile Bitfield Item(Global): Report Size, data= [ 0x06 ] 6 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0xbc 0xff ] 65468 (null) Item(Local ): Usage, data= [ 0x88 ] 136 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x08 ] 8 Item(Local ): Usage Minimum, data= [ 0x01 ] 1 (null) Item(Local ): Usage Maximum, data= [ 0xff ] 255 (null) Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 98 Report Descriptor: (length is 98) Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x10 ] 16 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x06 ] 6 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x11 ] 17 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x13 ] 19 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x04 ] 4 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x20 ] 32 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x0e ] 14 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x41 ] 65 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x41 ] 65 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x21 ] 33 Item(Global): Report Count, data= [ 0x1f ] 31 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x42 ] 66 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x42 ] 66 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 2 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/unifying/data/lsusb-U0008.txt000066400000000000000000000426511325145456600215130ustar00rootroot00000000000000Bus 003 Device 032: ID 046d:c52b Logitech, Inc. Unifying Receiver Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x046d Logitech, Inc. idProduct 0xc52b Unifying Receiver bcdDevice 24.05 iManufacturer 1 Logitech iProduct 2 USB Receiver iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 84 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 4 RQR24.05_B0029 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 98mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 59 Report Descriptor: (length is 59) Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x06 ] 6 Keyboard Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Usage Page, data= [ 0x07 ] 7 Keyboard Item(Local ): Usage Minimum, data= [ 0xe0 ] 224 Control Left Item(Local ): Usage Maximum, data= [ 0xe7 ] 231 GUI Right Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0x01 ] 1 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x08 ] 8 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x05 ] 5 Item(Global): Usage Page, data= [ 0x08 ] 8 LEDs Item(Local ): Usage Minimum, data= [ 0x01 ] 1 NumLock Item(Local ): Usage Maximum, data= [ 0x05 ] 5 Kana Item(Main ): Output, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x01 ] 1 Item(Global): Report Size, data= [ 0x03 ] 3 Item(Main ): Output, data= [ 0x01 ] 1 Constant Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x06 ] 6 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xa4 0x00 ] 164 Item(Global): Usage Page, data= [ 0x07 ] 7 Keyboard Item(Local ): Usage Minimum, data= [ 0x00 ] 0 No Event Item(Local ): Usage Maximum, data= [ 0xa4 0x00 ] 164 ExSel Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 2 Mouse iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 148 Report Descriptor: (length is 148) Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x02 ] 2 Mouse Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x02 ] 2 Item(Local ): Usage, data= [ 0x01 ] 1 Pointer Item(Main ): Collection, data= [ 0x00 ] 0 Physical Item(Global): Usage Page, data= [ 0x09 ] 9 Buttons Item(Local ): Usage Minimum, data= [ 0x01 ] 1 Button 1 (Primary) Item(Local ): Usage Maximum, data= [ 0x10 ] 16 (null) Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x10 ] 16 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Global): Logical Minimum, data= [ 0x01 0xf8 ] 63489 Item(Global): Logical Maximum, data= [ 0xff 0x07 ] 2047 Item(Global): Report Size, data= [ 0x0c ] 12 Item(Global): Report Count, data= [ 0x02 ] 2 Item(Local ): Usage, data= [ 0x30 ] 48 Direction-X Item(Local ): Usage, data= [ 0x31 ] 49 Direction-Y Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Logical Minimum, data= [ 0x81 ] 129 Item(Global): Logical Maximum, data= [ 0x7f ] 127 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Local ): Usage, data= [ 0x38 ] 56 Wheel Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0x0c ] 12 Consumer Item(Local ): Usage, data= [ 0x38 0x02 ] 568 AC Pan Item(Global): Report Count, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x0c ] 12 Consumer Item(Local ): Usage, data= [ 0x01 ] 1 Consumer Control Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x03 ] 3 Item(Global): Report Size, data= [ 0x10 ] 16 Item(Global): Report Count, data= [ 0x02 ] 2 Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0x8c 0x02 ] 652 Item(Local ): Usage Minimum, data= [ 0x01 ] 1 Consumer Control Item(Local ): Usage Maximum, data= [ 0x8c 0x02 ] 652 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x01 ] 1 Generic Desktop Controls Item(Local ): Usage, data= [ 0x80 ] 128 System Control Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x04 ] 4 Item(Global): Report Size, data= [ 0x02 ] 2 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0x03 ] 3 Item(Local ): Usage, data= [ 0x82 ] 130 System Sleep Item(Local ): Usage, data= [ 0x81 ] 129 System Power Down Item(Local ): Usage, data= [ 0x83 ] 131 System Wake Up Item(Main ): Input, data= [ 0x60 ] 96 Data Array Absolute No_Wrap Linear No_Preferred_State Null_State Non_Volatile Bitfield Item(Global): Report Size, data= [ 0x06 ] 6 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0xbc 0xff ] 65468 (null) Item(Local ): Usage, data= [ 0x88 ] 136 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x08 ] 8 Item(Local ): Usage Minimum, data= [ 0x01 ] 1 (null) Item(Local ): Usage Maximum, data= [ 0xff ] 255 (null) Item(Global): Logical Minimum, data= [ 0x01 ] 1 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0008 1x 8 bytes bInterval 2 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 98 Report Descriptor: (length is 98) Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x10 ] 16 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x06 ] 6 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x01 ] 1 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x11 ] 17 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x13 ] 19 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x02 ] 2 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 (null) Item(Local ): Usage, data= [ 0x04 ] 4 (null) Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x20 ] 32 Item(Global): Report Size, data= [ 0x08 ] 8 Item(Global): Report Count, data= [ 0x0e ] 14 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x41 ] 65 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x41 ] 65 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x21 ] 33 Item(Global): Report Count, data= [ 0x1f ] 31 Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 Item(Local ): Usage, data= [ 0x42 ] 66 (null) Item(Main ): Input, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x42 ] 66 (null) Item(Main ): Output, data= [ 0x00 ] 0 Data Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 2 Device Status: 0x0000 (Bus Powered) fwupd-1.0.6/plugins/unifying/fu-plugin-unifying.c000066400000000000000000000154561325145456600221020ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" #include "lu-context.h" #include "lu-device.h" #include "lu-device-peripheral.h" struct FuPluginData { LuContext *ctx; }; static gboolean fu_plugin_unifying_device_added (FuPlugin *plugin, LuDevice *device, GError **error) { g_autoptr(AsProfile) profile = as_profile_new (); g_autoptr(AsProfileTask) ptask = NULL; /* profile */ ptask = as_profile_start (profile, "FuPluginLu:added{%s}", fu_device_get_platform_id (FU_DEVICE (device))); g_assert (ptask != NULL); /* open the device */ if (!lu_device_open (device, error)) return FALSE; /* insert to hash */ fu_plugin_device_add (plugin, FU_DEVICE (device)); return TRUE; } static gboolean fu_plugin_unifying_detach_cb (gpointer user_data) { LuDevice *device = LU_DEVICE (user_data); g_autoptr(GError) error = NULL; /* ditch this device */ g_debug ("detaching"); if (!lu_device_detach (device, &error)) { g_warning ("failed to detach: %s", error->message); return FALSE; } return FALSE; } static gboolean fu_plugin_unifying_attach_cb (gpointer user_data) { LuDevice *device = LU_DEVICE (user_data); g_autoptr(GError) error = NULL; /* ditch this device */ g_debug ("attaching"); if (!lu_device_attach (device, &error)) { g_warning ("failed to detach: %s", error->message); return FALSE; } return FALSE; } gboolean fu_plugin_update_detach (FuPlugin *plugin, FuDevice *dev, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); LuDevice *device = LU_DEVICE (dev); /* get device */ if (!lu_device_open (device, error)) return FALSE; /* switch to bootloader if required */ if (!lu_device_has_flag (device, LU_DEVICE_FLAG_REQUIRES_DETACH)) return TRUE; /* wait for device to come back */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); if (lu_device_has_flag (device, LU_DEVICE_FLAG_DETACH_WILL_REPLUG)) { g_debug ("doing detach in idle"); g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, fu_plugin_unifying_detach_cb, g_object_ref (device), (GDestroyNotify) g_object_unref); if (!lu_context_wait_for_replug (data->ctx, device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; } else { g_debug ("doing detach in main thread"); if (!lu_device_detach (device, error)) return FALSE; } return TRUE; } gboolean fu_plugin_update_attach (FuPlugin *plugin, FuDevice *dev, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); LuDevice *device = LU_DEVICE (dev); /* get device */ if (!lu_device_open (device, error)) return FALSE; /* wait for it to appear back in runtime mode if required */ if (!lu_device_has_flag (device, LU_DEVICE_FLAG_REQUIRES_ATTACH)) return TRUE; /* wait for device to come back */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_RESTART); if (lu_device_has_flag (device, LU_DEVICE_FLAG_ATTACH_WILL_REPLUG)) { g_debug ("doing attach in idle"); g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, fu_plugin_unifying_attach_cb, g_object_ref (device), (GDestroyNotify) g_object_unref); if (!lu_context_wait_for_replug (data->ctx, device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; } else { g_debug ("doing attach in main thread"); if (!lu_device_attach (device, error)) return FALSE; } return TRUE; } gboolean fu_plugin_update_reload (FuPlugin *plugin, FuDevice *dev, GError **error) { LuDevice *device = LU_DEVICE (dev); /* get device */ if (!lu_device_open (device, error)) return FALSE; return TRUE; } gboolean fu_plugin_update (FuPlugin *plugin, FuDevice *dev, GBytes *blob_fw, FwupdInstallFlags flags, GError **error) { LuDevice *device = LU_DEVICE (dev); /* get version */ if (!lu_device_open (device, error)) return FALSE; /* write the firmware */ fu_device_set_status (dev, FWUPD_STATUS_DEVICE_WRITE); if (!lu_device_write_firmware (device, blob_fw, error)) return FALSE; /* success */ return TRUE; } static void fu_plugin_unifying_device_added_cb (LuContext *ctx, LuDevice *device, FuPlugin *plugin) { g_autoptr(GError) error = NULL; /* add */ if (!fu_plugin_unifying_device_added (plugin, device, &error)) { if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { g_debug ("Failed to add Logitech device: %s", error->message); } else { g_warning ("Failed to add Logitech device: %s", error->message); } } } static void fu_plugin_unifying_device_removed_cb (LuContext *ctx, LuDevice *device, FuPlugin *plugin) { fu_plugin_device_remove (plugin, FU_DEVICE (device)); } gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); /* check the kernel has CONFIG_HIDRAW */ if (!g_file_test ("/sys/class/hidraw", G_FILE_TEST_IS_DIR)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no kernel support for CONFIG_HIDRAW"); return FALSE; } /* coldplug */ g_signal_connect (data->ctx, "added", G_CALLBACK (fu_plugin_unifying_device_added_cb), plugin); g_signal_connect (data->ctx, "removed", G_CALLBACK (fu_plugin_unifying_device_removed_cb), plugin); lu_context_set_supported (data->ctx, fu_plugin_get_supported (plugin)); return TRUE; } gboolean fu_plugin_coldplug (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); lu_context_coldplug (data->ctx); lu_context_set_poll_interval (data->ctx, 5000); return TRUE; } void fu_plugin_init (FuPlugin *plugin) { FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); GUsbContext *usb_ctx = fu_plugin_get_usb_context (plugin); data->ctx = lu_context_new_full (usb_ctx); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); g_object_unref (data->ctx); } fwupd-1.0.6/plugins/unifying/lu-common.c000066400000000000000000000120061325145456600202400ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include "lu-common.h" guint8 lu_buffer_read_uint8 (const gchar *str) { guint64 tmp; gchar buf[3] = { 0x0, 0x0, 0x0 }; memcpy (buf, str, 2); tmp = g_ascii_strtoull (buf, NULL, 16); return tmp; } guint16 lu_buffer_read_uint16 (const gchar *str) { guint64 tmp; gchar buf[5] = { 0x0, 0x0, 0x0, 0x0, 0x0 }; memcpy (buf, str, 4); tmp = g_ascii_strtoull (buf, NULL, 16); return tmp; } void lu_dump_raw (const gchar *title, const guint8 *data, gsize len) { g_autoptr(GString) str = g_string_new (NULL); if (len == 0) return; g_string_append_printf (str, "%s:", title); for (gsize i = strlen (title); i < 16; i++) g_string_append (str, " "); for (gsize i = 0; i < len; i++) { g_string_append_printf (str, "%02x ", data[i]); if (i > 0 && i % 32 == 0) g_string_append (str, "\n"); } g_debug ("%s", str->str); } gchar * lu_format_version (const gchar *name, guint8 major, guint8 minor, guint16 build) { GString *str = g_string_new (NULL); for (guint i = 0; i < 3; i++) { if (g_ascii_isspace (name[i])) continue; g_string_append_c (str, name[i]); } g_string_append_printf (str, "%02x.%02x_B%04x", major, minor, build); return g_string_free (str, FALSE); } static gboolean lu_nonblock_flush (gint fd, GError **error) { GPollFD poll[] = { { .fd = fd, .events = G_IO_IN | G_IO_OUT | G_IO_ERR, }, }; while (g_poll (poll, G_N_ELEMENTS(poll), 0) > 0) { gchar c; gint r = read (fd, &c, 1); if (r < 0 && errno != EINTR) break; } return TRUE; } gboolean lu_nonblock_write (gint fd, const guint8 *data, gsize data_sz, GError **error) { gssize wrote; /* sanity check */ if (fd == 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write: fd is not open"); return FALSE; } /* flush pending reads */ if (!lu_nonblock_flush (fd, error)) return FALSE; /* write */ wrote = write (fd, data, data_sz); if (wrote != (gssize) data_sz) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write: " "wrote %" G_GSSIZE_FORMAT " of %" G_GSIZE_FORMAT, wrote, data_sz); return FALSE; } return TRUE; } gboolean lu_nonblock_read (gint fd, guint8 *data, gsize data_sz, gsize *data_len, guint timeout, GError **error) { gssize len = 0; gint64 ts_start; GPollFD poll[] = { { .fd = fd, .events = G_IO_IN | G_IO_OUT | G_IO_ERR, }, }; /* sanity check */ if (fd == 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to read: fd is not open"); return FALSE; } /* do a read with a timeout */ ts_start = g_get_monotonic_time (); while (1) { gint rc; gint ts_remain = ((g_get_monotonic_time () - ts_start) / 1000) + timeout; if (ts_remain <= 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "timeout already passed"); return FALSE; } /* waits for the fd to become ready */ rc = g_poll (poll, G_N_ELEMENTS (poll), ts_remain); if (rc < 0) { if (errno == EINTR) continue; g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "read interrupted: %s", g_strerror (errno)); return FALSE; } else if (rc == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "timeout"); return FALSE; } /* read data from fd */ len = read (fd, data, data_sz); if (len <= 0) { if (len == -1 && errno == EINTR) continue; g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to read data: %s", g_strerror (errno)); return FALSE; } /* success */ break; }; /* success */ if (data_len != NULL) *data_len = (gsize) len; return TRUE; } gint lu_nonblock_open (const gchar *filename, GError **error) { gint fd; fd = open (filename, O_RDWR | O_NONBLOCK); if (fd < 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to open %s", filename); return -1; } return fd; } fwupd-1.0.6/plugins/unifying/lu-common.h000066400000000000000000000033201325145456600202440ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_COMMON_H #define __LU_COMMON_H #include G_BEGIN_DECLS void lu_dump_raw (const gchar *title, const guint8 *data, gsize len); guint8 lu_buffer_read_uint8 (const gchar *str); guint16 lu_buffer_read_uint16 (const gchar *str); gchar *lu_format_version (const gchar *name, guint8 major, guint8 minor, guint16 build); gint lu_nonblock_open (const gchar *filename, GError **error); gboolean lu_nonblock_read (gint fd, guint8 *data, gsize data_sz, gsize *data_len, guint timeout, GError **error); gboolean lu_nonblock_write (gint fd, const guint8 *data, gsize data_sz, GError **error); G_END_DECLS #endif /* __LU_COMMON_H */ fwupd-1.0.6/plugins/unifying/lu-context.c000066400000000000000000000461301325145456600204410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "lu-common.h" #include "lu-context.h" #include "lu-device-bootloader-nordic.h" #include "lu-device-bootloader-texas.h" #include "lu-device-peripheral.h" #include "lu-device-runtime.h" #include "lu-hidpp.h" struct _LuContext { GObject parent_instance; GPtrArray *supported_guids; GPtrArray *devices; GHashTable *devices_active; /* LuDevice : 1 */ GUsbContext *usb_ctx; GUdevClient *gudev_client; GHashTable *hash_replug; gboolean done_coldplug; GHashTable *hash_devices; guint poll_id; }; G_DEFINE_TYPE (LuContext, lu_context, G_TYPE_OBJECT) enum { PROP_0, PROP_USB_CONTEXT, PROP_LAST }; enum { SIGNAL_ADDED, SIGNAL_REMOVED, SIGNAL_LAST }; static guint signals [SIGNAL_LAST] = { 0 }; typedef struct { GMainLoop *loop; LuDevice *device; guint timeout_id; } GUsbContextReplugHelper; GPtrArray * lu_context_get_devices (LuContext *ctx) { /* ensure we have devices */ if (!ctx->done_coldplug) lu_context_coldplug (ctx); return ctx->devices; } static gboolean lu_context_check_supported (LuContext *ctx, const gchar *guid) { if (ctx->supported_guids == NULL) { g_debug ("no list of supported GUIDs so assuming supported"); return TRUE; } for (guint i = 0; i < ctx->supported_guids->len; i++) { const gchar *guid_tmp = g_ptr_array_index (ctx->supported_guids, i); if (g_strcmp0 (guid, guid_tmp) == 0) return TRUE; } return FALSE; } void lu_context_set_supported (LuContext *ctx, GPtrArray *supported_guids) { if (ctx->supported_guids != NULL) g_ptr_array_unref (ctx->supported_guids); ctx->supported_guids = g_ptr_array_ref (supported_guids); } static void lu_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { LuContext *ctx = LU_CONTEXT (object); switch (prop_id) { case PROP_USB_CONTEXT: g_value_set_object (value, ctx->usb_ctx); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void lu_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { LuContext *ctx = LU_CONTEXT (object); switch (prop_id) { case PROP_USB_CONTEXT: ctx->usb_ctx = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void lu_context_finalize (GObject *object) { LuContext *ctx = LU_CONTEXT (object); if (ctx->poll_id != 0) g_source_remove (ctx->poll_id); if (ctx->supported_guids != NULL) g_ptr_array_unref (ctx->supported_guids); g_ptr_array_unref (ctx->devices); g_hash_table_unref (ctx->devices_active); g_object_unref (ctx->usb_ctx); g_object_unref (ctx->gudev_client); g_hash_table_unref (ctx->hash_devices); g_hash_table_unref (ctx->hash_replug); G_OBJECT_CLASS (lu_context_parent_class)->finalize (object); } static void lu_context_class_init (LuContextClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = lu_context_finalize; object_class->get_property = lu_device_get_property; object_class->set_property = lu_device_set_property; pspec = g_param_spec_object ("usb-context", NULL, NULL, G_USB_TYPE_CONTEXT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_USB_CONTEXT, pspec); signals [SIGNAL_ADDED] = g_signal_new ("added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, LU_TYPE_DEVICE); signals [SIGNAL_REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, LU_TYPE_DEVICE); } static void lu_context_device_flags_notify_cb (GObject *obj, GParamSpec *pspec, LuContext *ctx) { LuDevice *device = LU_DEVICE (obj); if (g_hash_table_lookup (ctx->devices_active, device) != NULL) { if (!lu_device_has_flag (device, LU_DEVICE_FLAG_ACTIVE)) { g_debug ("existing device now inactive, sending signal"); g_signal_emit (ctx, signals[SIGNAL_REMOVED], 0, device); g_hash_table_remove (ctx->devices_active, device); } } else { if (lu_device_has_flag (device, LU_DEVICE_FLAG_ACTIVE)) { g_debug ("existing device now active, sending signal"); g_signal_emit (ctx, signals[SIGNAL_ADDED], 0, device); g_hash_table_insert (ctx->devices_active, device, GINT_TO_POINTER (1)); } } } static void lu_context_add_device (LuContext *ctx, LuDevice *device) { GUsbContextReplugHelper *replug_helper; g_autoptr(GError) error = NULL; g_return_if_fail (LU_IS_CONTEXT (ctx)); g_return_if_fail (LU_IS_DEVICE (device)); g_debug ("device %s added", fu_device_get_platform_id (FU_DEVICE (device))); /* HID++1.0 devices have to sleep to allow Solaar to talk to the device * first -- we can't use the SwID as this is a HID++2.0 feature */ if (ctx->done_coldplug && lu_device_get_hidpp_version (device) <= 1.f) { g_debug ("waiting for device to settle..."); g_usleep (G_USEC_PER_SEC); } /* try to open */ if (!lu_device_open (device, &error)) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE)) { g_debug ("could not open: %s", error->message); } else { g_warning ("failed to open: %s", error->message); } return; } /* emit */ g_ptr_array_add (ctx->devices, g_object_ref (device)); if (lu_device_has_flag (device, LU_DEVICE_FLAG_ACTIVE)) { g_signal_emit (ctx, signals[SIGNAL_ADDED], 0, device); g_hash_table_insert (ctx->devices_active, device, GINT_TO_POINTER (1)); } g_signal_connect (device, "notify::flags", G_CALLBACK (lu_context_device_flags_notify_cb), ctx); /* if we're waiting for replug, quit the loop */ replug_helper = g_hash_table_lookup (ctx->hash_replug, fu_device_get_platform_id (FU_DEVICE (device))); if (replug_helper != NULL) { g_debug ("%s is in replug, quitting loop", fu_device_get_platform_id (FU_DEVICE (device))); g_main_loop_quit (replug_helper->loop); } } static void lu_context_remove_device (LuContext *ctx, LuDevice *device) { g_return_if_fail (LU_IS_CONTEXT (ctx)); g_return_if_fail (LU_IS_DEVICE (device)); g_debug ("device %s removed", fu_device_get_platform_id (FU_DEVICE (device))); /* no longer valid */ g_object_set (device, "usb-device", NULL, "udev-device", NULL, NULL); if (lu_device_has_flag (device, LU_DEVICE_FLAG_ACTIVE)) g_signal_emit (ctx, signals[SIGNAL_REMOVED], 0, device); g_ptr_array_remove (ctx->devices, device); } #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) #endif static const gchar * lu_context_get_platform_id_for_udev_device (GUdevDevice *udev_device) { g_autoptr(GUdevDevice) udev_device1 = NULL; udev_device1 = g_udev_device_get_parent_with_subsystem (udev_device, "usb", "usb_device"); if (udev_device1 == NULL) return NULL; return g_udev_device_get_sysfs_path (udev_device1); } static void lu_context_add_udev_device (LuContext *ctx, GUdevDevice *udev_device) { const gchar *val; const gchar *platform_id; guint16 pid; guint16 vid; g_autofree gchar *devid = NULL; g_autoptr(GUdevDevice) udev_parent = NULL; g_autoptr(LuDevice) device = NULL; g_return_if_fail (LU_IS_CONTEXT (ctx)); g_debug ("UDEV add %s = %s", g_udev_device_get_device_file (udev_device), g_udev_device_get_sysfs_path (udev_device)); /* check the vid:pid from property HID_ID=0003:0000046D:0000C52B */ udev_parent = g_udev_device_get_parent (udev_device); val = g_udev_device_get_property (udev_parent, "HID_ID"); if (val == NULL) { g_debug ("no HID_ID, skipping"); return; } if (strlen (val) != 22) { g_warning ("property HID_ID invalid '%s', skipping", val); return; } /* is logitech */ vid = lu_buffer_read_uint16 (val + 10); if (vid != LU_DEVICE_VID) { g_debug ("not a matching vid: %04x", vid); return; } /* is unifying runtime */ pid = lu_buffer_read_uint16 (val + 18); if (pid == LU_DEVICE_PID_RUNTIME) { platform_id = lu_context_get_platform_id_for_udev_device (udev_device); device = g_object_new (LU_TYPE_DEVICE_RUNTIME, "kind", LU_DEVICE_KIND_RUNTIME, "flags", LU_DEVICE_FLAG_ACTIVE | LU_DEVICE_FLAG_REQUIRES_DETACH | LU_DEVICE_FLAG_DETACH_WILL_REPLUG, "platform-id", platform_id, "udev-device", udev_device, "hidpp-id", HIDPP_DEVICE_ID_RECEIVER, NULL); g_hash_table_insert (ctx->hash_devices, g_strdup (fu_device_get_platform_id (FU_DEVICE (device))), g_object_ref (device)); lu_context_add_device (ctx, device); return; } /* is unifying bootloader */ if (pid == LU_DEVICE_PID_BOOTLOADER_NORDIC || pid == LU_DEVICE_PID_BOOTLOADER_NORDIC_PICO || pid == LU_DEVICE_PID_BOOTLOADER_TEXAS || pid == LU_DEVICE_PID_BOOTLOADER_TEXAS_PICO) { g_debug ("ignoring bootloader in HID mode"); return; } /* is peripheral */ platform_id = g_udev_device_get_sysfs_path (udev_device); device = g_object_new (LU_TYPE_DEVICE_PERIPHERAL, "kind", LU_DEVICE_KIND_PERIPHERAL, "platform-id", platform_id, "udev-device", udev_device, NULL); val = g_udev_device_get_property (udev_parent, "HID_NAME"); if (val != NULL) { if (g_str_has_prefix (val, "Logitech ")) val += 9; fu_device_set_name (FU_DEVICE (device), val); } /* generate GUID */ devid = g_strdup_printf ("UFY\\VID_%04X&PID_%04X", vid, pid); fu_device_add_guid (FU_DEVICE (device), devid); if (!lu_context_check_supported (ctx, fu_device_get_guid_default (FU_DEVICE (device)))) { g_debug ("%s not supported, so ignoring device", devid); return; } g_hash_table_insert (ctx->hash_devices, g_strdup (fu_device_get_platform_id (FU_DEVICE (device))), g_object_ref (device)); lu_context_add_device (ctx, device); } static gboolean g_usb_context_replug_timeout_cb (gpointer user_data) { GUsbContextReplugHelper *replug_helper = (GUsbContextReplugHelper *) user_data; replug_helper->timeout_id = 0; g_main_loop_quit (replug_helper->loop); return FALSE; } static void g_usb_context_replug_helper_free (GUsbContextReplugHelper *replug_helper) { if (replug_helper->timeout_id != 0) g_source_remove (replug_helper->timeout_id); g_main_loop_unref (replug_helper->loop); g_object_unref (replug_helper->device); g_free (replug_helper); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUsbContextReplugHelper, g_usb_context_replug_helper_free); gboolean lu_context_wait_for_replug (LuContext *ctx, LuDevice *device, guint timeout_ms, GError **error) { g_autoptr(GUsbContextReplugHelper) replug_helper = NULL; const gchar *platform_id; g_return_val_if_fail (LU_IS_CONTEXT (ctx), FALSE); g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); /* create a helper */ replug_helper = g_new0 (GUsbContextReplugHelper, 1); replug_helper->device = g_object_ref (device); replug_helper->loop = g_main_loop_new (NULL, FALSE); replug_helper->timeout_id = g_timeout_add (timeout_ms, g_usb_context_replug_timeout_cb, replug_helper); /* register */ platform_id = fu_device_get_platform_id (FU_DEVICE (device)); g_hash_table_insert (ctx->hash_replug, g_strdup (platform_id), replug_helper); /* wait for timeout, or replug */ g_main_loop_run (replug_helper->loop); /* unregister */ g_hash_table_remove (ctx->hash_replug, platform_id); /* so we timed out; emit the removal now */ if (replug_helper->timeout_id == 0) { g_set_error_literal (error, G_USB_CONTEXT_ERROR, G_USB_CONTEXT_ERROR_INTERNAL, "request timed out"); return FALSE; } return TRUE; } static void lu_context_remove_udev_device (LuContext *ctx, GUdevDevice *udev_device) { /* look for this udev_device in all the objects */ for (guint i = 0; i < ctx->devices->len; i++) { LuDevice *device = g_ptr_array_index (ctx->devices, i); GUdevDevice *udev_device_tmp = lu_device_get_udev_device (device); if (udev_device_tmp == NULL) continue; if (g_strcmp0 (g_udev_device_get_sysfs_path (udev_device_tmp), g_udev_device_get_sysfs_path (udev_device)) == 0) { lu_context_remove_device (ctx, device); break; } } } static gboolean lu_context_poll_cb (gpointer user_data) { LuContext *ctx = LU_CONTEXT (user_data); /* do not poll when we're waiting for device replug */ if (g_hash_table_size (ctx->hash_replug) > 0) { g_debug ("not polling device as replug in process"); return TRUE; } for (guint i = 0; i < ctx->devices->len; i++) { LuDevice *device = g_ptr_array_index (ctx->devices, i); g_autoptr(GError) error = NULL; if (!lu_device_open (device, &error)) { g_debug ("failed to open %s: %s", fu_device_get_platform_id (FU_DEVICE (device)), error->message); continue; } if (!lu_device_poll (device, &error)) { g_debug ("failed to probe %s: %s", fu_device_get_platform_id (FU_DEVICE (device)), error->message); continue; } } return TRUE; } void lu_context_set_poll_interval (LuContext *ctx, guint poll_interval) { /* enable or change */ if (poll_interval > 0) { if (ctx->poll_id > 0) g_source_remove (ctx->poll_id); ctx->poll_id = g_timeout_add (poll_interval, lu_context_poll_cb, ctx); return; } /* disable */ if (poll_interval == 0 && ctx->poll_id != 0) { g_source_remove (ctx->poll_id); ctx->poll_id = 0; return; } } static void lu_context_udev_uevent_cb (GUdevClient *gudev_client, const gchar *action, GUdevDevice *udev_device, LuContext *ctx) { if (g_strcmp0 (action, "remove") == 0) { lu_context_remove_udev_device (ctx, udev_device); return; } if (g_strcmp0 (action, "add") == 0) { lu_context_add_udev_device (ctx, udev_device); return; } } static void lu_context_init (LuContext *ctx) { const gchar *subsystems[] = { "hidraw", NULL }; ctx->gudev_client = g_udev_client_new (subsystems); g_signal_connect (ctx->gudev_client, "uevent", G_CALLBACK (lu_context_udev_uevent_cb), ctx); ctx->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); ctx->devices_active = g_hash_table_new (g_direct_hash, g_direct_equal); ctx->hash_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); ctx->hash_replug = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); } void lu_context_coldplug (LuContext *ctx) { g_autoptr(GList) devices = NULL; g_return_if_fail (LU_IS_CONTEXT (ctx)); if (ctx->done_coldplug) return; /* coldplug hidraw devices */ devices = g_udev_client_query_by_subsystem (ctx->gudev_client, "hidraw"); for (GList *l = devices; l != NULL; l = l->next) { GUdevDevice *udev_device = G_UDEV_DEVICE (l->data); lu_context_add_udev_device (ctx, udev_device); g_object_unref (udev_device); } /* done */ ctx->done_coldplug = TRUE; } LuDevice * lu_context_find_by_platform_id (LuContext *ctx, const gchar *platform_id, GError **error) { g_return_val_if_fail (LU_IS_CONTEXT (ctx), NULL); g_return_val_if_fail (platform_id != NULL, NULL); /* ensure we have devices */ if (!ctx->done_coldplug) lu_context_coldplug (ctx); for (guint i = 0; i < ctx->devices->len; i++) { LuDevice *device = g_ptr_array_index (ctx->devices, i); if (g_strcmp0 (fu_device_get_platform_id (FU_DEVICE (device)), platform_id) == 0) return g_object_ref (device); } g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "not found %s", platform_id); return NULL; } static void lu_context_usb_device_added_cb (GUsbContext *usb_ctx, GUsbDevice *usb_device, LuContext *ctx) { g_return_if_fail (LU_IS_CONTEXT (ctx)); /* logitech */ if (g_usb_device_get_vid (usb_device) != LU_DEVICE_VID) return; g_debug ("USB add %s", g_usb_device_get_platform_id (usb_device)); /* nordic, in bootloader mode */ if (g_usb_device_get_pid (usb_device) == LU_DEVICE_PID_BOOTLOADER_NORDIC || g_usb_device_get_pid (usb_device) == LU_DEVICE_PID_BOOTLOADER_NORDIC_PICO) { g_autoptr(LuDevice) device = NULL; device = g_object_new (LU_TYPE_DEVICE_BOOTLOADER_NORDIC, "kind", LU_DEVICE_KIND_BOOTLOADER_NORDIC, "flags", LU_DEVICE_FLAG_ACTIVE | LU_DEVICE_FLAG_REQUIRES_ATTACH | LU_DEVICE_FLAG_ATTACH_WILL_REPLUG, "hidpp-id", HIDPP_DEVICE_ID_RECEIVER, "usb-device", usb_device, NULL); lu_context_add_device (ctx, device); return; } /* texas, in bootloader mode */ if (g_usb_device_get_pid (usb_device) == LU_DEVICE_PID_BOOTLOADER_TEXAS || g_usb_device_get_pid (usb_device) == LU_DEVICE_PID_BOOTLOADER_TEXAS_PICO) { g_autoptr(LuDevice) device = NULL; device = g_object_new (LU_TYPE_DEVICE_BOOTLOADER_TEXAS, "kind", LU_DEVICE_KIND_BOOTLOADER_TEXAS, "flags", LU_DEVICE_FLAG_ACTIVE | LU_DEVICE_FLAG_REQUIRES_ATTACH | LU_DEVICE_FLAG_ATTACH_WILL_REPLUG, "hidpp-id", HIDPP_DEVICE_ID_RECEIVER, "usb-device", usb_device, NULL); lu_context_add_device (ctx, device); return; } } static void lu_context_usb_device_removed_cb (GUsbContext *usb_ctx, GUsbDevice *usb_device, LuContext *ctx) { g_return_if_fail (LU_IS_CONTEXT (ctx)); /* logitech */ if (g_usb_device_get_vid (usb_device) != LU_DEVICE_VID) return; /* look for this usb_device in all the objects */ for (guint i = 0; i < ctx->devices->len; i++) { LuDevice *device = g_ptr_array_index (ctx->devices, i); if (lu_device_get_usb_device (device) == usb_device) { lu_context_remove_device (ctx, device); break; } } } static void lu_context_init_real (LuContext *ctx) { g_signal_connect (ctx->usb_ctx, "device-added", G_CALLBACK (lu_context_usb_device_added_cb), ctx); g_signal_connect (ctx->usb_ctx, "device-removed", G_CALLBACK (lu_context_usb_device_removed_cb), ctx); } LuContext * lu_context_new (GError **error) { LuContext *ctx = NULL; g_autoptr(GUsbContext) usb_ctx = NULL; usb_ctx = g_usb_context_new (error); if (usb_ctx == NULL) return NULL; ctx = g_object_new (LU_TYPE_CONTEXT, "usb-context", usb_ctx, NULL); lu_context_init_real (ctx); g_usb_context_enumerate (ctx->usb_ctx); return ctx; } LuContext * lu_context_new_full (GUsbContext *usb_ctx) { LuContext *ctx = NULL; ctx = g_object_new (LU_TYPE_CONTEXT, "usb-context", usb_ctx, NULL); lu_context_init_real (ctx); return ctx; } fwupd-1.0.6/plugins/unifying/lu-context.h000066400000000000000000000035241325145456600204460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_CONTEXT_H #define __LU_CONTEXT_H #include #include #include "lu-device.h" G_BEGIN_DECLS #define LU_TYPE_CONTEXT (lu_context_get_type ()) G_DECLARE_FINAL_TYPE (LuContext, lu_context, LU, CONTEXT, GObject) GPtrArray *lu_context_get_devices (LuContext *ctx); LuDevice *lu_context_find_by_platform_id (LuContext *ctx, const gchar *platform_id, GError **error); void lu_context_coldplug (LuContext *ctx); void lu_context_set_poll_interval (LuContext *ctx, guint poll_interval); void lu_context_set_supported (LuContext *ctx, GPtrArray *supported_guids); gboolean lu_context_wait_for_replug (LuContext *ctx, LuDevice *device, guint timeout_ms, GError **error); LuContext *lu_context_new (GError **error); LuContext *lu_context_new_full (GUsbContext *usb_ctx); G_END_DECLS #endif /* __LU_CONTEXT_H */ fwupd-1.0.6/plugins/unifying/lu-device-bootloader-nordic.c000066400000000000000000000210141325145456600236120ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "lu-common.h" #include "lu-device-bootloader-nordic.h" struct _LuDeviceBootloaderNordic { LuDeviceBootloader parent_instance; }; G_DEFINE_TYPE (LuDeviceBootloaderNordic, lu_device_bootloader_nordic, LU_TYPE_DEVICE_BOOTLOADER) static gchar * lu_device_bootloader_nordic_get_hw_platform_id (LuDevice *device, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_GET_HW_PLATFORM_ID; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to get HW ID: "); return NULL; } return g_strndup ((const gchar *) req->data, req->len); } static gchar * lu_device_bootloader_nordic_get_fw_version (LuDevice *device, GError **error) { guint16 micro; g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_GET_FW_VERSION; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to get firmware version: "); return NULL; } /* RRRxx.yy_Bzzzz * 012345678901234*/ micro = (guint16) lu_buffer_read_uint8 ((const gchar *) req->data + 10) << 8; micro += lu_buffer_read_uint8 ((const gchar *) req->data + 12); return lu_format_version ("RQR", lu_buffer_read_uint8 ((const gchar *) req->data + 3), lu_buffer_read_uint8 ((const gchar *) req->data + 6), micro); } static gboolean lu_device_bootloader_nordic_probe (LuDevice *device, GError **error) { g_autofree gchar *hw_platform_id = NULL; g_autofree gchar *version_fw = NULL; g_autoptr(GError) error_local = NULL; /* get MCU */ hw_platform_id = lu_device_bootloader_nordic_get_hw_platform_id (device, error); if (hw_platform_id == NULL) return FALSE; g_debug ("hw-platform-id=%s", hw_platform_id); /* get firmware version, which is not fatal */ version_fw = lu_device_bootloader_nordic_get_fw_version (device, &error_local); if (version_fw == NULL) { g_warning ("failed to get firmware version: %s", error_local->message); fu_device_set_version (FU_DEVICE (device), "RQR12.xx_Bxxxx"); } else { fu_device_set_version (FU_DEVICE (device), version_fw); } return TRUE; } static gboolean lu_device_bootloader_nordic_write_signature (LuDevice *device, guint16 addr, guint8 len, const guint8 *data, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new(); req->cmd = 0xC0; req->addr = addr; req->len = len; memcpy (req->data, data, req->len); if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to write sig @0x%02x: ", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER_INVALID_ADDR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: signature is too big", addr); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_nordic_write (LuDevice *device, guint16 addr, guint8 len, const guint8 *data, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_WRITE; req->addr = addr; req->len = len; if (req->len > 28) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: data length too large %02x", addr, req->len); return FALSE; } memcpy (req->data, data, req->len); if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to transfer fw @0x%02x: ", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_INVALID_ADDR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: invalid address", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_VERIFY_FAIL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: failed to verify flash content", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_NONZERO_START) { g_debug ("wrote %d bytes at address %04x, value %02x", req->len, req->addr, req->data[0]); g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: only 1 byte write of 0xff supported", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_INVALID_CRC) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write @%04x: invalid CRC", addr); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_nordic_erase (LuDevice *device, guint16 addr, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE; req->addr = addr; req->len = 0x01; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to erase fw @0x%02x: ", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE_INVALID_ADDR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to erase @%04x: invalid page", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE_NONZERO_START) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to erase @%04x: byte 0x00 is not 0xff", addr); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_nordic_write_firmware (LuDevice *device, GBytes *fw, GError **error) { const LuDeviceBootloaderRequest *payload; guint16 addr; g_autoptr(GPtrArray) reqs = NULL; /* erase firmware pages up to the bootloader */ for (addr = lu_device_bootloader_get_addr_lo (device); addr < lu_device_bootloader_get_addr_hi (device); addr += lu_device_bootloader_get_blocksize (device)) { if (!lu_device_bootloader_nordic_erase (device, addr, error)) return FALSE; } /* transfer payload */ reqs = lu_device_bootloader_parse_requests (device, fw, error); if (reqs == NULL) return FALSE; for (guint i = 1; i < reqs->len; i++) { gboolean res; payload = g_ptr_array_index (reqs, i); if (payload->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE) { res = lu_device_bootloader_nordic_write_signature(device, payload->addr, payload->len, payload->data, error); } else { res = lu_device_bootloader_nordic_write (device, payload->addr, payload->len, payload->data, error); } if (!res) return FALSE; fu_device_set_progress_full (FU_DEVICE (device), i * 32, reqs->len * 32); } /* send the first managed packet last, excluding the reset vector */ payload = g_ptr_array_index (reqs, 0); if (!lu_device_bootloader_nordic_write (device, payload->addr + 1, payload->len - 1, payload->data + 1, error)) return FALSE; if (!lu_device_bootloader_nordic_write (device, 0x0000, 0x01, payload->data, error)) return FALSE; /* mark as complete */ fu_device_set_progress_full (FU_DEVICE (device), reqs->len * 32, reqs->len * 32); /* success! */ return TRUE; } static void lu_device_bootloader_nordic_class_init (LuDeviceBootloaderNordicClass *klass) { LuDeviceClass *klass_device = LU_DEVICE_CLASS (klass); LuDeviceBootloaderClass *klass_device_bootloader = LU_DEVICE_BOOTLOADER_CLASS (klass); klass_device->write_firmware = lu_device_bootloader_nordic_write_firmware; klass_device_bootloader->probe = lu_device_bootloader_nordic_probe; } static void lu_device_bootloader_nordic_init (LuDeviceBootloaderNordic *device) { } fwupd-1.0.6/plugins/unifying/lu-device-bootloader-nordic.h000066400000000000000000000025171325145456600236260ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_BOOTLOADER_NORDIC_H #define __LU_DEVICE_BOOTLOADER_NORDIC_H #include "lu-device-bootloader.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE_BOOTLOADER_NORDIC (lu_device_bootloader_nordic_get_type ()) G_DECLARE_FINAL_TYPE (LuDeviceBootloaderNordic, lu_device_bootloader_nordic, LU, DEVICE_BOOTLOADER_NORDIC, LuDeviceBootloader) G_END_DECLS #endif /* __LU_DEVICE_BOOTLOADER_NORDIC_H */ fwupd-1.0.6/plugins/unifying/lu-device-bootloader-texas.c000066400000000000000000000161371325145456600234720ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "lu-common.h" #include "lu-device-bootloader-texas.h" struct _LuDeviceBootloaderTexas { LuDeviceBootloader parent_instance; }; G_DEFINE_TYPE (LuDeviceBootloaderTexas, lu_device_bootloader_texas, LU_TYPE_DEVICE_BOOTLOADER) static gboolean lu_device_bootloader_texas_erase_all (LuDevice *device, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM; req->len = 0x01; /* magic number */ req->data[0] = 0x00; /* magic number */ if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to erase all pages: "); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_texas_compute_and_test_crc (LuDevice *device, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM; req->len = 0x01; /* magic number */ req->data[0] = 0x03; /* magic number */ if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to compute and test CRC: "); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_WRONG_CRC) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "CRC is incorrect"); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_texas_flash_ram_buffer (LuDevice *device, guint16 addr, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM; req->addr = addr; req->len = 0x01; /* magic number */ req->data[0] = 0x01; /* magic number */ if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to flash ram buffer @%04x: ", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_INVALID_ADDR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to flash ram buffer @%04x: invalid flash page", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_PAGE0_INVALID) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to flash ram buffer @%04x: invalid App JMP vector", addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_INVALID_ORDER) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to flash ram buffer @%04x: page flashed before page 0", addr); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_texas_clear_ram_buffer (LuDevice *device, guint16 addr, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM; req->addr = addr; req->len = 0x01; /* magic number */ req->data[0] = 0x02; /* magic number */ if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to clear ram buffer @%04x: ", addr); return FALSE; } return TRUE; } static gboolean lu_device_bootloader_texas_write_firmware (LuDevice *device, GBytes *fw, GError **error) { const LuDeviceBootloaderRequest *payload; g_autoptr(GPtrArray) reqs = NULL; g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); /* transfer payload */ reqs = lu_device_bootloader_parse_requests (device, fw, error); if (reqs == NULL) return FALSE; /* erase all flash pages */ if (!lu_device_bootloader_texas_erase_all (device, error)) return FALSE; /* set existing RAM buffer to 0xff's */ if (!lu_device_bootloader_texas_clear_ram_buffer (device, 0x0000, error)) return FALSE; /* transfer payload */ for (guint i = 0; i < reqs->len; i++) { payload = g_ptr_array_index (reqs, i); /* check size */ if (payload->len != 16) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "payload size invalid @%04x: got 0x%02x", payload->addr, payload->len); return FALSE; } /* build packet */ req->cmd = payload->cmd; /* signature addresses do not need to fit inside 128 bytes */ if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE) req->addr = payload->addr; else req->addr = payload->addr % 0x80; req->len = payload->len; memcpy (req->data, payload->data, payload->len); if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to write ram bufer @0x%02x: ", req->addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER_INVALID_ADDR) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write ram buffer @%04x: invalid location", req->addr); return FALSE; } if (req->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER_OVERFLOW) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to write ram buffer @%04x: invalid size 0x%02x", req->addr, req->len); return FALSE; } /* flush RAM buffer to EEPROM */ if ((payload->addr + 0x10) % 0x80 == 0 && req->cmd != LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE) { guint16 addr_start = payload->addr - (7 * 0x10); g_debug ("addr flush @ 0x%04x for 0x%04x", payload->addr, addr_start); if (!lu_device_bootloader_texas_flash_ram_buffer (device, addr_start, error)) { g_prefix_error (error, "failed to flash ram buffer @0x%04x: ", addr_start); return FALSE; } } /* update progress */ fu_device_set_progress_full (FU_DEVICE (device), i * 32, reqs->len * 32); } /* check CRC */ if (!lu_device_bootloader_texas_compute_and_test_crc (device, error)) return FALSE; /* mark as complete */ fu_device_set_progress_full (FU_DEVICE (device), reqs->len * 32, reqs->len * 32); /* success! */ return TRUE; } static void lu_device_bootloader_texas_class_init (LuDeviceBootloaderTexasClass *klass) { LuDeviceClass *klass_device = LU_DEVICE_CLASS (klass); klass_device->write_firmware = lu_device_bootloader_texas_write_firmware; } static void lu_device_bootloader_texas_init (LuDeviceBootloaderTexas *device) { fu_device_set_version (FU_DEVICE (device), "RQR24.xx_Bxxxx"); } fwupd-1.0.6/plugins/unifying/lu-device-bootloader-texas.h000066400000000000000000000025071325145456600234730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_BOOTLOADER_TEXAS_H #define __LU_DEVICE_BOOTLOADER_TEXAS_H #include "lu-device-bootloader.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE_BOOTLOADER_TEXAS (lu_device_bootloader_texas_get_type ()) G_DECLARE_FINAL_TYPE (LuDeviceBootloaderTexas, lu_device_bootloader_texas, LU, DEVICE_BOOTLOADER_TEXAS, LuDeviceBootloader) G_END_DECLS #endif /* __LU_DEVICE_BOOTLOADER_TEXAS_H */ fwupd-1.0.6/plugins/unifying/lu-device-bootloader.c000066400000000000000000000306761325145456600223540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "lu-common.h" #include "lu-device-bootloader.h" #include "lu-hidpp.h" typedef struct { guint16 flash_addr_lo; guint16 flash_addr_hi; guint16 flash_blocksize; } LuDeviceBootloaderPrivate; G_DEFINE_TYPE_WITH_PRIVATE (LuDeviceBootloader, lu_device_bootloader, LU_TYPE_DEVICE) #define GET_PRIVATE(o) (lu_device_bootloader_get_instance_private (o)) LuDeviceBootloaderRequest * lu_device_bootloader_request_new (void) { LuDeviceBootloaderRequest *req = g_new0 (LuDeviceBootloaderRequest, 1); return req; } GPtrArray * lu_device_bootloader_parse_requests (LuDevice *device, GBytes *fw, GError **error) { const gchar *tmp; g_auto(GStrv) lines = NULL; g_autoptr(GPtrArray) reqs = NULL; guint32 last_addr = 0; reqs = g_ptr_array_new_with_free_func (g_free); tmp = g_bytes_get_data (fw, NULL); lines = g_strsplit_set (tmp, "\n\r", -1); for (guint i = 0; lines[i] != NULL; i++) { g_autoptr(LuDeviceBootloaderRequest) payload = NULL; guint8 rec_type = 0x00; /* skip empty lines */ tmp = lines[i]; if (strlen (tmp) < 5) continue; payload = lu_device_bootloader_request_new (); payload->len = lu_buffer_read_uint8 (tmp + 0x01); if (payload->len > 28) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware data invalid: too large %u bytes", payload->len); return NULL; } payload->addr = ((guint16) lu_buffer_read_uint8 (tmp + 0x03)) << 8; payload->addr |= lu_buffer_read_uint8 (tmp + 0x05); rec_type = lu_buffer_read_uint8 (tmp + 0x07); /* record type of 0xFD indicates signature data */ if (rec_type == 0xFD) { payload->cmd = LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE; } else { payload->cmd = LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER; } /* read the data, but skip the checksum byte */ for (guint j = 0; j < payload->len; j++) { const gchar *ptr = tmp + 0x09 + (j * 2); if (ptr[0] == '\0') { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware data invalid: expected %u bytes", payload->len); return NULL; } payload->data[j] = lu_buffer_read_uint8 (ptr); } /* no need to bound check signature addresses */ if (payload->cmd == LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE) { g_ptr_array_add (reqs, g_steal_pointer (&payload)); continue; } /* skip the bootloader */ if (payload->addr > lu_device_bootloader_get_addr_hi (device)) { g_debug ("skipping write @ %04x", payload->addr); continue; } /* skip the header */ if (payload->addr < lu_device_bootloader_get_addr_lo (device)) { g_debug ("skipping write @ %04x", payload->addr); continue; } /* make sure firmware addresses only go up */ if (payload->addr < last_addr) { g_debug ("skipping write @ %04x", payload->addr); continue; } last_addr = payload->addr; /* pending */ g_ptr_array_add (reqs, g_steal_pointer (&payload)); } if (reqs->len == 0) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware data invalid: no payloads found"); return NULL; } return g_steal_pointer (&reqs); } guint16 lu_device_bootloader_get_addr_lo (LuDevice *device) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); g_return_val_if_fail (LU_IS_DEVICE (device), 0x0000); return priv->flash_addr_lo; } guint16 lu_device_bootloader_get_addr_hi (LuDevice *device) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); g_return_val_if_fail (LU_IS_DEVICE (device), 0x0000); return priv->flash_addr_hi; } void lu_device_bootloader_set_addr_lo (LuDevice *device, guint16 addr) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); priv->flash_addr_lo = addr; } void lu_device_bootloader_set_addr_hi (LuDevice *device, guint16 addr) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); priv->flash_addr_hi = addr; } guint16 lu_device_bootloader_get_blocksize (LuDevice *device) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); g_return_val_if_fail (LU_IS_DEVICE (device), 0x0000); return priv->flash_blocksize; } static gboolean lu_device_bootloader_attach (LuDevice *device, GError **error) { g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_REBOOT; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to attach back to runtime: "); return FALSE; } return TRUE; } static guint16 cd_buffer_read_uint16_be (const guint8 *buffer) { guint16 tmp; memcpy (&tmp, buffer, sizeof(tmp)); return GUINT16_FROM_BE (tmp); } static gboolean lu_device_bootloader_open (LuDevice *device, GError **error) { LuDeviceBootloader *device_bootloader = LU_DEVICE_BOOTLOADER (device); LuDeviceBootloaderPrivate *priv = GET_PRIVATE (device_bootloader); g_autofree gchar *name = NULL; g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); /* generate name */ name = g_strdup_printf ("Unifying [%s]", lu_device_kind_to_string (lu_device_get_kind (device))); fu_device_set_name (FU_DEVICE (device), name); /* we can flash this */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); /* get memory map */ req->cmd = LU_DEVICE_BOOTLOADER_CMD_GET_MEMINFO; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to get meminfo: "); return FALSE; } if (req->len != 0x06) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to get meminfo: invalid size %02x", req->len); return FALSE; } /* parse values */ priv->flash_addr_lo = cd_buffer_read_uint16_be (req->data + 0); priv->flash_addr_hi = cd_buffer_read_uint16_be (req->data + 2); priv->flash_blocksize = cd_buffer_read_uint16_be (req->data + 4); return TRUE; } static gchar * lu_device_bootloader_get_bl_version (LuDevice *device, GError **error) { guint16 build; g_autoptr(LuDeviceBootloaderRequest) req = lu_device_bootloader_request_new (); req->cmd = LU_DEVICE_BOOTLOADER_CMD_GET_BL_VERSION; if (!lu_device_bootloader_request (device, req, error)) { g_prefix_error (error, "failed to get firmware version: "); return NULL; } /* BOTxx.yy_Bzzzz * 012345678901234 */ build = (guint16) lu_buffer_read_uint8 ((const gchar *) req->data + 10) << 8; build += lu_buffer_read_uint8 ((const gchar *) req->data + 12); return lu_format_version ("BOT", lu_buffer_read_uint8 ((const gchar *) req->data + 3), lu_buffer_read_uint8 ((const gchar *) req->data + 6), build); } static gboolean lu_device_bootloader_probe (LuDevice *device, GError **error) { LuDeviceBootloaderClass *klass = LU_DEVICE_BOOTLOADER_GET_CLASS (device); g_autofree gchar *version_bl = NULL; /* get bootloader version */ version_bl = lu_device_bootloader_get_bl_version (device, error); if (version_bl == NULL) return FALSE; fu_device_set_version_bootloader (FU_DEVICE (device), version_bl); /* subclassed further */ if (klass->probe != NULL) return klass->probe (device, error); return TRUE; } static gboolean lu_device_bootloader_close (LuDevice *device, GError **error) { GUsbDevice *usb_device = lu_device_get_usb_device (device); if (usb_device != NULL) { if (!g_usb_device_release_interface (usb_device, 0x00, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { return FALSE; } } return TRUE; } gboolean lu_device_bootloader_request (LuDevice *device, LuDeviceBootloaderRequest *req, GError **error) { GUsbDevice *usb_device = lu_device_get_usb_device (device); gsize actual_length = 0; guint8 buf_request[32]; guint8 buf_response[32]; /* build packet */ memset (buf_request, 0x00, sizeof (buf_request)); buf_request[0x00] = req->cmd; buf_request[0x01] = req->addr >> 8; buf_request[0x02] = req->addr & 0xff; buf_request[0x03] = req->len; memcpy (buf_request + 0x04, req->data, 28); /* send request */ lu_dump_raw ("host->device", buf_request, sizeof (buf_request)); if (usb_device != NULL) { if (!g_usb_device_control_transfer (usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, LU_REQUEST_SET_REPORT, 0x0200, 0x0000, buf_request, sizeof (buf_request), &actual_length, LU_DEVICE_TIMEOUT_MS, NULL, error)) { g_prefix_error (error, "failed to send data: "); return FALSE; } } /* no response required when rebooting */ if (usb_device != NULL && req->cmd == LU_DEVICE_BOOTLOADER_CMD_REBOOT) { g_autoptr(GError) error_ignore = NULL; if (!g_usb_device_interrupt_transfer (usb_device, LU_DEVICE_EP1, buf_response, sizeof (buf_response), &actual_length, LU_DEVICE_TIMEOUT_MS, NULL, &error_ignore)) { g_debug ("ignoring: %s", error_ignore->message); } else { lu_dump_raw ("device->host", buf_response, actual_length); } return TRUE; } /* get response */ memset (buf_response, 0x00, sizeof (buf_response)); if (usb_device != NULL) { if (!g_usb_device_interrupt_transfer (usb_device, LU_DEVICE_EP1, buf_response, sizeof (buf_response), &actual_length, LU_DEVICE_TIMEOUT_MS, NULL, error)) { g_prefix_error (error, "failed to get data: "); return FALSE; } } else { /* emulated */ buf_response[0] = buf_request[0]; if (buf_response[0] == LU_DEVICE_BOOTLOADER_CMD_GET_MEMINFO) { buf_response[3] = 0x06; /* len */ buf_response[4] = 0x40; /* lo MSB */ buf_response[5] = 0x00; /* lo LSB */ buf_response[6] = 0x6b; /* hi MSB */ buf_response[7] = 0xff; /* hi LSB */ buf_response[8] = 0x00; /* bs MSB */ buf_response[9] = 0x80; /* bs LSB */ } actual_length = sizeof (buf_response); } lu_dump_raw ("device->host", buf_response, actual_length); /* parse response */ if ((buf_response[0x00] & 0xf0) != req->cmd) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "invalid command response of %02x, expected %02x", buf_response[0x00], req->cmd); return FALSE; } req->cmd = buf_response[0x00]; req->addr = ((guint16) buf_response[0x01] << 8) + buf_response[0x02]; req->len = buf_response[0x03]; if (req->len > 28) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "invalid data size of %02x", req->len); return FALSE; } memset (req->data, 0x00, 28); if (req->len > 0) memcpy (req->data, buf_response + 0x04, req->len); return TRUE; } static void lu_device_bootloader_init (LuDeviceBootloader *device) { /* FIXME: we need something better */ fu_device_add_icon (FU_DEVICE (device), "preferences-desktop-keyboard"); fu_device_set_summary (FU_DEVICE (device), "A miniaturised USB wireless receiver (bootloader)"); } static void lu_device_bootloader_class_init (LuDeviceBootloaderClass *klass) { LuDeviceClass *klass_device = LU_DEVICE_CLASS (klass); klass_device->attach = lu_device_bootloader_attach; klass_device->open = lu_device_bootloader_open; klass_device->close = lu_device_bootloader_close; klass_device->probe = lu_device_bootloader_probe; } fwupd-1.0.6/plugins/unifying/lu-device-bootloader.h000066400000000000000000000074031325145456600223510ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_BOOTLOADER_H #define __LU_DEVICE_BOOTLOADER_H #include #include "lu-device.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE_BOOTLOADER (lu_device_bootloader_get_type ()) G_DECLARE_DERIVABLE_TYPE (LuDeviceBootloader, lu_device_bootloader, LU, DEVICE_BOOTLOADER, LuDevice) struct _LuDeviceBootloaderClass { LuDeviceClass parent_class; gboolean (*probe) (LuDevice *device, GError **error); }; typedef enum { LU_DEVICE_BOOTLOADER_CMD_GENERAL_ERROR = 0x01, LU_DEVICE_BOOTLOADER_CMD_READ = 0x10, LU_DEVICE_BOOTLOADER_CMD_WRITE = 0x20, LU_DEVICE_BOOTLOADER_CMD_WRITE_INVALID_ADDR = 0x21, LU_DEVICE_BOOTLOADER_CMD_WRITE_VERIFY_FAIL = 0x22, LU_DEVICE_BOOTLOADER_CMD_WRITE_NONZERO_START = 0x23, LU_DEVICE_BOOTLOADER_CMD_WRITE_INVALID_CRC = 0x24, LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE = 0x30, LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE_INVALID_ADDR = 0x31, LU_DEVICE_BOOTLOADER_CMD_ERASE_PAGE_NONZERO_START = 0x33, LU_DEVICE_BOOTLOADER_CMD_GET_HW_PLATFORM_ID = 0x40, LU_DEVICE_BOOTLOADER_CMD_GET_FW_VERSION = 0x50, LU_DEVICE_BOOTLOADER_CMD_GET_CHECKSUM = 0x60, LU_DEVICE_BOOTLOADER_CMD_REBOOT = 0x70, LU_DEVICE_BOOTLOADER_CMD_GET_MEMINFO = 0x80, LU_DEVICE_BOOTLOADER_CMD_GET_BL_VERSION = 0x90, LU_DEVICE_BOOTLOADER_CMD_GET_INIT_FW_VERSION = 0xa0, LU_DEVICE_BOOTLOADER_CMD_READ_SIGNATURE = 0xb0, LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER = 0xc0, LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER_INVALID_ADDR = 0xc1, LU_DEVICE_BOOTLOADER_CMD_WRITE_RAM_BUFFER_OVERFLOW = 0xc2, LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM = 0xd0, LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_INVALID_ADDR = 0xd1, LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_WRONG_CRC = 0xd2, LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_PAGE0_INVALID = 0xd3, LU_DEVICE_BOOTLOADER_CMD_FLASH_RAM_INVALID_ORDER = 0xd4, LU_DEVICE_BOOTLOADER_CMD_WRITE_SIGNATURE = 0xe0, LU_DEVICE_BOOTLOADER_CMD_LAST } LuDeviceBootloaderCmd; /* packet to and from device */ typedef struct __attribute__((packed)) { guint8 cmd; guint16 addr; guint8 len; guint8 data[28]; } LuDeviceBootloaderRequest; LuDeviceBootloaderRequest *lu_device_bootloader_request_new (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC(LuDeviceBootloaderRequest, g_free); GPtrArray *lu_device_bootloader_parse_requests (LuDevice *device, GBytes *fw, GError **error); gboolean lu_device_bootloader_request (LuDevice *device, LuDeviceBootloaderRequest *req, GError **error); guint16 lu_device_bootloader_get_addr_lo (LuDevice *device); guint16 lu_device_bootloader_get_addr_hi (LuDevice *device); void lu_device_bootloader_set_addr_lo (LuDevice *device, guint16 addr); void lu_device_bootloader_set_addr_hi (LuDevice *device, guint16 addr); guint16 lu_device_bootloader_get_blocksize (LuDevice *device); G_END_DECLS #endif /* __LU_DEVICE_BOOTLOADER_H */ fwupd-1.0.6/plugins/unifying/lu-device-peripheral.c000066400000000000000000000550001325145456600223410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "lu-common.h" #include "lu-device-peripheral.h" #include "lu-hidpp.h" struct _LuDevicePeripheral { LuDevice parent_instance; guint8 cached_fw_entity; }; G_DEFINE_TYPE (LuDevicePeripheral, lu_device_peripheral, LU_TYPE_DEVICE) typedef enum { LU_DEVICE_PERIPHERAL_KIND_KEYBOARD, LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL, LU_DEVICE_PERIPHERAL_KIND_NUMPAD, LU_DEVICE_PERIPHERAL_KIND_MOUSE, LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD, LU_DEVICE_PERIPHERAL_KIND_TRACKBALL, LU_DEVICE_PERIPHERAL_KIND_PRESENTER, LU_DEVICE_PERIPHERAL_KIND_RECEIVER, LU_DEVICE_PERIPHERAL_KIND_LAST } LuDevicePeripheralKind; static const gchar * lu_device_peripheral_get_icon (LuDevicePeripheralKind kind) { if (kind == LU_DEVICE_PERIPHERAL_KIND_KEYBOARD) return "input-keyboard"; if (kind == LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL) return "pda"; // ish if (kind == LU_DEVICE_PERIPHERAL_KIND_NUMPAD) return "input-dialpad"; if (kind == LU_DEVICE_PERIPHERAL_KIND_MOUSE) return "input-mouse"; if (kind == LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD) return "input-touchpad"; if (kind == LU_DEVICE_PERIPHERAL_KIND_TRACKBALL) return "input-mouse"; // ish if (kind == LU_DEVICE_PERIPHERAL_KIND_PRESENTER) return "pda"; // ish if (kind == LU_DEVICE_PERIPHERAL_KIND_RECEIVER) return "preferences-desktop-keyboard"; return NULL; } static const gchar * lu_device_peripheral_get_summary (LuDevicePeripheralKind kind) { if (kind == LU_DEVICE_PERIPHERAL_KIND_KEYBOARD) return "Unifying Keyboard"; if (kind == LU_DEVICE_PERIPHERAL_KIND_REMOTE_CONTROL) return "Unifying Remote Control"; if (kind == LU_DEVICE_PERIPHERAL_KIND_NUMPAD) return "Unifying Number Pad"; if (kind == LU_DEVICE_PERIPHERAL_KIND_MOUSE) return "Unifying Mouse"; if (kind == LU_DEVICE_PERIPHERAL_KIND_TOUCHPAD) return "Unifying Touchpad"; if (kind == LU_DEVICE_PERIPHERAL_KIND_TRACKBALL) return "Unifying Trackball"; if (kind == LU_DEVICE_PERIPHERAL_KIND_PRESENTER) return "Unifying Presenter"; if (kind == LU_DEVICE_PERIPHERAL_KIND_RECEIVER) return "Unifying Receiver"; return NULL; } static gboolean lu_device_peripheral_fetch_firmware_info (LuDevice *device, GError **error) { LuDevicePeripheral *self = LU_DEVICE_PERIPHERAL (device); guint8 idx; guint8 entity_count; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* get the feature index */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_I_FIRMWARE_INFO); if (idx == 0x00) return TRUE; /* get the entity count */ msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x00 << 4; /* getCount */ if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get firmware count: "); return FALSE; } entity_count = msg->data[0]; g_debug ("firmware entity count is %u", entity_count); /* get firmware, bootloader, hardware versions */ for (guint8 i = 0; i < entity_count; i++) { guint16 build; g_autofree gchar *version = NULL; g_autofree gchar *name = NULL; msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x01 << 4; /* getInfo */ msg->data[0] = i; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get firmware info: "); return FALSE; } if (msg->data[1] == 0x00 && msg->data[2] == 0x00 && msg->data[3] == 0x00 && msg->data[4] == 0x00 && msg->data[4] == 0x00 && msg->data[5] == 0x00 && msg->data[6] == 0x00 && msg->data[7] == 0x00) { g_debug ("no version set for entity %u", i); continue; } name = g_strdup_printf ("%c%c%c", msg->data[1], msg->data[2], msg->data[3]); build = ((guint16) msg->data[6]) << 8 | msg->data[7]; version = lu_format_version (name, msg->data[4], msg->data[5], build); g_debug ("firmware entity 0x%02x version is %s", i, version); if (msg->data[0] == 0) { fu_device_set_version (device, version); self->cached_fw_entity = i; } else if (msg->data[0] == 1) { fu_device_set_version_bootloader (FU_DEVICE (device), version); } else if (msg->data[0] == 2) { lu_device_set_version_hw (device, version); } } /* not an error, the device just doesn't support this */ return TRUE; } static gboolean lu_device_peripheral_fetch_battery_level (LuDevice *device, GError **error) { /* try using HID++2.0 */ if (lu_device_get_hidpp_version (device) >= 2.f) { guint8 idx; idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_BATTERY_LEVEL_STATUS); if (idx != 0x00) { g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x00; /* GetBatteryLevelStatus */ if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get battery info: "); return FALSE; } if (msg->data[0] != 0x00) lu_device_set_battery_level (device, msg->data[0]); return TRUE; } } /* try HID++1.0 battery mileage */ if (lu_device_get_hidpp_version (device) == 1.f) { g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = HIDPP_SUBID_GET_REGISTER; msg->function_id = HIDPP_REGISTER_BATTERY_MILEAGE; if (lu_device_hidpp_transfer (device, msg, NULL)) { if (msg->data[0] != 0x00) lu_device_set_battery_level (device, msg->data[0]); return TRUE; } /* try HID++1.0 battery status instead */ msg->function_id = HIDPP_REGISTER_BATTERY_STATUS; if (lu_device_hidpp_transfer (device, msg, NULL)) { switch (msg->data[0]) { case 1: /* 0 - 10 */ lu_device_set_battery_level (device, 5); break; case 3: /* 11 - 30 */ lu_device_set_battery_level (device, 20); break; case 5: /* 31 - 80 */ lu_device_set_battery_level (device, 55); break; case 7: /* 81 - 100 */ lu_device_set_battery_level (device, 90); break; default: g_warning ("unknown battery percentage: 0x%02x", msg->data[0]); break; } return TRUE; } } /* not an error, the device just doesn't support any of the methods */ return TRUE; } static gboolean lu_device_peripheral_ping (LuDevice *device, GError **error) { gdouble version; g_autoptr(GError) error_local = NULL; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* handle failure */ msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = 0x00; /* rootIndex */ msg->function_id = 0x01 << 4; /* ping */ msg->data[0] = 0x00; msg->data[1] = 0x00; msg->data[2] = 0xaa; /* user-selected value */ if (!lu_device_hidpp_transfer (device, msg, &error_local)) { if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { lu_device_set_hidpp_version (device, 1.f); return TRUE; } if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, "device %s is unreachable: %s", fu_device_get_name (device), error_local->message); lu_device_remove_flag (device, LU_DEVICE_FLAG_ACTIVE); return FALSE; } g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to ping %s: %s", fu_device_get_name (FU_DEVICE (device)), error_local->message); return FALSE; } /* format version in BCD format */ version = (gdouble) msg->data[0] + ((gdouble) msg->data[1]) / 100.f; lu_device_set_hidpp_version (device, version); /* success */ return TRUE; } static gboolean lu_device_peripheral_probe (LuDevice *device, GError **error) { guint8 idx; const guint16 map_features[] = { HIDPP_FEATURE_GET_DEVICE_NAME_TYPE, HIDPP_FEATURE_I_FIRMWARE_INFO, HIDPP_FEATURE_BATTERY_LEVEL_STATUS, HIDPP_FEATURE_DFU_CONTROL, HIDPP_FEATURE_DFU_CONTROL_SIGNED, HIDPP_FEATURE_DFU, HIDPP_FEATURE_ROOT }; /* ping device to get HID++ version */ if (!lu_device_peripheral_ping (device, error)) return FALSE; /* map some *optional* HID++2.0 features we might use */ for (guint i = 0; map_features[i] != HIDPP_FEATURE_ROOT; i++) { g_autoptr(GError) error_local = NULL; if (!lu_device_hidpp_feature_search (device, map_features[i], &error_local)) { g_debug ("%s", error_local->message); if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) { /* timed out, so not trying any more */ break; } } } /* get the firmware information */ if (!lu_device_peripheral_fetch_firmware_info (device, error)) return FALSE; /* get the battery level */ if (!lu_device_peripheral_fetch_battery_level (device, error)) return FALSE; /* try using HID++2.0 */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE); if (idx != 0x00) { const gchar *tmp; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x02 << 4; /* getDeviceType */ if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get device type: "); return FALSE; } /* add nice-to-have data */ tmp = lu_device_peripheral_get_summary (msg->data[0]); if (tmp != NULL) fu_device_set_summary (FU_DEVICE (device), tmp); tmp = lu_device_peripheral_get_icon (msg->data[0]); if (tmp != NULL) fu_device_add_icon (FU_DEVICE (device), tmp); } idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU_CONTROL); if (idx != 0x00) { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_DETACH); } idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU_CONTROL_SIGNED); if (idx != 0x00) { /* check the feature is available */ g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x00 << 4; /* getDfuStatus */ if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get DFU status: "); return FALSE; } if ((msg->data[2] & 0x01) > 0) { g_warning ("DFU mode not available"); } else { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_DETACH); lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE); } } idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU); if (idx != 0x00) { fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_ATTACH); if (fu_device_get_version (device) == NULL) { g_debug ("repairing device in bootloader mode"); fu_device_set_version (FU_DEVICE (device), "MPKxx.xx_Bxxxx"); } } /* this device is active right now */ lu_device_add_flag (device, LU_DEVICE_FLAG_ACTIVE); return TRUE; } static gboolean lu_device_peripheral_detach (LuDevice *device, GError **error) { guint8 idx; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* this requires user action */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU_CONTROL); if (idx != 0x00) { msg->report_id = HIDPP_REPORT_ID_LONG; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x01 << 4; /* setDfuControl */ msg->data[0] = 0x01; /* enterDfu */ msg->data[1] = 0x00; /* dfuControlParam */ msg->data[2] = 0x00; /* unused */ msg->data[3] = 0x00; /* unused */ msg->data[4] = 'D'; msg->data[5] = 'F'; msg->data[6] = 'U'; msg->flags = LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID | LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to put device into DFU mode: "); return FALSE; } lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_RESET); return TRUE; } /* this can reboot all by itself */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU_CONTROL_SIGNED); if (idx != 0x00) { msg->report_id = HIDPP_REPORT_ID_LONG; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x01 << 4; /* setDfuControl */ msg->data[0] = 0x01; /* startDfu */ msg->data[1] = 0x00; /* dfuControlParam */ msg->data[2] = 0x00; /* unused */ msg->data[3] = 0x00; /* unused */ msg->data[4] = 'D'; msg->data[5] = 'F'; msg->data[6] = 'U'; msg->flags = LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to put device into DFU mode: "); return FALSE; } /* reprobe */ return lu_device_probe (device, error); } /* we don't know how */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "no method to detach"); return FALSE; } static gboolean lu_device_peripheral_check_status (guint8 status, GError **error) { switch (status & 0x7f) { case 0x00: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "invalid status value 0x%02x", status); break; case 0x01: /* packet success */ case 0x02: /* DFU success */ case 0x05: /* DFU success: entity restart required */ case 0x06: /* DFU success: system restart required */ /* success */ return TRUE; break; case 0x03: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PENDING, "wait for event (command in progress)"); break; case 0x04: case 0x10: /* unknown */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "generic error"); break; case 0x11: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "bad voltage (power too low?)"); break; case 0x12: case 0x14: /* bad magic string */ case 0x21: /* bad firmware */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unsupported firmware"); break; case 0x13: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unsupported encryption mode"); break; case 0x15: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "erase failure"); break; case 0x16: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "DFU not started"); break; case 0x17: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "bad sequence number"); break; case 0x18: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unsupported command"); break; case 0x19: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "command in progress"); break; case 0x1a: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "address out of range"); break; case 0x1b: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unaligned address"); break; case 0x1c: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "bad size"); break; case 0x1d: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "missing program data"); break; case 0x1e: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "missing check data"); break; case 0x1f: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "program failed to write"); break; case 0x20: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "program failed to verify"); break; case 0x22: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "firmware check failure"); break; case 0x23: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "blocked command (restart required)"); break; default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "unhandled status value 0x%02x", status); break; } return FALSE; } static gboolean lu_device_peripheral_write_firmware_pkt (LuDevice *device, guint8 idx, guint8 cmd, const guint8 *data, GError **error) { guint32 packet_cnt; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); g_autoptr(GError) error_local = NULL; /* send firmware data */ msg->report_id = HIDPP_REPORT_ID_LONG; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = cmd << 4; /* dfuStart or dfuCmdDataX */ memcpy (msg->data, data, 16); if (!lu_device_hidpp_transfer (device, msg, &error_local)) { g_prefix_error (error, "failed to supply program data: "); return FALSE; } /* check error */ packet_cnt = fu_common_read_uint32 (msg->data, G_BIG_ENDIAN); g_debug ("packet_cnt=0x%04x", packet_cnt); if (lu_device_peripheral_check_status (msg->data[4], &error_local)) return TRUE; /* fatal error */ if (!g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_PENDING)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, error_local->message); return FALSE; } /* wait for the HID++ notification */ g_debug ("ignoring: %s", error_local->message); for (guint retry = 0; retry < 10; retry++) { g_autoptr(LuHidppMsg) msg2 = lu_hidpp_msg_new (); msg2->flags = LU_HIDPP_MSG_FLAG_IGNORE_FNCT_ID; if (!lu_device_hidpp_receive (device, msg2, 15000, error)) return FALSE; if (lu_hidpp_msg_is_reply (msg, msg2)) { g_autoptr(GError) error2 = NULL; if (!lu_device_peripheral_check_status (msg2->data[4], &error2)) { g_debug ("got %s, waiting a bit longer", error2->message); continue; } return TRUE; } else { g_debug ("got wrong packet, continue to wait..."); } } /* nothing in the queue */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to get event after timeout"); return FALSE; } static gboolean lu_device_peripheral_write_firmware (LuDevice *device, GBytes *fw, GError **error) { gsize sz = 0; const guint8 *data; guint8 cmd = 0x04; guint8 idx; /* if we're in bootloader mode, we should be able to get this feature */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU); if (idx == 0x00) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "no DFU feature available"); return FALSE; } /* flash hardware */ data = g_bytes_get_data (fw, &sz); for (gsize i = 0; i < sz / 16; i++) { /* send packet and wait for reply */ g_debug ("send data at addr=0x%04x", (guint) i * 16); if (!lu_device_peripheral_write_firmware_pkt (device, idx, cmd, data + (i * 16), error)) { g_prefix_error (error, "failed to write @0x%04x: ", (guint) i * 16); return FALSE; } /* use sliding window */ cmd = (cmd + 1) % 4; /* update progress-bar */ fu_device_set_progress_full (FU_DEVICE (device), i * 16, sz); } return TRUE; } static gboolean lu_device_peripheral_attach (LuDevice *device, GError **error) { LuDevicePeripheral *self = LU_DEVICE_PERIPHERAL (device); guint8 idx; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* if we're in bootloader mode, we should be able to get this feature */ idx = lu_device_hidpp_feature_get_idx (device, HIDPP_FEATURE_DFU); if (idx == 0x00) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "no DFU feature available"); return FALSE; } /* reboot back into firmware mode */ msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = idx; msg->function_id = 0x05 << 4; /* restart */ msg->data[0] = self->cached_fw_entity; /* fwEntity */ msg->flags = LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID | LU_HIDPP_MSG_FLAG_IGNORE_SWID | // inferred? LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to restart device: "); return FALSE; } /* reprobe */ if (!lu_device_probe (device, error)) return FALSE; /* success */ return TRUE; } static gboolean lu_device_peripheral_poll (LuDevice *device, GError **error) { const guint timeout = 1; /* ms */ g_autoptr(GError) error_local = NULL; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* flush pending data */ if (!lu_device_hidpp_receive (device, msg, timeout, &error_local)) { if (!g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to get pending read: %s", error_local->message); return FALSE; } } /* just ping */ if (lu_device_has_flag (device, LU_DEVICE_FLAG_ACTIVE)) return lu_device_peripheral_ping (device, error); /* probe, which also involves a ping first */ return lu_device_probe (device, error); } static void lu_device_peripheral_finalize (GObject *object) { G_OBJECT_CLASS (lu_device_peripheral_parent_class)->finalize (object); } static void lu_device_peripheral_class_init (LuDevicePeripheralClass *klass) { LuDeviceClass *klass_device = LU_DEVICE_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = lu_device_peripheral_finalize; klass_device->probe = lu_device_peripheral_probe; klass_device->poll = lu_device_peripheral_poll; klass_device->write_firmware = lu_device_peripheral_write_firmware; klass_device->attach = lu_device_peripheral_attach; klass_device->detach = lu_device_peripheral_detach; } static void lu_device_peripheral_init (LuDevicePeripheral *self) { } fwupd-1.0.6/plugins/unifying/lu-device-peripheral.h000066400000000000000000000023761325145456600223560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_PERIPHERAL_H #define __LU_DEVICE_PERIPHERAL_H #include "lu-device.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE_PERIPHERAL (lu_device_peripheral_get_type ()) G_DECLARE_FINAL_TYPE (LuDevicePeripheral, lu_device_peripheral, LU, DEVICE_PERIPHERAL, LuDevice) G_END_DECLS #endif /* __LU_DEVICE_PERIPHERAL_H */ fwupd-1.0.6/plugins/unifying/lu-device-runtime.c000066400000000000000000000173161325145456600217010ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "lu-common.h" #include "lu-device-runtime.h" #include "lu-hidpp.h" struct _LuDeviceRuntime { LuDevice parent_instance; }; G_DEFINE_TYPE (LuDeviceRuntime, lu_device_runtime, LU_TYPE_DEVICE) #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) #endif static gboolean lu_device_runtime_enable_notifications (LuDevice *device, GError **error) { g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = HIDPP_SUBID_SET_REGISTER; msg->function_id = HIDPP_REGISTER_HIDPP_NOTIFICATIONS; msg->data[0] = 0x00; msg->data[1] = 0x05; /* Wireless + SoftwarePresent */ msg->data[2] = 0x00; return lu_device_hidpp_transfer (device, msg, error); } static gboolean lu_device_runtime_open (LuDevice *device, GError **error) { GUdevDevice *udev_device = lu_device_get_udev_device (device); GUsbDevice *usb_device = lu_device_get_usb_device (device); guint16 release = 0xffff; guint8 config[10]; guint8 version_bl_major = 0; g_autofree gchar *devid1 = NULL; g_autofree gchar *version_bl = NULL; g_autofree gchar *version_fw = NULL; /* add a generic GUID */ devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X", (guint) LU_DEVICE_VID, (guint) LU_DEVICE_PID_RUNTIME); fu_device_add_guid (FU_DEVICE (device), devid1); /* generate bootloadder-specific GUID */ if (usb_device != NULL) { release = g_usb_device_get_release (usb_device); } else if (udev_device != NULL) { g_autoptr(GUdevDevice) udev_parent = NULL; udev_parent = g_udev_device_get_parent_with_subsystem (udev_device, "usb", "usb_device"); if (udev_parent != NULL) { const gchar *release_str; release_str = g_udev_device_get_property (udev_parent, "ID_REVISION"); if (release_str != NULL) release = g_ascii_strtoull (release_str, NULL, 16); } } if (release != 0xffff) { g_autofree gchar *devid2 = NULL; switch (release &= 0xff00) { case 0x1200: /* Nordic */ devid2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X", (guint) LU_DEVICE_VID, (guint) LU_DEVICE_PID_BOOTLOADER_NORDIC); fu_device_add_guid (FU_DEVICE (device), devid2); version_bl_major = 0x01; break; case 0x2400: /* Texas */ devid2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X", (guint) LU_DEVICE_VID, (guint) LU_DEVICE_PID_BOOTLOADER_TEXAS); fu_device_add_guid (FU_DEVICE (device), devid2); version_bl_major = 0x03; break; default: g_warning ("bootloader release %04x invalid", release); break; } } /* read all 10 bytes of the version register */ memset (config, 0x00, sizeof (config)); for (guint i = 0x01; i < 0x05; i++) { g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* workaround a bug in the 12.01 firmware, which fails with * INVALID_VALUE when reading MCU1_HW_VERSION */ if (i == 0x03) continue; msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = HIDPP_SUBID_GET_REGISTER; msg->function_id = HIDPP_REGISTER_DEVICE_FIRMWARE_INFORMATION; msg->data[0] = i; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to read device config: "); return FALSE; } memcpy (config + (i * 2), msg->data + 1, 2); } /* get firmware version */ version_fw = lu_format_version ("RQR", config[2], config[3], (guint16) config[4] << 8 | config[5]); fu_device_set_version (FU_DEVICE (device), version_fw); /* get bootloader version */ if (version_bl_major > 0) { version_bl = lu_format_version ("BOT", version_bl_major, config[8], config[9]); fu_device_set_version_bootloader (FU_DEVICE (device), version_bl); /* is the dongle expecting signed firmware */ if ((version_bl_major == 0x01 && config[8] >= 0x04) || (version_bl_major == 0x03 && config[8] >= 0x02)) { lu_device_add_flag (device, LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE); } } /* enable HID++ notifications */ if (!lu_device_runtime_enable_notifications (device, error)) { g_prefix_error (error, "failed to enable notifications: "); return FALSE; } /* this only exists with the original HID++1.0 version */ lu_device_set_hidpp_version (device, 1.f); /* we can flash this */ fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE); /* only the bootloader can do the update */ fu_device_set_name (FU_DEVICE (device), "Unifying Receiver"); return TRUE; } static gboolean lu_device_runtime_detach (LuDevice *device, GError **error) { g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = lu_device_get_hidpp_id (device); msg->sub_id = HIDPP_SUBID_SET_REGISTER; msg->function_id = HIDPP_REGISTER_DEVICE_FIRMWARE_UPDATE_MODE; msg->data[0] = 'I'; msg->data[1] = 'C'; msg->data[2] = 'P'; msg->flags = LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT; if (!lu_device_hidpp_send (device, msg, LU_DEVICE_TIMEOUT_MS, error)) { g_prefix_error (error, "failed to detach to bootloader: "); return FALSE; } return TRUE; } static gboolean lu_device_runtime_poll (LuDevice *device, GError **error) { const guint timeout = 1; /* ms */ g_autoptr(GError) error_local = NULL; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* is there any pending data to read */ if (!lu_device_hidpp_receive (device, msg, timeout, &error_local)) { if (g_error_matches (error_local, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) { return TRUE; } g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to get pending read: %s", error_local->message); return FALSE; } /* HID++1.0 error */ if (!lu_hidpp_msg_is_error (msg, error)) return FALSE; /* unifying receiver notification */ if (msg->report_id == HIDPP_REPORT_ID_SHORT) { switch (msg->sub_id) { case HIDPP_SUBID_DEVICE_CONNECTION: case HIDPP_SUBID_DEVICE_DISCONNECTION: case HIDPP_SUBID_DEVICE_LOCKING_CHANGED: g_debug ("device connection event, do something"); break; case HIDPP_SUBID_LINK_QUALITY: g_debug ("ignoring link quality message"); break; case HIDPP_SUBID_ERROR_MSG: g_debug ("ignoring link quality message"); break; default: g_debug ("unknown SubID %02x", msg->sub_id); break; } } return TRUE; } static void lu_device_runtime_class_init (LuDeviceRuntimeClass *klass) { LuDeviceClass *klass_device = LU_DEVICE_CLASS (klass); klass_device->open = lu_device_runtime_open; klass_device->poll = lu_device_runtime_poll; klass_device->detach = lu_device_runtime_detach; } static void lu_device_runtime_init (LuDeviceRuntime *device) { /* FIXME: we need something better */ fu_device_add_icon (FU_DEVICE (device), "preferences-desktop-keyboard"); fu_device_set_summary (FU_DEVICE (device), "A miniaturised USB wireless receiver"); } fwupd-1.0.6/plugins/unifying/lu-device-runtime.h000066400000000000000000000023531325145456600217010ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_RUNTIME_H #define __LU_DEVICE_RUNTIME_H #include "lu-device.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE_RUNTIME (lu_device_runtime_get_type ()) G_DECLARE_FINAL_TYPE (LuDeviceRuntime, lu_device_runtime, LU, DEVICE_RUNTIME, LuDevice) G_END_DECLS #endif /* __LU_DEVICE_RUNTIME_H */ fwupd-1.0.6/plugins/unifying/lu-device.c000066400000000000000000000754211325145456600202210ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include "lu-common.h" #include "lu-device-bootloader-nordic.h" #include "lu-device-bootloader-texas.h" #include "lu-device.h" #include "lu-device-runtime.h" #include "lu-hidpp.h" typedef struct { LuDeviceKind kind; GUdevDevice *udev_device; gint udev_device_fd; GUsbDevice *usb_device; FuDeviceLocker *usb_device_locker; gchar *version_hw; LuDeviceFlags flags; guint8 hidpp_id; guint8 battery_level; gdouble hidpp_version; GPtrArray *feature_index; } LuDevicePrivate; typedef struct { guint8 idx; guint16 feature; } LuDeviceHidppMap; G_DEFINE_TYPE_WITH_PRIVATE (LuDevice, lu_device, FU_TYPE_DEVICE) enum { PROP_0, PROP_KIND, PROP_HIDPP_ID, PROP_FLAGS, PROP_UDEV_DEVICE, PROP_USB_DEVICE, PROP_LAST }; #define GET_PRIVATE(o) (lu_device_get_instance_private (o)) LuDeviceKind lu_device_kind_from_string (const gchar *kind) { if (g_strcmp0 (kind, "runtime") == 0) return LU_DEVICE_KIND_RUNTIME; if (g_strcmp0 (kind, "bootloader-nordic") == 0) return LU_DEVICE_KIND_BOOTLOADER_NORDIC; if (g_strcmp0 (kind, "bootloader-texas") == 0) return LU_DEVICE_KIND_BOOTLOADER_TEXAS; if (g_strcmp0 (kind, "peripheral") == 0) return LU_DEVICE_KIND_PERIPHERAL; return LU_DEVICE_KIND_UNKNOWN; } const gchar * lu_device_kind_to_string (LuDeviceKind kind) { if (kind == LU_DEVICE_KIND_RUNTIME) return "runtime"; if (kind == LU_DEVICE_KIND_BOOTLOADER_NORDIC) return "bootloader-nordic"; if (kind == LU_DEVICE_KIND_BOOTLOADER_TEXAS) return "bootloader-texas"; if (kind == LU_DEVICE_KIND_PERIPHERAL) return "peripheral"; return NULL; } static const gchar * lu_hidpp_feature_to_string (guint16 feature) { if (feature == HIDPP_FEATURE_ROOT) return "Root"; if (feature == HIDPP_FEATURE_I_FIRMWARE_INFO) return "IFirmwareInfo"; if (feature == HIDPP_FEATURE_GET_DEVICE_NAME_TYPE) return "GetDevicenameType"; if (feature == HIDPP_FEATURE_BATTERY_LEVEL_STATUS) return "BatteryLevelStatus"; if (feature == HIDPP_FEATURE_DFU_CONTROL) return "DfuControl"; if (feature == HIDPP_FEATURE_DFU_CONTROL_SIGNED) return "DfuControlSigned"; if (feature == HIDPP_FEATURE_DFU) return "Dfu"; return NULL; } static gchar * lu_device_flags_to_string (LuDeviceFlags flags) { GString *str = g_string_new (NULL); if (flags & LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE) g_string_append (str, "signed-firmware,"); if (flags & LU_DEVICE_FLAG_REQUIRES_RESET) g_string_append (str, "requires-reset,"); if (flags & LU_DEVICE_FLAG_ACTIVE) g_string_append (str, "active,"); if (flags & LU_DEVICE_FLAG_IS_OPEN) g_string_append (str, "is-open,"); if (flags & LU_DEVICE_FLAG_REQUIRES_ATTACH) g_string_append (str, "requires-attach,"); if (flags & LU_DEVICE_FLAG_REQUIRES_DETACH) g_string_append (str, "requires-detach,"); if (flags & LU_DEVICE_FLAG_DETACH_WILL_REPLUG) g_string_append (str, "detach-will-replug,"); if (str->len == 0) { g_string_append (str, "none"); } else { g_string_truncate (str, str->len - 1); } return g_string_free (str, FALSE); } static void lu_device_to_string (FuDevice *device, GString *str) { LuDevice *self = LU_DEVICE (device); LuDevicePrivate *priv = GET_PRIVATE (self); g_autofree gchar *flags_str = NULL; g_string_append_printf (str, " Type:\t\t\t%s\n", lu_device_kind_to_string (priv->kind)); flags_str = lu_device_flags_to_string (priv->flags); g_string_append_printf (str, " Flags:\t\t%s\n", flags_str); g_string_append_printf (str, " HidppVersion:\t\t%.2f\n", priv->hidpp_version); if (priv->hidpp_id != HIDPP_DEVICE_ID_UNSET) g_string_append_printf (str, " HidppId:\t\t0x%02x\n", (guint) priv->hidpp_id); if (priv->udev_device_fd > 0) g_string_append_printf (str, " UdevDevice:\t\t%i\n", priv->udev_device_fd); if (priv->usb_device != NULL) g_string_append_printf (str, " UsbDevice:\t\t%p\n", priv->usb_device); if (priv->version_hw != NULL) g_string_append_printf (str, " VersionHardware:\t%s\n", priv->version_hw); if (priv->battery_level != 0) g_string_append_printf (str, " Battery-level:\t\t%u\n", priv->battery_level); for (guint i = 0; i < priv->feature_index->len; i++) { LuDeviceHidppMap *map = g_ptr_array_index (priv->feature_index, i); g_string_append_printf (str, " Feature%02x:\t\t%s [0x%04x]\n", map->idx, lu_hidpp_feature_to_string (map->feature), map->feature); } /* fixme: superclass? */ if (LU_IS_DEVICE_BOOTLOADER (device)) { g_string_append_printf (str, " FlashAddrHigh:\t0x%04x\n", lu_device_bootloader_get_addr_hi (self)); g_string_append_printf (str, " FlashAddrLow:\t0x%04x\n", lu_device_bootloader_get_addr_lo (self)); g_string_append_printf (str, " FlashBlockSize:\t0x%04x\n", lu_device_bootloader_get_blocksize (self)); } } guint8 lu_device_hidpp_feature_get_idx (LuDevice *device, guint16 feature) { LuDevicePrivate *priv = GET_PRIVATE (device); for (guint i = 0; i < priv->feature_index->len; i++) { LuDeviceHidppMap *map = g_ptr_array_index (priv->feature_index, i); if (map->feature == feature) return map->idx; } return 0x00; } guint16 lu_device_hidpp_feature_find_by_idx (LuDevice *device, guint8 idx) { LuDevicePrivate *priv = GET_PRIVATE (device); for (guint i = 0; i < priv->feature_index->len; i++) { LuDeviceHidppMap *map = g_ptr_array_index (priv->feature_index, i); if (map->idx == idx) return map->feature; } return 0x0000; } static void lu_device_hidpp_dump (LuDevice *device, const gchar *title, const guint8 *data, gsize len) { LuDevicePrivate *priv = GET_PRIVATE (device); g_autofree gchar *title_prefixed = NULL; if (priv->usb_device != NULL) title_prefixed = g_strdup_printf ("[USB] %s", title); else if (priv->udev_device != NULL) title_prefixed = g_strdup_printf ("[HID] %s", title); else title_prefixed = g_strdup_printf ("[EMU] %s", title); lu_dump_raw (title_prefixed, data, len); } static const gchar * lu_device_hidpp20_function_to_string (guint16 feature, guint8 function_id) { if (feature == HIDPP_FEATURE_ROOT) { if (function_id == 0x00) return "getFeature"; if (function_id == 0x01) return "ping"; return NULL; } if (feature == HIDPP_FEATURE_I_FIRMWARE_INFO) { if (function_id == 0x00) return "getCount"; if (function_id == 0x01) return "getInfo"; return NULL; } if (feature == HIDPP_FEATURE_BATTERY_LEVEL_STATUS) { if (function_id == 0x00) return "GetBatteryLevelStatus"; return NULL; } if (feature == HIDPP_FEATURE_DFU_CONTROL) { if (function_id == 0x00) return "getDfuControl"; if (function_id == 0x01) return "setDfuControl"; return NULL; } if (feature == HIDPP_FEATURE_DFU_CONTROL_SIGNED) { if (function_id == 0x00) return "getDfuStatus"; if (function_id == 0x01) return "startDfu"; return NULL; } if (feature == HIDPP_FEATURE_DFU) { if (function_id == 0x00) return "dfuCmdData0"; if (function_id == 0x01) return "dfuCmdData1"; if (function_id == 0x02) return "dfuCmdData2"; if (function_id == 0x03) return "dfuCmdData3"; if (function_id == 0x04) return "dfuStart"; if (function_id == 0x05) return "restart"; return NULL; } return NULL; } static gchar * lu_device_hidpp_msg_to_string (LuDevice *device, LuHidppMsg *msg) { GString *str = g_string_new (NULL); LuDevicePrivate *priv = GET_PRIVATE (device); const gchar *tmp; const gchar *kind_str = lu_device_kind_to_string (priv->kind); g_autoptr(GError) error = NULL; g_autoptr(GString) flags_str = g_string_new (NULL); g_return_val_if_fail (msg != NULL, NULL); g_string_append_printf (str, "device-kind: %s\n", kind_str); if (msg->flags == LU_HIDPP_MSG_FLAG_NONE) { g_string_append (flags_str, "none"); } else { if (msg->flags & LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT) g_string_append (flags_str, "longer-timeout,"); if (msg->flags & LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID) g_string_append (flags_str, "ignore-sub-id,"); if (msg->flags & LU_HIDPP_MSG_FLAG_IGNORE_FNCT_ID) g_string_append (flags_str, "ignore-fnct-id,"); if (msg->flags & LU_HIDPP_MSG_FLAG_IGNORE_SWID) g_string_append (flags_str, "ignore-swid,"); if (str->len > 0) g_string_truncate (str, str->len - 1); } g_string_append_printf (str, "flags: %02x [%s]\n", msg->flags, flags_str->str); g_string_append_printf (str, "report-id: %02x [%s]\n", msg->report_id, lu_hidpp_msg_rpt_id_to_string (msg)); tmp = lu_hidpp_msg_dev_id_to_string (msg); g_string_append_printf (str, "device-id: %02x [%s]\n", msg->device_id, tmp ); if (priv->hidpp_version >= 2.f) { guint16 feature = lu_device_hidpp_feature_find_by_idx (device, msg->sub_id); guint8 sw_id = msg->function_id & 0x0f; guint8 function_id = (msg->function_id & 0xf0) >> 4; g_string_append_printf (str, "feature: %04x [%s]\n", feature, lu_hidpp_feature_to_string (feature)); g_string_append_printf (str, "function-id: %02x [%s]\n", function_id, lu_device_hidpp20_function_to_string (feature, function_id)); g_string_append_printf (str, "sw-id: %02x [%s]\n", sw_id, sw_id == LU_HIDPP_MSG_SW_ID ? "fwupd" : "???"); } else { g_string_append_printf (str, "sub-id: %02x [%s]\n", msg->sub_id, lu_hidpp_msg_sub_id_to_string (msg)); g_string_append_printf (str, "function-id: %02x [%s]\n", msg->function_id, lu_hidpp_msg_fcn_id_to_string (msg)); } if (!lu_hidpp_msg_is_error (msg, &error)) { g_string_append_printf (str, "error: %s\n", error->message); } return g_string_free (str, FALSE); } gboolean lu_device_hidpp_send (LuDevice *device, LuHidppMsg *msg, guint timeout, GError **error) { LuDevicePrivate *priv = GET_PRIVATE (device); gsize len = lu_hidpp_msg_get_payload_length (msg); /* only for HID++2.0 */ if (lu_device_get_hidpp_version (device) >= 2.f) msg->function_id |= LU_HIDPP_MSG_SW_ID; lu_device_hidpp_dump (device, "host->device", (guint8 *) msg, len); /* detailed debugging */ if (g_getenv ("FWUPD_UNIFYING_VERBOSE") != NULL) { g_autofree gchar *str = lu_device_hidpp_msg_to_string (device, msg); g_print ("%s", str); } /* USB */ if (priv->usb_device != NULL) { gsize actual_length = 0; if (!g_usb_device_control_transfer (priv->usb_device, G_USB_DEVICE_DIRECTION_HOST_TO_DEVICE, G_USB_DEVICE_REQUEST_TYPE_CLASS, G_USB_DEVICE_RECIPIENT_INTERFACE, LU_REQUEST_SET_REPORT, 0x0210, 0x0002, (guint8 *) msg, len, &actual_length, timeout, NULL, error)) { g_prefix_error (error, "failed to send data: "); return FALSE; } if (actual_length != len) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "failed to send data: " "wrote %" G_GSIZE_FORMAT " of %" G_GSIZE_FORMAT, actual_length, len); return FALSE; } /* HID */ } else if (priv->udev_device != NULL) { if (!lu_nonblock_write (priv->udev_device_fd, (guint8 *) msg, len, error)) { g_prefix_error (error, "failed to send: "); return FALSE; } } /* success */ return TRUE; } gboolean lu_device_hidpp_receive (LuDevice *device, LuHidppMsg *msg, guint timeout, GError **error) { LuDevicePrivate *priv = GET_PRIVATE (device); gsize read_size = 0; /* USB */ if (priv->usb_device != NULL) { if (!g_usb_device_interrupt_transfer (priv->usb_device, LU_DEVICE_EP3, (guint8 *) msg, sizeof(LuHidppMsg), &read_size, timeout, NULL, error)) { g_prefix_error (error, "failed to get data: "); return FALSE; } /* HID */ } else if (priv->udev_device != NULL) { if (!lu_nonblock_read (priv->udev_device_fd, (guint8 *) msg, sizeof(LuHidppMsg), &read_size, timeout, error)) { g_prefix_error (error, "failed to receive: "); return FALSE; } } /* check long enough, but allow returning oversize packets */ lu_device_hidpp_dump (device, "device->host", (guint8 *) msg, read_size); if (read_size < lu_hidpp_msg_get_payload_length (msg)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "message length too small, " "got %" G_GSIZE_FORMAT " expected %" G_GSIZE_FORMAT, read_size, lu_hidpp_msg_get_payload_length (msg)); return FALSE; } /* detailed debugging */ if (g_getenv ("FWUPD_UNIFYING_VERBOSE") != NULL) { g_autofree gchar *str = lu_device_hidpp_msg_to_string (device, msg); g_print ("%s", str); } /* success */ return TRUE; } gboolean lu_device_hidpp_transfer (LuDevice *device, LuHidppMsg *msg, GError **error) { LuDevicePrivate *priv = GET_PRIVATE (device); guint timeout = LU_DEVICE_TIMEOUT_MS; g_autoptr(LuHidppMsg) msg_tmp = lu_hidpp_msg_new (); /* increase timeout for some operations */ if (msg->flags & LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT) timeout *= 10; /* send request */ if (!lu_device_hidpp_send (device, msg, timeout, error)) return FALSE; /* keep trying to receive until we get a valid reply */ while (1) { if (!lu_device_hidpp_receive (device, msg_tmp, timeout, error)) return FALSE; /* we don't know how to handle this report packet */ if (lu_hidpp_msg_get_payload_length (msg_tmp) == 0x0) { g_debug ("HID++1.0 report 0x%02x has unknown length, ignoring", msg_tmp->report_id); continue; } if (!lu_hidpp_msg_is_error (msg_tmp, error)) return FALSE; /* is valid reply */ if (lu_hidpp_msg_is_reply (msg, msg_tmp)) break; /* to ensure compatibility when an HID++ 2.0 device is * connected to an HID++ 1.0 receiver, any feature index * corresponding to an HID++ 1.0 sub-identifier which could be * sent by the receiver, must be assigned to a dummy feature */ if (lu_device_get_hidpp_version (device) >= 2.f) { if (lu_hidpp_msg_is_hidpp10_compat (msg_tmp)) { g_debug ("ignoring HID++1.0 reply"); continue; } /* not us */ if ((msg->flags & LU_HIDPP_MSG_FLAG_IGNORE_SWID) == 0) { if (!lu_hidpp_msg_verify_swid (msg_tmp)) { g_debug ("ignoring reply with SwId 0x%02i, expected 0x%02i", msg_tmp->function_id & 0x0f, LU_HIDPP_MSG_SW_ID); continue; } } } g_debug ("ignoring message"); }; /* if the HID++ ID is unset, grab it from the reply */ if (priv->hidpp_id == HIDPP_DEVICE_ID_UNSET) { priv->hidpp_id = msg_tmp->device_id; g_debug ("HID++ ID now %02x", priv->hidpp_id); } /* copy over data */ lu_hidpp_msg_copy (msg, msg_tmp); return TRUE; } gboolean lu_device_hidpp_feature_search (LuDevice *device, guint16 feature, GError **error) { LuDevicePrivate *priv = GET_PRIVATE (device); LuDeviceHidppMap *map; g_autoptr(LuHidppMsg) msg = lu_hidpp_msg_new (); /* find the idx for the feature */ msg->report_id = HIDPP_REPORT_ID_SHORT; msg->device_id = priv->hidpp_id; msg->sub_id = 0x00; /* rootIndex */ msg->function_id = 0x00 << 4; /* getFeature */ msg->data[0] = feature >> 8; msg->data[1] = feature; msg->data[2] = 0x00; if (!lu_device_hidpp_transfer (device, msg, error)) { g_prefix_error (error, "failed to get idx for feature %s [0x%04x]: ", lu_hidpp_feature_to_string (feature), feature); return FALSE; } /* zero index */ if (msg->data[0] == 0x00) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "feature %s [0x%04x] not found", lu_hidpp_feature_to_string (feature), feature); return FALSE; } /* add to map */ map = g_new0 (LuDeviceHidppMap, 1); map->idx = msg->data[0]; map->feature = feature; g_ptr_array_add (priv->feature_index, map); g_debug ("added feature %s [0x%04x] as idx %02x", lu_hidpp_feature_to_string (feature), feature, map->idx); return TRUE; } LuDeviceKind lu_device_get_kind (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->kind; } guint8 lu_device_get_hidpp_id (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->hidpp_id; } void lu_device_set_hidpp_id (LuDevice *device, guint8 hidpp_id) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->hidpp_id = hidpp_id; } guint8 lu_device_get_battery_level (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->battery_level; } void lu_device_set_battery_level (LuDevice *device, guint8 percentage) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->battery_level = percentage; } gdouble lu_device_get_hidpp_version (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->hidpp_version; } void lu_device_set_hidpp_version (LuDevice *device, gdouble hidpp_version) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->hidpp_version = hidpp_version; } const gchar * lu_device_get_version_hw (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->version_hw; } void lu_device_set_version_hw (LuDevice *device, const gchar *version_hw) { LuDevicePrivate *priv = GET_PRIVATE (device); g_free (priv->version_hw); priv->version_hw = g_strdup (version_hw); } gboolean lu_device_has_flag (LuDevice *device, LuDeviceFlags flag) { LuDevicePrivate *priv = GET_PRIVATE (device); return (priv->flags & flag) > 0; } void lu_device_add_flag (LuDevice *device, LuDeviceFlags flag) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->flags |= flag; g_object_notify (G_OBJECT (device), "flags"); } void lu_device_remove_flag (LuDevice *device, LuDeviceFlags flag) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->flags &= ~flag; g_object_notify (G_OBJECT (device), "flags"); } LuDeviceFlags lu_device_get_flags (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->flags; } GUdevDevice * lu_device_get_udev_device (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->udev_device; } GUsbDevice * lu_device_get_usb_device (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); return priv->usb_device; } gboolean lu_device_probe (LuDevice *device, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); LuDevicePrivate *priv = GET_PRIVATE (device); /* clear the feature map (leaving only the root) */ g_ptr_array_set_size (priv->feature_index, 0); /* probe the hardware */ if (klass->probe != NULL) return klass->probe (device, error); return TRUE; } gboolean lu_device_open (LuDevice *device, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); LuDevicePrivate *priv = GET_PRIVATE (device); g_autofree gchar *device_str = NULL; g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already done */ if (lu_device_has_flag (device, LU_DEVICE_FLAG_IS_OPEN)) return TRUE; /* set default vendor */ fu_device_set_vendor (FU_DEVICE (device), "Logitech"); /* USB */ if (priv->usb_device != NULL) { guint8 num_interfaces = 0x01; g_autofree gchar *devid = NULL; /* open device */ if (priv->usb_device_locker == NULL) { g_autoptr(FuDeviceLocker) locker = NULL; g_debug ("opening unifying device using USB"); locker = fu_device_locker_new (priv->usb_device, error); if (locker == NULL) return FALSE; if (priv->kind == LU_DEVICE_KIND_RUNTIME) num_interfaces = 0x03; for (guint i = 0; i < num_interfaces; i++) { g_debug ("claiming interface 0x%02x", i); if (!g_usb_device_claim_interface (priv->usb_device, i, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, error)) { g_prefix_error (error, "Failed to claim 0x%02x: ", i); return FALSE; } } priv->usb_device_locker = g_steal_pointer (&locker); } /* generate GUID */ devid = g_strdup_printf ("USB\\VID_%04X&PID_%04X", g_usb_device_get_vid (priv->usb_device), g_usb_device_get_pid (priv->usb_device)); fu_device_add_guid (FU_DEVICE (device), devid); /* HID */ } else if (priv->udev_device != NULL) { const gchar *devpath = g_udev_device_get_device_file (priv->udev_device); g_debug ("opening unifying device using %s", devpath); priv->udev_device_fd = lu_nonblock_open (devpath, error); if (priv->udev_device_fd < 0) return FALSE; } /* subclassed */ if (klass->open != NULL) { if (!klass->open (device, error)) { lu_device_close (device, NULL); return FALSE; } } lu_device_add_flag (device, LU_DEVICE_FLAG_IS_OPEN); /* subclassed */ if (!lu_device_probe (device, error)) { lu_device_close (device, NULL); return FALSE; } /* add known root for HID++2.0 */ if (lu_device_get_hidpp_version (device) >= 2.f) { LuDeviceHidppMap *map = g_new0 (LuDeviceHidppMap, 1); map->idx = 0x00; map->feature = HIDPP_FEATURE_ROOT; g_ptr_array_add (priv->feature_index, map); } /* show the device */ device_str = fu_device_to_string (FU_DEVICE (device)); g_debug ("%s", device_str); /* success */ return TRUE; } gboolean lu_device_poll (LuDevice *device, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); if (klass->poll != NULL) { if (!klass->poll (device, error)) return FALSE; } return TRUE; } /** * lu_device_close: * @device: A #LuDevice * @error: A #GError, or %NULL * * Closes the device. * * Returns: %TRUE for success **/ gboolean lu_device_close (LuDevice *device, GError **error) { LuDevicePrivate *priv = GET_PRIVATE (device); LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* not open */ if (!lu_device_has_flag (device, LU_DEVICE_FLAG_IS_OPEN)) return TRUE; /* subclassed */ g_debug ("closing device"); if (klass->close != NULL) { if (!klass->close (device, error)) return FALSE; } /* USB */ if (priv->usb_device_locker != NULL) { guint8 num_interfaces = 0x01; if (priv->kind == LU_DEVICE_KIND_RUNTIME) num_interfaces = 0x03; for (guint i = 0; i < num_interfaces; i++) { g_autoptr(GError) error_local = NULL; g_debug ("releasing interface 0x%02x", i); if (!g_usb_device_release_interface (priv->usb_device, i, G_USB_DEVICE_CLAIM_INTERFACE_BIND_KERNEL_DRIVER, &error_local)) { if (!g_error_matches (error_local, G_USB_DEVICE_ERROR, G_USB_DEVICE_ERROR_INTERNAL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to release 0x%02x: %s", i, error_local->message); return FALSE; } } } g_clear_object (&priv->usb_device_locker); } g_clear_object (&priv->usb_device); /* HID */ if (priv->udev_device != NULL && priv->udev_device_fd > 0) { if (!g_close (priv->udev_device_fd, error)) return FALSE; priv->udev_device_fd = 0; } /* success */ lu_device_remove_flag (device, LU_DEVICE_FLAG_IS_OPEN); return TRUE; } gboolean lu_device_detach (LuDevice *device, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* subclassed */ g_debug ("detaching device"); if (klass->detach != NULL) return klass->detach (device, error); /* nothing to do */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "device detach is not supported"); return FALSE; } gboolean lu_device_attach (LuDevice *device, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* check kind */ if (lu_device_get_kind (device) == LU_DEVICE_KIND_RUNTIME) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "device is not in bootloader state"); return FALSE; } /* subclassed */ if (klass->attach != NULL) return klass->attach (device, error); return TRUE; } gboolean lu_device_write_firmware (LuDevice *device, GBytes *fw, GError **error) { LuDeviceClass *klass = LU_DEVICE_GET_CLASS (device); g_return_val_if_fail (LU_IS_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* corrupt */ if (g_bytes_get_size (fw) < 0x4000) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "firmware is too small"); return FALSE; } /* call device-specific method */ if (klass->write_firmware == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "not supported in %s", lu_device_kind_to_string (lu_device_get_kind (device))); return FALSE; } /* call either nordic or texas vfunc */ return klass->write_firmware (device, fw, error); } #ifndef HAVE_GUDEV_232 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref) #endif static GUdevDevice * lu_device_find_udev_device (GUsbDevice *usb_device) { g_autoptr(GUdevClient) gudev_client = g_udev_client_new (NULL); g_autoptr(GList) devices = NULL; devices = g_udev_client_query_by_subsystem (gudev_client, "usb"); for (GList *l = devices; l != NULL; l = l->next) { guint busnum; guint devnum; g_autoptr(GUdevDevice) udev_device = G_UDEV_DEVICE (l->data); g_autoptr(GUdevDevice) udev_parent = g_udev_device_get_parent (udev_device); busnum = g_udev_device_get_sysfs_attr_as_int (udev_parent, "busnum"); if (busnum != g_usb_device_get_bus (usb_device)) continue; devnum = g_udev_device_get_sysfs_attr_as_int (udev_parent, "devnum"); if (devnum != g_usb_device_get_address (usb_device)) continue; return g_object_ref (udev_parent); } return NULL; } static void lu_device_update_platform_id (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); if (priv->usb_device != NULL && priv->udev_device == NULL) { g_autoptr(GUdevDevice) udev_device = NULL; udev_device = lu_device_find_udev_device (priv->usb_device); if (udev_device != NULL) { const gchar *tmp = g_udev_device_get_sysfs_path (udev_device); fu_device_set_platform_id (FU_DEVICE (device), tmp); } } } static void lu_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { LuDevice *device = LU_DEVICE (object); LuDevicePrivate *priv = GET_PRIVATE (device); switch (prop_id) { case PROP_KIND: g_value_set_uint (value, priv->kind); break; case PROP_HIDPP_ID: g_value_set_uint (value, priv->hidpp_id); break; case PROP_FLAGS: g_value_set_uint64 (value, priv->flags); break; case PROP_UDEV_DEVICE: g_value_set_object (value, priv->udev_device); break; case PROP_USB_DEVICE: g_value_set_object (value, priv->usb_device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void lu_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { LuDevice *device = LU_DEVICE (object); LuDevicePrivate *priv = GET_PRIVATE (device); switch (prop_id) { case PROP_KIND: priv->kind = g_value_get_uint (value); break; case PROP_HIDPP_ID: priv->hidpp_id = g_value_get_uint (value); break; case PROP_FLAGS: priv->flags = g_value_get_uint64 (value); break; case PROP_UDEV_DEVICE: priv->udev_device = g_value_dup_object (value); break; case PROP_USB_DEVICE: priv->usb_device = g_value_dup_object (value); lu_device_update_platform_id (device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void lu_device_finalize (GObject *object) { LuDevice *device = LU_DEVICE (object); LuDevicePrivate *priv = GET_PRIVATE (device); if (priv->usb_device != NULL) g_object_unref (priv->usb_device); if (priv->usb_device_locker != NULL) g_object_unref (priv->usb_device_locker); if (priv->udev_device != NULL) g_object_unref (priv->udev_device); g_ptr_array_unref (priv->feature_index); g_free (priv->version_hw); G_OBJECT_CLASS (lu_device_parent_class)->finalize (object); } static void lu_device_init (LuDevice *device) { LuDevicePrivate *priv = GET_PRIVATE (device); priv->hidpp_id = HIDPP_DEVICE_ID_UNSET; priv->feature_index = g_ptr_array_new_with_free_func (g_free); fu_device_set_vendor_id (FU_DEVICE (device), "USB:0x046D"); } static void lu_device_class_init (LuDeviceClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); object_class->finalize = lu_device_finalize; object_class->get_property = lu_device_get_property; object_class->set_property = lu_device_set_property; klass_device->to_string = lu_device_to_string; pspec = g_param_spec_uint ("kind", NULL, NULL, LU_DEVICE_KIND_UNKNOWN, LU_DEVICE_KIND_LAST, LU_DEVICE_KIND_UNKNOWN, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_KIND, pspec); pspec = g_param_spec_uint ("hidpp-id", NULL, NULL, HIDPP_DEVICE_ID_WIRED, HIDPP_DEVICE_ID_RECEIVER, HIDPP_DEVICE_ID_UNSET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_HIDPP_ID, pspec); pspec = g_param_spec_uint64 ("flags", NULL, NULL, LU_DEVICE_FLAG_NONE, 0xffff, LU_DEVICE_FLAG_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_FLAGS, pspec); pspec = g_param_spec_object ("udev-device", NULL, NULL, G_UDEV_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_UDEV_DEVICE, pspec); pspec = g_param_spec_object ("usb-device", NULL, NULL, G_USB_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_USB_DEVICE, pspec); } LuDevice * lu_device_fake_new (LuDeviceKind kind) { LuDevice *device = NULL; switch (kind) { case LU_DEVICE_KIND_BOOTLOADER_NORDIC: device = g_object_new (LU_TYPE_DEVICE_BOOTLOADER_NORDIC, "kind", kind, NULL); break; case LU_DEVICE_KIND_BOOTLOADER_TEXAS: device = g_object_new (LU_TYPE_DEVICE_BOOTLOADER_TEXAS, "kind", kind, NULL); break; case LU_DEVICE_KIND_RUNTIME: device = g_object_new (LU_TYPE_DEVICE_RUNTIME, "kind", kind, NULL); break; default: break; } return device; } fwupd-1.0.6/plugins/unifying/lu-device.h000066400000000000000000000123041325145456600202150ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_DEVICE_H #define __LU_DEVICE_H #include #include #include "fu-plugin.h" #include "lu-hidpp-msg.h" G_BEGIN_DECLS #define LU_TYPE_DEVICE (lu_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (LuDevice, lu_device, LU, DEVICE, FuDevice) struct _LuDeviceClass { FuDeviceClass parent_class; gboolean (*open) (LuDevice *device, GError **error); gboolean (*close) (LuDevice *device, GError **error); gboolean (*probe) (LuDevice *device, GError **error); gboolean (*poll) (LuDevice *device, GError **error); gboolean (*attach) (LuDevice *device, GError **error); gboolean (*detach) (LuDevice *device, GError **error); gboolean (*write_firmware) (LuDevice *device, GBytes *fw, GError **error); }; #define LU_DEVICE_VID 0x046d #define LU_DEVICE_PID_RUNTIME 0xc52b #define LU_DEVICE_PID_BOOTLOADER_NORDIC 0xaaaa #define LU_DEVICE_PID_BOOTLOADER_NORDIC_PICO 0xaaae #define LU_DEVICE_PID_BOOTLOADER_TEXAS 0xaaac #define LU_DEVICE_PID_BOOTLOADER_TEXAS_PICO 0xaaad #define LU_DEVICE_EP1 0x81 #define LU_DEVICE_EP3 0x83 /* Signed firmware are very long to verify on the device */ #define LU_DEVICE_TIMEOUT_MS 20000 typedef enum { LU_DEVICE_KIND_UNKNOWN, LU_DEVICE_KIND_RUNTIME, LU_DEVICE_KIND_BOOTLOADER_NORDIC, LU_DEVICE_KIND_BOOTLOADER_TEXAS, LU_DEVICE_KIND_PERIPHERAL, /*< private >*/ LU_DEVICE_KIND_LAST } LuDeviceKind; typedef enum { LU_DEVICE_FLAG_NONE, LU_DEVICE_FLAG_ACTIVE = 1 << 0, LU_DEVICE_FLAG_IS_OPEN = 1 << 1, LU_DEVICE_FLAG_REQUIRES_SIGNED_FIRMWARE = 1 << 3, LU_DEVICE_FLAG_REQUIRES_RESET = 1 << 4, LU_DEVICE_FLAG_REQUIRES_ATTACH = 1 << 5, LU_DEVICE_FLAG_REQUIRES_DETACH = 1 << 6, LU_DEVICE_FLAG_ATTACH_WILL_REPLUG = 1 << 7, LU_DEVICE_FLAG_DETACH_WILL_REPLUG = 1 << 8, /*< private >*/ LU_DEVICE_FLAG_LAST } LuDeviceFlags; LuDeviceKind lu_device_kind_from_string (const gchar *kind); const gchar *lu_device_kind_to_string (LuDeviceKind kind); LuDeviceKind lu_device_get_kind (LuDevice *device); guint8 lu_device_get_hidpp_id (LuDevice *device); void lu_device_set_hidpp_id (LuDevice *device, guint8 hidpp_id); guint8 lu_device_get_battery_level (LuDevice *device); void lu_device_set_battery_level (LuDevice *device, guint8 percentage); gdouble lu_device_get_hidpp_version (LuDevice *device); void lu_device_set_hidpp_version (LuDevice *device, gdouble hidpp_version); gboolean lu_device_has_flag (LuDevice *device, LuDeviceFlags flag); void lu_device_add_flag (LuDevice *device, LuDeviceFlags flag); void lu_device_remove_flag (LuDevice *device, LuDeviceFlags flag); LuDeviceFlags lu_device_get_flags (LuDevice *device); const gchar *lu_device_get_version_hw (LuDevice *device); void lu_device_set_version_hw (LuDevice *device, const gchar *version_hw); GUdevDevice *lu_device_get_udev_device (LuDevice *device); GUsbDevice *lu_device_get_usb_device (LuDevice *device); LuDevice *lu_device_fake_new (LuDeviceKind kind); gboolean lu_device_open (LuDevice *device, GError **error); gboolean lu_device_close (LuDevice *device, GError **error); gboolean lu_device_detach (LuDevice *device, GError **error); gboolean lu_device_attach (LuDevice *device, GError **error); gboolean lu_device_probe (LuDevice *device, GError **error); gboolean lu_device_poll (LuDevice *device, GError **error); gboolean lu_device_write_firmware (LuDevice *device, GBytes *fw, GError **error); gboolean lu_device_hidpp_send (LuDevice *device, LuHidppMsg *msg, guint timeout, GError **error); gboolean lu_device_hidpp_receive (LuDevice *device, LuHidppMsg *msg, guint timeout, GError **error); gboolean lu_device_hidpp_transfer (LuDevice *device, LuHidppMsg *msg, GError **error); gboolean lu_device_hidpp_feature_search (LuDevice *device, guint16 feature, GError **error); guint8 lu_device_hidpp_feature_get_idx (LuDevice *device, guint16 feature); guint16 lu_device_hidpp_feature_find_by_idx (LuDevice *device, guint8 idx); G_END_DECLS #endif /* __LU_DEVICE_H */ fwupd-1.0.6/plugins/unifying/lu-hidpp-msg.c000066400000000000000000000303521325145456600206440ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "lu-hidpp.h" #include "lu-hidpp-msg.h" LuHidppMsg * lu_hidpp_msg_new (void) { return g_new0 (LuHidppMsg, 1); } const gchar * lu_hidpp_msg_dev_id_to_string (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, NULL); if (msg->device_id == HIDPP_DEVICE_ID_WIRED) return "wired"; if (msg->device_id == HIDPP_DEVICE_ID_RECEIVER) return "receiver"; if (msg->device_id == HIDPP_DEVICE_ID_UNSET) return "unset"; return NULL; } const gchar * lu_hidpp_msg_rpt_id_to_string (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, NULL); if (msg->report_id == HIDPP_REPORT_ID_SHORT) return "short"; if (msg->report_id == HIDPP_REPORT_ID_LONG) return "long"; if (msg->report_id == HIDPP_REPORT_ID_VERY_LONG) return "very-long"; return NULL; } gsize lu_hidpp_msg_get_payload_length (LuHidppMsg *msg) { if (msg->report_id == HIDPP_REPORT_ID_SHORT) return 0x07; if (msg->report_id == HIDPP_REPORT_ID_LONG) return 0x14; if (msg->report_id == HIDPP_REPORT_ID_VERY_LONG) return 0x2f; if (msg->report_id == HIDPP_REPORT_NOTIFICATION) return 0x08; return 0x0; } const gchar * lu_hidpp_msg_fcn_id_to_string (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, NULL); switch (msg->sub_id) { case HIDPP_SUBID_SET_REGISTER: case HIDPP_SUBID_GET_REGISTER: case HIDPP_SUBID_SET_LONG_REGISTER: case HIDPP_SUBID_GET_LONG_REGISTER: case HIDPP_SUBID_SET_VERY_LONG_REGISTER: case HIDPP_SUBID_GET_VERY_LONG_REGISTER: if (msg->function_id == HIDPP_REGISTER_HIDPP_NOTIFICATIONS) return "hidpp-notifications"; if (msg->function_id == HIDPP_REGISTER_ENABLE_INDIVIDUAL_FEATURES) return "individual-features"; if (msg->function_id == HIDPP_REGISTER_BATTERY_STATUS) return "battery-status"; if (msg->function_id == HIDPP_REGISTER_BATTERY_MILEAGE) return "battery-mileage"; if (msg->function_id == HIDPP_REGISTER_PROFILE) return "profile"; if (msg->function_id == HIDPP_REGISTER_LED_STATUS) return "led-status"; if (msg->function_id == HIDPP_REGISTER_LED_INTENSITY) return "led-intensity"; if (msg->function_id == HIDPP_REGISTER_LED_COLOR) return "led-color"; if (msg->function_id == HIDPP_REGISTER_OPTICAL_SENSOR_SETTINGS) return "optical-sensor-settings"; if (msg->function_id == HIDPP_REGISTER_CURRENT_RESOLUTION) return "current-resolution"; if (msg->function_id == HIDPP_REGISTER_USB_REFRESH_RATE) return "usb-refresh-rate"; if (msg->function_id == HIDPP_REGISTER_GENERIC_MEMORY_MANAGEMENT) return "generic-memory-management"; if (msg->function_id == HIDPP_REGISTER_HOT_CONTROL) return "hot-control"; if (msg->function_id == HIDPP_REGISTER_READ_MEMORY) return "read-memory"; if (msg->function_id == HIDPP_REGISTER_DEVICE_CONNECTION_DISCONNECTION) return "device-connection-disconnection"; if (msg->function_id == HIDPP_REGISTER_PAIRING_INFORMATION) return "pairing-information"; if (msg->function_id == HIDPP_REGISTER_DEVICE_FIRMWARE_UPDATE_MODE) return "device-firmware-update-mode"; if (msg->function_id == HIDPP_REGISTER_DEVICE_FIRMWARE_INFORMATION) return "device-firmware-information"; break; default: break; } return NULL; } const gchar * lu_hidpp_msg_sub_id_to_string (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, NULL); if (msg->sub_id == HIDPP_SUBID_VENDOR_SPECIFIC_KEYS) return "vendor-specific-keys"; if (msg->sub_id == HIDPP_SUBID_POWER_KEYS) return "power-keys"; if (msg->sub_id == HIDPP_SUBID_ROLLER) return "roller"; if (msg->sub_id == HIDPP_SUBID_MOUSE_EXTRA_BUTTONS) return "mouse-extra-buttons"; if (msg->sub_id == HIDPP_SUBID_BATTERY_CHARGING_LEVEL) return "battery-charging-level"; if (msg->sub_id == HIDPP_SUBID_USER_INTERFACE_EVENT) return "user-interface-event"; if (msg->sub_id == HIDPP_SUBID_F_LOCK_STATUS) return "f-lock-status"; if (msg->sub_id == HIDPP_SUBID_CALCULATOR_RESULT) return "calculator-result"; if (msg->sub_id == HIDPP_SUBID_MENU_NAVIGATE) return "menu-navigate"; if (msg->sub_id == HIDPP_SUBID_FN_KEY) return "fn-key"; if (msg->sub_id == HIDPP_SUBID_BATTERY_MILEAGE) return "battery-mileage"; if (msg->sub_id == HIDPP_SUBID_UART_RX) return "uart-rx"; if (msg->sub_id == HIDPP_SUBID_BACKLIGHT_DURATION_UPDATE) return "backlight-duration-update"; if (msg->sub_id == HIDPP_SUBID_DEVICE_DISCONNECTION) return "device-disconnection"; if (msg->sub_id == HIDPP_SUBID_DEVICE_CONNECTION) return "device-connection"; if (msg->sub_id == HIDPP_SUBID_DEVICE_DISCOVERY) return "device-discovery"; if (msg->sub_id == HIDPP_SUBID_PIN_CODE_REQUEST) return "pin-code-request"; if (msg->sub_id == HIDPP_SUBID_RECEIVER_WORKING_MODE) return "receiver-working-mode"; if (msg->sub_id == HIDPP_SUBID_ERROR_MESSAGE) return "error-message"; if (msg->sub_id == HIDPP_SUBID_RF_LINK_CHANGE) return "rf-link-change"; if (msg->sub_id == HIDPP_SUBID_HCI) return "hci"; if (msg->sub_id == HIDPP_SUBID_LINK_QUALITY) return "link-quality"; if (msg->sub_id == HIDPP_SUBID_DEVICE_LOCKING_CHANGED) return "device-locking-changed"; if (msg->sub_id == HIDPP_SUBID_WIRELESS_DEVICE_CHANGE) return "wireless-device-change"; if (msg->sub_id == HIDPP_SUBID_ACL) return "acl"; if (msg->sub_id == HIDPP_SUBID_VOIP_TELEPHONY_EVENT) return "voip-telephony-event"; if (msg->sub_id == HIDPP_SUBID_LED) return "led"; if (msg->sub_id == HIDPP_SUBID_GESTURE_AND_AIR) return "gesture-and-air"; if (msg->sub_id == HIDPP_SUBID_TOUCHPAD_MULTI_TOUCH) return "touchpad-multi-touch"; if (msg->sub_id == HIDPP_SUBID_TRACEABILITY) return "traceability"; if (msg->sub_id == HIDPP_SUBID_SET_REGISTER) return "set-register"; if (msg->sub_id == HIDPP_SUBID_GET_REGISTER) return "get-register"; if (msg->sub_id == HIDPP_SUBID_SET_LONG_REGISTER) return "set-long-register"; if (msg->sub_id == HIDPP_SUBID_GET_LONG_REGISTER) return "get-long-register"; if (msg->sub_id == HIDPP_SUBID_SET_VERY_LONG_REGISTER) return "set-very-long-register"; if (msg->sub_id == HIDPP_SUBID_GET_VERY_LONG_REGISTER) return "get-very-long-register"; if (msg->sub_id == HIDPP_SUBID_ERROR_MSG) return "error-msg"; if (msg->sub_id == HIDPP_SUBID_ERROR_MSG_20) return "error-msg-v2"; return NULL; } gboolean lu_hidpp_msg_is_reply (LuHidppMsg *msg1, LuHidppMsg *msg2) { g_return_val_if_fail (msg1 != NULL, FALSE); g_return_val_if_fail (msg2 != NULL, FALSE); if (msg1->device_id != msg2->device_id && msg1->device_id != HIDPP_DEVICE_ID_UNSET && msg2->device_id != HIDPP_DEVICE_ID_UNSET) return FALSE; if (msg1->flags & LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID || msg2->flags & LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID) return TRUE; if (msg1->sub_id != msg2->sub_id) return FALSE; if (msg1->flags & LU_HIDPP_MSG_FLAG_IGNORE_FNCT_ID || msg2->flags & LU_HIDPP_MSG_FLAG_IGNORE_FNCT_ID) return TRUE; if (msg1->function_id != msg2->function_id) return FALSE; return TRUE; } /* HID++ error */ gboolean lu_hidpp_msg_is_error (LuHidppMsg *msg, GError **error) { g_return_val_if_fail (msg != NULL, FALSE); if (msg->sub_id == HIDPP_SUBID_ERROR_MSG) { switch (msg->data[1]) { case HIDPP_ERR_INVALID_SUBID: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "invalid SubID"); break; case HIDPP_ERR_INVALID_ADDRESS: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "invalid address"); break; case HIDPP_ERR_INVALID_VALUE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "invalid value"); break; case HIDPP_ERR_CONNECT_FAIL: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "connection request failed"); break; case HIDPP_ERR_TOO_MANY_DEVICES: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE, "too many devices connected"); break; case HIDPP_ERR_ALREADY_EXISTS: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS, "already exists"); break; case HIDPP_ERR_BUSY: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_BUSY, "busy"); break; case HIDPP_ERR_UNKNOWN_DEVICE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "unknown device"); break; case HIDPP_ERR_RESOURCE_ERROR: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_HOST_UNREACHABLE, "resource error"); break; case HIDPP_ERR_REQUEST_UNAVAILABLE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_EXISTS, "request not valid in current context"); break; case HIDPP_ERR_INVALID_PARAM_VALUE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "request parameter has unsupported value"); break; case HIDPP_ERR_WRONG_PIN_CODE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED, "the pin code was wrong"); break; default: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "generic failure"); } return FALSE; } if (msg->sub_id == HIDPP_SUBID_ERROR_MSG_20) { switch (msg->data[1]) { case HIDPP_ERROR_CODE_INVALID_ARGUMENT: g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Invalid argument 0x%02x", msg->data[2]); break; case HIDPP_ERROR_CODE_OUT_OF_RANGE: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "out of range"); break; case HIDPP_ERROR_CODE_HW_ERROR: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE, "hardware error"); break; case HIDPP_ERROR_CODE_INVALID_FEATURE_INDEX: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "invalid feature index"); break; case HIDPP_ERROR_CODE_INVALID_FUNCTION_ID: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "invalid function ID"); break; case HIDPP_ERROR_CODE_BUSY: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_BUSY, "busy"); break; case HIDPP_ERROR_CODE_UNSUPPORTED: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "unsupported"); break; default: g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "generic failure"); break; } return FALSE; } return TRUE; } void lu_hidpp_msg_copy (LuHidppMsg *msg_dst, LuHidppMsg *msg_src) { g_return_if_fail (msg_dst != NULL); g_return_if_fail (msg_src != NULL); memset (msg_dst->data, 0x00, sizeof(msg_dst->data)); msg_dst->device_id = msg_src->device_id; msg_dst->sub_id = msg_src->sub_id; msg_dst->function_id = msg_src->function_id; memcpy (msg_dst->data, msg_src->data, sizeof(msg_dst->data)); } /* filter HID++1.0 messages */ gboolean lu_hidpp_msg_is_hidpp10_compat (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, FALSE); if (msg->sub_id == 0x40 || msg->sub_id == 0x41 || msg->sub_id == 0x49 || msg->sub_id == 0x4b || msg->sub_id == 0x8f) { return TRUE; } return FALSE; } gboolean lu_hidpp_msg_verify_swid (LuHidppMsg *msg) { g_return_val_if_fail (msg != NULL, FALSE); if ((msg->function_id & 0x0f) != LU_HIDPP_MSG_SW_ID) return FALSE; return TRUE; } fwupd-1.0.6/plugins/unifying/lu-hidpp-msg.h000066400000000000000000000046511325145456600206540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU_HIDPP_MSG_H #define __LU_HIDPP_MSG_H #include G_BEGIN_DECLS typedef enum { LU_HIDPP_MSG_FLAG_NONE, LU_HIDPP_MSG_FLAG_LONGER_TIMEOUT = 1 << 0, LU_HIDPP_MSG_FLAG_IGNORE_SUB_ID = 1 << 1, LU_HIDPP_MSG_FLAG_IGNORE_FNCT_ID = 1 << 2, LU_HIDPP_MSG_FLAG_IGNORE_SWID = 1 << 3, /*< private >*/ LU_HIDPP_MSG_FLAG_LAST } LuHidppMsgFlags; typedef struct __attribute__((packed)) { guint8 report_id; guint8 device_id; guint8 sub_id; guint8 function_id; /* funcId:software_id */ guint8 data[47]; /* maximum supported by Windows XP SP2 */ /* not included in the packet sent to the hardware */ guint32 flags; } LuHidppMsg; /* this is specific to fwupd */ #define LU_HIDPP_MSG_SW_ID 0x07 G_DEFINE_AUTOPTR_CLEANUP_FUNC(LuHidppMsg, g_free); LuHidppMsg *lu_hidpp_msg_new (void); void lu_hidpp_msg_copy (LuHidppMsg *msg_dst, LuHidppMsg *msg_src); gsize lu_hidpp_msg_get_payload_length (LuHidppMsg *msg); gboolean lu_hidpp_msg_is_reply (LuHidppMsg *msg1, LuHidppMsg *msg2); gboolean lu_hidpp_msg_is_hidpp10_compat (LuHidppMsg *msg); gboolean lu_hidpp_msg_is_error (LuHidppMsg *msg, GError **error); gboolean lu_hidpp_msg_verify_swid (LuHidppMsg *msg); const gchar *lu_hidpp_msg_dev_id_to_string (LuHidppMsg *msg); const gchar *lu_hidpp_msg_rpt_id_to_string (LuHidppMsg *msg); const gchar *lu_hidpp_msg_sub_id_to_string (LuHidppMsg *msg); const gchar *lu_hidpp_msg_fcn_id_to_string (LuHidppMsg *msg); G_END_DECLS #endif /* __LU_HIDPP_MSG_H */ fwupd-1.0.6/plugins/unifying/lu-hidpp.h000066400000000000000000000134771325145456600200760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016-2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __LU__HIDPP_H #define __LU__HIDPP_H G_BEGIN_DECLS #define LU_REQUEST_SET_REPORT 0x09 /* * Based on the HID++ documentation provided by Nestor Lopez Casado at: * https://drive.google.com/folderview?id=0BxbRzx7vEV7eWmgwazJ3NUFfQ28&usp=sharing */ #define HIDPP_DEVICE_ID_WIRED 0x00 #define HIDPP_DEVICE_ID_RECEIVER 0xFF #define HIDPP_DEVICE_ID_UNSET 0xFE #define HIDPP_REPORT_NOTIFICATION 0x01 #define HIDPP_REPORT_ID_SHORT 0x10 #define HIDPP_REPORT_ID_LONG 0x11 #define HIDPP_REPORT_ID_VERY_LONG 0x12 #define HIDPP_SUBID_VENDOR_SPECIFIC_KEYS 0x03 #define HIDPP_SUBID_POWER_KEYS 0x04 #define HIDPP_SUBID_ROLLER 0x05 #define HIDPP_SUBID_MOUSE_EXTRA_BUTTONS 0x06 #define HIDPP_SUBID_BATTERY_CHARGING_LEVEL 0x07 #define HIDPP_SUBID_USER_INTERFACE_EVENT 0x08 #define HIDPP_SUBID_F_LOCK_STATUS 0x09 #define HIDPP_SUBID_CALCULATOR_RESULT 0x0A #define HIDPP_SUBID_MENU_NAVIGATE 0x0B #define HIDPP_SUBID_FN_KEY 0x0C #define HIDPP_SUBID_BATTERY_MILEAGE 0x0D #define HIDPP_SUBID_UART_RX 0x0E #define HIDPP_SUBID_BACKLIGHT_DURATION_UPDATE 0x17 #define HIDPP_SUBID_DEVICE_DISCONNECTION 0x40 #define HIDPP_SUBID_DEVICE_CONNECTION 0x41 #define HIDPP_SUBID_DEVICE_DISCOVERY 0x42 #define HIDPP_SUBID_PIN_CODE_REQUEST 0x43 #define HIDPP_SUBID_RECEIVER_WORKING_MODE 0x44 #define HIDPP_SUBID_ERROR_MESSAGE 0x45 #define HIDPP_SUBID_RF_LINK_CHANGE 0x46 #define HIDPP_SUBID_HCI 0x48 #define HIDPP_SUBID_LINK_QUALITY 0x49 #define HIDPP_SUBID_DEVICE_LOCKING_CHANGED 0x4a #define HIDPP_SUBID_WIRELESS_DEVICE_CHANGE 0x4B #define HIDPP_SUBID_ACL 0x51 #define HIDPP_SUBID_VOIP_TELEPHONY_EVENT 0x5B #define HIDPP_SUBID_LED 0x60 #define HIDPP_SUBID_GESTURE_AND_AIR 0x65 #define HIDPP_SUBID_TOUCHPAD_MULTI_TOUCH 0x66 #define HIDPP_SUBID_TRACEABILITY 0x78 #define HIDPP_SUBID_SET_REGISTER 0x80 #define HIDPP_SUBID_GET_REGISTER 0x81 #define HIDPP_SUBID_SET_LONG_REGISTER 0x82 #define HIDPP_SUBID_GET_LONG_REGISTER 0x83 #define HIDPP_SUBID_SET_VERY_LONG_REGISTER 0x84 #define HIDPP_SUBID_GET_VERY_LONG_REGISTER 0x85 #define HIDPP_SUBID_ERROR_MSG 0x8F #define HIDPP_SUBID_ERROR_MSG_20 0xFF #define HIDPP_ERR_SUCCESS 0x00 #define HIDPP_ERR_INVALID_SUBID 0x01 #define HIDPP_ERR_INVALID_ADDRESS 0x02 #define HIDPP_ERR_INVALID_VALUE 0x03 #define HIDPP_ERR_CONNECT_FAIL 0x04 #define HIDPP_ERR_TOO_MANY_DEVICES 0x05 #define HIDPP_ERR_ALREADY_EXISTS 0x06 #define HIDPP_ERR_BUSY 0x07 #define HIDPP_ERR_UNKNOWN_DEVICE 0x08 #define HIDPP_ERR_RESOURCE_ERROR 0x09 #define HIDPP_ERR_REQUEST_UNAVAILABLE 0x0A #define HIDPP_ERR_INVALID_PARAM_VALUE 0x0B #define HIDPP_ERR_WRONG_PIN_CODE 0x0C /* * HID++1.0 registers */ #define HIDPP_REGISTER_HIDPP_NOTIFICATIONS 0x00 #define HIDPP_REGISTER_ENABLE_INDIVIDUAL_FEATURES 0x01 #define HIDPP_REGISTER_BATTERY_STATUS 0x07 #define HIDPP_REGISTER_BATTERY_MILEAGE 0x0D #define HIDPP_REGISTER_PROFILE 0x0F #define HIDPP_REGISTER_LED_STATUS 0x51 #define HIDPP_REGISTER_LED_INTENSITY 0x54 #define HIDPP_REGISTER_LED_COLOR 0x57 #define HIDPP_REGISTER_OPTICAL_SENSOR_SETTINGS 0x61 #define HIDPP_REGISTER_CURRENT_RESOLUTION 0x63 #define HIDPP_REGISTER_USB_REFRESH_RATE 0x64 #define HIDPP_REGISTER_GENERIC_MEMORY_MANAGEMENT 0xA0 #define HIDPP_REGISTER_HOT_CONTROL 0xA1 #define HIDPP_REGISTER_READ_MEMORY 0xA2 #define HIDPP_REGISTER_DEVICE_CONNECTION_DISCONNECTION 0xB2 #define HIDPP_REGISTER_PAIRING_INFORMATION 0xB5 #define HIDPP_REGISTER_DEVICE_FIRMWARE_UPDATE_MODE 0xF0 #define HIDPP_REGISTER_DEVICE_FIRMWARE_INFORMATION 0xF1 /* * HID++2.0 error codes */ #define HIDPP_ERROR_CODE_NO_ERROR 0x00 #define HIDPP_ERROR_CODE_UNKNOWN 0x01 #define HIDPP_ERROR_CODE_INVALID_ARGUMENT 0x02 #define HIDPP_ERROR_CODE_OUT_OF_RANGE 0x03 #define HIDPP_ERROR_CODE_HW_ERROR 0x04 #define HIDPP_ERROR_CODE_LOGITECH_INTERNAL 0x05 #define HIDPP_ERROR_CODE_INVALID_FEATURE_INDEX 0x06 #define HIDPP_ERROR_CODE_INVALID_FUNCTION_ID 0x07 #define HIDPP_ERROR_CODE_BUSY 0x08 #define HIDPP_ERROR_CODE_UNSUPPORTED 0x09 /* * HID++2.0 features */ #define HIDPP_FEATURE_ROOT 0x0000 #define HIDPP_FEATURE_I_FEATURE_SET 0x0001 #define HIDPP_FEATURE_I_FIRMWARE_INFO 0x0003 #define HIDPP_FEATURE_GET_DEVICE_NAME_TYPE 0x0005 #define HIDPP_FEATURE_DFU_CONTROL 0x00c1 #define HIDPP_FEATURE_DFU_CONTROL_SIGNED 0x00c2 #define HIDPP_FEATURE_DFU 0x00d0 #define HIDPP_FEATURE_BATTERY_LEVEL_STATUS 0x1000 #define HIDPP_FEATURE_KBD_REPROGRAMMABLE_KEYS 0x1b00 #define HIDPP_FEATURE_SPECIAL_KEYS_BUTTONS 0x1b04 #define HIDPP_FEATURE_MOUSE_POINTER_BASIC 0x2200 #define HIDPP_FEATURE_ADJUSTABLE_DPI 0x2201 #define HIDPP_FEATURE_ADJUSTABLE_REPORT_RATE 0x8060 #define HIDPP_FEATURE_COLOR_LED_EFFECTS 0x8070 #define HIDPP_FEATURE_ONBOARD_PROFILES 0x8100 #define HIDPP_FEATURE_MOUSE_BUTTON_SPY 0x8110 G_END_DECLS #endif /* __LU__HIDPP_H */ fwupd-1.0.6/plugins/unifying/lu-self-test.c000066400000000000000000000031501325145456600206560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "lu-common.h" static void lu_common_func (void) { guint8 u8; guint16 u16; g_autofree gchar *ver1 = NULL; u8 = lu_buffer_read_uint8 ("12"); g_assert_cmpint (u8, ==, 0x12); u16 = lu_buffer_read_uint16 ("1234"); g_assert_cmpint (u16, ==, 0x1234); ver1 = lu_format_version (" A ", 0x87, 0x65, 0x4321); g_assert_cmpstr (ver1, ==, "A87.65_B4321"); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); /* tests go here */ g_test_add_func ("/unifying/common", lu_common_func); return g_test_run (); } fwupd-1.0.6/plugins/unifying/lu-tool.c000066400000000000000000000352221325145456600177320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "lu-context.h" #include "lu-device-bootloader.h" #include "lu-hidpp.h" typedef struct { GCancellable *cancellable; GPtrArray *cmd_array; LuContext *ctx; LuDeviceKind emulation_kind; } FuLuToolPrivate; static void lu_tool_private_free (FuLuToolPrivate *priv) { if (priv == NULL) return; if (priv->ctx != NULL) g_object_unref (priv->ctx); g_object_unref (priv->cancellable); if (priv->cmd_array != NULL) g_ptr_array_unref (priv->cmd_array); g_free (priv); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuLuToolPrivate, lu_tool_private_free) typedef gboolean (*FuLuToolPrivateCb) (FuLuToolPrivate *util, gchar **values, GError **error); typedef struct { gchar *name; gchar *arguments; gchar *description; FuLuToolPrivateCb callback; } FuLuToolItem; static void lu_tool_item_free (FuLuToolItem *item) { g_free (item->name); g_free (item->arguments); g_free (item->description); g_free (item); } static gint lu_tool_sort_command_name_cb (FuLuToolItem **item1, FuLuToolItem **item2) { return g_strcmp0 ((*item1)->name, (*item2)->name); } static void lu_tool_add (GPtrArray *array, const gchar *name, const gchar *arguments, const gchar *description, FuLuToolPrivateCb callback) { g_auto(GStrv) names = NULL; g_return_if_fail (name != NULL); g_return_if_fail (description != NULL); g_return_if_fail (callback != NULL); /* add each one */ names = g_strsplit (name, ",", -1); for (guint i = 0; names[i] != NULL; i++) { FuLuToolItem *item = g_new0 (FuLuToolItem, 1); item->name = g_strdup (names[i]); if (i == 0) { item->description = g_strdup (description); } else { item->description = g_strdup_printf ("Alias to %s", names[0]); } item->arguments = g_strdup (arguments); item->callback = callback; g_ptr_array_add (array, item); } } static gchar * lu_tool_get_descriptions (GPtrArray *array) { const gsize max_len = 31; GString *str; /* print each command */ str = g_string_new (""); for (guint i = 0; i < array->len; i++) { FuLuToolItem *item = g_ptr_array_index (array, i); gsize len; g_string_append (str, " "); g_string_append (str, item->name); len = strlen (item->name) + 2; if (item->arguments != NULL) { g_string_append (str, " "); g_string_append (str, item->arguments); len += strlen (item->arguments) + 1; } if (len < max_len) { for (guint j = len; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } else { g_string_append_c (str, '\n'); for (guint j = 0; j < max_len + 1; j++) g_string_append_c (str, ' '); g_string_append (str, item->description); g_string_append_c (str, '\n'); } } /* remove trailing newline */ if (str->len > 0) g_string_set_size (str, str->len - 1); return g_string_free (str, FALSE); } static gboolean lu_tool_run (FuLuToolPrivate *priv, const gchar *command, gchar **values, GError **error) { /* find command */ for (guint i = 0; i < priv->cmd_array->len; i++) { FuLuToolItem *item = g_ptr_array_index (priv->cmd_array, i); if (g_strcmp0 (item->name, command) == 0) return item->callback (priv, values, error); } /* not found */ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Command not found"); return FALSE; } static LuDevice * lu_get_default_device (FuLuToolPrivate *priv, GError **error) { GPtrArray *devices = NULL; LuDevice *device = NULL; devices = lu_context_get_devices (priv->ctx); for (guint i = 0; i < devices->len; i++) { LuDevice *device_tmp = g_ptr_array_index (devices, i); g_debug ("got %s", lu_device_kind_to_string (lu_device_get_kind (device_tmp))); if (lu_device_get_kind (device_tmp) != LU_DEVICE_KIND_PERIPHERAL) { device = g_object_ref (device_tmp); break; } } /* nothing supported */ if (device == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No supported device plugged in"); return NULL; } return device; } static gboolean lu_tool_info_device (LuDevice *device) { g_autofree gchar *str = fu_device_to_string (FU_DEVICE (device)); g_print ("%s", str); return TRUE; } static gboolean lu_tool_info (FuLuToolPrivate *priv, gchar **values, GError **error) { GPtrArray *devices = NULL; g_autoptr(LuContext) ctx = NULL; /* emulated */ if (priv->emulation_kind != LU_DEVICE_KIND_UNKNOWN) { g_autoptr(LuDevice) device = NULL; device = lu_device_fake_new (priv->emulation_kind); lu_tool_info_device (device); } /* get the devices */ ctx = lu_context_new (error); if (ctx == NULL) { g_prefix_error (error, "Failed to create context: "); return FALSE; } devices = lu_context_get_devices (ctx); for (guint i = 0; i < devices->len; i++) { LuDevice *device = g_ptr_array_index (devices, i); lu_tool_info_device (device); if (i != devices->len - 1) g_print ("\n"); } return TRUE; } static void lu_write_progress_cb (FuDevice *device, GParamSpec *pspec, gpointer user_data) { g_print ("Written %u%%\n", fu_device_get_progress (device)); } static gboolean lu_tool_dump (FuLuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) reqs = NULL; g_autoptr(LuDevice) device = NULL; g_autoptr(GBytes) fw = NULL; g_autofree gchar *data = NULL; gsize len = 0; /* check args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid arguments, expected FILENAME" " -- e.g. `firmware.hex`"); return FALSE; } /* fake a huge device */ device = g_object_new (LU_TYPE_DEVICE_BOOTLOADER, NULL); lu_device_bootloader_set_addr_lo (device, 0x0000); lu_device_bootloader_set_addr_hi (device, 0xffff); /* load file and display */ if (!g_file_get_contents (values[0], &data, &len, error)) return FALSE; fw = g_bytes_new_static (data, len); reqs = lu_device_bootloader_parse_requests (device, fw, error); if (reqs == NULL) return FALSE; for (guint i = 0; i < reqs->len; i++) { LuDeviceBootloaderRequest *req = g_ptr_array_index (reqs, i); g_print ("0x%04x [0x%02x]", req->addr, req->len); for (guint j = 0; j < req->len; j++) g_print (" %02x", req->data[j]); g_print ("\n"); } return TRUE; } static gboolean lu_tool_write (FuLuToolPrivate *priv, gchar **values, GError **error) { gsize len; g_autofree guint8 *data = NULL; g_autoptr(GBytes) fw = NULL; g_autoptr(LuDevice) device = NULL; /* check args */ if (g_strv_length (values) < 1) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid arguments, expected " "FILENAME [PLATFORM-ID]" " -- e.g. `firmware.hex`"); return FALSE; } /* open device */ if (g_strv_length (values) == 2) { device = lu_context_find_by_platform_id (priv->ctx, values[1], error); } else if (priv->emulation_kind == LU_DEVICE_KIND_UNKNOWN) { device = lu_get_default_device (priv, error); } else { device = lu_device_fake_new (priv->emulation_kind); } if (device == NULL) return FALSE; /* do we need to go into bootloader mode */ if (lu_device_has_flag (device, LU_DEVICE_FLAG_REQUIRES_DETACH)) { if (!lu_device_detach (device, error)) return FALSE; if (lu_device_has_flag (device, LU_DEVICE_FLAG_DETACH_WILL_REPLUG)) { if (!lu_context_wait_for_replug (priv->ctx, device, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE, error)) return FALSE; g_usleep (G_USEC_PER_SEC); g_clear_object (&device); if (g_strv_length (values) == 2) { device = lu_context_find_by_platform_id (priv->ctx, values[1], error); } else if (priv->emulation_kind == LU_DEVICE_KIND_UNKNOWN) { device = lu_get_default_device (priv, error); } else { device = lu_device_fake_new (priv->emulation_kind); } if (device == NULL) return FALSE; if (!lu_device_open (device, error)) { g_prefix_error (error, "failed to reclaim device: "); return FALSE; } } } /* load firmware file */ if (!g_file_get_contents (values[0], (gchar **) &data, &len, error)) { g_prefix_error (error, "Failed to load %s: ", values[0]); return FALSE; } /* update with data blob */ fw = g_bytes_new (data, len); g_signal_connect (device, "notify::progress", G_CALLBACK (lu_write_progress_cb), NULL); if (!lu_device_write_firmware (device, fw, error)) return FALSE; /* detach back into runtime */ if (!lu_device_attach (device, error)) return FALSE; return TRUE; } static gboolean lu_tool_attach (FuLuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(LuDevice) device = NULL; if (g_strv_length (values) == 1) { device = lu_context_find_by_platform_id (priv->ctx, values[0], error); if (device == NULL) return FALSE; } else { GPtrArray *devices = NULL; devices = lu_context_get_devices (priv->ctx); for (guint i = 0; i < devices->len; i++) { LuDevice *device_tmp = g_ptr_array_index (devices, i); g_debug ("got %s", lu_device_kind_to_string (lu_device_get_kind (device_tmp))); if (lu_device_has_flag (device_tmp, LU_DEVICE_FLAG_REQUIRES_ATTACH)) { device = g_object_ref (device_tmp); break; } } if (device == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "No attachable device plugged in"); return FALSE; } } if (!lu_device_attach (device, error)) return FALSE; return TRUE; } static void lu_tool_device_added_cb (LuContext* ctx, LuDevice *device, FuLuToolPrivate *priv) { g_print ("ADDED\tLogitech Unifying device %s {%p} [%s]\n", lu_device_kind_to_string (lu_device_get_kind (device)), device, fu_device_get_platform_id (FU_DEVICE (device))); lu_tool_info_device (device); } static void lu_tool_device_removed_cb (LuContext* ctx, LuDevice *device, FuLuToolPrivate *priv) { g_print ("REMOVED\tLogitech Unifying device %s {%p} [%s]\n", lu_device_kind_to_string (lu_device_get_kind (device)), device, fu_device_get_platform_id (FU_DEVICE (device))); } static gboolean lu_tool_watch (FuLuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(GMainLoop) loop = g_main_loop_new (NULL, FALSE); g_signal_connect (priv->ctx, "added", G_CALLBACK (lu_tool_device_added_cb), priv); g_signal_connect (priv->ctx, "removed", G_CALLBACK (lu_tool_device_removed_cb), priv); lu_context_coldplug (priv->ctx); lu_context_set_poll_interval (priv->ctx, 2000); g_main_loop_run (loop); return TRUE; } static gboolean lu_tool_detach (FuLuToolPrivate *priv, gchar **values, GError **error) { g_autoptr(LuDevice) device = NULL; if (g_strv_length (values) == 1) { device = lu_context_find_by_platform_id (priv->ctx, values[0], error); } else { device = lu_get_default_device (priv, error); } if (device == NULL) return FALSE; if (!lu_device_detach (device, error)) return FALSE; return TRUE; } static void lu_tool_log_handler_cb (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { g_print ("%s\t%s\n", log_domain, message); } int main (int argc, char **argv) { gboolean verbose = FALSE; g_autofree gchar *cmd_descriptions = NULL; g_autofree gchar *emulation_kind = NULL; g_autoptr(GError) error = NULL; g_autoptr(GOptionContext) context = NULL; g_autoptr(FuLuToolPrivate) priv = g_new0 (FuLuToolPrivate, 1); const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Print verbose debug statements", NULL }, { "emulate", 'e', 0, G_OPTION_ARG_STRING, &emulation_kind, "Emulate a device type", NULL }, { NULL} }; /* FIXME: do stuff on ctrl+c */ priv->cancellable = g_cancellable_new (); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) lu_tool_item_free); lu_tool_add (priv->cmd_array, "info", NULL, "Show information about the device", lu_tool_info); lu_tool_add (priv->cmd_array, "write", "FILENAME", "Update the firmware", lu_tool_write); lu_tool_add (priv->cmd_array, "dump", "FILENAME", "Dump the firmware", lu_tool_dump); lu_tool_add (priv->cmd_array, "attach", NULL, "Attach to firmware mode", lu_tool_attach); lu_tool_add (priv->cmd_array, "watch", NULL, "Watch for hardare changes", lu_tool_watch); lu_tool_add (priv->cmd_array, "detach", NULL, "Detach to bootloader mode", lu_tool_detach); /* sort by command name */ g_ptr_array_sort (priv->cmd_array, (GCompareFunc) lu_tool_sort_command_name_cb); /* get a list of the commands */ context = g_option_context_new (NULL); cmd_descriptions = lu_tool_get_descriptions (priv->cmd_array); g_option_context_set_summary (context, cmd_descriptions); g_set_application_name ("Logitech Lu Debug Tool"); g_option_context_add_main_entries (context, options, NULL); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("%s: %s\n", "Failed to parse arguments", error->message); return EXIT_FAILURE; } /* emulate */ priv->emulation_kind = lu_device_kind_from_string (emulation_kind); if (priv->emulation_kind != LU_DEVICE_KIND_UNKNOWN) g_log_set_default_handler (lu_tool_log_handler_cb, priv); /* get the device */ priv->ctx = lu_context_new (&error); if (priv->ctx == NULL) { g_print ("Failed to open USB devices: %s\n", error->message); return EXIT_FAILURE; } /* set verbose? */ if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); /* run the specified command */ if (!lu_tool_run (priv, argv[1], (gchar**) &argv[2], &error)) { if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_autofree gchar *tmp = NULL; tmp = g_option_context_get_help (context, TRUE, NULL); g_print ("%s\n\n%s", error->message, tmp); } else { g_print ("%s\n", error->message); } return EXIT_FAILURE; } return 0; } fwupd-1.0.6/plugins/unifying/meson.build000066400000000000000000000031331325145456600203310ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginUnifying"'] shared_module('fu_plugin_unifying', sources : [ 'fu-plugin-unifying.c', 'lu-common.c', 'lu-context.c', 'lu-device-bootloader.c', 'lu-device-bootloader-nordic.c', 'lu-device-bootloader-texas.c', 'lu-device.c', 'lu-device-peripheral.c', 'lu-device-runtime.c', 'lu-hidpp-msg.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, gudev, ], ) executable( 'fu-unifying-util', sources : [ 'lu-tool.c', 'lu-common.c', 'lu-context.c', 'lu-device-bootloader.c', 'lu-device-bootloader-nordic.c', 'lu-device-bootloader-texas.c', 'lu-device.c', 'lu-device-peripheral.c', 'lu-device-runtime.c', 'lu-hidpp-msg.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, gudev, ], link_with : [ fwupd, libfwupdprivate, ], c_args : cargs, ) if get_option('tests') e = executable( 'unifying-self-test', sources : [ 'lu-self-test.c', 'lu-common.c', ], include_directories : [ include_directories('../..'), include_directories('../../libfwupd'), ], dependencies : [ plugin_deps, gudev, ], link_with : [ fwupd, ], c_args : cargs, ) test('unifying-self-test', e) endif fwupd-1.0.6/plugins/upower/000077500000000000000000000000001325145456600156605ustar00rootroot00000000000000fwupd-1.0.6/plugins/upower/README.md000066400000000000000000000002111325145456600171310ustar00rootroot00000000000000UPower Support ============== Introduction ------------ This plugin is used to ensure that some updates are not done on battery power. fwupd-1.0.6/plugins/upower/fu-plugin-upower.c000066400000000000000000000047611325145456600212610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2016 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "fu-plugin.h" #include "fu-plugin-vfuncs.h" struct FuPluginData { GDBusProxy *proxy; }; void fu_plugin_init (FuPlugin *plugin) { fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); } void fu_plugin_destroy (FuPlugin *plugin) { FuPluginData *data = fu_plugin_get_data (plugin); if (data->proxy != NULL) g_object_unref (data->proxy); } gboolean fu_plugin_startup (FuPlugin *plugin, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); data->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, NULL, "org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", NULL, error); if (data->proxy == NULL) { g_prefix_error (error, "failed to connect to upower: "); return FALSE; } return TRUE; } gboolean fu_plugin_update_prepare (FuPlugin *plugin, FuDevice *device, GError **error) { FuPluginData *data = fu_plugin_get_data (plugin); g_autoptr(GVariant) value = NULL; /* can we only do this on AC power */ if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC)) return TRUE; value = g_dbus_proxy_get_cached_property (data->proxy, "OnBattery"); if (value == NULL) { g_warning ("failed to get OnBattery value, assume on AC power"); return TRUE; } if (g_variant_get_boolean (value)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_AC_POWER_REQUIRED, "Cannot install update " "when not on AC power"); return FALSE; } return TRUE; } fwupd-1.0.6/plugins/upower/meson.build000066400000000000000000000005701325145456600200240ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="FuPluginUpower"'] shared_module('fu_plugin_upower', sources : [ 'fu-plugin-upower.c', ], include_directories : [ include_directories('../..'), include_directories('../../src'), include_directories('../../libfwupd'), ], install : true, install_dir: plugin_dir, c_args : cargs, dependencies : [ plugin_deps, ], ) fwupd-1.0.6/po/000077500000000000000000000000001325145456600132745ustar00rootroot00000000000000fwupd-1.0.6/po/.gitignore000066400000000000000000000000061325145456600152600ustar00rootroot00000000000000*.pot fwupd-1.0.6/po/LINGUAS000066400000000000000000000001451325145456600143210ustar00rootroot00000000000000ast ca cs de en_GB eu fi fr fur he hi hr hu id it kk ko nl oc pl pt_BR ru sk sr sv tr uk zh_CN zh_TW fwupd-1.0.6/po/POTFILES.in000066400000000000000000000003551325145456600150540ustar00rootroot00000000000000data/org.freedesktop.fwupd.metainfo.xml policy/org.freedesktop.fwupd.policy.in plugins/dfu/dfu-tool.c plugins/synapticsmst/synapticsmst-tool.c plugins/uefi/fu-plugin-uefi.c src/fu-debug.c src/fu-main.c src/fu-progressbar.c src/fu-util.c fwupd-1.0.6/po/ast.po000066400000000000000000000572101325145456600144300ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # enolp , 2017 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Asturian (http://www.transifex.com/freedesktop/fwupd/language/ast/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ast\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Anueva'l firmware de preseos en Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Esti proyeutu tien l'oxetivu d'anovar automáticamente'l firmware en Linux d'un mou seguru y fiable. Pues usar un xestor de software GUI como Gnome Software pa ver y aplicar los anovamientos, la ferramienta en llinia de comandos o la interfaz D-Bus direutamente." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Amestóse" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Desanicióse" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Camudóse" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Encaboxóse" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Nome" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Cifráu" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Rexón" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Alcontróse" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protocolu" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Estáu" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Serial" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Mou" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Estáu" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Tamañu de tresferencia" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "" #: src/fu-util.c:694 msgid "Done!" msgstr "" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/ca.po000066400000000000000000000754171325145456600142350ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Antoni Bella Pérez , 2017-2018 # Robert Antoni Buj Gelonch , 2017 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Catalan (http://www.transifex.com/freedesktop/fwupd/language/ca/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ca\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Actualitza el microprogramari del dispositiu a Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Aquest projecte pretén fer que actualitzar automàticament el microprogramari a Linux, sigui segur i fiable. Com a IGU, podeu usar un gestor de programari com el Programari GNOME per a veure i aplicar les actualitzacions, directament l'eina de la línia d'ordres o la interfície de D-Bus." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "El procés del «fwupd» és un dimoni senzill que permet que una sessió de programari actualitzi el microprogramari del dispositiu a la màquina local. Està dissenyat per a equips d'escriptori, però aquest projecte també és usable a telèfons, tauletes i servidors sense perifèrics." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Instal·la microprogramari signat per al sistema" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Es requereix autenticació per actualitzar el microprogramari en aquesta màquina" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Instal·la microprogramari sense signar per al sistema" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Instal·la la versió antiga del microprogramari per al sistema" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Es requereix autenticació per a desactualitzar el microprogramari en aquesta màquina" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Instal·la microprogramari signat per al dispositiu" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Es requereix autenticació per actualitzar el microprogramari en un dispositiu extraible" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Instal·la microprogramari sense signar per al dispositiu" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Es requereix autenticació per a desactualitzar el microprogramari en un dispositiu extraible" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Desbloqueja el dispositiu per a permetre l'accés" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Es requereix autenticació per a desbloquejar un dispositiu" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Actualitza la informació de verificació dels dispositius emmagatzemats" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "Es requereix autenticació per actualitzar les sumes de verificació emmagatzemades pels dispositius" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Modifica un remot configurat" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "Es necessita l'autenticació per a modificar un remot configurat emprat per a les actualitzacions del microprogramari" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Àlies per a %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "No s'ha trobat cap ordre" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "S'ha afegit" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "S'ha eliminat" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "S'ha canviat" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "S'ha cancel·lat" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Nom" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Xifra" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Regió" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "S'ha trobat" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protocol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Estat" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Permís denegat" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Sèrie" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Mode" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Temps d'execució" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Estat" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Mida a transferir" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Atributs" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Peculiaritats" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "Id. xip" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Converteix el microprogramari al format DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Fusiona múltiples fitxers de microprogramari en un de sol" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Estableix l'ID del proveïdor al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Estableix l'ID del producte al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Estableix l'adreça de l'element al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Estableix la mida del microprogramari per a l'objectiu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Estableix la versió de llançament al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Estableix el número alternatiu al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Estableix el nom alternatiu al fitxer del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Connecta un dispositiu amb capacitat DFU en temps real" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "Restableix un dispositiu DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Llegeix el microprogramari des del dispositiu a un fitxer" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Llegeix el microprogramari des d'una partició a un fitxer" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Escriu el microprogramari des d'un fitxer a dins del dispositiu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Escriu el microprogramari des d'un fitxer a dins d'una partició" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Llista els dispositius amb capacitat DFU actualment connectats" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Desconecta el dispositiu amb capacitat DFU actualment connectat" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Bolca els detalls sobre un fitxer de microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Vigila els dispositius DFU que han estat connectats en calent" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Encripta les dades del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Desencripta les dades del microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Estableix les metadades en un fitxer de microprogramari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Substitueix les dades en un fitxer de microprogramari existent" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Crea un pedaç binari emprant dos fitxers" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Aplica un pedaç binari" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Bolca la informació sobre un pedaç binari a la pantalla" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "No s'han pogut carregar les peculiaritats" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "Utilitat DFU" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Ha fallat en analitzar els arguments" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Enumera tots els dispositius de «Synaptics MST»" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Instal·la un fitxer de microprogramari en un dispositiu MST" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Utilitat «Synaptics Multistream Transport»" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "S'està instal·lant l'actualització de microprogramari..." #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Mostra la informació de depuració per a tots els fitxers" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Mostra la informació detallada del connector" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Opcions per a la depuració" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Mostra les opcions per a la depuració" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Surt després d'un petit retard" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Sur una vegada s'hagi carregat el motor" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Dimoni per a l'actualització de microprogramari" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Servei de D-Bus per a l'actualització de microprogramari" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Està ociós..." #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "S'està descomprimint..." #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "S'està carregant..." #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "S'està reiniciant el dispositiu..." #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "S'està llegint..." #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "S'està escrivint..." #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "S'està esborrant..." #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "S'està verificant..." #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Planificació..." #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "S'està descarregant..." #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "S'està autenticant..." #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "S'està esperant…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Desconegut" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Trieu un dispositiu:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Els dispositius que no s'han actualitzat correctament:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Els dispositius que s'han actualitzat correctament:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Pujo l'informe ara?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Requereix connexió a Internet" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "No s'ha detectat cap maquinari amb capacitat per a l'actualització del microprogramari" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "S'està reinstal·lant %s amb %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "S'està desactualitzant %s des de %s a %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "S'està actualitzant %s des de %s a %s... " #: src/fu-util.c:694 msgid "Done!" msgstr "Fet!" #: src/fu-util.c:726 msgid "Target" msgstr "Objectiu" #: src/fu-util.c:727 msgid "Payload" msgstr "Carrega útil" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Continuo amb la pujada?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "Que falli en actualitzar és un problema conegut, visiteu aquest URL per obtenir més informació:" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "Missatge de la pujada:" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "D'acord" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "S'està obtenint la signatura" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "S'estan obtenint les metadades" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "S'està obtenint el microprogramari" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "S'està obtenint el fitxer" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Versió:" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Resum" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Remot" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Descripció" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Suma de comprovació" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Trieu un alliberament:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "Les metadades del microprogramari no s'han actualitzat durant %u dia i podria ser que no estiguin actualitzades." msgstr[1] "Les metadades del microprogramari no s'han actualitzat durant %u dies i podria ser que no estiguin actualitzades." #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Actualitzo ara?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s té actualitzacions de microprogramari:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Versió de l'actualització" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Actualitza el nom" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Actualitza el resum" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Actualitza l'ID remot:" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Suma de verificació de l'actualització" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Ubicació de l'actualització" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Descripció de l'actualització" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "ID remot" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Títol" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Tipus" #: src/fu-util.c:1631 msgid "Keyring" msgstr " Anell de claus" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Habilitat" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Antiguitat" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Prioritat" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Nom d'usuari" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Contrasenya" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Nom del fitxer" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Signatura del nom del fitxer" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "URI de les metadades" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Signatura de l'URI de les metadades" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "URI base del microprogramari" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "URI de l'informe" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "S'ha afegit el dispositiu:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "S'ha eliminat el dispositiu:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "S'ha canviat el dispositiu:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "Una actualització requereix un reinici per a completar-se." #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "Reinicio ara?" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Mostra la informació de depuració addicional" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Mostra les versions del client i el dimoni" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Planifica la instal·lació per al següent reinici quan sigui posible" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Permet tornar a instal·lar les versions de microprogramari existents" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Permet tornar a la versió anterior del microprogramari" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Passa per alt els avisos del connector" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Respon sí a totes les preguntes" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "No comprovar si hi ha un historial sense informar" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "No comprovar si hi ha metadades antigues" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "No realitzis el reinici després de l'actualització" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Obté tots els dispositius que admeten actualitzacions de microprogramari" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Retorna tots els ID del maquinari de la màquina" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Instal·la ara les actualitzacions preparades" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Mostra l'historial de les actualitzacions de microprogramari" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Esborra tot l'historial de les actualitzacions de microprogramari" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Comparteix l'historial de microprogramari amb els desenvolupadors" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Instal·la un fitxer de microprogramari en aquest maquinari" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Obté la informació sobre un fitxer de microprogramari" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Obté la llista d'actualitzacions per al maquinari connectat" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Actualitza tot el microprogramari a les versions més recents" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Obté el resultat d'aplicar la funció criptogràfica de resum sobre el microprogramari bolcat" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Desbloqueja el dispositiu per accedir al microprogramari" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Esborra els resultats de l'última actualització" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Neteja qualsevol actualització programyada per a ser actualitzada sense connexió" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Obté els resultats de l'última actualització" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Obté els alliberaments per a un dispositiu" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Obtén els remots configurats" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Desactualitza el microprogramari en un dispositiu" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Refresca les metadades des del servidor remot" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Actualitza les metadades emmagatzemades amb el contingut de la ROM actual" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Monitora el dimoni pels esdeveniments" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Construeix el microprogramari usant un entorn de proves" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Bolca les dades al SMBIOS des d'un fitxer" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Modifica un remot indicat" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Utilitat per al microprogramari" fwupd-1.0.6/po/cs.po000066400000000000000000000710501325145456600142440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Daniel Rusek , 2017 # Daniel Rusek , 2017 # Marek Černocký , 2016 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Czech (http://www.transifex.com/freedesktop/fwupd/language/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Aktualizace firmwaru zařízení na Linuxu" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Cílem tohoto projektu je učinit aktualizaci firmwaru na Linuxu automatickou, bezpečnou a spolehlivou. Pro zobrazení a aplikaci aktualizací můžete použít GUI správce softwaru typu GNOME Software, nástroj pro příkazovou řádku nebo přímo D-Bus." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "Proces fwupd je jednoduchý démon, který umožňuje softwaru sezení aktualizovat firmware zařízení na vašem počítači. Je navržen pro stolní počítače, ale je možno jej použít také na telefonech, tabletech a serverech bez monitoru." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Instalace podepsaného systémového firmwaru" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "K aktualizaci firmwaru na tomto počítači je vyžadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Instalace nepodepsaného systémového firmwaru" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Instalace starší verze systémového firmwaru" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "K ponížení verze firmwaru na tomto počítači je vyžadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Instalace podepsaného firmwaru zařízení" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "K aktualizaci firmwaru na výměnném zařízení je vyžadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Instalace nepodepsaného firmwaru zařízení" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "K ponížení verze firmwaru na výměnném zařízení je vyžadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Odemknutí zařízení pro umožnění přístupu" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Pro odemknutí zařízení je požadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Aktualizace uložené informace o ověření zařízení" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "K aktualizaci uložených kontrolních součtů zařízení je vyžadováno ověření" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Upravit nastavený vzdálený zdroj" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "K úpravě nastaveného vzdáleného zdroje používaného pro aktualizace firmwaru je vyžadováno ověření" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias pro %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Příkaz nebyl nalezen" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Přidáno" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Odebráno" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Změněno" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Zrušeno" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Název" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Šifra" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Oblast" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Nalezeno" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Stav" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Sériové číslo" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Režim" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Stav" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Přenášená velikost" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Zvláštní požadavky" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Převést firmware do formátu DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Sloučit více firmwarů do jednoho" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Nastavit ID výrobce v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Nastavit ID produktu v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Nastavit adresu prvku na firmwaru zařízení" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Nastavit velikost firmwaru pro cíl" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Nastavit verzi vydání v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Nastavit alternativní číslo v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Nastavit alternativní název v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Napojit zařízení podporující DFU zpět do běhového režimu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Přečíst firmware ze zařízení do souboru" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Přečíst firmware z jednoho oddílu do souboru" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Zapsat firmware ze souboru do zařízení" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Zapsat firmware ze souboru do jednoho oddílu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Vypsat právě napojená zařízení podporující DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Odpojit aktuálně napojené zařízení podporující DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Vypsat podrobnosti o souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Sledovat připojení zařízení podporujících DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Zašifrovat data firmwaru" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Dešifrovat data firmwaru" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Nastavit metadata v souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Nahradit data v existujícím souboru s firmwarem" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Vytvořit binární záplatu za použití dvou souborů" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Použít binární záplatu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Vypsat na obrazovku informace o binární záplatě" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "Nástroj pro práci s DFU" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Selhalo zpracování argumentů" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Enumerovat všechny zařízení Synaptics MST" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Zapsat soubor firmwaru do zařízení MST" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Synaptics Multistream Transport Utility" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Instaluje se aktualizace firmwaru…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Zobrazovat ladicí informace pro všechny soubory" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Volby ladění" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Zobrazit volby ladění" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Skončit po krátké prodlevě" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Skončit po načtení výkonné části" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Démon pro aktualizaci firmwaru" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Služba D-Bus pro aktualizaci firmwaru" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Nečinný…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Rozbaluje se firmware…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Načítá se…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Zařízení se restartuje…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Čte se…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Zapisuje se…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Maže se…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Ověřuje se…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Plánuje se…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Stahuje se…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Ověřuje se…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Neznámý" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Vyberte zařízení:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Nebylo nalezeno žádné zařízení schopné aktualizace firmwaru" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Přeinstalovává se %s na %s…" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Ponižuje se %s z verze %s na %s…" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Aktualizuje se %s z verze %s na %s…" #: src/fu-util.c:694 msgid "Done!" msgstr "Hotovo!" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "V pořádku" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Stahuje se podpis" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Stahují se metadata" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Stahuje se firmware" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Stahuje se soubor" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Verze" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Vzdálený zdroj" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Popis" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Kontrolní součet" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Vyberte verzi:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" msgstr[2] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s má aktualizace firmwaru:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Verze aktualizace" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Vzdálené ID aktualizace" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Kontrolní součet aktualizace" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Umístění aktualizace" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Popis aktualizace" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "Vzdálené ID" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Název" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Typ" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Klíčenka" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Povoleno" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Věk" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Priorita" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Uživatelské jméno" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Heslo" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Název souboru" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Podpis názvu souboru" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "URI metadat" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Podpis URI metadat" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "Základní URI firmwaru" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Přidáno zařízení:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Odebráno zařízení:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Změněno zařízení:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Zobrazovat doplňující informace pro ladění" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Zobrazit verzi klienta a démonu" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Pokud je to možné, naplánovat instalaci na příští restart" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Povolit reinstalaci stávající verze firmwaru" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Povolit ponížení verze firmwaru" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Potlačit varování zásuvného modulu" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Zjistit všechna zařízení podporující aktualizaci firmwaru" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Vrátit všechna ID hardwaru počítače" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Nainstalovat připravené aktualizace nyní" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Nainstalovat soubor s firmwarem na tento hardware" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Vypsat podrobnosti o souboru s firmwarem" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Vypsat seznam aktualizací pro připojený hardware" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Aktualizovat všechen firmware na nejnovější dostupné verze" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Vypsat kryptografický otisk vypsaného firmwaru" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Odemknout zařízení pro přístup k firmwaru" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Smazat výsledky z poslední aktualizace" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Smazat všechny aktualizace naplánované pro offline aktualizaci" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Vypsat výsledky z poslední aktualizace" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Vypsat vydání pro zařízení" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Vypsat nastavené vzdálené zdroje" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Ponížit verzi firmwaru na zařízení" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Aktualizovat metadata ze vzdáleného serveru" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Aktualizovat uložená metadata pomocí aktuálního obsahu ROM" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Sledovat události démonu" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Sestavit firmware za použití izolovaného prostředí" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Vypsat SMBIOS data ze souboru" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Upraví zadaný vzdálený zdroj" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Nástroj pro práci s firmwarem" fwupd-1.0.6/po/de.po000066400000000000000000000653331325145456600142360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Marco Tedaldi , 2015 # Wolfgang Stöggl , 2015 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: German (http://www.transifex.com/freedesktop/fwupd/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Signierte System-Firmware installieren" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Auf diesem System ist eine Authentifizierung notwendig, um das Firmware Update durch zu führen" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Nicht-signierte System-Firmware installieren" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Alte Version der System-Firmware installieren" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Auf diesem System ist eine Legitimierung erforderlich, um das Firmware-Downgrade durchzuführen" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Signierte Geräte-Firmware installieren" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Legitimierung ist notwendig, um die Firmware auf einem entfernbaren Gerät zu aktualisieren" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Nicht-signierte Geräte-Firmware installieren" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Legitimierung ist erforderlich, um das Firmware-Downgrade auf einem entfernbaren Gerät durchzuführen" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Das Gerät entsperren, um Zugriff zu ermöglichen" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Legitimation ist zum Entsperren eines Geräts erforderlich" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Verweis auf %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Befehl nicht gefunden" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Hinzugefügt" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Entfernt" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Geändert" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Abgebrochen" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "Kennung" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Name" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Verschlüsselungsverfahren" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Bereich" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Gefunden" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokoll" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Status" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Seriell" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Modus" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Zustand" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Macken" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Firmware in das DFU-Format konvertieren" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Mehrere Firmware-Dateien in eine zusammenführen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Hersteller-Kennung einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Produkt-Kennung einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Die Elementadresse in Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Die Firmware-Größe für das Ziel festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Veröffentlichungsversion einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Alternative Nummer einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Alternativen Namen einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "DFU-fähiges Gerät wieder zurück in Laufzeit einhängen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Firmware von Gerät in Datei schreiben" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Firmware von einzelner Partition in Datei lesen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Firmware von Datei auf Gerät schreiben" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Firmware aus Datei in einzelne Partition schreiben" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Derzeit angeschlossene DFU-fähige Geräte auflisten" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Derzeit eingehängtes DFU-fähiges Gerät entfernen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Details zu einer Firmware-Datei ausgeben" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Geräteanschluss von DFU-Geräten überwachen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Firmwaredaten verschlüsseln" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Firmwaredaten entschlüsseln" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Metadaten einer Firmware-Datei festlegen" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "DFU-Werkzeug" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Verarbeitung der Argumente schlug fehl" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Debuginformationen für alle Dateien anzeigen" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Debug Optionen" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Debug Optionen anzeigen" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Verlassen nach einer kurzen Verzögerung" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Nach dem Laden der Engine beenden" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Dienst für Firmware-Aktualisierung" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "D-Bus-Dienst für Firmware-Aktualisierung" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Bereit …" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Entpacken …" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Laden …" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Gerät wird neu gestartet …" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Schreiben …" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Überprüfung läuft …" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Einplanen …" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Unbekannt" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Es wurde keine Hardware erkannt, deren Firmware aktualisiert werden kann" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Erneute Installation von %s mit %s …" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Downgrade für %s von %s auf %s wird eingespielt …" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Aktualisieren von %s von %s nach %s …" #: src/fu-util.c:694 msgid "Done!" msgstr "Fertig." #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "Ok" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Version" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Beschreibung" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Prüfsumme" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "Firmwareaktualisierungen für %s verfügbar:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Version aktualisieren" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Prüfsumme aktualisieren" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Ort aktualisieren" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Beschreibung aktualisieren" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Gerät hinzugefügt:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Gerät entfernt:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Gerät geändert:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Zusätzliche Informationen zur Fehlerdiagnose anzeigen" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Erneute Installation vorhandener Firmware-Versionen erlauben" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Einspielen niedrigerer Firmwareversionen zulassen (Downgrade)" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Alle Geräte ermitteln, die Firmware-Aktualisierungen unterstützen" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Vorbereitete Aktualisierungen jetzt installieren" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Eine Firmware-Datei auf dieser Hardware installieren" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Ermittelt Details über eine Firmware-Datei" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Ermittelt die Liste der Aktualisierungen für angeschlossene Hardware" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Alle Firmware auf die neueste verfügbare Version aktualisieren" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Ermittelt den kryptographischen Hash-Wert der abgelegten Firmware" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Entsperrt das Gerät für Zugriff auf die Firmware" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Bereinigt die Ergebnisse der letzten Aktualisierung" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Ermittelt die Ergebnisse der letzten Aktualisierung" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Metadaten von entferntem Server aktualisieren" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Gespeicherte Metadaten mit dem aktuellen ROM-Inhalt aktualisieren" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Den Daemon auf Ereignisse überwachen" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Firmware-Werkzeug" fwupd-1.0.6/po/en_GB.po000066400000000000000000000700151325145456600146110ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Richard Hughes , 2015,2017-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: English (United Kingdom) (http://www.transifex.com/freedesktop/fwupd/language/en_GB/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: en_GB\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Update device firmware on Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "This project aims to make updating firmware on Linux automatic, safe and reliable. You can either use a GUI software manager like GNOME Software to view and apply updates, the command-line tool or the D-Bus interface directly." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "The fwupd process is a simple daemon to allow session software to update device firmware on your local machine. It is designed for desktops, but this project is also usable on phones, tablets and on headless servers." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Install signed system firmware" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Authentication is required to update the firmware on this machine" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Install unsigned system firmware" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Install old version of system firmware" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Authentication is required to downgrade the firmware on this machine" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Install signed device firmware" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Authentication is required to update the firmware on a removable device" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Install unsigned device firmware" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Authentication is required to downgrade the firmware on a removable device" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Unlock the device to allow access" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Authentication is required to unlock a device" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Update the stored device verification information" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "Authentication is required to update the stored checksums for the device" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Modify a configured remote" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "Authentication is required to modify a configured remote used for firmware updates" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias to %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Command not found" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Added" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Removed" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Changed" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Cancelled" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Name" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Cipher" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Region" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Found" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protocol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Status" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Permission denied" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Serial" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Mode" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Runtime" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "State" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Transfer Size" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Attributes" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Quirks" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "Chip ID" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Convert firmware to DFU format" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Merge multiple firmware files into one" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Set vendor ID on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Set product ID on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Set element address on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Set the firmware size for the target" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Set release version on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Set alternative number on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Set alternative name on firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Attach DFU capable device back to runtime" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "Reset a DFU device" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Read firmware from device into a file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Read firmware from one partition into a file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Write firmware from file into device" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Write firmware from file into one partition" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "List currently attached DFU capable devices" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Detach currently attached DFU capable device" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Dump details about a firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Watch DFU devices being hotplugged" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Encrypt firmware data" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Decrypt firmware data" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Sets metadata on a firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Replace data in an existing firmware file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Create a binary patch using two files" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Apply a binary patch" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Dump information about a binary patch to the screen" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "Failed to load quirks" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "DFU Utility" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Failed to parse arguments" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Enumerate all Synaptics MST devices" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Flash firmware file to MST device" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Synaptics Multistream Transport Utility" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Installing firmware update…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Show debugging information for all files" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Show plugin verbose information" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Debugging Options" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Show debugging options" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Exit after a small delay" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Exit after the engine has loaded" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Firmware Update Daemon" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Firmware Update D-Bus Service" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Idle…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Decompressing…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Loading…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Restarting device…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Reading…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Writing…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Erasing…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Verifying…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Scheduling…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Downloading…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Authenticating…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Waiting…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Unknown" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Choose a device:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Devices that were not updated correctly:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Devices that have been updated successfully:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Upload report now?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Requires internet connection" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "No hardware detected with firmware update capability" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Reinstalling %s with %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Downgrading %s from %s to %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Updating %s from %s to %s... " #: src/fu-util.c:694 msgid "Done!" msgstr "Done!" #: src/fu-util.c:726 msgid "Target" msgstr "Target" #: src/fu-util.c:727 msgid "Payload" msgstr "Payload" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Proceed with upload?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "OK" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Fetching signature" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Fetching metadata" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Fetching firmware" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Fetching file" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Version" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Summary" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Remote" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Description" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Checksum" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Choose a release:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Update now?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s has firmware updates:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Update Version" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Update Name" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Update Summary" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Update Remote ID" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Update Checksum" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Update Location" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Update Description" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "Remote ID" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Title" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Type" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Keyring" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Enabled" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Age" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Priority" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Username" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Password" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Filename" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Filename Signature" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "Metadata URI" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Metadata URI Signature" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "Firmware Base URI" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "Report URI" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Device added:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Device removed:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Device changed:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Show extra debugging information" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Show client and daemon versions" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Schedule installation for next reboot when possible" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Allow re-installing existing firmware versions" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Allow downgrading firmware versions" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Override plugin warning" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Answer yes to all questions" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "Do not check for unreported history" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "Do not check for old metadata" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Get all devices that support firmware updates" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Return all the hardware IDs for the machine" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Install prepared updates now" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Show history of firmware updates" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Erase all firmware update history" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Share firmware history with the developers" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Install a firmware file on this hardware" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Gets details about a firmware file" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Gets the list of updates for connected hardware" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Updates all firmware to latest versions available" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Gets the cryptographic hash of the dumped firmware" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Unlocks the device for firmware access" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Clears the results from the last update" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Clears any updates scheduled to be updated offline" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Gets the results from the last update" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Gets the releases for a device" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Gets the configured remotes" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Downgrades the firmware on a device" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Refresh metadata from remote server" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Update the stored metadata with current ROM contents" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Monitor the daemon for events" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Build firmware using a sandbox" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Dump SMBIOS data from a file" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Modifies a given remote" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Firmware Utility" fwupd-1.0.6/po/eu.po000066400000000000000000000564571325145456600142660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # assar , 2017 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Basque (http://www.transifex.com/freedesktop/fwupd/language/eu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: eu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Ez da komandoa aurkitu" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Gehitua" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Kendua" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Aldatua" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "IDa" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Izena" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Eskualdea" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Aurkitua" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokoloa" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Egoera" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "" #: src/fu-util.c:694 msgid "Done!" msgstr "" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/fi.po000066400000000000000000000601001325145456600142270ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Jiri Grönroos , 2017-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Finnish (http://www.transifex.com/freedesktop/fwupd/language/fi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Päivitä laitteiden firmware-laiteohjelmistoja Linuxilla" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Tämän laitteen firmwaren päivittäminen vaatii tunnistautumisen" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Erillisen laitteen firmwaren päivittäminen vaatii tunnistautumisen" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Laitteen lukituksen avaaminen vaatii tunnistautumisen" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Komentoa ei löytynyt" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Lisätty" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Poistettu" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Muutettu" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Peruttu" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Nimi" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Asennetaan firmware-päivitystä…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Vianjäljitysvalinnat" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Näytä vianjäljitysvalinnat" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Poistu pienen viiveen jälkeen" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Jouten…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Puretaan…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Ladataan…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Käynnistetään laite uudelleen…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Luetaan…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Kirjoitetaan…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Poistetaan…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Vahvistetaan…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Ajoitetaan…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Ladataan…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Tunnistaudutaan…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Odotetaan…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Tuntematon" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Valitse laite:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "" #: src/fu-util.c:694 msgid "Done!" msgstr "Valmis!" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "OK" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Noudetaan allekirjoitus" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Noudetaan metatietoja" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Noudetaan firmware" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Noudetaan tiedosto" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Versio" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Kuvaus" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Tarkistussumma" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Valitse julkaisu:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Tyyppi" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Käyttäjätunnus" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Salasana" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Tiedostonimi" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Laite lisätty:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Laite poistettu:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Laite muutettu:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Firmware-työkalu" fwupd-1.0.6/po/fr.po000066400000000000000000000600521325145456600142460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Franck , 2015 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: French (http://www.transifex.com/freedesktop/fwupd/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Une authentification est nécessaire pour mettre à jour le micrologiciel sur cette machine" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias de %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Echec de l'analyse des paramètres" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Montrer les informations de débogage pour tous les fichiers" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Options de débogage" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Montrer les options de débogage" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Quitter après un bref délai" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Quitter après le chargement du moteur" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Service D-Bus de mise à jour des micrologiciels" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Aucun matériel ayant des capacités de mise à jour du micrologiciel n'a été détecté" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Réinstallation de %s en %s" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Rétrogradation de %s de %s en %s" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Mise à jour de %s de %s en %s" #: src/fu-util.c:694 msgid "Done!" msgstr "Terminé !" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Montre des informations de débogage complémentaires" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Obtenir la liste des périphériques supportant les mises à jour de micrologiciel" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Installer immédiatement les mises à jour préparées" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Installer un fichier de micrologiciel sur ce matériel" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Obtenir les détails d'un fichier de micrologiciel" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/fur.po000066400000000000000000000617221325145456600144400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Fabio Tomat , 2017-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Friulian (http://www.transifex.com/freedesktop/fwupd/language/fur/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fur\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Inzorne il firmware dal dispositîf su Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Instale firmware di sisteme firmât" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "La autenticazion e je necessarie par inzornâ il firmware su cheste machine" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Instale firmware di sisteme cence firme" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Instale une version vecje dal firmware di sisteme" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Instasle firmware di dispositîf firmât" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "La autenticazion e je necessarie par inzornâ il firmware suntun dispositîf estraibil" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Instale firmware di dispositîf cence firme" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Sbloche il dispositîf par permeti l'acès" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "La autenticazion e je necessarie par sblocâ un dispositîf" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Inzorne lis informazions di verifiche dal dispositîf archiviadis" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "La autenticazion e je necessarie par inzornâ i checksum archiviâts pal dispositîf" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias a %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Comant no cjatât" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Zontât" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Gjavât" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Modificât" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Non" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Regjon" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Cjatât" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protocol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Stât" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Permès dineât" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Seriâl" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Modalitât" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Stât" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Atribûts" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "ID chip" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Opzions di debug" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Mostre opzions di debug" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Jes dopo un piçul ritart" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Demoni di inzornament firmware" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Servizi D-Bus inzornament firmware" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "No cognossût" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Sielç un dispositîf:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "" #: src/fu-util.c:694 msgid "Done!" msgstr "Fat!" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "Va ben" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Version" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Rimot" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Descrizion" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Checksum" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Sielç une publicazion:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Titul" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Gjenar" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Puarteclâfs" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Abilitât" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Prioritât" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Non utent" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Password" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Non file" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Firme non file" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Dispositîf zontât:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Dispositîf gjavât:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Dispositîf modificât:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Mostre informazions di debug adizionâls" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Mostre versions di client e demoni" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Oten ducj i dispositîfs che a supuartin i inzornaments dal firmware" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Torne ducj i ID dal hardware pe machine" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Instale inzornaments preparâts cumò" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Instale un file firmware su chest hardware" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Al oten detais su un file di firmware" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Al oten la liste di inzornaments pal hardware tacât" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Al inzorne ducj i firmware ae ultime version disponibile" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Al sbloche il dispositîf pal acès al firmware" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Al nete i risultâts dal ultin inzornament" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Al nete ducj i inzornaments programâts di fâ fûr rêt" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Al oten i risultâts dal ultin inzornament" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/he.po000066400000000000000000000603671325145456600142440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # dhead666 , 2015 # GenghisKhan , 2015 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Hebrew (http://www.transifex.com/freedesktop/fwupd/language/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: he\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "אימות משתמש נדרש לעדכון קושחה מערכת זו" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "כינוי עבור %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "פקודה לא נמצאה" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "נכשל בפענוח הארגומנטים" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "הצג מידע ניפוי שגיאות לכל הקבצים" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "אפשרויות ניפוי שגיאות" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "הצג אפשרויות ניפוי שגיאות" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "יציאה לאחר השהייה קצרה" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "יציאה לאחר טעינת מנוע התכנה" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "שדון עדכון קושחה" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "שירות D-Bus עדכון קושחה" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "לא אותרה חומרה בעלת יכולת עדכון קושחה" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "מתקין מחדש %s עם %s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "משנמך גרסת %s מ־%s ל־%s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "מעדכן %s מ־%s ל־%s..." #: src/fu-util.c:694 msgid "Done!" msgstr "הסתיים!" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "אישור" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "גרסא" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "תיאור" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "סכום ביקורת" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "ישנם עדכוני קושחה עבור %s:" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "הצג מידע ניפוי שגיאות מורחב" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "מציג כל המכשירים התומכים בעדכוני קושחה" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "מתקין כעת עדכונים מוכנים" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "מתקין קובץ קושחה בחומרה זו" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "מציג פרטים אודות קובץ קושחה" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/hi.po000066400000000000000000000614421325145456600142430ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Prashant Gupta , 2015 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Hindi (http://www.transifex.com/freedesktop/fwupd/language/hi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hi\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "फर्मवेयर अपडेट के लिए प्रमाणीकरण चाहिए " #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "%s का उपनाम " #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "आर्गुमेंट पार्स करने में असफल " #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "फाइल्स की डिबगिंग की जानकारी दिखाए " #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "डिबगिंग के विकल्प " #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "डिबगिंग के विकल्प दिखाए " #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "थोड़ी देरी के बाद बहार जाएँ " #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "इंजन के लोड हो जाने पर बहार जाएँ " #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "फर्मवेयर अपडेट डी-बस सेवा " #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "अपडेट की क्षमता वाला हार्डवेयर उपलब्ध नहीं " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "%s को %s से दोबारा स्थापित करा जा रहा है " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "%s की %s से %s तक अधोगति हो रही है " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "%s को %s से %s तक अपडेट करा जा रहा है " #: src/fu-util.c:694 msgid "Done!" msgstr "हो गया !" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" msgstr[1] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1540 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "" #: src/fu-util.c:1631 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "डिबगिंग की अतिरिक्त जानकारी दिखाएँ " #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "फर्मवेयर अपडेट का समर्थन करने वाली सभी युक्तियाँ प्राप्त करें " #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "तैयार अपडेट अभी स्थापित करें " #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "फर्मवेयर फाइल को इस हार्डवेयर पर स्थापित करें " #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "फर्मवेयर फाइल की अधिक जानकारी प्राप्त करें " #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/hr.po000066400000000000000000000725671325145456600142660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # FIRST AUTHOR , 2016 # gogo , 2016 # gogo , 2016-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Croatian (http://www.transifex.com/freedesktop/fwupd/language/hr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hr\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Nadopunite frimvere uređaja na Linuxu" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Svrha ovog projekta je automatsko, sigurno i pouzdano nadopunjivanje frimvera na linuxu. Kako bi vidjeli i primijenili nadopune frimvera možete koristiti upravitelja softverom poput GNOME Softvera, alat naredbenog redka ili izravno D-Bus sučelje." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "fwupd je jednostavan pozadinski program koji omogućuje softveru sesije nadopunu frimvera uređaja na vašem lokalnom računalu. Dizajniran je za stolna računala, ali ovaj projekt se može koristiti i na mobilnim telefonima, tabletima i poslužiteljima." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Instaliraj frimver potpisan sustavom" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Potrebna je ovjera za nadopunu frimvera na ovom računalu" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Instaliraj frimver nepotpisan sustavom" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Instaliraj stariju inačicu frimvera sustava" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Potrebna je ovjera za vraćanje starije inačicu frimvera na ovom računalu" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Instaliraj frimver potpisan uređajem" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Potrebna je ovjera za nadopunu frimvera na uklonjivom uređaju" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Instaliraj frimver nepotpisan uređajem" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Potrebna je ovjera za vraćanje starije inačicu frimvera na uklonjivom uređaju" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Otključaj uređaj za dopuštenje pristupa" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Potrebna je ovjera za otključavanje uređaja" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Nadopuni spremljenu informaciju provjere uređaja" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "Potrebna je ovjera za nadopunu spremljenog kontrolnog zbroja uređaja" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Promijeni zadanu udaljenu lokaciju" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "Potrebna je ovjera za promjenu udaljene lokacije koja se koristi za nadopunu frimvera" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Zamjena za %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Naredba nije pronađena" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Dodano" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Uklonjeno" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Promijenjeno" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Prekinuto" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Naziv" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Cipher" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Regija" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Pronađen" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Stanje" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Dozvola odbijena" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Serijski broj" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Način" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Vrijeme trajanja" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Stanje" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Veličina prijenosa" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Značajke" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Okolnosti uređaja" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "ID čipa" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Pretvori firmver u DFU format" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Spoji više frimver datoteka u jednu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Postavi ID proizvođača u datoteku firmvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Postavi ID proizvoda u datoteku firmvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Postavi adresu elementa na datoteku frimvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Postavi veličinu frimvera za metu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Postavi inačicu izdanja u datoteku firmvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Postavi zamjenski broj u datoteku firmvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Postavi zamjenski naziv u datoteku firmvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Poveži DFU sposoban uređaj natrag u vremenu izvršavanja" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "Vrati na izvorno DFU uređaj" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Očitaj frimver iz uređaja u datoteku" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Očitaj frimver iz jedne particije u datoteku" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Zapiši frimver iz datoteke u uređaj" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Zapiši frimver iz datoteke u jednu particiju uređaja" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Prikaži trenutno povezane DFU sposobne uređaje" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Odspoji trenutno povezane DFU sposobne uređaje" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Ispiši opširnije pojedinosti o frimveru u datoteku" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Nadgledaj odspajanje DFU uređaja" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Šifriraj podatke frimvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Dešifriraj podatke frimvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Postavlja metapodatke u datoteku frimvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Zamijeni podatke u postojećoj datoteci frimvera" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Stvori binarnu zakrpu koristeći dvije datoteke" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Primijeni binarnu zakrpu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Ispiši informacije o binarnoj zakrpi na zaslonu" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "Neuspjelo učitavanje okolnosti uređaja" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "DFU pomagalo" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Neuspjela obrada argumenata" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Pobroji sve Synaptics MST uređaje" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Zapiši datoteku frimvera u MST uređaj" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Synaptics Multistream Transport pomagalo" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Instalacija nadopune frimvera..." #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Prikaži informacije otklanjanja greške za sve datoteke" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Prikaži dodatne informacije priključka" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Mogućnosti otklanjanja greške" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Prikaži mogućnosti otklanjanja greške" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Izađi nakon kratke odgode" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Izađi nakon učitavanja pogona" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Pozadinski program nadopune frimvera" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Firmver nadopuna D-Bus usluge" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Mirovanje..." #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Raspakiravanje..." #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Učitavanje..." #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Ponovno pokretanje uređaja..." #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Čitanje..." #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Zapisivanje..." #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Brisanje..." #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Provjeravanje..." #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Zakazivanje..." #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Preuzimanje..." #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Ovjeravanje..." #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Čekanje…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Nepoznat" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Odaberite uređaj:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Uređaji koji nisu ispravno nadopunjeni:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Uređaji koji su ispravno nadopunjeni:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Pošalji izvještaj odmah?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Potreban je pristup internetu" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Nema otkrivenog hardvera s mogućnosti nadopune frimvera" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Ponovna instalacija %s inačice %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Vraćanje %s s inačice %s na inačicu %s... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Nadopuna %s s inačice %s na inačicu %s... " #: src/fu-util.c:694 msgid "Done!" msgstr "Završeno!" #: src/fu-util.c:726 msgid "Target" msgstr "Odredište" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Nastavi sa slanjem?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "Neuspješna nadopuna je poznat problem, posjetite ovaj URL za više informacija:" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "Pošalji poruku:" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "U redu" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Dohvaćanje potpisa" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Dohvaćanje metapodataka" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Dohvaćanje frimvera" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Dohvaćanje datoteke" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Inačica" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Sažetak" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Udaljena lokacija" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Opis" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Kontrolni zbroj" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Odaberi izdanje:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "Metapodaci firmvera nisu nadopunjeni %u dan i možda nisu najnoviji." msgstr[1] "Metapodaci firmvera nisu nadopunjeni %u dana i možda nisu najnoviji." msgstr[2] "Metapodaci firmvera nisu nadopunjeni %u dana i možda nisu najnoviji." #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Nadopuni odmah?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s ima nadopune frimvera:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Inačica nadopune" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Naziv nadopune" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Sažetak nadopune" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Udaljeni ID nadopune" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Kontrolni zbroj nadopune" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Lokacija nadopune" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Opis nadopune" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "Udaljeni ID" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Naziv" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Vrsta" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Skup ključeva" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Omogućeno" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Dob" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Prioritet" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Korisničko ime" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Lozinka" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Naziv datoteke" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Potpis naziva datoteke" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "URI metapodataka" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Potpis URI metapodataka" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "Osnovni URI frimvera" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "URI izvještaja" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Uređaj dodan:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Uređaj uklonjen:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Uređaj promijenjen:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "Nadopuna zahtijeva ponovno pokretanje za završetak." #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "Ponovno pokreni odmah?" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Prikaži dodatne informacije otklanjanja grešaka" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Prikaži inačicu klijenta i pozadinskog programa" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Zakaži instalaciju pri sljedećem pokretanju kada je moguće" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Dopusti ponovnu instalaciju frimvera postojeće inačice" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Dopusti vraćanje starije inačice frimvera" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Zaobiđi upozorenja priključka" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Odgovori 'da' na sva pitanja" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "Ne provjeravaj neprijavljenu povijest" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "Ne provjeravaj stare metapodatke" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "Ne provjeravaj za ponovno pokretanje nakon nadopune" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Prikaži sve uređaje koji podržavaju nadopunu frimvera" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Vrati sve ID-ove hardvera za uređaj" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Instaliraj pripremljene uređaje odmah" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Prikaži povijest nadopune metapodataka" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Obriši svu povijest nadopune frimvera" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Podijeli povijest frimvera sa razvijateljima" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Instaliraj datoteku frimvera na ovaj uređaj" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Prikaži pojedinosti datoteke frimvera" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Prikaži popis nadopuna za povezani hardver" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Nadopuni sav frimver na najnovije dostupne inačice" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Prikaži kriptografsku jedinstvenu vrijednost opširnijih informacija frimvera" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Otključava uređaj za pristup frimvera" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Uklanja rezultate posljednje nadopune" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Uklanja sve nadopune zakazne za izvanmrežno nadopunjivanje" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Prikaži rezultate posljednje nadopune" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Prikazuje izdanja za uređaj" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Prikazuje udaljena podešavanja" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Vraća stariju inačicu frimvera na uređaju" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Osvježi metapodatke s udaljenog poslužitelja" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Nadopuni pohranjene metapodatke s trenutnim sadržajem ROM-a" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Nadgledaj događaje pozadinskim programom" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Izgradi frimver u osiguranom okruženju" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Ispiši opširnije podatke SMBIOS-a iz datoteke" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Promjena zadane udaljene lokacije" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Firmver pomagalo" fwupd-1.0.6/po/hu.po000066400000000000000000000741341325145456600142610ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Balázs Meskó , 2017-2018 # Balázs Úr , 2015-2018 # Gabor Kelemen , 2016 # kelemeng , 2016 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Hungarian (http://www.transifex.com/freedesktop/fwupd/language/hu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Eszköz firmware frissítése Linuxon" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "A projekt célja a firmwarek frissítését automatikussá, biztonságossá és megbízhatóvá tétele Linuxon. Használhat grafikus szoftverkezelőket, mint a GNOME Szoftverek a frissítések megtekintéséhez és alkalmazásához, használhatja a parancssoros eszközt, vagy közvetlenül a D-Bus interfészt." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "A fwupd folyamat egy egyszerű démon, amely lehetővé teszi más szoftvereknek a számítógép eszközeinek firmware-jének frissítését. Asztali számítógépekre lett tervezve, de használható telefonokon, táblagépeken és képernyő nélküli kiszolgálókon is. " #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Aláírt rendszer firmware telepítése" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Hitelesítés szükséges a firmware frissítéséhez ezen a gépen" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Nem aláírt rendszer firmware telepítése" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "A rendszer firmware régi verziójának telepítése" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Hitelesítés szükséges a firmware visszafejlesztéséhez ezen a gépen" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Aláírt eszköz firmware telepítése" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Hitelesítés szükséges a firmware frissítéséhez egy cserélhető eszközön" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Nem aláírt eszköz firmware telepítése" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Hitelesítés szükséges a firmware visszafejlesztéséhez egy cserélhető eszközön" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Eszköz feloldása hozzáférés engedélyezéséhez" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Hitelesítés szükséges az eszköz feloldásához" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "A tárolt eszközellenőrzési információk frissítése" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "Hitelesítés szükséges az eszköz tárolt ellenőrzőösszegeinek frissítéséhez" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "A beállított távoli tároló módosítása" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "Hitelesítés szükséges a firmware frissítéshez beállított távoli tároló módosításához." #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Álnév ehhez: %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "A parancs nem található" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Hozzáadva" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Eltávolítva" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Módosítva" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Megszakítva" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "Azonosító" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Név" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Titkosító" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Régió" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Megtalálva" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokoll" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Állapot" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Hozzáférés megtagadva" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Sorozat" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Mód" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Futtatókörnyezet" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Állapot" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Átviteli méret" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Attribútumok" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Kompatibilitási trükkök" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "Chipazonosító" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Firmware átalakítása DFU formátumra" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Több firmware fájl egyesítése" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Gyártóazonosító beállítása a firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Termékazonosító beállítása a firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Elem címének beállítása a firmware fájlban" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "A firmware méretének beállítása a célhoz" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Kiadási verzió beállítása a firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Alternatív szám beállítása a firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Alternatív név beállítása a firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "DFU-képes eszköz visszacsatolása a futtatókörnyezethez" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "DFU eszköz visszaállítása" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Firmware beolvasása eszközről egy fájlba" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Firmware beolvasása egy partícióról fájlba" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Firmware írása fájlból egy eszközre" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Firmware írása fájlból egy partícióra" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Jelenleg csatlakoztatott DFU-képes eszközök felsorolása" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Jelenleg csatlakoztatott DFU-képes eszközök leválasztása" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Részletek kiírása egy firmware fájlról" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "DFU-eszközök menet közbeni csatlakoztatásának figyelése" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Firmware adatok titkosítása" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Firmware adatok visszafejtése" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Metaadatok beállítása egy firmware fájlon" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Adatok cseréje egy meglévő firmware fájlban" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Bináris folt készítése két fájl használatával" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Bináris folt alkalmazása" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Információk kiírása a képernyőre a bináris foltról" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "A trükkök betöltése sikertelen" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "DFU segédprogram" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Nem sikerült feldolgozni az argumentumokat" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Az összes Synaptics MST eszköz felsorolása" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Firmware fájl beírása az MST eszközbe" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Synaptics több adatfolyamos átviteli segédprogram" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Firmware frissítés telepítése…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Hibakeresési információk megjelenítése minden fájlnál" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Bővítmény bőbeszédű információinak megjelenítése" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Hibakeresési beállítások" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Hibakeresési beállítások megjelenítése" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Kilépés egy kis késleltetés után" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Kilépés a motor betöltődése után" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Firmware frissítő démon" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Firmware frissítés D-Bus szolgáltatás" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Üresjárat…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Kibontás…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Betöltés…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Eszköz újraindítása…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Olvasás…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Írás…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Törlés…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Ellenőrzés…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Ütemezés…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Letöltés…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Hitelesítés…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Várakozás…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Ismeretlen" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Válasszon eszközt:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Eszközök, melyek nem lettek helyesen frissítve:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Eszközök, melyek sikeresen frissítve lettek:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Feltölti most a jelentést?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Internetkapcsolat szükséges" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Nem észlelhető firmware frissítési képességgel rendelkező hardver" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "%s újratelepítése ezzel: %s…" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "%s visszafejlesztése: %s -> %s…" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "%s frissítése: %s -> %s…" #: src/fu-util.c:694 msgid "Done!" msgstr "Kész!" #: src/fu-util.c:726 msgid "Target" msgstr "Cél" #: src/fu-util.c:727 msgid "Payload" msgstr "Tartalom" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Folytatja a feltöltést?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "A feltöltési hiba ismert probléma, további információkért látogassa meg ezt az URL-t:" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "Feltöltési üzenet:" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "OK" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Aláírás lekérése" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Metaadatok lekérése" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Firmware lekérése" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Fájl lekérése" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Verzió" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Összegzés" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Távoli tároló" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Leírás" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Ellenőrzőösszeg" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Válasszon kiadást:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "A firmware metaadatok %u napja nem lettek frissítve, és lehet hogy elavultak." msgstr[1] "A firmware metaadatok %u napja nem lettek frissítve, és lehet hogy elavultak." #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Frissíti most?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s firmware frissítésekkel rendelkezik:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Frissítés verziója" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Frissítés neve" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Frissítés összegzése" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Távoli azonosító frissítése" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Frissítés ellenőrzőösszege" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Frissítés helye" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Frissítés leírása" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "Távoli azonosító" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Cím" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Típus" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Kulcstartó" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Engedélyezve" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Kor" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Prioritás" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Felhasználónév" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Jelszó" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Fájlnév" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Fájlnév aláírása" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "Metaadat URI" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Metaadat URI aláírása" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "Firmware kiindulópont URI" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "Jelentési URI" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Eszköz hozzáadva:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Eszköz eltávolítva:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Eszköz módosítva:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "Egy frissítés újraindítást igényel a befejezéshez." #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "Újraindítja most?" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "További hibakeresési információk megjelenítése" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Ügyfél és démon verziók megjelenítése" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Telepítés ütemezése a következő újraindításkor, ha lehetséges" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Meglévő firmware verziók újratelepítésének engedélyezése" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Firmware verziók visszafejlesztésének engedélyezése" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Bővítmény figyelmeztetés felülbírálása" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Igen az összes kérdésre" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "Ne ellenőrizze a nem jelentett előzményeket" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "Ne ellenőrizze a régi metaadatokat" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "Ne ellenőrizze az újraindítást a frissítés után" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Minden eszköz lekérése, amelyek támogatják a firmware frissítéseket" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "A géphez tartoó összes hardverazonosító visszaadása" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Az előkészített frissítések telepítés most" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Firmware frissítési előzmények megtekintése" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Firmware frissítési előzmények törlése" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Firmware frissítése előzmények megosztása a fejlesztőkkel" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Egy firmware fájl telepítése ezen a hardveren" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Részleteket kér le egy firmware fájlról" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "A frissítések listáját kéri le a csatlakoztatott hardverhez" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Minden firmware-t az elérhető legfrissebb verziókra frissít" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Lekéri a kiírt firmware kriptográfiai hash-ét" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Eszköz feloldása a firmware eléréséhez" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Törli a legutóbbi frissítésből származó eredményeket" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Törli a beütemezett offline frissítéseket" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "A legutóbbi frissítésből származó eredményeket kéri le" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Lekéri az eszközhöz tartozó kiadásokat" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Lekéri a beállított távoli tárolókat" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "A firmware visszafejlesztése az eszközön" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Metaadatok frissítése a távoli kiszolgálóról" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "A tárolt metaadatok frissítése a jelenlegi ROM tartalmával" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "A démon eseményeinek figyelése" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Firmware összeállítása egy homokozóban" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "SMBIOS adatok kiírása egy fájlból" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "A megadott távoli tároló módosítása" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Firmware segédprogram" fwupd-1.0.6/po/id.po000066400000000000000000000721761325145456600142450ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Andika Triwidada , 2017-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Indonesian (http://www.transifex.com/freedesktop/fwupd/language/id/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: id\n" "Plural-Forms: nplurals=1; plural=0;\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Perbarui firmware peranti pada Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Proyek ini bertujuan membuat pemutakhiran firmware pada Linux otomatis, aman, dan handal. Anda dapat memakai manajer perangkat lunak GUI seperti GNOME Perangkat Lunak untuk melihat dan menerapkan pembaruan, perkakas perintah baris, atau antar muka D-Bus secara langsung." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "Proses fwupd adalah sebuah daemon sederhana yang memungkinkan perangkat lunak sesi memperbarui firmware peranti pada mesin lokal Anda. Ini dirancang untuk desktop, tapi proyek ini juga dapat dipakai pada telepon, tablet, dan server headless." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Pasang firmware sistem yang ditandatangani" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "Otentikasi diperlukan untuk memutakhirkan firmware pada mesin ini" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Pasang firmware sistem yang tak ditandatangani" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Pasang versi lama dari firmware sistem" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "Otentikasi diperlukan untuk menuruntingkatkan firmware pada mesin ini" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Pasang firmware perangkat yang ditandatangani" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "Otentikasi diperlukan untuk memutakhirkan firmware pada perangkat lepas pasang" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Pasang firmware perangkat yang tak ditandatangani" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "Otentikasi diperlukan untuk menuruntingkatkan firmware pada perangkat lepas pasang" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Buka kunci perangkat untuk mengizinkan akses" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "Otentikasi diperlukan untuk membuka kunci suatu perangkat" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Mutakhirkan informasi verifikasi perangkat yang tersimpan" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "Otentikasi diperlukan untuk memutakhirkan checksum tersimpan bagi perangkat" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Ubah suatu remote yang ditata" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "Otentikasi diperlukan untuk mengubah sebuah remote yang ditata yang dipakai untuk pembaruan firmware" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias ke %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Perintah tidak ditemukan" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Ditambahkan" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Dihapus" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Diubah" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Dibatalkan" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Nama" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Cipher" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Wilayah" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Ditemukan" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protokol" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Status" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Izin ditolak" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Serial" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Mode" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Runtime" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Keadaan" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Ukuran Transfer" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Atribut" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Keanehan" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "ID Chip" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Konversikan firmware ke format DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Gabungkan beberapa berkas firmware menjadi satu" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Atur ID vendor pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Atur ID produk pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Atur alamat elemen pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Atur ukuran firmware bagi target" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Atur versi rilis pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Atur nomor alternatif pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Atur nama alternatif pada berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Cantolkan kembali perangkat mampu-DFU ke runtime" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "Reset suatu peranti DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Baca firmware dari perangkat ke dalam suatu berkas" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Baca firmware dari satu partisi ke dalam suatu berkas" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Tulis firmware dari berkas ke dalam perangkat" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Tulis firmware dari berkas ke dalam suatu partisi" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Tampilkan daftar perangkat mampu-DFU yang kini tercantol" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Lepas perangkat mampu-DFU yang kini tercantol" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Curahkan rincian tentang suatu berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Amati perangkat DFU yang sedang di-hotplug" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Enkripsikan data firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Dekripsikan data firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Atur metadata pada suatu berkas firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Gantikan data dalam suatu berkas firmware yang telah ada" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Buat suatu patch biner mamakai dua berkas" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Terapkan sebuah patch biner" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Curahkan informasi tentang suatu patch biner ke layar" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "Gagal memuat quirk" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "Utilitas DFU" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Gagal mengurai argumen" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Enumerasikan semua perangkat MST Synaptics" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Flash-kan berkas firmware ke perangkat MST" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Utilitas Transport Multistream Synaptics" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Sedang memasang pembaruan firmware..." #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Tampilkan informasi pengawakutuan bagi semua berkas" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Tampilkan informasi rinci pengaya" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Opsi Pengawakutuan" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Tampilkan opsi pengawakutuan" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Keluar setelah tundaan sejenak" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Keluar setelah mesin telah dimuat" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Daemon Pemutakhiran Firmware" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Layanan D-Bus Pemutakhiran Firmware" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Menganggur..." #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Mendekompresi..." #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Memuat..." #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Memulai ulang perangkat..." #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Membaca..." #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Menulis..." #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Menghapus..." #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Verifikasi..." #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Menjadwalkan..." #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Sedang mengunduh..." #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Mengotentikasi..." #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Menunggu..." #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Tidak diketahui" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Pilih suatu peranti:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Peranti yang tidak diperbarui dengan benar:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Peranti yang sukses diperbarui:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Unggah laporan sekarang?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Memerlukan koneksi internet" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Tidak terdeteksi perangkat keras dengan kapabilitas pemutakhiran firmware" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Memasang ulang %s dengan %s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Menuruntingkatkan %s dari %s ke %s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Memutakhirkan %s dari %s ke %s..." #: src/fu-util.c:694 msgid "Done!" msgstr "Selesai!" #: src/fu-util.c:726 msgid "Target" msgstr "Target" #: src/fu-util.c:727 msgid "Payload" msgstr "Payload" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Lanjutkan mengunggah?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "Kegagalan pembaruan adalah masalah yang telah diketahui, kunjungi URL ini untuk informasi lebih lanjut:" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "Pesan unggah:" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "OK" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Sedang mengambil tanda tangan" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Sedang mengambil metadata" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Sedang mengambil firmware" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Sedang mengambil berkas" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Versi" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Ringkasan" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Remote" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Deskripsi" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Checksum" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Pilih sebuah rilis:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "Metadata firmware belum diperbarui selama %uhari dan mungkin tidak mutakhir." #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Perbarui sekarang?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s memiliki pemutakhiran firmware:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Mutakhirkan Versi" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Nama Pembaruan" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Ringkasan Pembaruan" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "Mutakhirkan ID Remote" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Mutakhirkan Checksum" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Mutakhirkan Lokasi" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Mutakhirkan Keterangan" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "ID Remote" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Judul" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Tipe" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Keyring" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Difungsikan" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Usia" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Prioritas" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Nama Pengguna" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Kata Sandi" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Nama Berkas" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Tanda Tangan Nama Berkas" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "URI Metadata" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Tanda Tangan URI Metadata" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "URI Basis Firmware" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "URI Lapor" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Perangkat ditambahkan:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Perangkat dilepas:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Perangkat diubah:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "Suatu pembaruan memerlukan boot ulang agar lengkap." #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "Mulai ulang sekarang?" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Tampilkan informasi pengawakutuan ekstra" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Tampilkan versi daemon dan klien" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Jadwalkan instalasi untuk boot ulang selanjutnya bila mungkin" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Izinkan pemasangan ulang versi firmware yang telah ada" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Izinkan penuruntingkatan versi firmware" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Timpa peringatan plugin" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Jawab ya untuk semua pertanyaan" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "Jangan periksa untuk riwayat yang tak dilaporkan" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "Jangan periksa untuk metadata lama" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "Jangan periksa untuk boot ulang setelah pembaruan" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Dapatkan semua perangkat yang mendukung pemutakhiran firmware" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Kembalikan semua ID perangkat keras bagi mesin" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Pasang pemutakhiran yang disiapkan sekarang" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Tampilkan riwayat pembaruan firmware" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Hapus semua riwayat pembaruan firmware" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Bagikan riwayat firmware dengan para pengembang" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Pasang suatu berkas firmware pada perangkat keras ini" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Dapatkan rincian tentang suatu berkas firmware" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Dapatkan daftar pemutakhiran bagi perangkat keras yang tersambung" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Mutakhirkan semua firmware ke versi terbaru yang tersedia" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Dapatkan hash kriptografis dari firmware yang dicurahkan" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Buka kunci perangkat bagi akses firmware" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Bersihkan hasil dari pemutakhiran terakhir" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Bersihkan semua pembaruan yang dijadwalkan untuk diperbarui luring" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Dapatkan hasil dari pemutakhiran terakhir" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Dapatkan rilis-rilis bagi sebuah peranti" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Dapatkan remote-remote yang terkonfigurasi" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Turuntingkatkan firmware pada suatu peranti" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Segarkan metadata dari server remote" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Mutakhirkan metadata tersimpan dengan isi ROM saat ini" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Pantau daemon untuk kejadian" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Bangun firmware memakai suatu sandbox" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Curahkan data SMBIOS dari suatu berkas" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Mengubah suatu remote yang diberikan" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Utilitas Firmware" fwupd-1.0.6/po/it.po000066400000000000000000000732551325145456600142640ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Gianvito Cavasoli , 2016 # Milo Casagrande , 2017-2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Italian (http://www.transifex.com/freedesktop/fwupd/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "Aggiorna firmware dispositivi su Linux" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "Questo progetto vuole rendere l'aggiornamento di firmware su Linux un processo automatico, sicuro e affidabile. È possibile usare uno strumento grafico come GNOME Software per visualizzare e applicare gli aggiornamenti, oppure lo strumento a riga di comando o l'interfaccia D-Bus." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "Il processo fwupd è un demone che consente di aggiornare il firmware di un dispositivo sul proprio computer. È progettato per un ambiente desktop, ma è possibile utilizzarlo anche su telefonini, tablet e server." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "Installa firmware firmato di sistema" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "È richiesto autenticarsi per aggiornare il firmware su questa macchina" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "Installa firmware non firmato di sistema" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "Installa una vecchia versione del firmware di sistema" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "È richiesto autenticarsi tornare al precedente firmware su questa macchina" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "Installa firmware firmato del dispositivo" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "È richiesto autenticarsi per aggiornare il firmware su un dispositivo rimovibile" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "Installa firmware non firmato del dispositivo" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "È richiesto autenticarsi per tornare al precedente firmware su un dispositivo rimovibile" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "Sblocco del dispositivo per consentire l'accesso" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "È richiesto autenticarsi per sbloccare un dispositivo" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "Aggiornamento delle informazioni di verifica del dispositivo salvate" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "È richiesto autenticarsi per aggiornare il codice di controllo del dispositivo salvato" #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "Modifica un remoto configurato" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "È richiesto autenticarsi per modificare un remoto configurato utilizzato per aggiornamenti firmware" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "Alias di %s" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "Comando non trovato" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "Aggiunto" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "Rimosso" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "Modificato" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "Annullato" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "Identificativo" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "Nome" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "Cifratura" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "Regione" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "Trovato" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "Protocollo" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "Stato" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "Permesso negato" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "Seriale" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "Modalità" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "Runtime" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "DFU" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "Stato" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "Dimensione trasferimento" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "Attributi" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "Stranezze" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "ID processore" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "Converte il firmware nel formato DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "Unisce più file di firmware in uno" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "Imposta l'identificativo del produttore sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "Imposta l'identificativo del prodotto sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "Imposta l'indirizzo dell'elemento sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "Imposta la dimensione del firmware per la destinazione" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "Imposta la versione di rilascio sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "Imposta il numero alternativo sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "Imposta il nome alternativo sul file del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "Collega dispositivo DFU al runtime" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "Ripristina un dispositivo DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "Legge il firmware dal dispositivo in un file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "Legge il firmware da una partizione in un file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "Scrive il firmware dal file nel dispositivo" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "Scrive il firmware dal file in una partizione" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "Elenca gli attuali dispositivi collegati con supporto DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "Rimuove l'attuale dispositivo collegato con supporto DFU" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "Scarta informazioni su un file di firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "Controlla i dispositivi DFU che sono collegati a caldo" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "Cifra i dati del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "Decifra i dati del firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "Imposta i metadati su un file di firmware" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "Sostituisce i dati su un file di firmware esistente" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "Crea una patch binaria utilizzando due file" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "Applica una patch binaria" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "Stampa le informazioni riguardo a una patch binaria su schermo" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "Caricamento stranezze non riuscito" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "Strumento DFU" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "Analisi degli argomenti non riuscita" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "Elenca tutti i dispositivi Synaptics MST" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "Scrive il file di firmware sul dispositivo MST" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "Strumento «Synaptics Multistream Transport»" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "Installazione aggiornamento firmware…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "Mostra le informazioni di debug per tutti i file" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "Mostra informazioni dettagliate del plugin" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "Opzioni di debug" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "Mostra le opzioni di debug" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "Esce dopo una breve attesa" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "Esce dopo che il motore è stato caricato" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "Demone di aggiornamento firmware" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "Servizio D-Bus di aggiornamento firmware" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "Inattivo…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "Estrazione…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "Caricamento…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "Riavvio del dispositivo…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "Lettura…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "Scrittura…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "Eliminazione…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "Verifica…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "Pianificazione…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "Scaricamento…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "Autenticazione…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "Attesa…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "Sconosciuto" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "Scegliere un dispositivo:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "Dispositivi non aggiornati correttamente:" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "Dispositivi aggiornati con successo:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "Caricare il rapporto ora?" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "Richiede una connessione a Internet" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "Non è stato rilevato nessun hardware con capacità di aggiornamento del firmware" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "Reinstallazione di %s con %s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "Arretramento di %s da %s a %s..." #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "Aggiornamento di %s da %s a %s..." #: src/fu-util.c:694 msgid "Done!" msgstr "Fatto." #: src/fu-util.c:726 msgid "Target" msgstr "Obiettivo" #: src/fu-util.c:727 msgid "Payload" msgstr "Carico" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "Procedere con il caricamento?" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "Questo è un problema noto, consultare il seguente URL per maggiori informazioni:" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "Messaggio di caricamento:" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "Fatto" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "Recupero firma" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "Recupero metadati" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "Recupero firmware" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "Recupero file" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "Versione" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "Riepilogo" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "Remoto" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "Descrizione" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "Codice di controllo" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "Scegliere un rilascio:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "I metadati del firmware non sono stati controllati per %u giorno e potrebbero non essere aggiornati." msgstr[1] "I metadati del firmware non sono stati controllati per %u giorni e potrebbero non essere aggiornati." #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "Aggiornare ora?" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s ha degli aggiornamenti del firmware:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "Versione aggiornamento" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "Nome aggiornamento" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "Riepilogo aggiornameto" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "ID remoto aggiornamento" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "Codice di controllo aggiornamento" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "Posizione aggiornamento" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "Descrizione aggiornamento" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "ID remoto" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "Titolo" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "Tipo" #: src/fu-util.c:1631 msgid "Keyring" msgstr "Portachiavi" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "Abilitato" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "Età" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "Priorità" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "Nome utente" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "Password" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "Nome file" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "Firma nome file" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "URI metadati" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "Firma URI dei metadati" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "URI di base del firmware" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "URI del rapporto" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "Dispositivo aggiunto:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "Dispositivo rimosso:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "Dispositivo modificato:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "Per essere completato, un aggiornamento richiede un riavvio." #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "Riavviare ora?" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "Mostra maggiori informazioni di debug" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "Mostra la versione del client e del demone" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "Pianifica l'installazione al prossimo riavvio quando è possibile" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "Consente di reinstallare versioni del firmware esistenti" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "Consente di tornare alle precedenti versioni del firmware" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "Scavalca l'avviso sul plugin" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "Risponde affermativamente a tutte le domande" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "Non controlla la cronologia non segnalata " #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "Non controlla i metadati vecchi" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "Non controlla se è necessario riavviare dopo un aggiornamento" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "Ottiene tutti i dispositivi che supportano gli aggiornamenti del firmware" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "Fornisce tutti gli ID hardware per un dispositivo" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "Installa ora gli aggiornamenti preparati" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "Mostra la cronologia degli aggiornamenti firmware" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "Elimina tutta la cronologia degli aggiornamenti firmware" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "Condivide la cronologia del firmware con gli sviluppatori" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "Installa un file di firmware su questo hardware" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "Ottiene le informazioni su un file di firmware" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "Ottiene l'elenco degli aggiornamenti per l'hardware connesso" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "Aggiorna tutti i firmware all'ultima versione disponibile" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "Ottiene l'hash crittografico del firmware scartato" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "Sblocca il dispositivo per accedere al firmware" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "Pulisce i risultati dell'ultimo aggiornamento" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "Annulla gli aggiornamenti pianificati per essere eseguiti offline" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "Ottiene i risultati dell'ultimo aggiornamento" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "Ottiene i rilasci di un dispositivo" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "Ottiene i remoti configurati" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "Ripristina una vecchia versione del firmare su un dispositivo" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "Ricarica i metadati dal server remoto" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "Aggiorna i metadati salvati con gli attuali contenuti della ROM" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "Controlla il demone per gli eventi" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "Compila il firmware utilizzando una sandbox" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "Scarica i dati SMBIOS da un file" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "Modifica un remoto" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "Strumento gestione firmware" fwupd-1.0.6/po/kk.po000066400000000000000000000460771325145456600142570ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Baurzhan Muftakhidinov , 2017 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-09-01 14:26+0100\n" "PO-Revision-Date: 2017-09-01 13:27+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Kazakh (http://www.transifex.com/freedesktop/fwupd/language/kk/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: kk\n" "Plural-Forms: nplurals=1; plural=0;\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "" #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "" #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: libdfu/dfu-tool.c:121 plugins/synapticsmst/synapticsmst-tool.c:115 #: src/fu-util.c:112 #, c-format msgid "Alias to %s" msgstr "" #. TRANSLATORS: error message #: libdfu/dfu-tool.c:194 plugins/synapticsmst/synapticsmst-tool.c:362 #: src/fu-util.c:176 msgid "Command not found" msgstr "" #. TRANSLATORS: read from device to host #: libdfu/dfu-tool.c:1236 msgid "Reading" msgstr "Оқылуда" #. TRANSLATORS: write from host to device #: libdfu/dfu-tool.c:1242 msgid "Writing" msgstr "Жазылуда" #. TRANSLATORS: read from device to host #: libdfu/dfu-tool.c:1248 msgid "Verifying" msgstr "Тексерілуде" #. TRANSLATORS: read from device to host #: libdfu/dfu-tool.c:1254 msgid "Erasing" msgstr "Өшірілуде" #. TRANSLATORS: waiting for device #: libdfu/dfu-tool.c:1260 msgid "Detaching" msgstr "" #. TRANSLATORS: waiting for device #: libdfu/dfu-tool.c:1266 msgid "Attaching" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: libdfu/dfu-tool.c:1487 msgid "Added" msgstr "Қосылған" #. TRANSLATORS: this is when a device is hotplugged #: libdfu/dfu-tool.c:1498 msgid "Removed" msgstr "Өшірілген" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: libdfu/dfu-tool.c:1507 src/fu-util.c:1251 msgid "Changed" msgstr "Өзгертілген" #. TRANSLATORS: this is when a device ctrl+c's a watch #: libdfu/dfu-tool.c:1515 src/fu-util.c:1213 msgid "Cancelled" msgstr "Бас тартылған" #. TRANSLATORS: Appstream ID for the hardware type #: libdfu/dfu-tool.c:2024 src/fu-util.c:1040 msgid "ID" msgstr "" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #: libdfu/dfu-tool.c:2030 libdfu/dfu-tool.c:2036 libdfu/dfu-tool.c:2123 msgid "Name" msgstr "" #. TRANSLATORS: this is the encryption method used when writing #: libdfu/dfu-tool.c:2043 msgid "Cipher" msgstr "" #. TRANSLATORS: these are areas of memory on the chip #: libdfu/dfu-tool.c:2057 msgid "Region" msgstr "" #. TRANSLATORS: detected a DFU device #: libdfu/dfu-tool.c:2092 msgid "Found" msgstr "" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: libdfu/dfu-tool.c:2100 msgid "Protocol" msgstr "" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: libdfu/dfu-tool.c:2112 libdfu/dfu-tool.c:2115 libdfu/dfu-tool.c:2138 msgid "Status" msgstr "" #: libdfu/dfu-tool.c:2112 msgid "Unknown: permission denied" msgstr "" #. TRANSLATORS: serial number, e.g. '00012345' #: libdfu/dfu-tool.c:2129 msgid "Serial" msgstr "" #. TRANSLATORS: device mode, e.g. runtime or DFU #: libdfu/dfu-tool.c:2134 msgid "Mode" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: libdfu/dfu-tool.c:2142 msgid "State" msgstr "" #. TRANSLATORS: transfer size in bytes #: libdfu/dfu-tool.c:2150 msgid "Transfer Size" msgstr "" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: libdfu/dfu-tool.c:2158 msgid "Quirks" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2237 msgid "Convert firmware to DFU format" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2243 msgid "Merge multiple firmware files into one" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2249 msgid "Set vendor ID on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2255 msgid "Set product ID on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2261 msgid "Set element address on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2267 msgid "Set the firmware size for the target" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2273 msgid "Set release version on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2279 msgid "Set alternative number on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2285 msgid "Set alternative name on firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2291 msgid "Attach DFU capable device back to runtime" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2297 msgid "Read firmware from device into a file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2303 msgid "Read firmware from one partition into a file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2309 msgid "Write firmware from file into device" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2315 msgid "Write firmware from file into one partition" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2321 msgid "List currently attached DFU capable devices" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2327 msgid "Detach currently attached DFU capable device" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2333 msgid "Dump details about a firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2339 msgid "Watch DFU devices being hotplugged" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2345 msgid "Encrypt firmware data" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2351 msgid "Decrypt firmware data" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2357 msgid "Sets metadata on a firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2363 msgid "Replace data in an existing firmware file" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2369 msgid "Create a binary patch using two files" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2375 msgid "Apply a binary patch" msgstr "" #. TRANSLATORS: command description #: libdfu/dfu-tool.c:2381 msgid "Dump information about a binary patch to the screen" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: libdfu/dfu-tool.c:2407 msgid "DFU Utility" msgstr "" #. TRANSLATORS: the user didn't read the man page #: libdfu/dfu-tool.c:2412 plugins/synapticsmst/synapticsmst-tool.c:439 #: src/fu-util.c:1733 msgid "Failed to parse arguments" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:408 msgid "Enumerate all Synaptics MST devices" msgstr "" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:414 msgid "Flash firmware file to MST device" msgstr "" #: plugins/synapticsmst/synapticsmst-tool.c:434 msgid "Synaptics Multistream Transport Utility" msgstr "" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:194 msgid "Installing firmware update…" msgstr "" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:130 msgid "Show debugging information for all files" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:180 msgid "Debugging Options" msgstr "" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:182 msgid "Show debugging options" msgstr "" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:863 msgid "Exit after a small delay" msgstr "" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:866 msgid "Exit after the engine has loaded" msgstr "" #. TRANSLATORS: program name #: src/fu-main.c:880 msgid "Firmware Update Daemon" msgstr "" #. TRANSLATORS: program summary #: src/fu-main.c:885 msgid "Firmware Update D-Bus Service" msgstr "" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:51 msgid "Idle…" msgstr "" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:55 msgid "Decompressing…" msgstr "" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:59 msgid "Loading…" msgstr "" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:63 msgid "Restarting device…" msgstr "" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:67 msgid "Writing…" msgstr "" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:71 msgid "Verifying…" msgstr "" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:75 msgid "Scheduling…" msgstr "" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:79 msgid "Downloading…" msgstr "" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:86 msgid "Unknown" msgstr "" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:234 #, c-format msgid "Please enter a number from 1 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:277 msgid "Choose a device:" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:303 msgid "No hardware detected with firmware update capability" msgstr "" #. TRANSLATOR: the plugin only supports offline #: src/fu-util.c:337 msgid "Retrying as an offline update" msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:501 #, c-format msgid "Reinstalling %s with %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:508 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:516 #, c-format msgid "Updating %s from %s to %s... " msgstr "" #: src/fu-util.c:543 msgid "Done!" msgstr "" #: src/fu-util.c:585 src/fu-util.c:985 msgid "OK" msgstr "" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:719 msgid "Fetching signature" msgstr "" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:722 msgid "Fetching metadata" msgstr "" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:725 msgid "Fetching firmware" msgstr "" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:728 msgid "Fetching file" msgstr "" #. TRANSLATORS: section header for release version number #: src/fu-util.c:898 msgid "Version" msgstr "" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:901 msgid "URI" msgstr "" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:907 msgid "Description" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:915 msgid "Checksum" msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:947 msgid "Choose a release:" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1036 #, c-format msgid "%s has firmware updates:" msgstr "" #: src/fu-util.c:1046 msgid "GUID" msgstr "" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1050 msgid "Update Version" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1054 msgid "Update Remote ID" msgstr "" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1063 msgid "Update Checksum" msgstr "" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1067 msgid "Update Location" msgstr "" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1078 msgid "Update Description" msgstr "" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1104 msgid "Remote ID" msgstr "" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1108 msgid "Type" msgstr "" #: src/fu-util.c:1113 msgid "Keyring" msgstr "" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1118 msgid "Enabled" msgstr "" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1145 msgid "Age" msgstr "" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1152 msgid "Priority" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1157 msgid "Username" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1162 msgid "Password" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1167 msgid "Filename" msgstr "" #. TRANSLATORS: remote filename base #: src/fu-util.c:1172 msgid "Filename Signature" msgstr "" #. TRANSLATORS: locatation of the local file #: src/fu-util.c:1177 msgid "Location" msgstr "" #. TRANSLATORS: locatation of the local file #: src/fu-util.c:1182 msgid "Location Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1187 msgid "Metadata URI" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1192 msgid "Metadata URI Signature" msgstr "" #. TRANSLATORS: remote URI #: src/fu-util.c:1197 msgid "Firmware Base URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1224 msgid "Device added:" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1234 msgid "Device removed:" msgstr "" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1244 msgid "Device changed:" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1568 msgid "Show extra debugging information" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1571 msgid "Show client and daemon versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1574 msgid "Schedule installation for next reboot when possible" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1577 msgid "Allow re-installing existing firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1580 msgid "Allow downgrading firmware versions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:1583 msgid "Override plugin warning" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1607 msgid "Get all devices that support firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1613 msgid "Return all the hardware IDs for the machine" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1619 msgid "Install prepared updates now" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1625 msgid "Install a firmware file on this hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1631 msgid "Gets details about a firmware file" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1637 msgid "Gets the list of updates for connected hardware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1643 msgid "Updates all firmware to latest versions available" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1649 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1655 msgid "Unlocks the device for firmware access" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1661 msgid "Clears the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1667 msgid "Gets the results from the last update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1673 msgid "Gets the releases for a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1679 msgid "Gets the configured remotes" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1685 msgid "Downgrades the firmware on a device" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1691 msgid "Refresh metadata from remote server" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1697 msgid "Update the stored metadata with current ROM contents" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1703 msgid "Monitor the daemon for events" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:1709 msgid "Build firmware using a sandbox" msgstr "" #. TRANSLATORS: program name #: src/fu-util.c:1728 msgid "Firmware Utility" msgstr "" fwupd-1.0.6/po/ko.po000066400000000000000000000715231325145456600142550ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fwupd package. # # Translators: # Seong-ho Cho , 2017 # Shinjo Park , 2018 msgid "" msgstr "" "Project-Id-Version: fwupd\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-12 10:37+0000\n" "PO-Revision-Date: 2018-03-12 10:37+0000\n" "Last-Translator: Richard Hughes \n" "Language-Team: Korean (http://www.transifex.com/freedesktop/fwupd/language/ko/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ko\n" "Plural-Forms: nplurals=1; plural=0;\n" #: data/org.freedesktop.fwupd.metainfo.xml:7 msgid "fwupd" msgstr "fwupd" #: data/org.freedesktop.fwupd.metainfo.xml:8 msgid "Update device firmware on Linux" msgstr "리눅스에서 장치 펌웨어를 업데이트합니다" #: data/org.freedesktop.fwupd.metainfo.xml:10 msgid "" "This project aims to make updating firmware on Linux automatic, safe and " "reliable. You can either use a GUI software manager like GNOME Software to " "view and apply updates, the command-line tool or the D-Bus interface " "directly." msgstr "이 프로젝트에서는 리눅스에서 자동으로 안전하고 믿을 수 있게 펌웨어를 업데이트할 수 있게 하려고 합니다. 업데이트를 보고 적용할 때 그놈 소프트웨어, 명령행 도구를 쓰거나 D-Bus 인터페이스를 바로 쓸 수 있습니다." #: data/org.freedesktop.fwupd.metainfo.xml:16 msgid "" "The fwupd process is a simple daemon to allow session software to update " "device firmware on your local machine. It is designed for desktops, but this" " project is also usable on phones, tablets and on headless servers." msgstr "fwupd 프로세스는 로컬 머신의 장치 펌웨어를 세션 프로그램에서 업데이트할 수 있게 하는 간단한 데몬입니다. 데스크톱용으로 설계했지만, 전화기, 태블릭, 헤드리스 서버에서도 사용할 수 있습니다." #: policy/org.freedesktop.fwupd.policy.in:17 msgid "Install signed system firmware" msgstr "서명한 시스템 펌웨어 설치" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:19 #: policy/org.freedesktop.fwupd.policy.in:30 msgid "Authentication is required to update the firmware on this machine" msgstr "이 머신의 펌웨어를 업데이트하려면 인증이 필요합니다" #: policy/org.freedesktop.fwupd.policy.in:28 msgid "Install unsigned system firmware" msgstr "서명하지 않은 시스템 펌웨어 설치" #: policy/org.freedesktop.fwupd.policy.in:39 msgid "Install old version of system firmware" msgstr "시스템 펌웨어 이전 버전 설치" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:41 msgid "Authentication is required to downgrade the firmware on this machine" msgstr "이 머신에 이전 버전의 펌웨어를 설치하려면 인증이 필요합니다" #: policy/org.freedesktop.fwupd.policy.in:50 msgid "Install signed device firmware" msgstr "서명한 장치 펌웨어 설치" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:52 #: policy/org.freedesktop.fwupd.policy.in:63 msgid "" "Authentication is required to update the firmware on a removable device" msgstr "이동식 장치의 펌웨어를 업데이트하려면 인증이 필요합니다" #: policy/org.freedesktop.fwupd.policy.in:61 #: policy/org.freedesktop.fwupd.policy.in:72 msgid "Install unsigned device firmware" msgstr "서명하지 않은 장치 펌웨어 설치" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:74 msgid "" "Authentication is required to downgrade the firmware on a removable device" msgstr "이동식 장치의 펌웨어를 이전 버전으로 되돌리려면 인증이 필요합니다" #: policy/org.freedesktop.fwupd.policy.in:83 msgid "Unlock the device to allow access" msgstr "접근을 허용하려면 장치 잠금을 해제하십시오" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:85 msgid "Authentication is required to unlock a device" msgstr "장치 잠금을 해제하려면 인증이 필요합니다" #: policy/org.freedesktop.fwupd.policy.in:94 msgid "Update the stored device verification information" msgstr "보관된 장치 검증 정보 업데이트" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:96 msgid "" "Authentication is required to update the stored checksums for the device" msgstr "장치 보관 검사합을 업데이트하려면 인증이 필요합니다 " #: policy/org.freedesktop.fwupd.policy.in:105 msgid "Modify a configured remote" msgstr "원격 설정 수정" #. TRANSLATORS: this is the PolicyKit modal dialog #: policy/org.freedesktop.fwupd.policy.in:107 msgid "" "Authentication is required to modify a configured remote used for firmware " "updates" msgstr "펌웨어 업데이트에 사용할 원격 설정을 수정하려면 인증이 필요합니다" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #: plugins/dfu/dfu-tool.c:124 plugins/synapticsmst/synapticsmst-tool.c:105 #: src/fu-util.c:120 #, c-format msgid "Alias to %s" msgstr "%s(으)로 별칭 부여" #. TRANSLATORS: error message #: plugins/dfu/dfu-tool.c:192 plugins/synapticsmst/synapticsmst-tool.c:347 #: src/fu-util.c:184 msgid "Command not found" msgstr "명령을 찾을 수 없습니다" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1458 msgid "Added" msgstr "추가함" #. TRANSLATORS: this is when a device is hotplugged #: plugins/dfu/dfu-tool.c:1469 msgid "Removed" msgstr "제거함" #. TRANSLATORS: this is when a device is hotplugged #. TRANSLATORS: this is when the daemon state changes #: plugins/dfu/dfu-tool.c:1478 src/fu-util.c:1768 msgid "Changed" msgstr "바뀜" #. TRANSLATORS: this is when a device ctrl+c's a watch #: plugins/dfu/dfu-tool.c:1486 src/fu-util.c:1730 msgid "Cancelled" msgstr "취소함" #. TRANSLATORS: Appstream ID for the hardware type #: plugins/dfu/dfu-tool.c:1978 src/fu-util.c:1549 msgid "ID" msgstr "ID" #. TRANSLATORS: interface name, e.g. "Flash" #. TRANSLATORS: device name, e.g. 'ColorHug2' #. TRANSLATORS: section header for the release name #: plugins/dfu/dfu-tool.c:1984 plugins/dfu/dfu-tool.c:1990 #: plugins/dfu/dfu-tool.c:2104 src/fu-util.c:1321 msgid "Name" msgstr "이름" #. TRANSLATORS: this is the encryption method used when writing #: plugins/dfu/dfu-tool.c:1997 msgid "Cipher" msgstr "암호화 방식" #. TRANSLATORS: these are areas of memory on the chip #: plugins/dfu/dfu-tool.c:2011 msgid "Region" msgstr "메모리 영역" #. TRANSLATORS: detected a DFU device #: plugins/dfu/dfu-tool.c:2064 msgid "Found" msgstr "감지 장치" #. TRANSLATORS: DFU protocol version, e.g. 1.1 #: plugins/dfu/dfu-tool.c:2072 msgid "Protocol" msgstr "프로토콜" #. TRANSLATORS: probably not run as root... #. TRANSLATORS: device has failed to report status #. TRANSLATORS: device status, e.g. "OK" #: plugins/dfu/dfu-tool.c:2082 plugins/dfu/dfu-tool.c:2091 #: plugins/dfu/dfu-tool.c:2097 plugins/dfu/dfu-tool.c:2119 msgid "Status" msgstr "장치 상태" #: plugins/dfu/dfu-tool.c:2082 msgid "Permission denied" msgstr "권한 거부" #. TRANSLATORS: serial number, e.g. '00012345' #: plugins/dfu/dfu-tool.c:2110 msgid "Serial" msgstr "시리얼" #: plugins/dfu/dfu-tool.c:2115 msgid "Mode" msgstr "모드" #: plugins/dfu/dfu-tool.c:2115 msgid "Runtime" msgstr "" #: plugins/dfu/dfu-tool.c:2115 msgid "DFU" msgstr "" #. TRANSLATORS: device state, i.e. appIDLE #: plugins/dfu/dfu-tool.c:2123 msgid "State" msgstr "상태" #. TRANSLATORS: transfer size in bytes #: plugins/dfu/dfu-tool.c:2131 msgid "Transfer Size" msgstr "전송 용량" #. TRANSLATORS: device attributes, i.e. things that #. * the device can do #: plugins/dfu/dfu-tool.c:2139 msgid "Attributes" msgstr "속성" #. TRANSLATORS: device quirks, i.e. things that #. * it does that we have to work around #: plugins/dfu/dfu-tool.c:2147 msgid "Quirks" msgstr "특이사항" #. TRANSLATORS: chip ID, e.g. "0x58200204" #: plugins/dfu/dfu-tool.c:2154 msgid "Chip ID" msgstr "칩 ID" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2234 msgid "Convert firmware to DFU format" msgstr "펌웨어를 DFU 형식으로 변환" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2240 msgid "Merge multiple firmware files into one" msgstr "다중 펌웨어 파일을 하나로 병합" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2246 msgid "Set vendor ID on firmware file" msgstr "펌웨어 파일의 제조자 ID 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2252 msgid "Set product ID on firmware file" msgstr "펌웨어 파일의 제품 ID 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2258 msgid "Set element address on firmware file" msgstr "펌웨어 파일의 구성요소 주소 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2264 msgid "Set the firmware size for the target" msgstr "대상 펌웨어 크기 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2270 msgid "Set release version on firmware file" msgstr "펌웨어 파일의 출시 버전 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2276 msgid "Set alternative number on firmware file" msgstr "펌웨어 파일의 대체 번호 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2282 msgid "Set alternative name on firmware file" msgstr "펌웨어 파일의 대체 명칭 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2288 msgid "Attach DFU capable device back to runtime" msgstr "DFU 기능 장치를 런타임에 연결" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2294 msgid "Reset a DFU device" msgstr "DFU 장치 초기화" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2300 msgid "Read firmware from device into a file" msgstr "장치 펌웨어를 읽어 파일에 기록" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2306 msgid "Read firmware from one partition into a file" msgstr "파티션의 펌웨어를 읽어 파일에 기록" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2312 msgid "Write firmware from file into device" msgstr "파일의 펌웨어를 장치에 기록" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2318 msgid "Write firmware from file into one partition" msgstr "파일의 펌웨어를 파티션 하나에 기록" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2324 msgid "List currently attached DFU capable devices" msgstr "현재 연결한 DFU 기능 장치 목록 보기" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2330 msgid "Detach currently attached DFU capable device" msgstr "현재 연결한 DFU 기능 장치 분리" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2336 msgid "Dump details about a firmware file" msgstr "펌웨어 파일 세부 정보 덤프" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2342 msgid "Watch DFU devices being hotplugged" msgstr "DFU 핫 플러그 장치 보기" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2348 msgid "Encrypt firmware data" msgstr "펌웨어 데이터 암호화" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2354 msgid "Decrypt firmware data" msgstr "펌웨어 데이터 복호화" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2360 msgid "Sets metadata on a firmware file" msgstr "펌웨어 파일의 메타데이터 설정" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2366 msgid "Replace data in an existing firmware file" msgstr "기존 펌웨어 파일의 데이터 교체" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2372 msgid "Create a binary patch using two files" msgstr "파일 두 개를 활용하여 바이너리 패치 만들기" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2378 msgid "Apply a binary patch" msgstr "바이너리 패치 적용" #. TRANSLATORS: command description #: plugins/dfu/dfu-tool.c:2384 msgid "Dump information about a binary patch to the screen" msgstr "바이너리 패치 정보 덤프 스크린에 출력" #. TRANSLATORS: quirks are device-specific workarounds #: plugins/dfu/dfu-tool.c:2396 msgid "Failed to load quirks" msgstr "" #. TRANSLATORS: DFU stands for device firmware update #: plugins/dfu/dfu-tool.c:2418 msgid "DFU Utility" msgstr "DFU 유틸리티" #. TRANSLATORS: the user didn't read the man page #: plugins/dfu/dfu-tool.c:2423 plugins/synapticsmst/synapticsmst-tool.c:424 #: src/fu-util.c:2339 msgid "Failed to parse arguments" msgstr "인자 해석에 실패했습니다" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:393 msgid "Enumerate all Synaptics MST devices" msgstr "모든 시냅틱스 MST 장치에 열거 번호를 부여합니다" #. TRANSLATORS: command description #: plugins/synapticsmst/synapticsmst-tool.c:399 msgid "Flash firmware file to MST device" msgstr "MST 장치에 펌웨어 파일을 기록합니다" #: plugins/synapticsmst/synapticsmst-tool.c:419 msgid "Synaptics Multistream Transport Utility" msgstr "시냅틱스 멀티스트림 전송 유틸리티" #. TRANSLATORS: this is shown when updating the firmware after the reboot #: plugins/uefi/fu-plugin-uefi.c:403 msgid "Installing firmware update…" msgstr "펌웨어 업데이트 설치 중…" #. TRANSLATORS: turn on all debugging #: src/fu-debug.c:128 msgid "Show debugging information for all files" msgstr "모든 파일의 디버깅 정보 표시" #. TRANSLATORS: this is for plugin development #: src/fu-debug.c:131 msgid "Show plugin verbose information" msgstr "자세한 플러그인 정보 표시" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:186 msgid "Debugging Options" msgstr "디버깅 옵션" #. TRANSLATORS: for the --verbose arg #: src/fu-debug.c:188 msgid "Show debugging options" msgstr "디버깅 옵션을 표시합니다" #. TRANSLATORS: exit after we've started up, used for user profiling #: src/fu-main.c:1036 msgid "Exit after a small delay" msgstr "짧은 대기 시간 경과 후 나가기" #. TRANSLATORS: exit straight away, used for automatic profiling #: src/fu-main.c:1039 msgid "Exit after the engine has loaded" msgstr "엔진을 불러온 후 나가기" #. TRANSLATORS: program name #: src/fu-main.c:1053 msgid "Firmware Update Daemon" msgstr "펌웨어 업데이트 데몬" #. TRANSLATORS: program summary #: src/fu-main.c:1058 msgid "Firmware Update D-Bus Service" msgstr "펌웨어 업데이트 D-Bus 서비스" #. TRANSLATORS: daemon is inactive #: src/fu-progressbar.c:52 msgid "Idle…" msgstr "대기 중…" #. TRANSLATORS: decompressing the firmware file #: src/fu-progressbar.c:56 msgid "Decompressing…" msgstr "압축 해제 중…" #. TRANSLATORS: parsing the firmware information #: src/fu-progressbar.c:60 msgid "Loading…" msgstr "불러오는 중…" #. TRANSLATORS: restarting the device to pick up new F/W #: src/fu-progressbar.c:64 msgid "Restarting device…" msgstr "장치 다시 시작하는 중…" #. TRANSLATORS: reading from the flash chips #: src/fu-progressbar.c:68 msgid "Reading…" msgstr "읽는 중…" #. TRANSLATORS: writing to the flash chips #: src/fu-progressbar.c:72 msgid "Writing…" msgstr "쓰는 중…" #. TRANSLATORS: erasing contents of the flash chips #: src/fu-progressbar.c:76 msgid "Erasing…" msgstr "지우는 중…" #. TRANSLATORS: verifying we wrote the firmware correctly #: src/fu-progressbar.c:80 msgid "Verifying…" msgstr "검증 중…" #. TRANSLATORS: scheduing an update to be done on the next boot #: src/fu-progressbar.c:84 msgid "Scheduling…" msgstr "작업 계획 중…" #. TRANSLATORS: downloading from a remote server #: src/fu-progressbar.c:88 msgid "Downloading…" msgstr "내려받는 중…" #. TRANSLATORS: waiting for user to authenticate #: src/fu-progressbar.c:92 msgid "Authenticating…" msgstr "인증 중…" #. TRANSLATORS: waiting for device to do something #: src/fu-progressbar.c:96 msgid "Waiting…" msgstr "기다리는 중…" #. TRANSLATORS: currect daemon status is unknown #: src/fu-progressbar.c:103 msgid "Unknown" msgstr "알 수 없음" #. TRANSLATORS: the user isn't reading the question #: src/fu-util.c:242 #, c-format msgid "Please enter a number from 0 to %u: " msgstr "" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:305 msgid "Choose a device:" msgstr "장치를 선택하십시오:" #. TRANSLATORS: this is to abort the interactive prompt #: src/fu-util.c:307 msgid "Cancel" msgstr "" #. TRANSLATORS: a list of failed updates #: src/fu-util.c:427 msgid "Devices that were not updated correctly:" msgstr "" #. TRANSLATORS: a list of successful updates #: src/fu-util.c:441 msgid "Devices that have been updated successfully:" msgstr "" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:455 msgid "Upload report now?" msgstr "" #. TRANSLATORS: metadata is downloaded from the Internet #: src/fu-util.c:457 src/fu-util.c:1490 msgid "Requires internet connection" msgstr "" #. TRANSLATORS: nothing attached that can be upgraded #: src/fu-util.c:479 msgid "No hardware detected with firmware update capability" msgstr "펌웨어 업데이트가 가능한 하드웨어가 없습니다" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number #. * e.g. "1.2.3" #: src/fu-util.c:651 #, c-format msgid "Reinstalling %s with %s... " msgstr "%2$s(으)로 %1$s 다시 설치하는 중... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:658 #, c-format msgid "Downgrading %s from %s to %s... " msgstr "%2$s에서 %3$s(으)로 %1$s 다운그레이드 중... " #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" #: src/fu-util.c:666 #, c-format msgid "Updating %s from %s to %s... " msgstr "%2$s에서 %3$s(으)로 %1$s 업데이트 중... " #: src/fu-util.c:694 msgid "Done!" msgstr "완료!" #: src/fu-util.c:726 msgid "Target" msgstr "" #: src/fu-util.c:727 msgid "Payload" msgstr "" #: src/fu-util.c:728 msgid "Proceed with upload?" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:807 msgid "Update failure is a known issue, visit this URL for more information:" msgstr "" #. TRANSLATORS: the server sent the user a small message #: src/fu-util.c:811 msgid "Upload message:" msgstr "" #: src/fu-util.c:1034 src/fu-util.c:1414 msgid "OK" msgstr "확인" #. TRANSLATORS: downloading new signing file #: src/fu-util.c:1139 msgid "Fetching signature" msgstr "서명 가져오는 중" #. TRANSLATORS: downloading new metadata file #: src/fu-util.c:1142 msgid "Fetching metadata" msgstr "메타데이터 가져오는 중" #. TRANSLATORS: downloading new firmware file #: src/fu-util.c:1145 msgid "Fetching firmware" msgstr "펌웨어 가져오는 중" #. TRANSLATORS: downloading unknown file #: src/fu-util.c:1148 msgid "Fetching file" msgstr "파일 가져오는 중" #. TRANSLATORS: section header for release version number #: src/fu-util.c:1318 msgid "Version" msgstr "버전" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1324 msgid "Summary" msgstr "" #. TRANSLATORS: section header for the remote the file is coming from #: src/fu-util.c:1327 msgid "Remote" msgstr "원격" #. TRANSLATORS: section header for firmware URI #: src/fu-util.c:1330 msgid "URI" msgstr "URI" #. TRANSLATORS: section header for firmware description #: src/fu-util.c:1336 msgid "Description" msgstr "설명" #. TRANSLATORS: section header for firmware checksum #. TRANSLATORS: remote checksum #: src/fu-util.c:1344 src/fu-util.c:1640 msgid "Checksum" msgstr "검사합" #. TRANSLATORS: get interactive prompt #: src/fu-util.c:1376 msgid "Choose a release:" msgstr "출시 버전을 선택하십시오:" #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #: src/fu-util.c:1480 #, c-format msgid "" "Firmware metadata has not been updated for %u day and may not be up to date." msgid_plural "" "Firmware metadata has not been updated for %u days and may not be up to " "date." msgstr[0] "" #. TRANSLATORS: ask the user if we can update the metadata #: src/fu-util.c:1488 msgid "Update now?" msgstr "" #. TRANSLATORS: first replacement is device name #: src/fu-util.c:1533 #, c-format msgid "%s has firmware updates:" msgstr "%s의 최신 펌웨어가 있습니다:" #: src/fu-util.c:1540 msgid "GUID" msgstr "GUID" #. TRANSLATORS: section header for firmware version #: src/fu-util.c:1552 msgid "Update Version" msgstr "업데이트 버전" #. TRANSLATORS: section header for the release name #: src/fu-util.c:1556 msgid "Update Name" msgstr "" #. TRANSLATORS: section header for the release one line summary #: src/fu-util.c:1559 msgid "Update Summary" msgstr "" #. TRANSLATORS: section header for remote ID, e.g. lvfs-testing #: src/fu-util.c:1562 msgid "Update Remote ID" msgstr "업데이트 원격 ID" #. TRANSLATORS: section header for firmware checksum #: src/fu-util.c:1571 msgid "Update Checksum" msgstr "업데이트 검사합" #. TRANSLATORS: section header for firmware remote http:// #: src/fu-util.c:1575 msgid "Update Location" msgstr "업데이트 위치" #. TRANSLATORS: section header for long firmware desc #: src/fu-util.c:1586 msgid "Update Description" msgstr "업데이트 설명" #. TRANSLATORS: remote identifier, e.g. lvfs-testing #: src/fu-util.c:1618 msgid "Remote ID" msgstr "원격 ID" #. TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" #: src/fu-util.c:1622 msgid "Title" msgstr "제목" #. TRANSLATORS: remote type, e.g. remote or local #: src/fu-util.c:1626 msgid "Type" msgstr "형식" #: src/fu-util.c:1631 msgid "Keyring" msgstr "키 모음" #. TRANSLATORS: if the remote is enabled #: src/fu-util.c:1636 msgid "Enabled" msgstr "활성화 여부" #. TRANSLATORS: the age of the metadata #: src/fu-util.c:1667 msgid "Age" msgstr "경과기간" #. TRANSLATORS: the numeric priority #: src/fu-util.c:1674 msgid "Priority" msgstr "우선순위" #. TRANSLATORS: remote filename base #: src/fu-util.c:1679 msgid "Username" msgstr "사용자 이름" #. TRANSLATORS: remote filename base #: src/fu-util.c:1684 msgid "Password" msgstr "암호" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1689 msgid "Filename" msgstr "파일 이름" #. TRANSLATORS: filename of the local file #: src/fu-util.c:1694 msgid "Filename Signature" msgstr "파일이름 서명" #. TRANSLATORS: remote URI #: src/fu-util.c:1699 msgid "Metadata URI" msgstr "메타데이터 URI" #. TRANSLATORS: remote URI #: src/fu-util.c:1704 msgid "Metadata URI Signature" msgstr "메타데이터 URI 서명" #. TRANSLATORS: remote URI #: src/fu-util.c:1709 msgid "Firmware Base URI" msgstr "펌웨어 기본 URI" #. TRANSLATORS: URI to send success/failure reports #: src/fu-util.c:1714 msgid "Report URI" msgstr "" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1741 msgid "Device added:" msgstr "장치 추가함:" #. TRANSLATORS: this is when a device is hotplugged #: src/fu-util.c:1751 msgid "Device removed:" msgstr "장치 제거함:" #. TRANSLATORS: this is when a device has been updated #: src/fu-util.c:1761 msgid "Device changed:" msgstr "장치 상태 바꿈:" #. TRANSLATORS: explain why we want to upload #: src/fu-util.c:1952 msgid "An update requires a reboot to complete." msgstr "" #. TRANSLATORS: reboot to apply the update #: src/fu-util.c:1954 msgid "Restart now?" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2116 msgid "Show extra debugging information" msgstr "추가 디버깅 정보 표시" #. TRANSLATORS: command line option #: src/fu-util.c:2119 msgid "Show client and daemon versions" msgstr "클라이언트와 데몬 버전 표시" #. TRANSLATORS: command line option #: src/fu-util.c:2122 msgid "Schedule installation for next reboot when possible" msgstr "가능하다면 다음 재부팅시 설치 예약" #. TRANSLATORS: command line option #: src/fu-util.c:2125 msgid "Allow re-installing existing firmware versions" msgstr "기존 펌웨어 버전 재설치를 허용합니다" #. TRANSLATORS: command line option #: src/fu-util.c:2128 msgid "Allow downgrading firmware versions" msgstr "펌웨어를 이전 버전으로 되돌릴 수 있게 합니다" #. TRANSLATORS: command line option #: src/fu-util.c:2131 msgid "Override plugin warning" msgstr "플러그인 경고 무시" #. TRANSLATORS: command line option #: src/fu-util.c:2134 msgid "Answer yes to all questions" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2137 msgid "Do not check for unreported history" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2140 msgid "Do not check for old metadata" msgstr "" #. TRANSLATORS: command line option #: src/fu-util.c:2143 msgid "Do not check for reboot after update" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2166 msgid "Get all devices that support firmware updates" msgstr "펌웨어 업데이트를 지원하는 모든 장치 정보를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2172 msgid "Return all the hardware IDs for the machine" msgstr "머신의 모든 하드웨어 ID를 반환합니다" #. TRANSLATORS: command description #: src/fu-util.c:2178 msgid "Install prepared updates now" msgstr "현재 준비한 업데이트를 설치합니다" #. TRANSLATORS: command description #: src/fu-util.c:2184 msgid "Show history of firmware updates" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2190 msgid "Erase all firmware update history" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2196 msgid "Share firmware history with the developers" msgstr "" #. TRANSLATORS: command description #: src/fu-util.c:2202 msgid "Install a firmware file on this hardware" msgstr "이 하드웨어에 펌웨어 파일을 설치합니다" #. TRANSLATORS: command description #: src/fu-util.c:2208 msgid "Gets details about a firmware file" msgstr "펌웨어 파일 세부 정보를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2214 msgid "Gets the list of updates for connected hardware" msgstr "연결한 하드웨어의 업데이트 목록을 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2220 msgid "Updates all firmware to latest versions available" msgstr "모든 펌웨어를 가용 최신 버전으로 업데이트합니다" #. TRANSLATORS: command description #: src/fu-util.c:2226 msgid "Gets the cryptographic hash of the dumped firmware" msgstr "덤프 펌웨어의 암호화 해시 정보를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2232 msgid "Unlocks the device for firmware access" msgstr "펌웨어 접근시 장치 잠금을 해제합니다" #. TRANSLATORS: command description #: src/fu-util.c:2238 msgid "Clears the results from the last update" msgstr "최근 업데이트 결과를 지웁니다" #. TRANSLATORS: command description #: src/fu-util.c:2244 msgid "Clears any updates scheduled to be updated offline" msgstr "오프라인으로 업데이트할 업데이트를 지웁니다" #. TRANSLATORS: command description #: src/fu-util.c:2250 msgid "Gets the results from the last update" msgstr "최근 업데이트 결과를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2256 msgid "Gets the releases for a device" msgstr "장치에 대한 출시 펌웨어를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2262 msgid "Gets the configured remotes" msgstr "원격 설정 정보를 가져옵니다" #. TRANSLATORS: command description #: src/fu-util.c:2268 msgid "Downgrades the firmware on a device" msgstr "장치 펌웨어 버전을 이전으로 되돌립니다" #. TRANSLATORS: command description #: src/fu-util.c:2274 msgid "Refresh metadata from remote server" msgstr "원격 서버의 메타데이터를 새로 고칩니다" #. TRANSLATORS: command description #: src/fu-util.c:2280 msgid "Update the stored metadata with current ROM contents" msgstr "현재 ROM에 저장한 메타데이터를 업데이트합니다" #. TRANSLATORS: command description #: src/fu-util.c:2286 msgid "Monitor the daemon for events" msgstr "데몬 이벤트를 감시합니다" #. TRANSLATORS: command description #: src/fu-util.c:2292 msgid "Build firmware using a sandbox" msgstr "샌드박스에서 펌웨어를 빌드합니다" #. TRANSLATORS: command description #: src/fu-util.c:2298 msgid "Dump SMBIOS data from a file" msgstr "파일의 SMBIOS 데이터 덤프를 출력합니다" #. TRANSLATORS: command description #: src/fu-util.c:2304 msgid "Modifies a given remote" msgstr "주어진 원격 정보를 수정합니다" #. TRANSLATORS: program name #: src/fu-util.c:2334 msgid "Firmware Utility" msgstr "펌웨어 유틸리티" fwupd-1.0.6/po/make-images000077500000000000000000000156211325145456600154070ustar00rootroot00000000000000#!/usr/bin/env python3 """ This thing rasterizes text for use later """ # pylint: disable=wrong-import-position,too-many-locals,unused-argument # pylint: disable=invalid-name,too-many-instance-attributes """ Licensed under the GNU General Public License Version 2 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . """ import os import sys import gettext import math import cairo import gi gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango, PangoCairo from PIL import Image def usage(return_code): """ print usage and exit with the supplied return code """ if return_code == 0: out = sys.stdout else: out = sys.stderr out.write("usage: make-images

We fixed things

\n" " \n" " \n" " \n" " org.freedesktop.fwupd\n" " \n" "", "firmware.dfu", "world", "firmware.dfu.asc", "signature", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_no_error (error); g_assert (store != NULL); /* verify */ app = as_store_get_app_by_id (store, "com.acme.example.firmware"); g_assert_nonnull (app); rel = as_app_get_release_default (app); g_assert_nonnull (rel); g_assert_cmpstr (as_release_get_version (rel), ==, "1.2.3"); csum = as_release_get_checksum_by_target (rel, AS_CHECKSUM_TARGET_CONTENT); g_assert_cmpstr (as_checksum_get_value (csum), ==, "7c211433f02071597741e6ff5a8ea34789abbf43"); blob_tmp = as_release_get_blob (rel, "firmware.dfu"); g_assert_nonnull (blob_tmp); blob_tmp = as_release_get_blob (rel, "firmware.dfu.asc"); g_assert_nonnull (blob_tmp); req = as_app_get_require_by_value (app, AS_REQUIRE_KIND_ID, "org.freedesktop.fwupd"); g_assert_nonnull (req); } static void fu_common_store_cab_unsigned_func (void) { AsApp *app; AsChecksum *csum; AsRelease *rel; GBytes *blob_tmp; g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; /* create store */ blob = _build_cab (GCAB_COMPRESSION_NONE, "acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " \n" "", "firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_no_error (error); g_assert (store != NULL); /* verify */ app = as_store_get_app_by_id (store, "com.acme.example.firmware"); g_assert_nonnull (app); rel = as_app_get_release_default (app); g_assert_nonnull (rel); g_assert_cmpstr (as_release_get_version (rel), ==, "1.2.3"); csum = as_release_get_checksum_by_target (rel, AS_CHECKSUM_TARGET_CONTENT); g_assert_cmpstr (as_checksum_get_value (csum), ==, "7c211433f02071597741e6ff5a8ea34789abbf43"); blob_tmp = as_release_get_blob (rel, "firmware.bin"); g_assert_nonnull (blob_tmp); blob_tmp = as_release_get_blob (rel, "firmware.bin.asc"); g_assert_null (blob_tmp); } static void fu_common_store_cab_folder_func (void) { AsApp *app; AsChecksum *csum; AsRelease *rel; GBytes *blob_tmp; g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; /* create store */ blob = _build_cab (GCAB_COMPRESSION_NONE, "lvfs\\acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " \n" "", "lvfs\\firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_no_error (error); g_assert (store != NULL); /* verify */ app = as_store_get_app_by_id (store, "com.acme.example.firmware"); g_assert_nonnull (app); rel = as_app_get_release_default (app); g_assert_nonnull (rel); g_assert_cmpstr (as_release_get_version (rel), ==, "1.2.3"); csum = as_release_get_checksum_by_target (rel, AS_CHECKSUM_TARGET_CONTENT); g_assert_cmpstr (as_checksum_get_value (csum), ==, "7c211433f02071597741e6ff5a8ea34789abbf43"); blob_tmp = as_release_get_blob (rel, "firmware.bin"); g_assert_nonnull (blob_tmp); } static void fu_common_store_cab_error_no_metadata_func (void) { g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; blob = _build_cab (GCAB_COMPRESSION_NONE, "foo.txt", "hello", "bar.txt", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (store == NULL); } static void fu_common_store_cab_error_wrong_size_func (void) { g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; blob = _build_cab (GCAB_COMPRESSION_NONE, "acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " 7004701\n" " deadbeef\n" " \n" " \n" "", "firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (store == NULL); } static void fu_common_store_cab_error_missing_file_func (void) { g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; blob = _build_cab (GCAB_COMPRESSION_NONE, "acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " \n" " \n" " \n" "", "firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (store == NULL); } static void fu_common_store_cab_error_size_func (void) { g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; blob = _build_cab (GCAB_COMPRESSION_NONE, "acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " \n" "", "firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 123, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (store == NULL); } static void fu_common_store_cab_error_wrong_checksum_func (void) { g_autoptr(AsStore) store = NULL; g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; blob = _build_cab (GCAB_COMPRESSION_NONE, "acme.metainfo.xml", "\n" " com.acme.example.firmware\n" " \n" " \n" " deadbeef\n" " \n" " \n" "", "firmware.bin", "world", NULL); if (blob == NULL) { g_test_skip ("libgcab too old"); return; } store = fu_common_store_from_cab_bytes (blob, 10240, &error); g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE); g_assert (store == NULL); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); /* only critical and error are fatal */ g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); fu_common_rmtree ("/tmp/fwupd-self-test", NULL); g_assert_cmpint (g_mkdir_with_parents ("/tmp/fwupd-self-test/var/lib/fwupd", 0755), ==, 0); /* tests go here */ if (g_test_slow ()) g_test_add_func ("/fwupd/progressbar", fu_progressbar_func); g_test_add_func ("/fwupd/device-locker{success}", fu_device_locker_func); g_test_add_func ("/fwupd/device-locker{fail}", fu_device_locker_fail_func); g_test_add_func ("/fwupd/device{metadata}", fu_device_metadata_func); g_test_add_func ("/fwupd/device-list", fu_device_list_func); g_test_add_func ("/fwupd/device-list{delay}", fu_device_list_delay_func); g_test_add_func ("/fwupd/device-list{compatible}", fu_device_list_compatible_func); g_test_add_func ("/fwupd/engine{history-success}", fu_engine_history_func); g_test_add_func ("/fwupd/engine{history-error}", fu_engine_history_error_func); g_test_add_func ("/fwupd/engine{require-hwid}", fu_engine_require_hwid_func); g_test_add_func ("/fwupd/engine{partial-hash}", fu_engine_partial_hash_func); g_test_add_func ("/fwupd/engine{downgrade}", fu_engine_downgrade_func); g_test_add_func ("/fwupd/hwids", fu_hwids_func); g_test_add_func ("/fwupd/smbios", fu_smbios_func); g_test_add_func ("/fwupd/smbios3", fu_smbios3_func); g_test_add_func ("/fwupd/history", fu_history_func); g_test_add_func ("/fwupd/history{migrate}", fu_history_migrate_func); g_test_add_func ("/fwupd/plugin-list", fu_plugin_list_func); g_test_add_func ("/fwupd/plugin-list{depsolve}", fu_plugin_list_depsolve_func); g_test_add_func ("/fwupd/plugin{delay}", fu_plugin_delay_func); g_test_add_func ("/fwupd/plugin{module}", fu_plugin_module_func); g_test_add_func ("/fwupd/plugin{quirks}", fu_plugin_quirks_func); g_test_add_func ("/fwupd/keyring{gpg}", fu_keyring_gpg_func); g_test_add_func ("/fwupd/keyring{pkcs7}", fu_keyring_pkcs7_func); g_test_add_func ("/fwupd/common{endian}", fu_common_endian_func); g_test_add_func ("/fwupd/common{cab-success}", fu_common_store_cab_func); g_test_add_func ("/fwupd/common{cab-success-unsigned}", fu_common_store_cab_unsigned_func); g_test_add_func ("/fwupd/common{cab-success-folder}", fu_common_store_cab_folder_func); g_test_add_func ("/fwupd/common{cab-error-no-metadata}", fu_common_store_cab_error_no_metadata_func); g_test_add_func ("/fwupd/common{cab-error-wrong-size}", fu_common_store_cab_error_wrong_size_func); g_test_add_func ("/fwupd/common{cab-error-wrong-checksum}", fu_common_store_cab_error_wrong_checksum_func); g_test_add_func ("/fwupd/common{cab-error-missing-file}", fu_common_store_cab_error_missing_file_func); g_test_add_func ("/fwupd/common{cab-error-size}", fu_common_store_cab_error_size_func); g_test_add_func ("/fwupd/common{spawn)", fu_common_spawn_func); g_test_add_func ("/fwupd/common{firmware-builder}", fu_common_firmware_builder_func); return g_test_run (); } fwupd-1.0.6/src/fu-smbios.c000066400000000000000000000320401325145456600155140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include "fu-smbios.h" #include "fwupd-error.h" struct _FuSmbios { GObject parent_instance; gchar *smbios_ver; guint32 structure_table_len; GPtrArray *items; }; /* little endian */ typedef struct __attribute__((packed)) { gchar anchor_str[4]; guint8 entry_point_csum; guint8 entry_point_len; guint8 smbios_major_ver; guint8 smbios_minor_ver; guint16 max_structure_sz; guint8 entry_point_rev; guint8 formatted_area[5]; gchar intermediate_anchor_str[5]; guint8 intermediate_csum; guint16 structure_table_len; guint32 structure_table_addr; guint16 number_smbios_structs; guint8 smbios_bcd_rev; } FuSmbiosStructureEntryPoint32; /* little endian */ typedef struct __attribute__((packed)) { gchar anchor_str[5]; guint8 entry_point_csum; guint8 entry_point_len; guint8 smbios_major_ver; guint8 smbios_minor_ver; guint8 smbios_docrev; guint8 entry_point_rev; guint8 reserved0; guint32 structure_table_len; guint64 structure_table_addr; } FuSmbiosStructureEntryPoint64; /* little endian */ typedef struct __attribute__((packed)) { guint8 type; guint8 len; guint16 handle; } FuSmbiosStructure; typedef struct { guint8 type; guint16 handle; GBytes *data; GPtrArray *strings; } FuSmbiosItem; G_DEFINE_TYPE (FuSmbios, fu_smbios, G_TYPE_OBJECT) static gboolean fu_smbios_setup_from_data (FuSmbios *self, const guint8 *buf, gsize sz, GError **error) { /* go through each structure */ for (gsize i = 0; i < sz; i++) { FuSmbiosStructure *str = (FuSmbiosStructure *) &buf[i]; FuSmbiosItem *item; /* invalid */ if (str->len == 0x00) break; if (str->len >= sz) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "structure larger than available data"); return FALSE; } /* create a new result */ item = g_new0 (FuSmbiosItem, 1); item->type = str->type; item->handle = GUINT16_FROM_LE (str->handle); item->data = g_bytes_new (buf + i, str->len); item->strings = g_ptr_array_new_with_free_func (g_free); g_ptr_array_add (self->items, item); /* jump to the end of the struct */ i += str->len; if (buf[i] == '\0' && buf[i+1] == '\0') { i++; continue; } /* add strings from table */ for (gsize start_offset = i; i < sz; i++) { if (buf[i] == '\0') { if (start_offset == i) break; g_ptr_array_add (item->strings, g_strdup ((const gchar *) &buf[start_offset])); start_offset = i + 1; } } } return TRUE; } /** * fu_smbios_setup_from_file: * @self: A #FuSmbios * @filename: A filename * @error: A #GError or %NULL * * Reads all the SMBIOS values from a DMI blob. * * Returns: %TRUE for success **/ gboolean fu_smbios_setup_from_file (FuSmbios *self, const gchar *filename, GError **error) { gsize sz = 0; g_autofree gchar *buf = NULL; if (!g_file_get_contents (filename, &buf, &sz, error)) return FALSE; return fu_smbios_setup_from_data (self, (guint8 *) buf, sz, error); } static gboolean fu_smbios_parse_ep32 (FuSmbios *self, const gchar *buf, gsize sz, GError **error) { FuSmbiosStructureEntryPoint32 *ep; guint8 csum = 0; /* verify size */ if (sz != sizeof(FuSmbiosStructureEntryPoint32)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid smbios entry point got %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT, sz, sizeof(FuSmbiosStructureEntryPoint32)); return FALSE; } /* verify checksum */ for (guint i = 0; i < sz; i++) csum += buf[i]; if (csum != 0x00) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "entry point checksum invalid"); return FALSE; } /* verify intermediate section */ ep = (FuSmbiosStructureEntryPoint32 *) buf; if (memcmp (ep->intermediate_anchor_str, "_DMI_", 5) != 0) { g_autofree gchar *tmp = g_strndup (ep->intermediate_anchor_str, 5); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "intermediate anchor signature invalid, got %s", tmp); return FALSE; } for (guint i = 10; i < sz; i++) csum += buf[i]; if (csum != 0x00) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "intermediate checksum invalid"); return FALSE; } self->structure_table_len = GUINT16_FROM_LE (ep->structure_table_len); self->smbios_ver = g_strdup_printf ("%u.%u", ep->smbios_major_ver, ep->smbios_minor_ver); return TRUE; } static gboolean fu_smbios_parse_ep64 (FuSmbios *self, const gchar *buf, gsize sz, GError **error) { FuSmbiosStructureEntryPoint64 *ep; guint8 csum = 0; /* verify size */ if (sz != sizeof(FuSmbiosStructureEntryPoint64)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid smbios3 entry point got %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT, sz, sizeof(FuSmbiosStructureEntryPoint32)); return FALSE; } /* verify checksum */ for (guint i = 0; i < sz; i++) csum += buf[i]; if (csum != 0x00) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "entry point checksum invalid"); return FALSE; } ep = (FuSmbiosStructureEntryPoint64 *) buf; self->structure_table_len = GUINT32_FROM_LE (ep->structure_table_len); self->smbios_ver = g_strdup_printf ("%u.%u", ep->smbios_major_ver, ep->smbios_minor_ver); return TRUE; } /** * fu_smbios_setup: * @self: A #FuSmbios * @path: A path, e.g. `/sys/firmware/dmi/tables` * @error: A #GError or %NULL * * Reads all the SMBIOS values from a specific path. * * Returns: %TRUE for success **/ gboolean fu_smbios_setup_from_path (FuSmbios *self, const gchar *path, GError **error) { gsize sz = 0; g_autofree gchar *dmi_fn = NULL; g_autofree gchar *dmi_raw = NULL; g_autofree gchar *ep_fn = NULL; g_autofree gchar *ep_raw = NULL; g_return_val_if_fail (FU_IS_SMBIOS (self), FALSE); /* get the smbios entry point */ ep_fn = g_build_filename (path, "smbios_entry_point", NULL); if (!g_file_get_contents (ep_fn, &ep_raw, &sz, error)) return FALSE; /* check we got enough data to read the signature */ if (sz < 5) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid smbios entry point got %" G_GSIZE_FORMAT " bytes, expected %" G_GSIZE_FORMAT " or %" G_GSIZE_FORMAT, sz, sizeof(FuSmbiosStructureEntryPoint32), sizeof(FuSmbiosStructureEntryPoint64)); return FALSE; } /* parse 32 bit structure */ if (memcmp (ep_raw, "_SM_", 4) == 0) { if (!fu_smbios_parse_ep32 (self, ep_raw, sz, error)) return FALSE; } else if (memcmp (ep_raw, "_SM3_", 5) == 0) { if (!fu_smbios_parse_ep64 (self, ep_raw, sz, error)) return FALSE; } else { g_autofree gchar *tmp = g_strndup (ep_raw, 4); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "SMBIOS signature invalid, got %s", tmp); return FALSE; } /* get the DMI data */ dmi_fn = g_build_filename (path, "DMI", NULL); if (!g_file_get_contents (dmi_fn, &dmi_raw, &sz, error)) return FALSE; if (sz != self->structure_table_len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "invalid DMI data size, got %" G_GSIZE_FORMAT " bytes, expected %" G_GUINT32_FORMAT, sz, self->structure_table_len); return FALSE; } /* parse blob */ return fu_smbios_setup_from_data (self, (guint8 *) dmi_raw, sz, error); } /** * fu_smbios_setup: * @self: A #FuSmbios * @error: A #GError or %NULL * * Reads all the SMBIOS values from the hardware. * * Returns: %TRUE for success **/ gboolean fu_smbios_setup (FuSmbios *self, GError **error) { g_autofree gchar *path = NULL; g_return_val_if_fail (FU_IS_SMBIOS (self), FALSE); path = g_build_filename (SYSFSFIRMWAREDIR, "dmi", "tables", NULL); return fu_smbios_setup_from_path (self, path, error); } /** * fu_smbios_to_string: * @self: A #FuSmbios * * Dumps the parsed SMBIOS data to a string. * * Returns: a UTF-8 string **/ gchar * fu_smbios_to_string (FuSmbios *self) { GString *str; g_return_val_if_fail (FU_IS_SMBIOS (self), NULL); str = g_string_new (NULL); g_string_append_printf (str, "SmbiosVersion: %s\n", self->smbios_ver); for (guint i = 0; i < self->items->len; i++) { FuSmbiosItem *item = g_ptr_array_index (self->items, i); g_string_append_printf (str, "Type: %02x\n", item->type); g_string_append_printf (str, " Length: %" G_GSIZE_FORMAT "\n", g_bytes_get_size (item->data)); g_string_append_printf (str, " Handle: 0x%04x\n", item->handle); for (guint j = 0; j < item->strings->len; j++) { const gchar *tmp = g_ptr_array_index (item->strings, j); g_string_append_printf (str, " String[%02u]: %s\n", j, tmp); } } return g_string_free (str, FALSE); } static FuSmbiosItem * fu_smbios_get_item_for_type (FuSmbios *self, guint8 type) { for (guint i = 0; i < self->items->len; i++) { FuSmbiosItem *item = g_ptr_array_index (self->items, i); if (item->type == type) return item; } return NULL; } /** * fu_smbios_get_data: * @self: A #FuSmbios * @type: A structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS * @error: A #GError or %NULL * * Reads a SMBIOS data blob, which includes the SMBIOS section header. * * Returns: a #GBytes, or %NULL if invalid or not found **/ GBytes * fu_smbios_get_data (FuSmbios *self, guint8 type, GError **error) { FuSmbiosItem *item; g_return_val_if_fail (FU_IS_SMBIOS (self), NULL); item = fu_smbios_get_item_for_type (self, type); if (item == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no structure with type %02x", type); return NULL; } return item->data; } /** * fu_smbios_get_string: * @self: A #FuSmbios * @type: A structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS * @offset: A structure offset * @error: A #GError or %NULL * * Reads a string from the SMBIOS string table of a specific structure. * * The @type and @offset can be referenced from the DMTF SMBIOS specification: * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.1.1.pdf * * Returns: a string, or %NULL if invalid or not found **/ const gchar * fu_smbios_get_string (FuSmbios *self, guint8 type, guint8 offset, GError **error) { FuSmbiosItem *item; const guint8 *data; gsize sz; g_return_val_if_fail (FU_IS_SMBIOS (self), NULL); /* get item */ item = fu_smbios_get_item_for_type (self, type); if (item == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no structure with type %02x", type); return NULL; } /* check offset valid */ data = g_bytes_get_data (item->data, &sz); if (offset >= sz) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "offset bigger than size %" G_GSIZE_FORMAT, sz); return NULL; } if (data[offset] == 0x00) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND, "no data available"); return NULL; } /* check string index valid */ if (data[offset] > item->strings->len) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "index larger than string table %u", data[offset]); return NULL; } return g_ptr_array_index (item->strings, data[offset] - 1); } static void fu_smbios_item_free (FuSmbiosItem *item) { g_bytes_unref (item->data); g_ptr_array_unref (item->strings); g_free (item); } static void fu_smbios_finalize (GObject *object) { FuSmbios *self = FU_SMBIOS (object); g_free (self->smbios_ver); g_ptr_array_unref (self->items); G_OBJECT_CLASS (fu_smbios_parent_class)->finalize (object); } static void fu_smbios_class_init (FuSmbiosClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = fu_smbios_finalize; } static void fu_smbios_init (FuSmbios *self) { self->items = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_smbios_item_free); } /** * fu_smbios_new: * * Creates a new object to parse SMBIOS data. * * Returns: a #FuSmbios **/ FuSmbios * fu_smbios_new (void) { FuSmbios *self; self = g_object_new (FU_TYPE_SMBIOS, NULL); return FU_SMBIOS (self); } fwupd-1.0.6/src/fu-smbios.h000066400000000000000000000036471325145456600155340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_SMBIOS_H #define __FU_SMBIOS_H #include G_BEGIN_DECLS #define FU_TYPE_SMBIOS (fu_smbios_get_type ()) G_DECLARE_FINAL_TYPE (FuSmbios, fu_smbios, FU, SMBIOS, GObject) FuSmbios *fu_smbios_new (void); #define FU_SMBIOS_STRUCTURE_TYPE_BIOS 0x00 #define FU_SMBIOS_STRUCTURE_TYPE_SYSTEM 0x01 #define FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD 0x02 #define FU_SMBIOS_STRUCTURE_TYPE_CHASSIS 0x03 gboolean fu_smbios_setup (FuSmbios *self, GError **error); gboolean fu_smbios_setup_from_path (FuSmbios *self, const gchar *path, GError **error); gboolean fu_smbios_setup_from_file (FuSmbios *self, const gchar *filename, GError **error); gchar *fu_smbios_to_string (FuSmbios *self); const gchar *fu_smbios_get_string (FuSmbios *self, guint8 type, guint8 offset, GError **error); GBytes *fu_smbios_get_data (FuSmbios *self, guint8 type, GError **error); G_END_DECLS #endif /* __FU_SMBIOS_H */ fwupd-1.0.6/src/fu-test.c000066400000000000000000000055421325145456600152060ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2010-2017 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include "fu-test.h" static GMainLoop *_test_loop = NULL; static guint _test_loop_timeout_id = 0; static gboolean fu_test_hang_check_cb (gpointer user_data) { g_main_loop_quit (_test_loop); _test_loop_timeout_id = 0; return G_SOURCE_REMOVE; } void fu_test_loop_run_with_timeout (guint timeout_ms) { g_assert (_test_loop_timeout_id == 0); g_assert (_test_loop == NULL); _test_loop = g_main_loop_new (NULL, FALSE); _test_loop_timeout_id = g_timeout_add (timeout_ms, fu_test_hang_check_cb, NULL); g_main_loop_run (_test_loop); } void fu_test_loop_quit (void) { if (_test_loop_timeout_id > 0) { g_source_remove (_test_loop_timeout_id); _test_loop_timeout_id = 0; } if (_test_loop != NULL) { g_main_loop_quit (_test_loop); g_main_loop_unref (_test_loop); _test_loop = NULL; } } gchar * fu_test_get_filename (const gchar *testdatadirs, const gchar *filename) { g_auto(GStrv) split = g_strsplit (testdatadirs, ":", -1); for (guint i = 0; split[i] != NULL; i++) { gchar *tmp; char full_tmp[PATH_MAX]; g_autofree gchar *path = NULL; path = g_build_filename (split[i], filename, NULL); tmp = realpath (path, full_tmp); if (tmp != NULL) return g_strdup (full_tmp); } return NULL; } gboolean fu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error) { g_autofree gchar *output = NULL; /* exactly the same */ if (g_strcmp0 (txt1, txt2) == 0) return TRUE; /* matches a pattern */ if (fnmatch (txt2, txt1, FNM_NOESCAPE) == 0) return TRUE; /* save temp files and diff them */ if (!g_file_set_contents ("/tmp/a", txt1, -1, error)) return FALSE; if (!g_file_set_contents ("/tmp/b", txt2, -1, error)) return FALSE; if (!g_spawn_command_line_sync ("diff -urNp /tmp/b /tmp/a", &output, NULL, NULL, error)) return FALSE; /* just output the diff */ g_set_error_literal (error, 1, 0, output); return FALSE; } fwupd-1.0.6/src/fu-test.h000066400000000000000000000024311325145456600152050ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2010-2011 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __FU_TEST_H__ #define __FU_TEST_H__ #include gchar *fu_test_get_filename (const gchar *testdatadirs, const gchar *filename); void fu_test_loop_run_with_timeout (guint timeout_ms); void fu_test_loop_quit (void); gboolean fu_test_compare_lines (const gchar *txt1, const gchar *txt2, GError **error); #endif /* __FU_TEST_H__ */ fwupd-1.0.6/src/fu-usb-device.c000066400000000000000000000313431325145456600162530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include "fu-usb-device.h" /** * SECTION:fu-device * @short_description: a USB device * * An object that represents a USB device. * * See also: #FuDevice */ typedef struct { GUsbDevice *usb_device; FuDeviceLocker *usb_device_locker; gboolean done_probe; } FuUsbDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE (FuUsbDevice, fu_usb_device, FU_TYPE_DEVICE) enum { PROP_0, PROP_USB_DEVICE, PROP_LAST }; #define GET_PRIVATE(o) (fu_usb_device_get_instance_private (o)) static void fu_usb_device_apply_quirks (FuUsbDevice *device) { FuQuirks *quirks = fu_device_get_quirks (FU_DEVICE (device)); GUsbDevice *usb_device = fu_usb_device_get_dev (device); const gchar *type_name = G_OBJECT_TYPE_NAME (device); const gchar *tmp; /* not set */ if (quirks == NULL) return; /* type */ g_debug ("looking for USB quirks for %s type", type_name); tmp = fu_quirks_lookup_by_usb_device (quirks, type_name, usb_device); if (tmp != NULL) { g_debug ("default plugin hints set to: %s", tmp); fu_device_set_plugin_hints (FU_DEVICE (device), tmp); } /* name */ g_debug ("looking for USB quirks for %s device", fu_device_get_platform_id (FU_DEVICE (device))); tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_NAME, usb_device); if (tmp != NULL) fu_device_set_name (FU_DEVICE (device), tmp); /* summary */ tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_SUMMARY, usb_device); if (tmp != NULL) fu_device_set_summary (FU_DEVICE (device), tmp); /* vendor */ tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_VENDOR, usb_device); if (tmp != NULL) fu_device_set_vendor (FU_DEVICE (device), tmp); /* version */ tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_VERSION, usb_device); if (tmp != NULL) fu_device_set_version (FU_DEVICE (device), tmp); /* icon */ tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_ICON, usb_device); if (tmp != NULL) fu_device_add_icon (FU_DEVICE (device), tmp); /* GUID */ tmp = fu_quirks_lookup_by_usb_device (quirks, FU_QUIRKS_USB_GUID, usb_device); if (tmp != NULL) fu_device_add_guid (FU_DEVICE (device), tmp); } static void fu_usb_device_notify_quirks_cb (FuUsbDevice *device, GParamSpec *pspec, gpointer user_data) { fu_usb_device_apply_quirks (device); } static void fu_usb_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { FuUsbDevice *device = FU_USB_DEVICE (object); FuUsbDevicePrivate *priv = GET_PRIVATE (device); switch (prop_id) { case PROP_USB_DEVICE: g_value_set_object (value, priv->usb_device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void fu_usb_device_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FuUsbDevice *device = FU_USB_DEVICE (object); switch (prop_id) { case PROP_USB_DEVICE: fu_usb_device_set_dev (device, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void fu_usb_device_finalize (GObject *object) { FuUsbDevice *device = FU_USB_DEVICE (object); FuUsbDevicePrivate *priv = GET_PRIVATE (device); if (priv->usb_device_locker != NULL) g_object_unref (priv->usb_device_locker); if (priv->usb_device != NULL) g_object_unref (priv->usb_device); G_OBJECT_CLASS (fu_usb_device_parent_class)->finalize (object); } static void fu_usb_device_init (FuUsbDevice *device) { g_signal_connect (device, "notify::quirks", G_CALLBACK (fu_usb_device_notify_quirks_cb), NULL); } static void fu_usb_device_class_init (FuUsbDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; object_class->finalize = fu_usb_device_finalize; object_class->get_property = fu_usb_device_get_property; object_class->set_property = fu_usb_device_set_property; pspec = g_param_spec_object ("usb-device", NULL, NULL, G_USB_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_NAME); g_object_class_install_property (object_class, PROP_USB_DEVICE, pspec); } /** * fu_usb_device_is_open: * @device: A #FuUsbDevice * * Finds out if a USB device is currently open. * * Returns: %TRUE if the device is open. * * Since: 1.0.3 **/ gboolean fu_usb_device_is_open (FuUsbDevice *device) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE); return priv->usb_device_locker != NULL; } /** * fu_usb_device_open: * @device: A #FuUsbDevice * @error: A #GError, or %NULL * * Opens a USB device, optionally running a object-specific vfunc. * * Returns: %TRUE for success * * Since: 1.0.2 **/ gboolean fu_usb_device_open (FuUsbDevice *device, GError **error) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device); guint idx; g_autoptr(AsProfile) profile = as_profile_new (); g_autoptr(AsProfileTask) ptask = NULL; g_autoptr(FuDeviceLocker) locker = NULL; g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already open */ if (priv->usb_device_locker != NULL) return TRUE; /* probe */ if (!fu_usb_device_probe (device, error)) return FALSE; /* profile */ ptask = as_profile_start (profile, "added{%04x:%04x}", g_usb_device_get_vid (priv->usb_device), g_usb_device_get_pid (priv->usb_device)); g_assert (ptask != NULL); /* open */ locker = fu_device_locker_new (priv->usb_device, error); if (locker == NULL) return FALSE; /* get vendor */ if (fu_device_get_vendor (FU_DEVICE (device)) == NULL) { idx = g_usb_device_get_manufacturer_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_vendor (FU_DEVICE (device), tmp); } } /* get product */ if (fu_device_get_name (FU_DEVICE (device)) == NULL) { idx = g_usb_device_get_product_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_name (FU_DEVICE (device), tmp); } } /* get serial number */ if (fu_device_get_serial (FU_DEVICE (device)) == NULL) { idx = g_usb_device_get_serial_number_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_serial (FU_DEVICE (device), tmp); } } /* get version number, falling back to the USB device release */ idx = g_usb_device_get_custom_index (priv->usb_device, G_USB_DEVICE_CLASS_VENDOR_SPECIFIC, 'F', 'W', NULL); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, NULL); fu_device_set_version (FU_DEVICE (device), tmp); } /* get GUID from the descriptor if set */ idx = g_usb_device_get_custom_index (priv->usb_device, G_USB_DEVICE_CLASS_VENDOR_SPECIFIC, 'G', 'U', NULL); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, NULL); fu_device_add_guid (FU_DEVICE (device), tmp); } /* subclassed */ if (klass->open != NULL) { if (!klass->open (device, error)) return FALSE; } /* success */ priv->usb_device_locker = g_steal_pointer (&locker); return TRUE; } /** * fu_usb_device_open: * @device: A #FuUsbDevice * @error: A #GError, or %NULL * * Closes a USB device, optionally running a object-specific vfunc. * * Returns: %TRUE for success * * Since: 1.0.2 **/ gboolean fu_usb_device_close (FuUsbDevice *device, GError **error) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device); g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already open */ if (priv->usb_device_locker == NULL) return TRUE; /* subclassed */ if (klass->close != NULL) { if (!klass->close (device, error)) return FALSE; } g_clear_object (&priv->usb_device_locker); return TRUE; } /** * fu_usb_device_probe: * @device: A #FuUsbDevice * @error: A #GError, or %NULL * * Probes a USB device, setting parameters on the object that does not need * the device open or the interface claimed. * If the device is not compatible then an error should be returned. * * Returns: %TRUE for success * * Since: 1.0.2 **/ gboolean fu_usb_device_probe (FuUsbDevice *device, GError **error) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device); g_return_val_if_fail (FU_IS_USB_DEVICE (device), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already done */ if (priv->done_probe) return TRUE; /* subclassed */ if (klass->probe != NULL) { if (!klass->probe (device, error)) return FALSE; } priv->done_probe = TRUE; return TRUE; } static gchar * _bcd_version_from_uint16 (guint16 val) { #if AS_CHECK_VERSION(0,7,3) return as_utils_version_from_uint16 (val, AS_VERSION_PARSE_FLAG_USE_BCD); #else guint maj = ((val >> 12) & 0x0f) * 10 + ((val >> 8) & 0x0f); guint min = ((val >> 4) & 0x0f) * 10 + (val & 0x0f); return g_strdup_printf ("%u.%u", maj, min); #endif } /** * fu_usb_device_set_dev: * @device: A #FuUsbDevice * @usb_device: A #GUsbDevice, or %NULL * * Sets the #GUsbDevice to use. * * Since: 1.0.2 **/ void fu_usb_device_set_dev (FuUsbDevice *device, GUsbDevice *usb_device) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); guint16 release; g_autofree gchar *devid1 = NULL; g_autofree gchar *devid2 = NULL; g_autofree gchar *vendor_id = NULL; g_return_if_fail (FU_IS_USB_DEVICE (device)); /* need to re-probe hardware */ priv->done_probe = FALSE; /* allow replacement */ g_set_object (&priv->usb_device, usb_device); if (usb_device == NULL) { g_clear_object (&priv->usb_device_locker); return; } /* add both device IDs */ devid1 = g_strdup_printf ("USB\\VID_%04X&PID_%04X", g_usb_device_get_vid (usb_device), g_usb_device_get_pid (usb_device)); fu_device_add_guid (FU_DEVICE (device), devid1); release = g_usb_device_get_release (usb_device); devid2 = g_strdup_printf ("USB\\VID_%04X&PID_%04X&REV_%04X", g_usb_device_get_vid (usb_device), g_usb_device_get_pid (usb_device), release); fu_device_add_guid (FU_DEVICE (device), devid2); /* set vendor ID */ vendor_id = g_strdup_printf ("USB:0x%04X", g_usb_device_get_vid (usb_device)); fu_device_set_vendor_id (FU_DEVICE (device), vendor_id); /* set the version if the release has been set */ if (release != 0x0) { g_autofree gchar *version = _bcd_version_from_uint16 (release); fu_device_set_version (FU_DEVICE (device), version); } /* set USB platform ID automatically */ fu_device_set_platform_id (FU_DEVICE (device), g_usb_device_get_platform_id (usb_device)); /* set the quirks again */ fu_usb_device_apply_quirks (device); } /** * fu_usb_device_get_dev: * @device: A #FuUsbDevice * * Gets the #GUsbDevice. * * Returns: (transfer none): a #GUsbDevice, or %NULL * * Since: 1.0.2 **/ GUsbDevice * fu_usb_device_get_dev (FuUsbDevice *device) { FuUsbDevicePrivate *priv = GET_PRIVATE (device); g_return_val_if_fail (FU_IS_USB_DEVICE (device), NULL); return priv->usb_device; } /** * fu_usb_device_new: * * Creates a new #FuUsbDevice. * * Returns: (transfer full): a #FuUsbDevice * * Since: 1.0.2 **/ FuDevice * fu_usb_device_new (GUsbDevice *usb_device) { FuUsbDevice *device = g_object_new (FU_TYPE_USB_DEVICE, NULL); fu_usb_device_set_dev (device, usb_device); return FU_DEVICE (device); } fwupd-1.0.6/src/fu-usb-device.h000066400000000000000000000040171325145456600162560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2017 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __FU_USB_DEVICE_H #define __FU_USB_DEVICE_H #include #include #include "fu-plugin.h" G_BEGIN_DECLS #define FU_TYPE_USB_DEVICE (fu_usb_device_get_type ()) G_DECLARE_DERIVABLE_TYPE (FuUsbDevice, fu_usb_device, FU, USB_DEVICE, FuDevice) struct _FuUsbDeviceClass { FuDeviceClass parent_class; gboolean (*open) (FuUsbDevice *device, GError **error); gboolean (*close) (FuUsbDevice *device, GError **error); gboolean (*probe) (FuUsbDevice *device, GError **error); gpointer __reserved[28]; }; FuDevice *fu_usb_device_new (GUsbDevice *usb_device); GUsbDevice *fu_usb_device_get_dev (FuUsbDevice *device); void fu_usb_device_set_dev (FuUsbDevice *device, GUsbDevice *usb_device); gboolean fu_usb_device_open (FuUsbDevice *device, GError **error); gboolean fu_usb_device_close (FuUsbDevice *device, GError **error); gboolean fu_usb_device_probe (FuUsbDevice *device, GError **error); gboolean fu_usb_device_is_open (FuUsbDevice *device); G_END_DECLS #endif /* __FU_USB_DEVICE_H */ fwupd-1.0.6/src/fu-util.c000066400000000000000000002136451325145456600152110ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2015-2018 Richard Hughes * * Licensed under the GNU General Public License Version 2 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fu-hwids.h" #include "fu-history.h" #include "fu-plugin-private.h" #include "fu-progressbar.h" #include "fwupd-common-private.h" /* this is only valid in this file */ #define FWUPD_ERROR_INVALID_ARGS (FWUPD_ERROR_LAST+1) /* custom return code */ #define EXIT_NOTHING_TO_DO 2 typedef struct { GCancellable *cancellable; GMainLoop *loop; GOptionContext *context; GPtrArray *cmd_array; SoupSession *soup_session; FwupdInstallFlags flags; FwupdClient *client; FuProgressbar *progressbar; gboolean no_metadata_check; gboolean no_reboot_check; gboolean no_unreported_check; gboolean assume_yes; } FuUtilPrivate; typedef gboolean (*FuUtilPrivateCb) (FuUtilPrivate *util, gchar **values, GError **error); static gboolean fu_util_report_history (FuUtilPrivate *priv, gchar **values, GError **error); typedef struct { gchar *name; gchar *arguments; gchar *description; FuUtilPrivateCb callback; } FuUtilItem; static void fu_util_item_free (FuUtilItem *item) { g_free (item->name); g_free (item->arguments); g_free (item->description); g_free (item); } /* * fu_sort_command_name_cb: */ static gint fu_sort_command_name_cb (FuUtilItem **item1, FuUtilItem **item2) { return g_strcmp0 ((*item1)->name, (*item2)->name); } static void fu_util_add (GPtrArray *array, const gchar *name, const gchar *arguments, const gchar *description, FuUtilPrivateCb callback) { g_auto(GStrv) names = NULL; g_return_if_fail (name != NULL); g_return_if_fail (description != NULL); g_return_if_fail (callback != NULL); /* add each one */ names = g_strsplit (name, ",", -1); for (guint i = 0; names[i] != NULL; i++) { FuUtilItem *item = g_new0 (FuUtilItem, 1); item->name = g_strdup (names[i]); if (i == 0) { item->description = g_strdup (description); } else { /* TRANSLATORS: this is a command alias, e.g. 'get-devices' */ item->description = g_strdup_printf (_("Alias to %s"), names[0]); } item->arguments = g_strdup (arguments); item->callback = callback; g_ptr_array_add (array, item); } } static gchar * fu_util_get_descriptions (GPtrArray *array) { gsize len; const gsize max_len = 35; GString *string; /* print each command */ string = g_string_new (""); for (guint i = 0; i < array->len; i++) { FuUtilItem *item = g_ptr_array_index (array, i); g_string_append (string, " "); g_string_append (string, item->name); len = strlen (item->name) + 2; if (item->arguments != NULL) { g_string_append (string, " "); g_string_append (string, item->arguments); len += strlen (item->arguments) + 1; } if (len < max_len) { for (gsize j = len; j < max_len + 1; j++) g_string_append_c (string, ' '); g_string_append (string, item->description); g_string_append_c (string, '\n'); } else { g_string_append_c (string, '\n'); for (gsize j = 0; j < max_len + 1; j++) g_string_append_c (string, ' '); g_string_append (string, item->description); g_string_append_c (string, '\n'); } } /* remove trailing newline */ if (string->len > 0) g_string_set_size (string, string->len - 1); return g_string_free (string, FALSE); } static gboolean fu_util_run (FuUtilPrivate *priv, const gchar *command, gchar **values, GError **error) { /* find command */ for (guint i = 0; i < priv->cmd_array->len; i++) { FuUtilItem *item = g_ptr_array_index (priv->cmd_array, i); if (g_strcmp0 (item->name, command) == 0) return item->callback (priv, values, error); } /* not found */ g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, /* TRANSLATORS: error message */ _("Command not found")); return FALSE; } static void fu_util_client_notify_cb (GObject *object, GParamSpec *pspec, FuUtilPrivate *priv) { fu_progressbar_update (priv->progressbar, fwupd_client_get_status (priv->client), fwupd_client_get_percentage (priv->client)); } static void fu_util_print_data (const gchar *title, const gchar *msg) { gsize title_len; g_auto(GStrv) lines = NULL; if (msg == NULL) return; g_print ("%s:", title); /* pad */ title_len = strlen (title) + 1; lines = g_strsplit (msg, "\n", -1); for (guint j = 0; lines[j] != NULL; j++) { for (gsize i = title_len; i < 25; i++) g_print (" "); g_print ("%s\n", lines[j]); title_len = 0; } } static guint fu_util_prompt_for_number (guint maxnum) { gint retval; guint answer = 0; do { char buffer[64]; /* swallow the \n at end of line too */ if (!fgets (buffer, sizeof (buffer), stdin)) break; if (strlen (buffer) == sizeof (buffer) - 1) continue; /* get a number */ retval = sscanf (buffer, "%u", &answer); /* positive */ if (retval == 1 && answer <= maxnum) break; /* TRANSLATORS: the user isn't reading the question */ g_print (_("Please enter a number from 0 to %u: "), maxnum); } while (TRUE); return answer; } static gboolean fu_util_prompt_for_boolean (gboolean def) { do { char buffer[4]; if (!fgets (buffer, sizeof (buffer), stdin)) continue; if (strlen (buffer) == sizeof (buffer) - 1) continue; if (g_strcmp0 (buffer, "\n") == 0) return def; buffer[0] = g_ascii_toupper (buffer[0]); if (g_strcmp0 (buffer, "Y\n") == 0) return TRUE; if (g_strcmp0 (buffer, "N\n") == 0) return FALSE; } while (TRUE); return FALSE; } static FwupdDevice * fu_util_prompt_for_device (FuUtilPrivate *priv, GError **error) { FwupdDevice *dev; guint idx; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GPtrArray) devices_filtered = NULL; /* get devices from daemon */ devices = fwupd_client_get_devices (priv->client, NULL, error); if (devices == NULL) return NULL; /* filter results */ devices_filtered = g_ptr_array_new (); for (guint i = 0; i < devices->len; i++) { dev = g_ptr_array_index (devices, i); if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; g_ptr_array_add (devices_filtered, dev); } /* nothing */ if (devices_filtered->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No supported devices"); return NULL; } /* exactly one */ if (devices_filtered->len == 1) { dev = g_ptr_array_index (devices_filtered, 0); return g_object_ref (dev); } /* TRANSLATORS: get interactive prompt */ g_print ("%s\n", _("Choose a device:")); /* TRANSLATORS: this is to abort the interactive prompt */ g_print ("0.\t%s\n", _("Cancel")); for (guint i = 0; i < devices_filtered->len; i++) { dev = g_ptr_array_index (devices_filtered, i); g_print ("%u.\t%s (%s)\n", i + 1, fwupd_device_get_id (dev), fwupd_device_get_name (dev)); } idx = fu_util_prompt_for_number (devices_filtered->len); if (idx == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "Request canceled"); return NULL; } dev = g_ptr_array_index (devices_filtered, idx - 1); return g_object_ref (dev); } static gboolean fu_util_setup_networking (FuUtilPrivate *priv, GError **error) { const gchar *http_proxy; g_autofree gchar *user_agent = NULL; /* already done */ if (priv->soup_session != NULL) return TRUE; /* create the soup session */ user_agent = fwupd_build_user_agent (PACKAGE_NAME, PACKAGE_VERSION); priv->soup_session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, user_agent, SOUP_SESSION_TIMEOUT, 60, NULL); if (priv->soup_session == NULL) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "failed to setup networking"); return FALSE; } /* set the proxy */ http_proxy = g_getenv ("https_proxy"); if (http_proxy == NULL) http_proxy = g_getenv ("http_proxy"); if (http_proxy != NULL) { g_autoptr(SoupURI) proxy_uri = soup_uri_new (http_proxy); if (proxy_uri == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "invalid proxy URI: %s", http_proxy); return FALSE; } g_object_set (priv->soup_session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL); } /* this disables the double-compression of the firmware.xml.gz file */ soup_session_remove_feature_by_type (priv->soup_session, SOUP_TYPE_CONTENT_DECODER); return TRUE; } static gboolean fu_util_perhaps_show_unreported (FuUtilPrivate *priv, GError **error) { g_autoptr(GError) error_local = NULL; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GPtrArray) devices_failed = g_ptr_array_new (); g_autoptr(GPtrArray) devices_success = g_ptr_array_new (); /* we don't want to ask anything */ if (priv->no_unreported_check) { g_debug ("skipping unreported check"); return TRUE; } /* get all devices from the history database */ devices = fwupd_client_get_history (priv->client, NULL, &error_local); if (devices == NULL) { if (g_error_matches (error_local, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) return TRUE; g_propagate_error (error, g_steal_pointer (&error_local)); return FALSE; } for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_REPORTED)) continue; if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; switch (fwupd_device_get_update_state (dev)) { case FWUPD_UPDATE_STATE_FAILED: g_ptr_array_add (devices_failed, dev); break; case FWUPD_UPDATE_STATE_SUCCESS: g_ptr_array_add (devices_success, dev); break; default: break; } } /* nothing to do */ if (devices_failed->len == 0 && devices_success->len == 0) { g_debug ("no unreported devices"); return TRUE; } /* show the success and failures */ if (!priv->assume_yes) { /* delimit */ g_print ("________________________________________________\n"); /* failures */ if (devices_failed->len > 0) { /* TRANSLATORS: a list of failed updates */ g_print ("\n%s\n\n", _("Devices that were not updated correctly:")); for (guint i = 0; i < devices_failed->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices_failed, i); FwupdRelease *rel = fwupd_device_get_release_default (dev); g_print (" • %s (%s → %s)\n", fwupd_device_get_name (dev), fwupd_device_get_version (dev), fwupd_release_get_version (rel)); } } /* success */ if (devices_success->len > 0) { /* TRANSLATORS: a list of successful updates */ g_print ("\n%s\n\n", _("Devices that have been updated successfully:")); for (guint i = 0; i < devices_success->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices_success, i); FwupdRelease *rel = fwupd_device_get_release_default (dev); g_print (" • %s (%s → %s)\n", fwupd_device_get_name (dev), fwupd_device_get_version (dev), fwupd_release_get_version (rel)); } } /* ask for permission */ g_print ("\n%s (%s) [Y|n]: ", /* TRANSLATORS: explain why we want to upload */ _("Upload report now?"), /* TRANSLATORS: metadata is downloaded from the Internet */ _("Requires internet connection")); if (!fu_util_prompt_for_boolean (TRUE)) return TRUE; } /* success */ return fu_util_report_history (priv, NULL, error); } static gboolean fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) devs = NULL; /* get results from daemon */ devs = fwupd_client_get_devices (priv->client, NULL, error); if (devs == NULL) return FALSE; /* print */ if (devs->len == 0) { /* TRANSLATORS: nothing attached that can be upgraded */ g_print ("%s\n", _("No hardware detected with firmware update capability")); return TRUE; } for (guint i = 0; i < devs->len; i++) { g_autofree gchar *tmp = NULL; FwupdDevice *dev = g_ptr_array_index (devs, i); tmp = fwupd_device_to_string (dev); g_print ("%s\n", tmp); } /* nag? */ if (!fu_util_perhaps_show_unreported (priv, error)) return FALSE; return TRUE; } static gboolean fu_util_install (FuUtilPrivate *priv, gchar **values, GError **error) { const gchar *id; /* handle both forms */ if (g_strv_length (values) == 1) { id = FWUPD_DEVICE_ID_ANY; } else if (g_strv_length (values) == 2) { id = values[1]; } else { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } /* install with flags chosen by the user */ return fwupd_client_install (priv->client, id, values[0], priv->flags, NULL, error); } static gboolean fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) array = NULL; /* check args */ if (g_strv_length (values) != 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } array = fwupd_client_get_details (priv->client, values[0], NULL, error); if (array == NULL) return FALSE; for (guint i = 0; i < array->len; i++) { FwupdDevice *dev = g_ptr_array_index (array, i); g_autofree gchar *tmp = NULL; tmp = fwupd_device_to_string (dev); g_print ("%s", tmp); } return TRUE; } static gboolean fu_util_update_reboot (GError **error) { g_autoptr(GDBusConnection) connection = NULL; g_autoptr(GVariant) val = NULL; connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); if (connection == NULL) return FALSE; #ifdef HAVE_SYSTEMD /* reboot using systemd */ val = g_dbus_connection_call_sync (connection, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reboot", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); #elif HAVE_CONSOLEKIT /* reboot using ConsoleKit */ val = g_dbus_connection_call_sync (connection, "org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", "Restart", NULL, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); #else g_set_error_literal (&error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "No supported backend compiled in to perform the operation."); #endif return val != NULL; } static gboolean fu_util_install_prepared (FuUtilPrivate *priv, gchar **values, GError **error) { gint vercmp; guint cnt = 0; g_autofree gchar *link = NULL; g_autoptr(GPtrArray) results = NULL; g_autoptr(FuHistory) history = NULL; /* verify this is pointing to our cache */ link = g_file_read_link (FU_OFFLINE_TRIGGER_FILENAME, NULL); if (link == NULL) { g_debug ("No %s, exiting", FU_OFFLINE_TRIGGER_FILENAME); return TRUE; } if (g_strcmp0 (link, "/var/lib/fwupd") != 0) { g_debug ("Another framework set up the trigger, exiting"); return TRUE; } /* do this first to avoid a loop if this tool segfaults */ g_unlink (FU_OFFLINE_TRIGGER_FILENAME); if (g_strv_length (values) != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments: none expected"); return FALSE; } /* ensure root user */ if (getuid () != 0 || geteuid () != 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "This function can only be used as root"); return FALSE; } /* get prepared updates */ history = fu_history_new (); results = fu_history_get_devices (history, error); if (results == NULL) return FALSE; /* apply each update */ for (guint i = 0; i < results->len; i++) { FwupdDevice *dev = g_ptr_array_index (results, i); FwupdRelease *rel = fwupd_device_get_release_default (dev); /* check not already done */ if (fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_PENDING) continue; /* tell the user what's going to happen */ vercmp = as_utils_vercmp (fwupd_device_get_version (dev), fwupd_release_get_version (rel)); if (vercmp == 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second is a version number * e.g. "1.2.3" */ g_print (_("Reinstalling %s with %s... "), fwupd_device_get_name (dev), fwupd_release_get_version (rel)); } else if (vercmp > 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second and third are * version numbers e.g. "1.2.3" */ g_print (_("Downgrading %s from %s to %s... "), fwupd_device_get_name (dev), fwupd_device_get_version (dev), fwupd_release_get_version (rel)); } else if (vercmp < 0) { /* TRANSLATORS: the first replacement is a display name * e.g. "ColorHugALS" and the second and third are * version numbers e.g. "1.2.3" */ g_print (_("Updating %s from %s to %s... "), fwupd_device_get_name (dev), fwupd_device_get_version (dev), fwupd_release_get_version (rel)); } if (!fwupd_client_install (priv->client, fwupd_device_get_id (dev), fwupd_release_get_filename (rel), priv->flags, NULL, error)) return FALSE; cnt++; } /* nothing to do */ if (cnt == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No updates prepared"); return FALSE; } /* reboot */ if (!fu_util_update_reboot (error)) return FALSE; g_print ("%s\n", _("Done!")); return TRUE; } static gboolean fu_util_clear_history (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FuHistory) history = fu_history_new (); return fu_history_remove_all (history, error); } static gboolean fu_util_report_history_for_uri (FuUtilPrivate *priv, const gchar *report_uri, GPtrArray *devices, GError **error) { JsonNode *json_root; JsonObject *json_object; const gchar *server_msg = NULL; guint status_code; g_autofree gchar *data = NULL; g_autoptr(JsonParser) json_parser = NULL; g_autoptr(SoupMessage) msg = NULL; /* convert to JSON */ data = fwupd_build_history_report_json (devices, error); if (data == NULL) return FALSE; /* ask for permission */ if (!priv->assume_yes) { fu_util_print_data (_("Target"), report_uri); fu_util_print_data (_("Payload"), data); g_print ("%s [Y|n]: ", _("Proceed with upload?")); if (!fu_util_prompt_for_boolean (TRUE)) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_PERMISSION_DENIED, "User declined action"); return FALSE; } } /* POST request */ msg = soup_message_new (SOUP_METHOD_POST, report_uri); soup_message_set_request (msg, "application/json; charset=utf-8", SOUP_MEMORY_COPY, data, strlen (data)); status_code = soup_session_send_message (priv->soup_session, msg); g_debug ("server returned: %s", msg->response_body->data); /* server returned nothing, and probably exploded in a ball of flames */ if (msg->response_body->length == 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to upload to %s: %s", report_uri, soup_status_get_phrase (status_code)); return FALSE; } /* parse JSON reply */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, msg->response_body->data, msg->response_body->length, error)) { g_autofree gchar *str = g_strndup (msg->response_body->data, msg->response_body->length); g_prefix_error (error, "Failed to parse JSON response from '%s': ", str); return FALSE; } json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_autofree gchar *str = g_strndup (msg->response_body->data, msg->response_body->length); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_PERMISSION_DENIED, "JSON response was malformed: '%s'", str); return FALSE; } json_object = json_node_get_object (json_root); if (json_object == NULL) { g_autofree gchar *str = g_strndup (msg->response_body->data, msg->response_body->length); g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_PERMISSION_DENIED, "JSON response object was malformed: '%s'", str); return FALSE; } /* get any optional server message */ if (json_object_has_member (json_object, "msg")) server_msg = json_object_get_string_member (json_object, "msg"); /* server reported failed */ if (!json_object_get_boolean_member (json_object, "success")) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_PERMISSION_DENIED, "Server rejected report: %s", server_msg != NULL ? server_msg : "unspecified"); return FALSE; } /* server wanted us to see the message */ if (server_msg != NULL) { if (g_strstr_len (server_msg, -1, "known issue") != NULL && json_object_has_member (json_object, "uri")) { g_print ("%s %s\n", /* TRANSLATORS: the server sent the user a small message */ _("Update failure is a known issue, visit this URL for more information:"), json_object_get_string_member (json_object, "uri")); } else { /* TRANSLATORS: the server sent the user a small message */ g_print ("%s %s\n", _("Upload message:"), server_msg); } } /* fall back to HTTP status codes in case the server is offline */ if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to upload to %s: %s", report_uri, soup_status_get_phrase (status_code)); return FALSE; } return TRUE; } static gboolean fu_util_report_history (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GHashTable) remote_id_uri_map = NULL; g_autoptr(GHashTable) report_map = NULL; g_autoptr(GList) uris = NULL; g_autoptr(GPtrArray) devices = NULL; g_autoptr(GPtrArray) remotes = NULL; /* set up networking */ if (!fu_util_setup_networking (priv, error)) return FALSE; /* create a map of RemoteID to RemoteURI */ remotes = fwupd_client_get_remotes (priv->client, NULL, error); if (remotes == NULL) return FALSE; remote_id_uri_map = g_hash_table_new (g_str_hash, g_str_equal); for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); if (fwupd_remote_get_id (remote) == NULL) continue; if (fwupd_remote_get_report_uri (remote) == NULL) continue; g_debug ("adding %s for %s", fwupd_remote_get_report_uri (remote), fwupd_remote_get_id (remote)); g_hash_table_insert (remote_id_uri_map, (gpointer) fwupd_remote_get_id (remote), (gpointer) fwupd_remote_get_report_uri (remote)); } /* get all devices from the history database, then filter them, * adding to a hash map of report-ids */ devices = fwupd_client_get_history (priv->client, NULL, error); if (devices == NULL) return FALSE; report_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_ptr_array_unref); for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); FwupdRelease *rel = fwupd_device_get_release_default (dev); const gchar *remote_id; const gchar *remote_uri; GPtrArray *devices_tmp; /* filter, if not forcing */ if ((priv->flags & FWUPD_INSTALL_FLAG_FORCE) == 0) { if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_REPORTED)) continue; if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; } /* only send success and failure */ if (fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_FAILED && fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_SUCCESS) { g_debug ("ignoring %s with UpdateState %s", fwupd_device_get_id (dev), fwupd_update_state_to_string (fwupd_device_get_update_state (dev))); continue; } /* find the RemoteURI to use for the device */ remote_id = fwupd_release_get_remote_id (rel); if (remote_id == NULL) { g_debug ("%s has no RemoteID", fwupd_device_get_id (dev)); continue; } remote_uri = g_hash_table_lookup (remote_id_uri_map, remote_id); if (remote_uri == NULL) { g_debug ("%s has no RemoteURI", remote_id); continue; } /* add this to the hash map */ devices_tmp = g_hash_table_lookup (report_map, remote_uri); if (devices_tmp == NULL) { devices_tmp = g_ptr_array_new (); g_hash_table_insert (report_map, g_strdup (remote_uri), devices_tmp); } g_debug ("using %s for %s", remote_uri, fwupd_device_get_id (dev)); g_ptr_array_add (devices_tmp, dev); } /* nothing to report */ if (g_hash_table_size (report_map) == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "No reports require uploading"); return FALSE; } /* process each uri */ uris = g_hash_table_get_keys (report_map); for (GList *l = uris; l != NULL; l = l->next) { const gchar *uri = l->data; GPtrArray *devices_tmp = g_hash_table_lookup (report_map, uri); if (!fu_util_report_history_for_uri (priv, uri, devices_tmp, error)) return FALSE; } /* mark each device as reported */ for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_REPORTED)) continue; if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; g_debug ("setting flag on %s", fwupd_device_get_id (dev)); if (!fwupd_client_modify_device (priv->client, fwupd_device_get_id (dev), "Flags", "reported", NULL, error)) return FALSE; } return TRUE; } static gboolean fu_util_get_history (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) devices = NULL; /* get all devices from the history database */ devices = fwupd_client_get_history (priv->client, NULL, error); if (devices == NULL) return FALSE; /* show each device */ for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); g_autofree gchar *str = fwupd_device_to_string (dev); g_print ("%s\n", str); } return TRUE; } static FwupdDevice* fu_util_get_device_or_prompt (FuUtilPrivate *priv, gchar **values, GError **error) { FwupdDevice *dev = NULL; /* get device to use */ if (g_strv_length (values) >= 1) { g_autoptr(GError) error_local = NULL; if (g_strv_length (values) > 1) { for (guint i = 1; i < g_strv_length (values); i++) g_debug ("Ignoring extra input %s", values[i]); } dev = fwupd_client_get_device_by_id (priv->client, values[0], NULL, &error_local); if (dev != NULL) return dev; g_print ("%s\n", error_local->message); } return fu_util_prompt_for_device (priv, error); } static gboolean fu_util_clear_results (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; return fwupd_client_clear_results (priv->client, fwupd_device_get_id (dev), NULL, error); } static gboolean fu_util_clear_offline (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FuHistory) history = fu_history_new (); return fu_history_remove_all_with_state (history, FWUPD_UPDATE_STATE_PENDING, error); } static gboolean fu_util_verify_update_all (FuUtilPrivate *priv, GError **error) { g_autoptr(GPtrArray) devs = NULL; /* get devices from daemon */ devs = fwupd_client_get_devices (priv->client, NULL, error); if (devs == NULL) return FALSE; /* get results */ for (guint i = 0; i < devs->len; i++) { g_autoptr(GError) error_local = NULL; FwupdDevice *dev = g_ptr_array_index (devs, i); if (!fwupd_client_verify_update (priv->client, fwupd_device_get_id (dev), NULL, &error_local)) { g_print ("%s\tFAILED: %s\n", fwupd_device_get_guid_default (dev), error_local->message); continue; } g_print ("%s\t%s\n", fwupd_device_get_guid_default (dev), _("OK")); } return TRUE; } static gboolean fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; if (g_strv_length (values) == 0) return fu_util_verify_update_all (priv, error); dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; return fwupd_client_verify_update (priv->client, fwupd_device_get_id (dev), NULL, error); } static gboolean fu_util_file_exists_with_checksum (const gchar *fn, const gchar *checksum_expected, GChecksumType checksum_type) { gsize len = 0; g_autofree gchar *checksum_actual = NULL; g_autofree gchar *data = NULL; if (!g_file_get_contents (fn, &data, &len, NULL)) return FALSE; checksum_actual = g_compute_checksum_for_data (checksum_type, (guchar *) data, len); return g_strcmp0 (checksum_expected, checksum_actual) == 0; } static void fu_util_download_chunk_cb (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data) { guint percentage; goffset header_size; goffset body_length; FuUtilPrivate *priv = (FuUtilPrivate *) user_data; /* if it's returning "Found" or an error, ignore the percentage */ if (msg->status_code != SOUP_STATUS_OK) { g_debug ("ignoring status code %u (%s)", msg->status_code, msg->reason_phrase); return; } /* get data */ body_length = msg->response_body->length; header_size = soup_message_headers_get_content_length (msg->response_headers); /* size is not known */ if (header_size < body_length) return; /* calulate percentage */ percentage = (guint) ((100 * body_length) / header_size); g_debug ("progress: %u%%", percentage); fu_progressbar_update (priv->progressbar, FWUPD_STATUS_DOWNLOADING, percentage); } static gboolean fu_util_download_file (FuUtilPrivate *priv, SoupURI *uri, const gchar *fn, const gchar *checksum_expected, GError **error) { GChecksumType checksum_type; guint status_code; g_autoptr(GError) error_local = NULL; g_autofree gchar *checksum_actual = NULL; g_autofree gchar *uri_str = NULL; g_autoptr(SoupMessage) msg = NULL; /* check if the file already exists with the right checksum */ checksum_type = fwupd_checksum_guess_kind (checksum_expected); if (fu_util_file_exists_with_checksum (fn, checksum_expected, checksum_type)) { g_debug ("skpping download as file already exists"); return TRUE; } /* set up networking */ if (!fu_util_setup_networking (priv, error)) return FALSE; /* download data */ uri_str = soup_uri_to_string (uri, FALSE); g_debug ("downloading %s to %s", uri_str, fn); msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); if (msg == NULL) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to parse URI %s", uri_str); return FALSE; } if (g_str_has_suffix (uri_str, ".asc") || g_str_has_suffix (uri_str, ".p7b") || g_str_has_suffix (uri_str, ".p7c")) { /* TRANSLATORS: downloading new signing file */ g_print ("%s %s\n", _("Fetching signature"), uri_str); } else if (g_str_has_suffix (uri_str, ".gz")) { /* TRANSLATORS: downloading new metadata file */ g_print ("%s %s\n", _("Fetching metadata"), uri_str); } else if (g_str_has_suffix (uri_str, ".cab")) { /* TRANSLATORS: downloading new firmware file */ g_print ("%s %s\n", _("Fetching firmware"), uri_str); } else { /* TRANSLATORS: downloading unknown file */ g_print ("%s %s\n", _("Fetching file"), uri_str); } g_signal_connect (msg, "got-chunk", G_CALLBACK (fu_util_download_chunk_cb), priv); status_code = soup_session_send_message (priv->soup_session, msg); g_print ("\n"); if (status_code != SOUP_STATUS_OK) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Failed to download %s: %s", uri_str, soup_status_get_phrase (status_code)); return FALSE; } /* verify checksum */ if (checksum_expected != NULL) { checksum_actual = g_compute_checksum_for_data (checksum_type, (guchar *) msg->response_body->data, (gsize) msg->response_body->length); if (g_strcmp0 (checksum_expected, checksum_actual) != 0) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "Checksum invalid, expected %s got %s", checksum_expected, checksum_actual); return FALSE; } } /* save file */ if (!g_file_set_contents (fn, msg->response_body->data, msg->response_body->length, &error_local)) { g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_WRITE, "Failed to save file: %s", error_local->message); return FALSE; } return TRUE; } static gboolean fu_util_download_metadata_for_remote (FuUtilPrivate *priv, FwupdRemote *remote, GError **error) { g_autofree gchar *basename_asc = NULL; g_autofree gchar *basename_id_asc = NULL; g_autofree gchar *basename_id = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *cache_dir = NULL; g_autofree gchar *filename = NULL; g_autofree gchar *filename_asc = NULL; g_autoptr(SoupURI) uri = NULL; g_autoptr(SoupURI) uri_sig = NULL; /* generate some plausible local filenames */ basename = g_path_get_basename (fwupd_remote_get_filename_cache (remote)); basename_id = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename); /* download the metadata */ cache_dir = g_build_filename (g_get_user_cache_dir (), "fwupdmgr", NULL); filename = g_build_filename (cache_dir, basename_id, NULL); if (!fu_common_mkdir_parent (filename, error)) return FALSE; uri = soup_uri_new (fwupd_remote_get_metadata_uri (remote)); if (!fu_util_download_file (priv, uri, filename, NULL, error)) return FALSE; /* download the signature */ basename_asc = g_path_get_basename (fwupd_remote_get_filename_cache_sig (remote)); basename_id_asc = g_strdup_printf ("%s-%s", fwupd_remote_get_id (remote), basename_asc); filename_asc = g_build_filename (cache_dir, basename_id_asc, NULL); uri_sig = soup_uri_new (fwupd_remote_get_metadata_uri_sig (remote)); if (!fu_util_download_file (priv, uri_sig, filename_asc, NULL, error)) return FALSE; /* send all this to fwupd */ return fwupd_client_update_metadata (priv->client, fwupd_remote_get_id (remote), filename, filename_asc, NULL, error); } static gboolean fu_util_download_metadata (FuUtilPrivate *priv, GError **error) { g_autoptr(GPtrArray) remotes = NULL; remotes = fwupd_client_get_remotes (priv->client, NULL, error); if (remotes == NULL) return FALSE; for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); if (!fwupd_remote_get_enabled (remote)) continue; if (fwupd_remote_get_kind (remote) != FWUPD_REMOTE_KIND_DOWNLOAD) continue; if (!fu_util_download_metadata_for_remote (priv, remote, error)) return FALSE; } return TRUE; } static gboolean fu_util_refresh (FuUtilPrivate *priv, gchar **values, GError **error) { if (g_strv_length (values) == 0) return fu_util_download_metadata (priv, error); if (g_strv_length (values) != 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } /* open file */ return fwupd_client_update_metadata (priv->client, values[2], values[0], values[1], NULL, error); } static gboolean fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error) { g_autofree gchar *tmp = NULL; g_autoptr(FwupdDevice) dev = NULL; g_autoptr(FwupdDevice) rel = NULL; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; rel = fwupd_client_get_results (priv->client, fwupd_device_get_id (dev), NULL, error); if (rel == NULL) return FALSE; tmp = fwupd_device_to_string (rel); g_print ("%s", tmp); return TRUE; } static gboolean fu_util_get_releases (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; g_autoptr(GPtrArray) rels = NULL; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; /* get the releases for this device */ rels = fwupd_client_get_releases (priv->client, fwupd_device_get_id (dev), NULL, error); if (rels == NULL) return FALSE; g_print ("%s:\n", fwupd_device_get_name (dev)); for (guint i = 0; i < rels->len; i++) { FwupdRelease *rel = g_ptr_array_index (rels, i); GPtrArray *checksums; const gchar *tmp; /* TRANSLATORS: section header for release version number */ fu_util_print_data (_("Version"), fwupd_release_get_version (rel)); /* TRANSLATORS: section header for the release name */ fu_util_print_data (_("Name"), fwupd_release_get_name (rel)); /* TRANSLATORS: section header for the release one line summary */ fu_util_print_data (_("Summary"), fwupd_release_get_summary (rel)); /* TRANSLATORS: section header for the remote the file is coming from */ fu_util_print_data (_("Remote"), fwupd_release_get_remote_id (rel)); /* TRANSLATORS: section header for firmware URI */ fu_util_print_data (_("URI"), fwupd_release_get_uri (rel)); tmp = fwupd_release_get_description (rel); if (tmp != NULL) { g_autofree gchar *desc = NULL; desc = as_markup_convert_simple (tmp, NULL); /* TRANSLATORS: section header for firmware description */ fu_util_print_data (_("Description"), desc); } checksums = fwupd_release_get_checksums (rel); for (guint j = 0; j < checksums->len; j++) { const gchar *checksum = g_ptr_array_index (checksums, j); g_autofree gchar *checksum_display = NULL; checksum_display = fwupd_checksum_format_for_display (checksum); /* TRANSLATORS: section header for firmware checksum */ fu_util_print_data (_("Checksum"), checksum_display); } /* new line between all but last entries */ if (i != rels->len - 1) g_print ("\n"); } return TRUE; } static FwupdRelease * fu_util_prompt_for_release (FuUtilPrivate *priv, GPtrArray *rels, GError **error) { FwupdRelease *rel; guint idx; /* nothing */ if (rels->len == 0) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO, "No supported releases"); return NULL; } /* exactly one */ if (rels->len == 1) { rel = g_ptr_array_index (rels, 0); return g_object_ref (rel); } /* TRANSLATORS: get interactive prompt */ g_print ("%s\n", _("Choose a release:")); for (guint i = 0; i < rels->len; i++) { rel = g_ptr_array_index (rels, i); g_print ("%u.\t%s (%s)\n", i + 1, fwupd_release_get_version (rel), fwupd_release_get_description (rel)); } idx = fu_util_prompt_for_number (rels->len); rel = g_ptr_array_index (rels, idx - 1); return g_object_ref (rel); } static gboolean fu_util_verify_all (FuUtilPrivate *priv, GError **error) { g_autoptr(GPtrArray) devs = NULL; /* get devices from daemon */ devs = fwupd_client_get_devices (priv->client, NULL, error); if (devs == NULL) return FALSE; /* get results */ for (guint i = 0; i < devs->len; i++) { g_autoptr(GError) error_local = NULL; FwupdDevice *dev = g_ptr_array_index (devs, i); if (!fwupd_client_verify (priv->client, fwupd_device_get_id (dev), NULL, &error_local)) { g_print ("%s\tFAILED: %s\n", fwupd_device_get_guid_default (dev), error_local->message); continue; } g_print ("%s\t%s\n", fwupd_device_get_guid_default (dev), _("OK")); } return TRUE; } static gboolean fu_util_verify (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; if (g_strv_length (values) == 0) return fu_util_verify_all (priv, error); dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; return fwupd_client_verify (priv->client, fwupd_device_get_id (dev), NULL, error); } static gboolean fu_util_unlock (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; return fwupd_client_unlock (priv->client, fwupd_device_get_id (dev), NULL, error); } static gboolean fu_util_perhaps_refresh_remotes (FuUtilPrivate *priv, GError **error) { g_autoptr(GPtrArray) remotes = NULL; guint64 age_oldest = 0; const guint64 age_limit_days = 30; /* we don't want to ask anything */ if (priv->no_metadata_check) { g_debug ("skipping metadata check"); return TRUE; } /* get the age of the oldest enabled remotes */ remotes = fwupd_client_get_remotes (priv->client, NULL, error); if (remotes == NULL) return FALSE; for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); if (!fwupd_remote_get_enabled (remote)) continue; if (fwupd_remote_get_kind (remote) != FWUPD_REMOTE_KIND_DOWNLOAD) continue; if (fwupd_remote_get_age (remote) > age_oldest) age_oldest = fwupd_remote_get_age (remote); } /* metadata is new enough */ if (age_oldest < 60 * 60 * 24 * age_limit_days) return TRUE; /* ask for permission */ if (!priv->assume_yes) { /* TRANSLATORS: the metadata is very out of date; %u is a number > 1 */ g_print (ngettext("Firmware metadata has not been updated for %u" " day and may not be up to date.", "Firmware metadata has not been updated for %u" " days and may not be up to date.", (gint) age_limit_days), (guint) age_limit_days); g_print ("\n\n"); g_print ("%s (%s) [y|N]: ", /* TRANSLATORS: ask the user if we can update the metadata */ _("Update now?"), /* TRANSLATORS: metadata is downloaded from the Internet */ _("Requires internet connection")); if (!fu_util_prompt_for_boolean (FALSE)) return TRUE; } /* downloads new metadata */ return fu_util_download_metadata (priv, error); } static gboolean fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) devices = NULL; /* are the remotes very old */ if (!fu_util_perhaps_refresh_remotes (priv, error)) return FALSE; /* get devices from daemon */ devices = fwupd_client_get_devices (priv->client, NULL, error); if (devices == NULL) return FALSE; for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); GPtrArray *guids; const gchar *tmp; g_autoptr(GPtrArray) rels = NULL; g_autoptr(GError) error_local = NULL; /* not going to have results, so save a D-Bus round-trip */ if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; /* get the releases for this device and filter for validity */ rels = fwupd_client_get_upgrades (priv->client, fwupd_device_get_id (dev), NULL, &error_local); if (rels == NULL) { g_printerr ("%s\n", error_local->message); continue; } /* TRANSLATORS: first replacement is device name */ g_print (_("%s has firmware updates:"), fwupd_device_get_name (dev)); g_print ("\n"); /* TRANSLATORS: a GUID for the hardware */ guids = fwupd_device_get_guids (dev); for (guint j = 0; j < guids->len; j++) { tmp = g_ptr_array_index (guids, j); fu_util_print_data (_("GUID"), tmp); } /* print all releases */ for (guint j = 0; j < rels->len; j++) { FwupdRelease *rel = g_ptr_array_index (rels, j); GPtrArray *checksums; /* TRANSLATORS: Appstream ID for the hardware type */ fu_util_print_data (_("ID"), fwupd_release_get_appstream_id (rel)); /* TRANSLATORS: section header for firmware version */ fu_util_print_data (_("Update Version"), fwupd_release_get_version (rel)); /* TRANSLATORS: section header for the release name */ fu_util_print_data (_("Update Name"), fwupd_release_get_name (rel)); /* TRANSLATORS: section header for the release one line summary */ fu_util_print_data (_("Update Summary"), fwupd_release_get_summary (rel)); /* TRANSLATORS: section header for remote ID, e.g. lvfs-testing */ fu_util_print_data (_("Update Remote ID"), fwupd_release_get_remote_id (rel)); checksums = fwupd_release_get_checksums (rel); for (guint k = 0; k < checksums->len; k++) { const gchar *checksum = g_ptr_array_index (checksums, k); g_autofree gchar *checksum_display = NULL; checksum_display = fwupd_checksum_format_for_display (checksum); /* TRANSLATORS: section header for firmware checksum */ fu_util_print_data (_("Update Checksum"), checksum_display); } /* TRANSLATORS: section header for firmware remote http:// */ fu_util_print_data (_("Update Location"), fwupd_release_get_uri (rel)); /* convert XML -> text */ tmp = fwupd_release_get_description (rel); if (tmp != NULL) { g_autofree gchar *md = NULL; md = as_markup_convert (tmp, AS_MARKUP_CONVERT_FORMAT_SIMPLE, NULL); if (md != NULL) { /* TRANSLATORS: section header for long firmware desc */ fu_util_print_data (_("Update Description"), md); } } } } /* nag? */ if (!fu_util_perhaps_show_unreported (priv, error)) return FALSE; /* success */ return TRUE; } static gboolean fu_util_get_remotes (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(GPtrArray) remotes = NULL; /* print any updates */ remotes = fwupd_client_get_remotes (priv->client, NULL, error); if (remotes == NULL) return FALSE; for (guint i = 0; i < remotes->len; i++) { FwupdRemote *remote = g_ptr_array_index (remotes, i); FwupdRemoteKind kind = fwupd_remote_get_kind (remote); FwupdKeyringKind keyring_kind = fwupd_remote_get_keyring_kind (remote); const gchar *tmp; gint priority; gdouble age; /* TRANSLATORS: remote identifier, e.g. lvfs-testing */ fu_util_print_data (_("Remote ID"), fwupd_remote_get_id (remote)); /* TRANSLATORS: remote title, e.g. "Linux Vendor Firmware Service" */ fu_util_print_data (_("Title"), fwupd_remote_get_title (remote)); /* TRANSLATORS: remote type, e.g. remote or local */ fu_util_print_data (_("Type"), fwupd_remote_kind_to_string (kind)); /* TRANSLATORS: keyring type, e.g. GPG or PKCS7 */ if (keyring_kind != FWUPD_KEYRING_KIND_UNKNOWN) { fu_util_print_data (_("Keyring"), fwupd_keyring_kind_to_string (keyring_kind)); } /* TRANSLATORS: if the remote is enabled */ fu_util_print_data (_("Enabled"), fwupd_remote_get_enabled (remote) ? "True" : "False"); /* TRANSLATORS: remote checksum */ fu_util_print_data (_("Checksum"), fwupd_remote_get_checksum (remote)); /* optional parameters */ age = fwupd_remote_get_age (remote); if (kind == FWUPD_REMOTE_KIND_DOWNLOAD && age > 0 && age != G_MAXUINT64) { const gchar *unit = "s"; g_autofree gchar *age_str = NULL; if (age > 60) { age /= 60.f; unit = "m"; } if (age > 60) { age /= 60.f; unit = "h"; } if (age > 24) { age /= 24.f; unit = "d"; } if (age > 7) { age /= 7.f; unit = "w"; } age_str = g_strdup_printf ("%.2f%s", age, unit); /* TRANSLATORS: the age of the metadata */ fu_util_print_data (_("Age"), age_str); } priority = fwupd_remote_get_priority (remote); if (priority != 0) { g_autofree gchar *priority_str = NULL; priority_str = g_strdup_printf ("%i", priority); /* TRANSLATORS: the numeric priority */ fu_util_print_data (_("Priority"), priority_str); } tmp = fwupd_remote_get_username (remote); if (tmp != NULL) { /* TRANSLATORS: remote filename base */ fu_util_print_data (_("Username"), tmp); } tmp = fwupd_remote_get_password (remote); if (tmp != NULL) { /* TRANSLATORS: remote filename base */ fu_util_print_data (_("Password"), tmp); } tmp = fwupd_remote_get_filename_cache (remote); if (tmp != NULL) { /* TRANSLATORS: filename of the local file */ fu_util_print_data (_("Filename"), tmp); } tmp = fwupd_remote_get_filename_cache_sig (remote); if (tmp != NULL) { /* TRANSLATORS: filename of the local file */ fu_util_print_data (_("Filename Signature"), tmp); } tmp = fwupd_remote_get_metadata_uri (remote); if (tmp != NULL) { /* TRANSLATORS: remote URI */ fu_util_print_data (_("Metadata URI"), tmp); } tmp = fwupd_remote_get_metadata_uri_sig (remote); if (tmp != NULL) { /* TRANSLATORS: remote URI */ fu_util_print_data (_("Metadata URI Signature"), tmp); } tmp = fwupd_remote_get_firmware_base_uri (remote); if (tmp != NULL) { /* TRANSLATORS: remote URI */ fu_util_print_data (_("Firmware Base URI"), tmp); } tmp = fwupd_remote_get_report_uri (remote); if (tmp != NULL) { /* TRANSLATORS: URI to send success/failure reports */ fu_util_print_data (_("Report URI"), tmp); } /* newline */ if (i != remotes->len - 1) g_print ("\n"); } return TRUE; } static void fu_util_cancelled_cb (GCancellable *cancellable, gpointer user_data) { FuUtilPrivate *priv = (FuUtilPrivate *) user_data; /* TRANSLATORS: this is when a device ctrl+c's a watch */ g_print ("%s\n", _("Cancelled")); g_main_loop_quit (priv->loop); } static void fu_util_device_added_cb (FwupdClient *client, FwupdDevice *device, gpointer user_data) { g_autofree gchar *tmp = fwupd_device_to_string (device); /* TRANSLATORS: this is when a device is hotplugged */ g_print ("%s\n%s", _("Device added:"), tmp); } static void fu_util_device_removed_cb (FwupdClient *client, FwupdDevice *device, gpointer user_data) { g_autofree gchar *tmp = fwupd_device_to_string (device); /* TRANSLATORS: this is when a device is hotplugged */ g_print ("%s\n%s", _("Device removed:"), tmp); } static void fu_util_device_changed_cb (FwupdClient *client, FwupdDevice *device, gpointer user_data) { g_autofree gchar *tmp = fwupd_device_to_string (device); /* TRANSLATORS: this is when a device has been updated */ g_print ("%s\n%s", _("Device changed:"), tmp); } static void fu_util_changed_cb (FwupdClient *client, gpointer user_data) { /* TRANSLATORS: this is when the daemon state changes */ g_print ("%s\n", _("Changed")); } static gboolean fu_util_smbios_dump (FuUtilPrivate *priv, gchar **values, GError **error) { g_autofree gchar *tmp = NULL; g_autoptr(FuSmbios) smbios = NULL; if (g_strv_length (values) < 1) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } smbios = fu_smbios_new (); if (!fu_smbios_setup_from_file (smbios, values[0], error)) return FALSE; tmp = fu_smbios_to_string (smbios); g_print ("%s\n", tmp); return TRUE; } static gboolean fu_util_firmware_builder (FuUtilPrivate *priv, gchar **values, GError **error) { const gchar *script_fn = "startup.sh"; const gchar *output_fn = "firmware.bin"; g_autoptr(GBytes) archive_blob = NULL; g_autoptr(GBytes) firmware_blob = NULL; if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } archive_blob = fu_common_get_contents_bytes (values[0], error); if (archive_blob == NULL) return FALSE; if (g_strv_length (values) > 2) script_fn = values[2]; if (g_strv_length (values) > 3) output_fn = values[3]; firmware_blob = fu_common_firmware_builder (archive_blob, script_fn, output_fn, error); if (firmware_blob == NULL) return FALSE; return fu_common_set_contents_bytes (values[1], firmware_blob, error); } static gboolean fu_util_monitor (FuUtilPrivate *priv, gchar **values, GError **error) { /* get all the devices */ if (!fwupd_client_connect (priv->client, priv->cancellable, error)) return FALSE; /* watch for any hotplugged device */ g_signal_connect (priv->client, "changed", G_CALLBACK (fu_util_changed_cb), priv); g_signal_connect (priv->client, "device-added", G_CALLBACK (fu_util_device_added_cb), priv); g_signal_connect (priv->client, "device-removed", G_CALLBACK (fu_util_device_removed_cb), priv); g_signal_connect (priv->client, "device-changed", G_CALLBACK (fu_util_device_changed_cb), priv); g_signal_connect (priv->cancellable, "cancelled", G_CALLBACK (fu_util_cancelled_cb), priv); g_main_loop_run (priv->loop); return TRUE; } static gboolean fu_util_update_device_with_release (FuUtilPrivate *priv, FwupdDevice *dev, FwupdRelease *rel, GError **error) { GPtrArray *checksums; const gchar *remote_id; const gchar *uri_tmp; g_autofree gchar *basename = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *uri_str = NULL; g_autoptr(SoupURI) uri = NULL; /* work out what remote-specific URI fields this should use */ uri_tmp = fwupd_release_get_uri (rel); remote_id = fwupd_release_get_remote_id (rel); if (remote_id != NULL) { g_autoptr(FwupdRemote) remote = NULL; remote = fwupd_client_get_remote_by_id (priv->client, remote_id, NULL, error); if (remote == NULL) return FALSE; /* local remotes have the firmware already */ if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL) { const gchar *fn_cache = fwupd_remote_get_filename_cache (remote); g_autofree gchar *path = g_path_get_dirname (fn_cache); /* install with flags chosen by the user */ fn = g_build_filename (path, uri_tmp, NULL); return fwupd_client_install (priv->client, fwupd_device_get_id (dev), fn, priv->flags, NULL, error); } uri_str = fwupd_remote_build_firmware_uri (remote, uri_tmp, error); if (uri_str == NULL) return FALSE; } else { uri_str = g_strdup (uri_tmp); } /* download file */ g_print ("Downloading %s for %s...\n", fwupd_release_get_version (rel), fwupd_device_get_name (dev)); basename = g_path_get_basename (uri_str); fn = g_build_filename (g_get_user_cache_dir (), "fwupdmgr", basename, NULL); if (!fu_common_mkdir_parent (fn, error)) return FALSE; checksums = fwupd_release_get_checksums (rel); uri = soup_uri_new (uri_str); if (!fu_util_download_file (priv, uri, fn, fwupd_checksum_get_best (checksums), error)) return FALSE; g_print ("Updating %s on %s...\n", fwupd_release_get_version (rel), fwupd_device_get_name (dev)); return fwupd_client_install (priv->client, fwupd_device_get_id (dev), fn, priv->flags, NULL, error); } static gboolean fu_util_update (FuUtilPrivate *priv, gchar **values, GError **error) { gboolean requires_reboot = FALSE; g_autoptr(GPtrArray) devices = NULL; /* get devices from daemon */ devices = fwupd_client_get_devices (priv->client, NULL, error); if (devices == NULL) return FALSE; for (guint i = 0; i < devices->len; i++) { FwupdDevice *dev = g_ptr_array_index (devices, i); FwupdRelease *rel; g_autoptr(GPtrArray) rels = NULL; g_autoptr(GError) error_local = NULL; /* not going to have results, so save a D-Bus round-trip */ if (!fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_SUPPORTED)) continue; /* get the releases for this device and filter for validity */ rels = fwupd_client_get_upgrades (priv->client, fwupd_device_get_id (dev), NULL, &error_local); if (rels == NULL) { g_printerr ("%s\n", error_local->message); continue; } rel = g_ptr_array_index (rels, 0); if (!fu_util_update_device_with_release (priv, dev, rel, error)) return FALSE; if (fwupd_device_has_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT)) requires_reboot = TRUE; } /* we don't want to ask anything */ if (priv->no_reboot_check) { g_debug ("skipping reboot check"); return TRUE; } /* at least one of the updates needed a reboot */ if (requires_reboot) { g_print ("\n%s %s [Y|n]: ", /* TRANSLATORS: explain why we want to upload */ _("An update requires a reboot to complete."), /* TRANSLATORS: reboot to apply the update */ _("Restart now?")); if (!fu_util_prompt_for_boolean (TRUE)) return TRUE; return fu_util_update_reboot (error); } return TRUE; } static gboolean fu_util_modify_remote (FuUtilPrivate *priv, gchar **values, GError **error) { if (g_strv_length (values) < 3) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS, "Invalid arguments"); return FALSE; } return fwupd_client_modify_remote (priv->client, values[0], values[1], values[2], NULL, error); } static gboolean fu_util_downgrade (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FwupdDevice) dev = NULL; g_autoptr(FwupdRelease) rel = NULL; g_autoptr(GPtrArray) rels = NULL; dev = fu_util_get_device_or_prompt (priv, values, error); if (dev == NULL) return FALSE; /* get the releases for this device and filter for validity */ rels = fwupd_client_get_downgrades (priv->client, fwupd_device_get_id (dev), NULL, error); if (rels == NULL) return FALSE; /* get the chosen release */ rel = fu_util_prompt_for_release (priv, rels, error); if (rel == NULL) return FALSE; priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_OLDER; return fu_util_update_device_with_release (priv, dev, rel, error); } static gboolean fu_util_hwids (FuUtilPrivate *priv, gchar **values, GError **error) { g_autoptr(FuSmbios) smbios = fu_smbios_new (); g_autoptr(FuHwids) hwids = fu_hwids_new (); const gchar *hwid_keys[] = { FU_HWIDS_KEY_BIOS_VENDOR, FU_HWIDS_KEY_BIOS_VERSION, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE, FU_HWIDS_KEY_BIOS_MINOR_RELEASE, FU_HWIDS_KEY_MANUFACTURER, FU_HWIDS_KEY_FAMILY, FU_HWIDS_KEY_PRODUCT_NAME, FU_HWIDS_KEY_PRODUCT_SKU, FU_HWIDS_KEY_ENCLOSURE_KIND, FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, FU_HWIDS_KEY_BASEBOARD_PRODUCT, NULL }; /* read DMI data */ if (!fu_smbios_setup (smbios, error)) return FALSE; if (!fu_hwids_setup (hwids, smbios, error)) return FALSE; /* show debug output */ g_print ("Computer Information\n"); g_print ("--------------------\n"); for (guint i = 0; hwid_keys[i] != NULL; i++) { const gchar *tmp = fu_hwids_get_value (hwids, hwid_keys[i]); if (tmp == NULL) continue; g_print ("%s: %s\n", hwid_keys[i], tmp); } /* show GUIDs */ g_print ("\nHardware IDs\n"); g_print ("------------\n"); for (guint i = 0; i < 15; i++) { const gchar *keys = NULL; g_autofree gchar *guid = NULL; g_autofree gchar *key = NULL; g_autofree gchar *keys_str = NULL; g_auto(GStrv) keysv = NULL; g_autoptr(GError) error_local = NULL; /* get the GUID */ key = g_strdup_printf ("HardwareID-%u", i); keys = fu_hwids_get_replace_keys (hwids, key); guid = fu_hwids_get_guid (hwids, key, &error_local); if (guid == NULL) { g_print ("%s\n", error_local->message); continue; } /* show what makes up the GUID */ keysv = g_strsplit (keys, "&", -1); keys_str = g_strjoinv (" + ", keysv); g_print ("{%s} <- %s\n", guid, keys_str); } return TRUE; } static void fu_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { } static gboolean fu_util_sigint_cb (gpointer user_data) { FuUtilPrivate *priv = (FuUtilPrivate *) user_data; g_debug ("Handling SIGINT"); g_cancellable_cancel (priv->cancellable); return FALSE; } static void fu_util_private_free (FuUtilPrivate *priv) { if (priv->cmd_array != NULL) g_ptr_array_unref (priv->cmd_array); if (priv->client != NULL) g_object_unref (priv->client); if (priv->soup_session != NULL) g_object_unref (priv->soup_session); g_main_loop_unref (priv->loop); g_object_unref (priv->cancellable); g_object_unref (priv->progressbar); g_option_context_free (priv->context); g_free (priv); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuUtilPrivate, fu_util_private_free) int main (int argc, char *argv[]) { gboolean force = FALSE; gboolean allow_older = FALSE; gboolean allow_reinstall = FALSE; gboolean offline = FALSE; gboolean ret; gboolean verbose = FALSE; gboolean version = FALSE; g_autoptr(FuUtilPrivate) priv = g_new0 (FuUtilPrivate, 1); g_autoptr(GError) error = NULL; g_autofree gchar *cmd_descriptions = NULL; const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, /* TRANSLATORS: command line option */ _("Show extra debugging information"), NULL }, { "version", '\0', 0, G_OPTION_ARG_NONE, &version, /* TRANSLATORS: command line option */ _("Show client and daemon versions"), NULL }, { "offline", '\0', 0, G_OPTION_ARG_NONE, &offline, /* TRANSLATORS: command line option */ _("Schedule installation for next reboot when possible"), NULL }, { "allow-reinstall", '\0', 0, G_OPTION_ARG_NONE, &allow_reinstall, /* TRANSLATORS: command line option */ _("Allow re-installing existing firmware versions"), NULL }, { "allow-older", '\0', 0, G_OPTION_ARG_NONE, &allow_older, /* TRANSLATORS: command line option */ _("Allow downgrading firmware versions"), NULL }, { "force", '\0', 0, G_OPTION_ARG_NONE, &force, /* TRANSLATORS: command line option */ _("Override plugin warning"), NULL }, { "assume-yes", 'y', 0, G_OPTION_ARG_NONE, &priv->assume_yes, /* TRANSLATORS: command line option */ _("Answer yes to all questions"), NULL }, { "no-unreported-check", '\0', 0, G_OPTION_ARG_NONE, &priv->no_unreported_check, /* TRANSLATORS: command line option */ _("Do not check for unreported history"), NULL }, { "no-metadata-check", '\0', 0, G_OPTION_ARG_NONE, &priv->no_metadata_check, /* TRANSLATORS: command line option */ _("Do not check for old metadata"), NULL }, { "no-reboot-check", '\0', 0, G_OPTION_ARG_NONE, &priv->no_reboot_check, /* TRANSLATORS: command line option */ _("Do not check for reboot after update"), NULL }, { NULL} }; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); /* ensure D-Bus errors are registered */ fwupd_error_quark (); /* create helper object */ priv->loop = g_main_loop_new (NULL, FALSE); priv->progressbar = fu_progressbar_new (); /* add commands */ priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_util_item_free); fu_util_add (priv->cmd_array, "get-devices", NULL, /* TRANSLATORS: command description */ _("Get all devices that support firmware updates"), fu_util_get_devices); fu_util_add (priv->cmd_array, "hwids", NULL, /* TRANSLATORS: command description */ _("Return all the hardware IDs for the machine"), fu_util_hwids); fu_util_add (priv->cmd_array, "install-prepared", NULL, /* TRANSLATORS: command description */ _("Install prepared updates now"), fu_util_install_prepared); fu_util_add (priv->cmd_array, "get-history", NULL, /* TRANSLATORS: command description */ _("Show history of firmware updates"), fu_util_get_history); fu_util_add (priv->cmd_array, "clear-history", NULL, /* TRANSLATORS: command description */ _("Erase all firmware update history"), fu_util_clear_history); fu_util_add (priv->cmd_array, "report-history", NULL, /* TRANSLATORS: command description */ _("Share firmware history with the developers"), fu_util_report_history); fu_util_add (priv->cmd_array, "install", "FILE [ID]", /* TRANSLATORS: command description */ _("Install a firmware file on this hardware"), fu_util_install); fu_util_add (priv->cmd_array, "get-details", "FILE", /* TRANSLATORS: command description */ _("Gets details about a firmware file"), fu_util_get_details); fu_util_add (priv->cmd_array, "get-updates", NULL, /* TRANSLATORS: command description */ _("Gets the list of updates for connected hardware"), fu_util_get_updates); fu_util_add (priv->cmd_array, "update", NULL, /* TRANSLATORS: command description */ _("Updates all firmware to latest versions available"), fu_util_update); fu_util_add (priv->cmd_array, "verify", "[DEVICE_ID]", /* TRANSLATORS: command description */ _("Gets the cryptographic hash of the dumped firmware"), fu_util_verify); fu_util_add (priv->cmd_array, "unlock", "DEVICE_ID", /* TRANSLATORS: command description */ _("Unlocks the device for firmware access"), fu_util_unlock); fu_util_add (priv->cmd_array, "clear-results", "DEVICE_ID", /* TRANSLATORS: command description */ _("Clears the results from the last update"), fu_util_clear_results); fu_util_add (priv->cmd_array, "clear-offline", NULL, /* TRANSLATORS: command description */ _("Clears any updates scheduled to be updated offline"), fu_util_clear_offline); fu_util_add (priv->cmd_array, "get-results", "DEVICE_ID", /* TRANSLATORS: command description */ _("Gets the results from the last update"), fu_util_get_results); fu_util_add (priv->cmd_array, "get-releases", "[DEVICE_ID]", /* TRANSLATORS: command description */ _("Gets the releases for a device"), fu_util_get_releases); fu_util_add (priv->cmd_array, "get-remotes", NULL, /* TRANSLATORS: command description */ _("Gets the configured remotes"), fu_util_get_remotes); fu_util_add (priv->cmd_array, "downgrade", "[DEVICE_ID]", /* TRANSLATORS: command description */ _("Downgrades the firmware on a device"), fu_util_downgrade); fu_util_add (priv->cmd_array, "refresh", "[FILE FILE_SIG REMOTE_ID]", /* TRANSLATORS: command description */ _("Refresh metadata from remote server"), fu_util_refresh); fu_util_add (priv->cmd_array, "verify-update", "[DEVICE_ID]", /* TRANSLATORS: command description */ _("Update the stored metadata with current ROM contents"), fu_util_verify_update); fu_util_add (priv->cmd_array, "monitor", NULL, /* TRANSLATORS: command description */ _("Monitor the daemon for events"), fu_util_monitor); fu_util_add (priv->cmd_array, "build-firmware", "FILE-IN FILE-OUT [SCRIPT] [OUTPUT]", /* TRANSLATORS: command description */ _("Build firmware using a sandbox"), fu_util_firmware_builder); fu_util_add (priv->cmd_array, "smbios-dump", "FILE", /* TRANSLATORS: command description */ _("Dump SMBIOS data from a file"), fu_util_smbios_dump); fu_util_add (priv->cmd_array, "modify-remote", "REMOTE-ID KEY VALUE", /* TRANSLATORS: command description */ _("Modifies a given remote"), fu_util_modify_remote); /* do stuff on ctrl+c */ priv->cancellable = g_cancellable_new (); g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT, fu_util_sigint_cb, priv, NULL); /* sort by command name */ g_ptr_array_sort (priv->cmd_array, (GCompareFunc) fu_sort_command_name_cb); /* non-TTY consoles cannot answer questions */ if (isatty (fileno (stdout)) == 0) { priv->no_unreported_check = TRUE; priv->no_metadata_check = TRUE; priv->no_reboot_check = TRUE; } /* get a list of the commands */ priv->context = g_option_context_new (NULL); cmd_descriptions = fu_util_get_descriptions (priv->cmd_array); g_option_context_set_summary (priv->context, cmd_descriptions); g_option_context_set_description (priv->context, "This tool allows an administrator to query and control the " "fwupd daemon, allowing them to perform actions such as " "installing or downgrading firmware."); /* TRANSLATORS: program name */ g_set_application_name (_("Firmware Utility")); g_option_context_add_main_entries (priv->context, options, NULL); ret = g_option_context_parse (priv->context, &argc, &argv, &error); if (!ret) { /* TRANSLATORS: the user didn't read the man page */ g_print ("%s: %s\n", _("Failed to parse arguments"), error->message); return EXIT_FAILURE; } /* set verbose? */ if (verbose) { g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); } else { g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, fu_util_ignore_cb, NULL); } /* set flags */ if (offline) priv->flags |= FWUPD_INSTALL_FLAG_OFFLINE; if (allow_reinstall) priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_REINSTALL; if (allow_older) priv->flags |= FWUPD_INSTALL_FLAG_ALLOW_OLDER; if (force) priv->flags |= FWUPD_INSTALL_FLAG_FORCE; /* connect to the daemon */ priv->client = fwupd_client_new (); g_signal_connect (priv->client, "notify::percentage", G_CALLBACK (fu_util_client_notify_cb), priv); g_signal_connect (priv->client, "notify::status", G_CALLBACK (fu_util_client_notify_cb), priv); /* just show versions and exit */ if (version) { g_print ("client version:\t%i.%i.%i\n", FWUPD_MAJOR_VERSION, FWUPD_MINOR_VERSION, FWUPD_MICRO_VERSION); if (!fwupd_client_connect (priv->client, priv->cancellable, &error)) { g_printerr ("Failed to connect to daemon: %s\n", error->message); return EXIT_FAILURE; } g_print ("daemon version:\t%s\n", fwupd_client_get_daemon_version (priv->client)); #ifdef FWUPD_GIT_DESCRIBE g_print ("checkout info:\t%s\n", FWUPD_GIT_DESCRIBE); #endif g_print ("compile-time dependency versions\n"); g_print ("\tappstream-glib:\t%d.%d.%d\n", AS_MAJOR_VERSION, AS_MINOR_VERSION, AS_MICRO_VERSION); g_print ("\tgusb:\t%d.%d.%d\n", G_USB_MAJOR_VERSION, G_USB_MINOR_VERSION, G_USB_MICRO_VERSION); #ifdef LIBFWUP_LIBRARY_VERSION g_print ("\tfwupdate:\t%s\n", LIBFWUP_LIBRARY_VERSION); #endif #ifdef EFIVAR_LIBRARY_VERSION g_print ("\tefivar:\t%s\n", EFIVAR_LIBRARY_VERSION); #endif return EXIT_SUCCESS; } /* run the specified command */ ret = fu_util_run (priv, argv[1], (gchar**) &argv[2], &error); if (!ret) { if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_INVALID_ARGS)) { g_autofree gchar *tmp = NULL; tmp = g_option_context_get_help (priv->context, TRUE, NULL); g_print ("%s\n\n%s", error->message, tmp); return EXIT_FAILURE; } if (g_error_matches (error, FWUPD_ERROR, FWUPD_ERROR_NOTHING_TO_DO)) { g_print ("%s\n", error->message); return EXIT_NOTHING_TO_DO; } g_print ("%s\n", error->message); return EXIT_FAILURE; } /* success */ return EXIT_SUCCESS; } fwupd-1.0.6/src/fuzzing/000077500000000000000000000000001325145456600151415ustar00rootroot00000000000000fwupd-1.0.6/src/fuzzing/README.md000066400000000000000000000002741325145456600164230ustar00rootroot00000000000000Fuzzing ======= CC=afl-gcc meson --default-library=static ../ AFL_HARDEN=1 ninja afl-fuzz -m 300 -i ../src/fuzzing/smbios -o src/smbios/findings ./src/fwupdmgr smbios-dump @@ fwupd-1.0.6/src/fuzzing/smbios/000077500000000000000000000000001325145456600164355ustar00rootroot00000000000000fwupd-1.0.6/src/fuzzing/smbios/DMI-MicroServer.bin000066400000000000000000000000001325145456600217640ustar00rootroot00000000000000fwupd-1.0.6/src/fuzzing/smbios/DMI-T440s.bin000066400000000000000000000000001325145456600203420ustar00rootroot00000000000000fwupd-1.0.6/src/fuzzing/smbios/DMI-xps13.bin000066400000000000000000000000001325145456600205020ustar00rootroot00000000000000fwupd-1.0.6/src/fwupd.gresource.xml000066400000000000000000000003251325145456600173110ustar00rootroot00000000000000 org.freedesktop.fwupd.xml fwupd-1.0.6/src/meson.build000066400000000000000000000142721325145456600156150ustar00rootroot00000000000000cargs = ['-DG_LOG_DOMAIN="Fu"'] install_data(['org.freedesktop.fwupd.xml'], install_dir : join_paths(datadir, 'dbus-1', 'interfaces') ) keyring_deps = [] keyring_src = [] if get_option('gpg') keyring_src += 'fu-keyring-gpg.c' keyring_deps += gpgme keyring_deps += gpgerror endif if get_option('pkcs7') keyring_src += 'fu-keyring-pkcs7.c' keyring_deps += gnutls endif libfwupdprivate = static_library( 'fwupdprivate', sources : [ 'fu-common.c', 'fu-device.c', 'fu-device-locker.c', 'fu-hwids.c', 'fu-history.c', 'fu-plugin.c', 'fu-progressbar.c', 'fu-quirks.c', 'fu-smbios.c', 'fu-test.c', 'fu-usb-device.c', ], include_directories : [ include_directories('..'), include_directories('../libfwupd'), ], dependencies : [ appstream_glib, giounix, gudev, gusb, polkit, soup, sqlite, libarchive, valgrind, ], c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', '-DSYSFSFIRMWAREDIR="/sys/firmware"', '-DFWUPDDATADIR="' + join_paths(datadir, 'fwupd') + '"', '-DFWUPDCONFIGDIR="' + join_paths(default_sysconfdir, 'fwupd') + '"', '-DFU_OFFLINE_DESTDIR=""', ], ) fwupdmgr = executable( 'fwupdmgr', sources : [ 'fu-util.c', ], include_directories : [ include_directories('..'), include_directories('../libfwupd'), ], dependencies : [ appstream_glib, giounix, gudev, gusb, polkit, soup, sqlite, libarchive, libjsonglib, ], link_with : [ fwupd, libfwupdprivate, ], c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', '-DFU_OFFLINE_DESTDIR=""', ], install : true, install_dir : bindir ) if get_option('man') help2man = find_program('help2man') custom_target('fwupdmgr-man', input : fwupdmgr, output : 'fwupdmgr.1', command : [ help2man, '@INPUT@', '--no-info', '--output', '@OUTPUT@', '--name', 'fwupd', '--manual', 'User Commands', '--version-string', fwupd_version, ], install : true, install_dir : join_paths(mandir, 'man1'), ) endif resources_src = gnome.compile_resources( 'fwupd-resources', 'fwupd.gresource.xml', source_dir : '.', c_name : 'fu' ) executable( 'fwupd', resources_src, sources : [ keyring_src, 'fu-common.c', 'fu-common-cab.c', 'fu-config.c', 'fu-keyring.c', 'fu-keyring-result.c', 'fu-engine.c', 'fu-main.c', 'fu-hwids.c', 'fu-debug.c', 'fu-device.c', 'fu-device-list.c', 'fu-device-locker.c', 'fu-keyring.c', 'fu-history.c', 'fu-plugin.c', 'fu-plugin-list.c', 'fu-quirks.c', 'fu-smbios.c', 'fu-usb-device.c', ], include_directories : [ include_directories('..'), include_directories('../libfwupd'), ], dependencies : [ keyring_deps, appstream_glib, libgcab, giounix, gmodule, gudev, gusb, polkit, soup, sqlite, valgrind, libarchive, ], link_with : fwupd, c_args : [ cargs, '-DLOCALSTATEDIR="' + localstatedir + '"', '-DPLUGINDIR="' + plugin_dir + '"', '-DSYSFSFIRMWAREDIR="/sys/firmware"', '-DSYSCONFDIR="' + default_sysconfdir + '"', '-DFWUPDDATADIR="' + join_paths(datadir, 'fwupd') + '"', '-DFWUPDCONFIGDIR="' + join_paths(default_sysconfdir, 'fwupd') + '"', '-DFU_OFFLINE_DESTDIR=""', ], install : true, install_dir : join_paths(libexecdir, 'fwupd') ) if get_option('tests') testdatadir_src = join_paths(meson.source_root(), 'data', 'tests') testdatadir_dst = join_paths(meson.build_root(), 'data', 'tests') pluginbuilddir = join_paths(meson.build_root(), 'plugins', 'test') e = executable( 'fu-self-test', resources_src, colorhug_test_firmware, colorhug_pkcs7_signature, builder_test_firmware, hwid_test_firmware, noreqs_test_firmware, sources : [ keyring_src, 'fu-self-test.c', 'fu-common.c', 'fu-common-cab.c', 'fu-config.c', 'fu-engine.c', 'fu-keyring.c', 'fu-hwids.c', 'fu-device.c', 'fu-device-list.c', 'fu-device-locker.c', 'fu-history.c', 'fu-keyring.c', 'fu-keyring-result.c', 'fu-plugin.c', 'fu-plugin-list.c', 'fu-progressbar.c', 'fu-quirks.c', 'fu-smbios.c', 'fu-test.c', 'fu-usb-device.c', ], include_directories : [ include_directories('..'), include_directories('../libfwupd'), ], dependencies : [ keyring_deps, appstream_glib, libgcab, giounix, gmodule, gudev, gusb, polkit, soup, sqlite, valgrind, libarchive, ], link_with : [ fwupd, ], c_args : [ cargs, '-DTESTDATADIR_SRC="' + testdatadir_src + '"', '-DTESTDATADIR_DST="' + testdatadir_dst + '"', '-DTESTDATADIR="' + testdatadir_src + ':' + testdatadir_dst + '"', '-DLOCALSTATEDIR="/tmp/fwupd-self-test/var"', '-DPLUGINBUILDDIR="' + pluginbuilddir + '"', '-DFU_OFFLINE_DESTDIR="/tmp/fwupd-self-test"', '-DPLUGINDIR="' + testdatadir_src + '"', '-DSYSFSFIRMWAREDIR="' + testdatadir_src + '"', '-DFWUPDDATADIR="' + testdatadir_src + '"', '-DSYSCONFDIR="' + testdatadir_src + '"', '-DFWUPDCONFIGDIR="' + testdatadir_src + '"', ], ) test('fu-self-test', e, is_parallel:false) endif if get_option('introspection') gir_dep = declare_dependency(sources: gir) gnome.generate_gir(fwupd, sources : [ 'fu-common.c', 'fu-common.h', 'fu-device.c', 'fu-device.h', 'fu-device-locker.c', 'fu-device-locker.h', 'fu-plugin.c', 'fu-plugin.h', 'fu-quirks.c', 'fu-quirks.h', 'fu-usb-device.c', ], nsversion : '1.0', namespace : 'Fu', symbol_prefix : 'fu', identifier_prefix : 'Fu', export_packages : 'fu', include_directories : [ include_directories('..'), include_directories('../libfwupd'), ], dependencies : [ appstream_glib, gir_dep, giounix, gusb, soup, sqlite, ], link_with : [ libfwupdprivate, ], includes : [ 'Gio-2.0', 'GObject-2.0', 'GUsb-1.0', ], ) endif fwupd-1.0.6/src/org.freedesktop.fwupd.xml000066400000000000000000000371111325145456600204170ustar00rootroot00000000000000 The interface used for quering firmware for the system. The daemon version. The daemon status, e.g. decompressing. The job percentage completion, or 0 for unknown. Gets a list of all the devices that are supported. An array of devices, with any properties set on each. Gets a list of all the releases for a specific device. A device ID. An array of releases (with the release number as the key), with any properties set on each. Gets a list of all the downgrades possible for a specific device. A device ID. An array of releases (with the release number as the key), with any properties set on each. Gets a list of all the upgrades possible for a specific device. A device ID. An array of releases (with the release number as the key), with any properties set on each. Gets details about a local firmware file. An index into the array of file descriptors that may have been sent with the DBus message. An array of results, with any properties set on each. Gets a list of all the past firmware updates. An array of devices, with any properties set on each. Schedules a firmware to be installed. An ID, typically a GUID of the hardware to update, or the string * to match any applicable hardware. An index into the array of file descriptors that may have been sent with the DBus message. Options to be used when constructing the profile, e.g. offline=True. Verifies firmware on a device by reading it back and performing a cryptographic hash, typically SHA1. An ID, typically a GUID of the hardware. Updates the cryptographic hash stored for a device. An ID, typically a GUID of the hardware. Unlock the device to allow firmware access. An ID, typically a GUID of the hardware. Gets the results of an offline update. An ID, typically a GUID of the hardware that was updated, or the string * to match any hardware. Results about the update, e.g. success=True Gets the list of remotes. The array remotes, with properties Clears the results of an offline update. An ID, typically a GUID of the hardware that was updated, or the string * to match any hardware. Modifies a remote in some way. A device ID, or the string * to match any hardware. The key, e.g. 'Flags'. The value of the correct type, e.g. a URL. Adds AppStream resource information from a session client. Remote ID to tag the metadata objects with, e.g. 'lvfs-testing'. File handle to AppStream metadata. File handle to AppStream metadata GPG signature. Modifies a remote in some way. Remote ID, e.g. 'lvfs-testing'. The key, e.g. 'Enabled'. The value of the correct type, e.g. a URL. Some value on the interface or the number of devices or profiles has changed. A device structure. A device has been added. A device structure. A device has been removed. A device structure. A device has been changed.