From 444c06e022a3219924bd7c38b0be4d56298e52a3 Mon Sep 17 00:00:00 2001 From: lihuhua Date: Mon, 17 Oct 2022 16:05:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0TEE-GP-Proxy=E5=BC=80?= =?UTF-8?q?=E6=BA=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 127 + README.en.md | 36 - README.md | 39 +- demo/clientapp/parallel/p.sh | 17 + demo/clientapp/testcase1/CMakeLists.txt | 16 + demo/clientapp/testcase1/build/cmake.sh | 1 + demo/clientapp/testcase1/build/test.sh | 11 + demo/clientapp/testcase1/testcase.c | 1042 + demo/clientapp/testcase1/testcase.h | 39 + demo/clientapp/testcase2/CMakeLists.txt | 16 + demo/clientapp/testcase2/build/cmake.sh | 1 + demo/clientapp/testcase2/build/test.sh | 11 + demo/clientapp/testcase2/testcase.c | 941 + demo/clientapp/testcase2/testcase.h | 39 + demo/clientapp/testcase3/CMakeLists.txt | 16 + demo/clientapp/testcase3/build/cmake.sh | 1 + demo/clientapp/testcase3/build/test.sh | 11 + demo/clientapp/testcase3/testcase.c | 941 + demo/clientapp/testcase3/testcase.h | 39 + demo/clientapp/testcase4/CMakeLists.txt | 16 + demo/clientapp/testcase4/build/cmake.sh | 1 + demo/clientapp/testcase4/build/test.sh | 11 + demo/clientapp/testcase4/testcase.c | 940 + demo/clientapp/testcase4/testcase.h | 39 + demo/clientapp/testcase5/CMakeLists.txt | 16 + demo/clientapp/testcase5/build/cmake.sh | 1 + demo/clientapp/testcase5/build/test.sh | 11 + demo/clientapp/testcase5/testcase.c | 940 + demo/clientapp/testcase5/testcase.h | 39 + demo/clientapp/testcase6/CMakeLists.txt | 16 + demo/clientapp/testcase6/build/cmake.sh | 1 + demo/clientapp/testcase6/build/test.sh | 11 + demo/clientapp/testcase6/testcase.c | 940 + demo/clientapp/testcase6/testcase.h | 39 + demo/clientapp/testcase7/CMakeLists.txt | 16 + demo/clientapp/testcase7/build/cmake.sh | 1 + demo/clientapp/testcase7/build/test.sh | 11 + demo/clientapp/testcase7/testcase.c | 940 + demo/clientapp/testcase7/testcase.h | 39 + demo/clientapp/testcase8/CMakeLists.txt | 16 + demo/clientapp/testcase8/build/cmake.sh | 1 + demo/clientapp/testcase8/build/test.sh | 11 + demo/clientapp/testcase8/testcase.c | 940 + demo/clientapp/testcase8/testcase.h | 39 + demo/clientapp/testcase9/CMakeLists.txt | 16 + demo/clientapp/testcase9/build/cmake.sh | 1 + demo/clientapp/testcase9/build/test.sh | 11 + demo/clientapp/testcase9/testcase.c | 940 + demo/clientapp/testcase9/testcase.h | 39 + demo/dbusjwt/CMakeLists.txt | 71 + demo/dbusjwt/build/cmake.sh | 1 + demo/dbusjwt/dbus_return_code.h | 26 + demo/dbusjwt/dbusc_jwt.c | 458 + demo/dbusjwt/dbusc_jwt.h | 27 + demo/dbusjwt/dbuss_fetchjwt.c | 253 + demo/dbusjwt/dbuss_validatejwt.c | 219 + demo/libspiffejwt/CMakeLists.txt | 56 + demo/libspiffejwt/build/cmake.sh | 1 + demo/libspiffejwt/spiffejwt.c | 254 + demo/libspiffejwt/spiffejwt.h | 13 + demo/libspiffejwt/test_spiffejwt.c | 51 + demo/scripts/dbus.sh | 10 + demo/scripts/spire/createentry_workload.sh | 9 + demo/scripts/spire/gentoken_agent.sh | 1 + demo/scripts/spire/runagent.sh | 1 + demo/scripts/spire/runserver.sh | 1 + demo/scripts/spire/showdelentry.sh | 10 + demo/scripts/tcpdump.sh | 2 + docs/Design/design.docx | Bin 0 -> 1077774 bytes docs/deployment/deployment.docx | Bin 0 -> 84867 bytes docs/pic/arch-II.png | Bin 0 -> 142683 bytes docs/test.docx | Bin 0 -> 42774 bytes patch/c-spiffe_patch | 507 + teeproxy/gpproxy/CMakeLists.txt | 107 + teeproxy/gpproxy/build/cmake.sh | 3 + teeproxy/gpproxy/certs/ca_crt.pem | 22 + teeproxy/gpproxy/certs/ca_key.pem | 30 + teeproxy/gpproxy/certs/check_ca_crt.sh | 42 + teeproxy/gpproxy/certs/check_ca_key.sh | 63 + teeproxy/gpproxy/certs/check_client_crt.sh | 43 + teeproxy/gpproxy/certs/check_client_key.sh | 62 + teeproxy/gpproxy/certs/check_server_crt.sh | 43 + teeproxy/gpproxy/certs/check_server_key.sh | 62 + teeproxy/gpproxy/certs/gen_ca_crt.sh | 22 + teeproxy/gpproxy/certs/gen_ca_keycrt.sh | 22 + teeproxy/gpproxy/certs/gen_client_crt.sh | 22 + teeproxy/gpproxy/certs/gen_client_keycsr.sh | 22 + teeproxy/gpproxy/certs/gen_server_crt.sh | 32 + teeproxy/gpproxy/certs/gen_server_keycrt.sh | 32 + teeproxy/gpproxy/certs/msg.txt | 1 + teeproxy/gpproxy/certs/server_crt.pem | 20 + teeproxy/gpproxy/certs/server_key.pem | 30 + teeproxy/gpproxy/changelog.md | 7 + teeproxy/gpproxy/common.cmake | 129 + teeproxy/gpproxy/conf/gpproxy_config.yaml | 19 + teeproxy/gpproxy/gpproxy.cc | 4195 +++ teeproxy/gpproxy/gpproxy.h | 21 + teeproxy/gpproxy/protos/gt.proto | 392 + teeproxy/gpworker/README | 8 + teeproxy/gpworker/build/Makefile | 28 + teeproxy/gpworker/build/r.sh | 7 + teeproxy/gpworker/changelog.md | 7 + teeproxy/gpworker/condition.c | 55 + teeproxy/gpworker/condition.h | 28 + teeproxy/gpworker/gpworker.c | 50 + teeproxy/gpworker/threadpool.c | 155 + teeproxy/gpworker/threadpool.h | 108 + teeproxy/gpworker/tzcp_dbus.c | 22889 ++++++++++++++++ teeproxy/gpworker/tzcp_dbus.h | 550 + teeproxy/libdbuscgpw/CMakeLists.txt | 45 + teeproxy/libdbuscgpw/build/cmake.sh | 1 + teeproxy/libdbuscgpw/dbusc_gpw.c | 9291 +++++++ teeproxy/libdbuscgpw/dbusc_gpw.h | 406 + teeproxy/libteecc/CMakeLists.txt | 119 + teeproxy/libteecc/build/cmake.sh | 3 + teeproxy/libteecc/certs/ca_crt.pem | 22 + teeproxy/libteecc/certs/check_ca_crt.sh | 42 + teeproxy/libteecc/certs/check_client_crt.sh | 43 + teeproxy/libteecc/certs/check_client_key.sh | 62 + teeproxy/libteecc/certs/client_crt.pem | 20 + teeproxy/libteecc/certs/client_key.pem | 30 + teeproxy/libteecc/certs/gen_client_keycsr.sh | 22 + teeproxy/libteecc/certs/msg.txt | 1 + teeproxy/libteecc/changelog.md | 7 + teeproxy/libteecc/common.cmake | 129 + teeproxy/libteecc/conf/teecc_config.yaml | 10 + .../libteecc/include/teecc/tee_client_api.h | 184 + .../include/teecc/tee_client_constants.h | 165 + .../libteecc/include/teecc/tee_client_list.h | 100 + .../libteecc/include/teecc/tee_client_log.h | 29 + .../libteecc/include/teecc/tee_client_type.h | 150 + .../libteecc/include/teecc/teec_client_api.h | 192 + teeproxy/libteecc/protos/gt.proto | 392 + teeproxy/libteecc/teecc.cc | 4148 +++ teeproxy/libteecc/teecc.h | 351 + 135 files changed, 56592 insertions(+), 57 deletions(-) create mode 100644 LICENSE delete mode 100644 README.en.md create mode 100644 demo/clientapp/parallel/p.sh create mode 100644 demo/clientapp/testcase1/CMakeLists.txt create mode 100644 demo/clientapp/testcase1/build/cmake.sh create mode 100644 demo/clientapp/testcase1/build/test.sh create mode 100644 demo/clientapp/testcase1/testcase.c create mode 100644 demo/clientapp/testcase1/testcase.h create mode 100644 demo/clientapp/testcase2/CMakeLists.txt create mode 100644 demo/clientapp/testcase2/build/cmake.sh create mode 100644 demo/clientapp/testcase2/build/test.sh create mode 100644 demo/clientapp/testcase2/testcase.c create mode 100644 demo/clientapp/testcase2/testcase.h create mode 100644 demo/clientapp/testcase3/CMakeLists.txt create mode 100644 demo/clientapp/testcase3/build/cmake.sh create mode 100644 demo/clientapp/testcase3/build/test.sh create mode 100644 demo/clientapp/testcase3/testcase.c create mode 100644 demo/clientapp/testcase3/testcase.h create mode 100644 demo/clientapp/testcase4/CMakeLists.txt create mode 100644 demo/clientapp/testcase4/build/cmake.sh create mode 100644 demo/clientapp/testcase4/build/test.sh create mode 100644 demo/clientapp/testcase4/testcase.c create mode 100644 demo/clientapp/testcase4/testcase.h create mode 100644 demo/clientapp/testcase5/CMakeLists.txt create mode 100644 demo/clientapp/testcase5/build/cmake.sh create mode 100644 demo/clientapp/testcase5/build/test.sh create mode 100644 demo/clientapp/testcase5/testcase.c create mode 100644 demo/clientapp/testcase5/testcase.h create mode 100644 demo/clientapp/testcase6/CMakeLists.txt create mode 100644 demo/clientapp/testcase6/build/cmake.sh create mode 100644 demo/clientapp/testcase6/build/test.sh create mode 100644 demo/clientapp/testcase6/testcase.c create mode 100644 demo/clientapp/testcase6/testcase.h create mode 100644 demo/clientapp/testcase7/CMakeLists.txt create mode 100644 demo/clientapp/testcase7/build/cmake.sh create mode 100644 demo/clientapp/testcase7/build/test.sh create mode 100644 demo/clientapp/testcase7/testcase.c create mode 100644 demo/clientapp/testcase7/testcase.h create mode 100644 demo/clientapp/testcase8/CMakeLists.txt create mode 100644 demo/clientapp/testcase8/build/cmake.sh create mode 100644 demo/clientapp/testcase8/build/test.sh create mode 100644 demo/clientapp/testcase8/testcase.c create mode 100644 demo/clientapp/testcase8/testcase.h create mode 100644 demo/clientapp/testcase9/CMakeLists.txt create mode 100644 demo/clientapp/testcase9/build/cmake.sh create mode 100644 demo/clientapp/testcase9/build/test.sh create mode 100644 demo/clientapp/testcase9/testcase.c create mode 100644 demo/clientapp/testcase9/testcase.h create mode 100644 demo/dbusjwt/CMakeLists.txt create mode 100644 demo/dbusjwt/build/cmake.sh create mode 100644 demo/dbusjwt/dbus_return_code.h create mode 100644 demo/dbusjwt/dbusc_jwt.c create mode 100644 demo/dbusjwt/dbusc_jwt.h create mode 100644 demo/dbusjwt/dbuss_fetchjwt.c create mode 100644 demo/dbusjwt/dbuss_validatejwt.c create mode 100644 demo/libspiffejwt/CMakeLists.txt create mode 100644 demo/libspiffejwt/build/cmake.sh create mode 100644 demo/libspiffejwt/spiffejwt.c create mode 100644 demo/libspiffejwt/spiffejwt.h create mode 100644 demo/libspiffejwt/test_spiffejwt.c create mode 100644 demo/scripts/dbus.sh create mode 100644 demo/scripts/spire/createentry_workload.sh create mode 100644 demo/scripts/spire/gentoken_agent.sh create mode 100644 demo/scripts/spire/runagent.sh create mode 100644 demo/scripts/spire/runserver.sh create mode 100644 demo/scripts/spire/showdelentry.sh create mode 100644 demo/scripts/tcpdump.sh create mode 100644 docs/Design/design.docx create mode 100644 docs/deployment/deployment.docx create mode 100644 docs/pic/arch-II.png create mode 100644 docs/test.docx create mode 100644 patch/c-spiffe_patch create mode 100644 teeproxy/gpproxy/CMakeLists.txt create mode 100644 teeproxy/gpproxy/build/cmake.sh create mode 100644 teeproxy/gpproxy/certs/ca_crt.pem create mode 100644 teeproxy/gpproxy/certs/ca_key.pem create mode 100644 teeproxy/gpproxy/certs/check_ca_crt.sh create mode 100644 teeproxy/gpproxy/certs/check_ca_key.sh create mode 100644 teeproxy/gpproxy/certs/check_client_crt.sh create mode 100644 teeproxy/gpproxy/certs/check_client_key.sh create mode 100644 teeproxy/gpproxy/certs/check_server_crt.sh create mode 100644 teeproxy/gpproxy/certs/check_server_key.sh create mode 100644 teeproxy/gpproxy/certs/gen_ca_crt.sh create mode 100644 teeproxy/gpproxy/certs/gen_ca_keycrt.sh create mode 100644 teeproxy/gpproxy/certs/gen_client_crt.sh create mode 100644 teeproxy/gpproxy/certs/gen_client_keycsr.sh create mode 100644 teeproxy/gpproxy/certs/gen_server_crt.sh create mode 100644 teeproxy/gpproxy/certs/gen_server_keycrt.sh create mode 100644 teeproxy/gpproxy/certs/msg.txt create mode 100644 teeproxy/gpproxy/certs/server_crt.pem create mode 100644 teeproxy/gpproxy/certs/server_key.pem create mode 100644 teeproxy/gpproxy/changelog.md create mode 100644 teeproxy/gpproxy/common.cmake create mode 100644 teeproxy/gpproxy/conf/gpproxy_config.yaml create mode 100644 teeproxy/gpproxy/gpproxy.cc create mode 100644 teeproxy/gpproxy/gpproxy.h create mode 100644 teeproxy/gpproxy/protos/gt.proto create mode 100644 teeproxy/gpworker/README create mode 100644 teeproxy/gpworker/build/Makefile create mode 100644 teeproxy/gpworker/build/r.sh create mode 100644 teeproxy/gpworker/changelog.md create mode 100644 teeproxy/gpworker/condition.c create mode 100644 teeproxy/gpworker/condition.h create mode 100644 teeproxy/gpworker/gpworker.c create mode 100644 teeproxy/gpworker/threadpool.c create mode 100644 teeproxy/gpworker/threadpool.h create mode 100644 teeproxy/gpworker/tzcp_dbus.c create mode 100644 teeproxy/gpworker/tzcp_dbus.h create mode 100644 teeproxy/libdbuscgpw/CMakeLists.txt create mode 100644 teeproxy/libdbuscgpw/build/cmake.sh create mode 100644 teeproxy/libdbuscgpw/dbusc_gpw.c create mode 100644 teeproxy/libdbuscgpw/dbusc_gpw.h create mode 100644 teeproxy/libteecc/CMakeLists.txt create mode 100644 teeproxy/libteecc/build/cmake.sh create mode 100644 teeproxy/libteecc/certs/ca_crt.pem create mode 100644 teeproxy/libteecc/certs/check_ca_crt.sh create mode 100644 teeproxy/libteecc/certs/check_client_crt.sh create mode 100644 teeproxy/libteecc/certs/check_client_key.sh create mode 100644 teeproxy/libteecc/certs/client_crt.pem create mode 100644 teeproxy/libteecc/certs/client_key.pem create mode 100644 teeproxy/libteecc/certs/gen_client_keycsr.sh create mode 100644 teeproxy/libteecc/certs/msg.txt create mode 100644 teeproxy/libteecc/changelog.md create mode 100644 teeproxy/libteecc/common.cmake create mode 100644 teeproxy/libteecc/conf/teecc_config.yaml create mode 100644 teeproxy/libteecc/include/teecc/tee_client_api.h create mode 100644 teeproxy/libteecc/include/teecc/tee_client_constants.h create mode 100644 teeproxy/libteecc/include/teecc/tee_client_list.h create mode 100644 teeproxy/libteecc/include/teecc/tee_client_log.h create mode 100644 teeproxy/libteecc/include/teecc/tee_client_type.h create mode 100644 teeproxy/libteecc/include/teecc/teec_client_api.h create mode 100644 teeproxy/libteecc/protos/gt.proto create mode 100644 teeproxy/libteecc/teecc.cc create mode 100644 teeproxy/libteecc/teecc.h diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9e32cde --- /dev/null +++ b/LICENSE @@ -0,0 +1,127 @@ + 木兰宽松许可证, 第2版 + + 木兰宽松许可证, 第2版 + 2020年1月 http://license.coscl.org.cn/MulanPSL2 + + + 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: + + 0. 定义 + + “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 + + “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 + + “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 + + “法人实体”是指提交贡献的机构及其“关联实体”。 + + “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 + + 1. 授予版权许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 + + 2. 授予专利许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 + + 3. 无商标许可 + + “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 + + 4. 分发限制 + + 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 + + 5. 免责声明与责任限制 + + “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 + + 6. 语言 + “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 + + 条款结束 + + 如何将木兰宽松许可证,第2版,应用到您的软件 + + 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: + + 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; + + 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; + + 3, 请将如下声明文本放入每个源文件的头部注释中。 + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + + + Mulan Permissive Software License,Version 2 + + Mulan Permissive Software License,Version 2 (Mulan PSL v2) + January 2020 http://license.coscl.org.cn/MulanPSL2 + + Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: + + 0. Definition + + Software means the program and related documents which are licensed under this License and comprise all Contribution(s). + + Contribution means the copyrightable work licensed by a particular Contributor under this License. + + Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. + + Legal Entity means the entity making a Contribution and all its Affiliates. + + Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. + + 1. Grant of Copyright License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. + + 2. Grant of Patent License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. + + 3. No Trademark License + + No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. + + 4. Distribution Restriction + + You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. + + 5. Disclaimer of Warranty and Limitation of Liability + + THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 6. Language + + THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. + + END OF THE TERMS AND CONDITIONS + + How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software + + To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: + + i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; + + ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; + + iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. + + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. diff --git a/README.en.md b/README.en.md deleted file mode 100644 index d886802..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# tee-gp-proxy - -#### Description -This project aims to provide an implementation for RPC invoking TEE to facilitate the use of Kunpeng confidential computing in cloud scennarios. - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 400e2dd..b45312e 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,34 @@ -# tee-gp-proxy +# cc-resource-pooling #### 介绍 -This project aims to provide an implementation for RPC invoking TEE to facilitate the use of Kunpeng confidential computing in cloud scennarios. +机密计算资源池(Confidential Computeing Resource Pooling)项目旨在通过资源池化TrustZone的算力,方便鲲鹏机密计算的可信应用在云上部署。 +详细内容可参考仓库中的设计文档。 #### 软件架构 -软件架构说明 +![TrustZone资源池架构](docs/pic/arch-II.png) + +本项目借助了gPRC这一字节流框架,扩展新创建了可部署在任意位置的GP(Globle Platform) API 库-下文称为GP Client,用于部署在云上的TrustZone的Client APP访问真实的TrustZone TEE。同时在Host上 新建了 GP API proxy,用于接收来自远程的CA的 GP API的调用。 + +GP Client用于序列化CA的GP接口调用,GP Proxy则收到调用合反序列化后,将GP调用转化为本地TEE Client接口调用。考虑到并发处理的情况,GP API Proxy可管理多任时的队列。 +使用此方法,解决在VM或Docker中穿透虚拟化层访问TEE驱动的问题。如果需要,你也可以进一步开发,将多泰山服务器集群化管理。 + #### 安装教程 -1. xxxx -2. xxxx -3. xxxx +参考部署文档。 #### 使用说明 -1. xxxx -2. xxxx -3. xxxx +1. 本项目原项目中引入了Host端对客户端的认证机制,并在GP API 以及Service侧提供了透传JWT的API,JWT的获取以及确认需要应用实现; +2. 在配置gPRC时,建议启用TLS以及基于证书的双向认证,注意证书私钥为机密数据,在部署系统时需要考虑保护机制; +3. 本项目不包含其它开源项目的代码,涉及的第三方开源组件均需要使用者自行获取。 -#### 参与贡献 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +#### 参与贡献 #### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +1. 项目提供接口与原接口完全适配,用户仅需更换libteec.so文件即可直接使用 +2. 增加了token验证机制,并添加了两个扩展程序,作为token验证的中间件 +3. 性能上相较于一期项目显著提升 diff --git a/demo/clientapp/parallel/p.sh b/demo/clientapp/parallel/p.sh new file mode 100644 index 0000000..de4f582 --- /dev/null +++ b/demo/clientapp/parallel/p.sh @@ -0,0 +1,17 @@ +# ! /bin/bash + +# set maximal number of parallel jobs +MAX_NUM_LCOUNT=100 +MAX_NUM_CCA=9 +# END_NUM=$(($MAX_NUM_CCA-1)) +END_NUM=$MAX_NUM_CCA + +if true; then +for ((LCOUNT = 0; LCOUNT < $MAX_NUM_LCOUNT; LCOUNT++)) +do + echo -e "\n"remove {}_$LCOUNT.log ::: $(eval echo "{1..$END_NUM}") + parallel -j $MAX_NUM_CCA rm "-f" {}_$LCOUNT.log ::: $(eval echo "{1..$END_NUM}") + parallel -j $MAX_NUM_CCA --ungroup bash ../testcase{}/build/test.sh "| tee" {}_$LCOUNT.log ::: $(eval echo "{1..$END_NUM}") + # parallel -j $MAX_NUM_CCA --ungroup ../testcase0/build/testcase "| tee" {}_$LCOUNT.log ::: $(eval echo "{0..$END_NUM}") +done +fi diff --git a/demo/clientapp/testcase1/CMakeLists.txt b/demo/clientapp/testcase1/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase1/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase1/build/cmake.sh b/demo/clientapp/testcase1/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase1/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase1/build/test.sh b/demo/clientapp/testcase1/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase1/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase1/testcase.c b/demo/clientapp/testcase1/testcase.c new file mode 100644 index 0000000..6c4450a --- /dev/null +++ b/demo/clientapp/testcase1/testcase.c @@ -0,0 +1,1042 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 1 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) + { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) + { + if (i % PRINTF_SIZE == 0) + { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) + { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) + { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *) param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t) pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) + { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) + { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) + { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) + { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) + { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); + exit: + return (void *) ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) + { + pthread_create(&tid[i], NULL, thread_function, (void *) &context); + } + + for (i = 0; i < THREAD_COUNT; i++) + { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result) thread_ret != TEEC_SUCCESS) + { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result) thread_ret); + ret = TEEC_FAIL; + } + } + + exit: + TEEC_FinalizeContext(&context); + if (!ret) + { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *) "/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) + { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) + { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) + { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) + { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) + { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) + { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) + { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) + { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) + { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) + { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) + { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) + { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) + { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char *msgBuf, uint32_t msgLen, char *signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) + { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result) RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) + { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) + { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else + { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) + { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *) TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) + { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_10(void) +{ + + TEEC_Result ret; + char infile_path[1024]; + char *subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + //basic_function + sprintf(infile_path, + "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", + TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta(size <= 1M) failed. \n"); + return ret; + } else + { + printf("Deploy ta(size <= 1M) succed. \n"); + } + //8M_TA_TEST + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase1/8M_TA_TEST.sec"); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta(size = 8M) failed. \n", TESTCASE); + return ret; + } else + { + printf("Deploy ta(size = 8M) succed. \n", TESTCASE); + } + + //TA_NOT_FOUND + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase1/not_found.sec"); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret == TEEC_INFILE_NOT_FOUND) + { + printf("Deploy ta not found test success\n"); + } else + { + printf("Deploy TA not found test failed \n"); + return ret; + } + + //outfile_path_not_exist + subdir = "not_exist_path"; + sprintf(infile_path, + "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", + TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta outfile_path_not_exist failed. \n"); + return ret; + } else + { + printf("Deploy ta outfile_path_not_exist succed. \n"); + } + + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) + { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif + +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char *subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, + "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", + TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) + { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + case 10: + ret = testcase_10(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase1/testcase.h b/demo/clientapp/testcase1/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase1/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase2/CMakeLists.txt b/demo/clientapp/testcase2/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase2/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase2/build/cmake.sh b/demo/clientapp/testcase2/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase2/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase2/build/test.sh b/demo/clientapp/testcase2/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase2/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase2/testcase.c b/demo/clientapp/testcase2/testcase.c new file mode 100644 index 0000000..9082b63 --- /dev/null +++ b/demo/clientapp/testcase2/testcase.c @@ -0,0 +1,941 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 2 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif + +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase2/testcase.h b/demo/clientapp/testcase2/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase2/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase3/CMakeLists.txt b/demo/clientapp/testcase3/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase3/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase3/build/cmake.sh b/demo/clientapp/testcase3/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase3/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase3/build/test.sh b/demo/clientapp/testcase3/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase3/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase3/testcase.c b/demo/clientapp/testcase3/testcase.c new file mode 100644 index 0000000..918b48d --- /dev/null +++ b/demo/clientapp/testcase3/testcase.c @@ -0,0 +1,941 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 3 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif + +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase3/testcase.h b/demo/clientapp/testcase3/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase3/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase4/CMakeLists.txt b/demo/clientapp/testcase4/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase4/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase4/build/cmake.sh b/demo/clientapp/testcase4/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase4/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase4/build/test.sh b/demo/clientapp/testcase4/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase4/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase4/testcase.c b/demo/clientapp/testcase4/testcase.c new file mode 100644 index 0000000..44498ac --- /dev/null +++ b/demo/clientapp/testcase4/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 4 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase4/testcase.h b/demo/clientapp/testcase4/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase4/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase5/CMakeLists.txt b/demo/clientapp/testcase5/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase5/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase5/build/cmake.sh b/demo/clientapp/testcase5/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase5/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase5/build/test.sh b/demo/clientapp/testcase5/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase5/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase5/testcase.c b/demo/clientapp/testcase5/testcase.c new file mode 100644 index 0000000..df56bf4 --- /dev/null +++ b/demo/clientapp/testcase5/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 5 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase5/testcase.h b/demo/clientapp/testcase5/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase5/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase6/CMakeLists.txt b/demo/clientapp/testcase6/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase6/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase6/build/cmake.sh b/demo/clientapp/testcase6/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase6/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase6/build/test.sh b/demo/clientapp/testcase6/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase6/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase6/testcase.c b/demo/clientapp/testcase6/testcase.c new file mode 100644 index 0000000..8603324 --- /dev/null +++ b/demo/clientapp/testcase6/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 6 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase6/testcase.h b/demo/clientapp/testcase6/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase6/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase7/CMakeLists.txt b/demo/clientapp/testcase7/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase7/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase7/build/cmake.sh b/demo/clientapp/testcase7/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase7/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase7/build/test.sh b/demo/clientapp/testcase7/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase7/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase7/testcase.c b/demo/clientapp/testcase7/testcase.c new file mode 100644 index 0000000..0078f58 --- /dev/null +++ b/demo/clientapp/testcase7/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 7 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase7/testcase.h b/demo/clientapp/testcase7/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase7/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase8/CMakeLists.txt b/demo/clientapp/testcase8/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase8/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase8/build/cmake.sh b/demo/clientapp/testcase8/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase8/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase8/build/test.sh b/demo/clientapp/testcase8/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase8/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase8/testcase.c b/demo/clientapp/testcase8/testcase.c new file mode 100644 index 0000000..6ac5d90 --- /dev/null +++ b/demo/clientapp/testcase8/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 8 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase8/testcase.h b/demo/clientapp/testcase8/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase8/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/clientapp/testcase9/CMakeLists.txt b/demo/clientapp/testcase9/CMakeLists.txt new file mode 100644 index 0000000..80b4384 --- /dev/null +++ b/demo/clientapp/testcase9/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(testcase C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +add_executable(testcase testcase.c) +target_link_libraries( + testcase + pthread + libteecc.so + libdbusc_jwt.so +) diff --git a/demo/clientapp/testcase9/build/cmake.sh b/demo/clientapp/testcase9/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/clientapp/testcase9/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/clientapp/testcase9/build/test.sh b/demo/clientapp/testcase9/build/test.sh new file mode 100644 index 0000000..c73734d --- /dev/null +++ b/demo/clientapp/testcase9/build/test.sh @@ -0,0 +1,11 @@ +CUR_DIR=$( dirname -- "$0"; ) + +${CUR_DIR}/testcase 1 +${CUR_DIR}/testcase 2 +${CUR_DIR}/testcase 3 +${CUR_DIR}/testcase 4 +# ${CUR_DIR}/testcase 5 +${CUR_DIR}/testcase 6 +${CUR_DIR}/testcase 7 +${CUR_DIR}/testcase 8 +${CUR_DIR}/testcase 9 diff --git a/demo/clientapp/testcase9/testcase.c b/demo/clientapp/testcase9/testcase.c new file mode 100644 index 0000000..1181690 --- /dev/null +++ b/demo/clientapp/testcase9/testcase.c @@ -0,0 +1,940 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo + */ + +#include "testcase.h" +#include +#include +#include +#include +#include +#include +// #include +// #include +// #include +// #include +#include +#include +#include +#include + +// #include "tee_client_api.h" +#include "teecc/teec_client_api.h" +#include "dbusc_jwt.h" + +#define TESTCASE 9 + +#if TESTCASE == 2 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530002.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x02} +}; +#elif TESTCASE == 3 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530003.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x03} +}; +#elif TESTCASE == 4 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530004.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x04} +}; +#elif TESTCASE == 5 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530005.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x05} +}; +#elif TESTCASE == 6 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530006.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x06} +}; +#elif TESTCASE == 7 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530007.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x07} +}; +#elif TESTCASE == 8 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530008.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x08} +}; +#elif TESTCASE == 9 +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530009.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x09} +}; +#else +#define TEST_CASE_TA_PATH "/data/testcase/b8ff9049-9cbb-46b0-bcae-7aaa02530001.sec" +static const TEEC_UUID TEST_CASE_UUID = { + 0xb8ff9049, 0x9cbb, 0x46b0, + {0xbc, 0xae, 0x7a, 0xaa, 0x02, 0x53, 0x00, 0x01} +}; +#endif + +static void DumpBuff(const char *buffer, size_t bufLen) +{ + size_t i; + if (buffer == NULL || bufLen == 0) { + return; + } + + printf("\n--------------------------------------------------\n"); + printf("bufLen = %d\n", bufLen); + for (i = 0; i < bufLen; i++) { + if (i % PRINTF_SIZE == 0) { + printf("\n"); + } + printf("%02x ", *(buffer + i)); + } + printf("\n--------------------------------------------------\n"); + return; +} + +static TEEC_Result testcase_1() +{ + TEEC_Context context; + // uint64_t context_addr; + TEEC_Session session; + TEEC_Operation operation; + uint32_t origin; + TEEC_Result ret; + + //Interface_Function-001 + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + //Interface_Function-002 + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- no param + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + //Interface_Function-003 -- value param + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_A); + assert(operation.params[0].value.b == VALUE_B); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].value.a = 55; + operation.params[0].value.b = 33; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(operation.params[0].value.a == VALUE_B); + assert(operation.params[0].value.b == VALUE_A); + + // Interface_Function-003 -- temp buf param + char tmpbuf[TEMP_BUF_SIZE] = REE_TEMP_BUF; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].tmpref.buffer = tmpbuf; + operation.params[0].tmpref.size = TEMP_BUF_SIZE; + memset(tmpbuf, 0, TEMP_BUF_SIZE); + memcpy(tmpbuf, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(!ret); + assert(!strcmp(tmpbuf, TEE_TEMP_BUF)); + + //Interface_Function-004 + TEEC_CloseSession(&session); + //Interface_Function-005 + TEEC_FinalizeContext(&context); + if (!ret) { + printf("interface_testcase pass\n"); + } + return ret; +} + +static void share_mem_test( + TEEC_Session *session, + TEEC_SharedMemory *sharebuf +) +{ + TEEC_Result ret; + TEEC_Operation operation; + uint32_t origin; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_FULL, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); + + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INOUT, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = sharebuf; + operation.params[0].memref.offset = 1; + operation.params[0].memref.size = TEMP_BUF_SIZE - 1; + memset(sharebuf->buffer, 0, sharebuf->size); + memcpy(sharebuf->buffer + 1, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + ret = TEEC_InvokeCommand(session, CMD_SHARE_MEM_PATR, &operation, &origin); + assert(!ret); + assert(!strcmp(sharebuf->buffer + 1, TEE_TEMP_BUF)); +} + +static TEEC_Result testcase_2() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + char tmpbuf[TEMP_BUF_SIZE]; + uint32_t origin; + TEEC_Result ret; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Function-006 + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-011 + share_mem_test(&session, &sharebuf); + + // Interface_Function-008 + TEEC_ReleaseSharedMemory(&sharebuf); + + // Interface_Function-007 + memset(&sharebuf, 0, sizeof(sharebuf)); + sharebuf.buffer = tmpbuf; + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_RegisterSharedMemory(&context, &sharebuf); + assert(!ret); + + // Interface_Function-012 + share_mem_test(&session, &sharebuf); + + TEEC_ReleaseSharedMemory(&sharebuf); + +// exit: + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("sharemem_interface_testcase pass\n"); + } + return ret; +} + + +static void *thread_function(void *param) +{ + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharebuf; + TEEC_Context *context = (TEEC_Context *)param; + pthread_t tid; + uint32_t origin; + struct timeval start, end, tokenset; + + tid = (pthread_t)pthread_self(); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + ret = TEEC_OpenSession(context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("thread %u open session failed, ret=%x\n", tid, ret); + goto exit; + } + + sharebuf.size = TEMP_BUF_SIZE; + sharebuf.flags = TEEC_MEM_INOUT; + ret = TEEC_AllocateSharedMemory(context, &sharebuf); + if (ret) { + printf("thread %u share buffer alloc failed, ret=%x\n", tid, ret); + goto exit; + } + + printf("begin multi-thread test, during %u\n", TEST_TIME); + gettimeofday(&start, NULL); + gettimeofday(&tokenset, NULL); + while (1) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_VALUE_INOUT, TEEC_NONE, TEEC_NONE); + memset(sharebuf.buffer, 0, sharebuf.size); + memcpy(sharebuf.buffer, REE_TEMP_BUF, strlen(REE_TEMP_BUF)); + operation.params[0].memref.parent = &sharebuf; + operation.params[1].value.a = 1; + + ret = TEEC_InvokeCommand(&session, CMD_MUL_THREAD, &operation, &origin); + if (ret) { + printf("thread %u invoke failed, ret=%x, origin=%u\n", tid, ret, origin); + break; + } + + if (strcmp(sharebuf.buffer, TEE_TEMP_BUF) || operation.params[1].value.a || operation.params[1].value.b != 1) { + printf("thread %u get wrong comptue result.\n", tid); + break; + } + gettimeofday(&end, NULL); + if (end.tv_sec - start.tv_sec > TEST_TIME) + break; + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + + sleep(1); + } + + TEEC_CloseSession(&session); +exit: + return (void *)ret; +} + +static TEEC_Result testcase_3() +{ + TEEC_Result ret; + TEEC_Operation operation; + TEEC_Context context; + pthread_t tid[THREAD_COUNT]; + void *thread_ret = NULL; + uint32_t i; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_create(&tid[i], NULL, thread_function, (void *)&context); + } + + for (i = 0; i < THREAD_COUNT; i++) { + pthread_join(tid[i], &thread_ret); + if ((TEEC_Result)thread_ret != TEEC_SUCCESS) { + printf("thread %u return fail, ret=%x\n", tid[i], (TEEC_Result)thread_ret); + ret = TEEC_FAIL; + } + } + +exit: + TEEC_FinalizeContext(&context); + if (!ret) { + printf("multi_thread_testcase pass\n"); + } + return ret; +} + + +// Exception Test +static TEEC_Result testcase_4() +{ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 + TEEC_Result ret = TEEC_SUCCESS; + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_SharedMemory sharemem; + uint32_t origin; + + // Interface_Exception_001ll + ret = TEEC_InitializeContext(NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + + // Interface_Exception_002 + ret = TEEC_OpenSession(NULL, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + NULL, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + ret = TEEC_OpenSession(&context, + &session, NULL, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + context.ta_path = (uint8_t *)"/data/not_found.sec"; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_TRUSTED_APP_LOAD_ERROR); + // assert(ret == TEEC_ERROR_NOT_IMPLEMENTED); + printf("OpenSession tapath not_found.sec case, ret = 0x %16.16lx. \n", ret); + assert(ret); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // Interface_Exception_003 + ret = TEEC_InvokeCommand(NULL, CMD_NULL, &operation, &origin); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + session.session_id++; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + // assert(ret == TEEC_ERROR_ACCESS_DENIED); + assert(ret == TEEC_ERROR_NO_WORKER_MATCHED); + + session.session_id--; + operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_WHOLE, TEEC_NONE, TEEC_NONE, TEEC_NONE); + operation.params[0].memref.parent = &sharemem; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + assert(ret); + + ret = TEEC_InvokeCommand(&session, CMD_NULL, NULL, NULL); + assert(ret == TEEC_ERROR_BAD_PARAMETERS); + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, NULL); + assert(!ret); + + // Interface_Exception_004 + TEEC_CloseSession(NULL); + + // Interface_Exception_005 + TEEC_FinalizeContext(NULL); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + + if (!ret) { + printf("exception_testcase pass\n"); + } + return ret; +} + +static TEEC_Result testcase_5() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + assert(!ret); + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + assert(!ret); + + // CA_KILL_Test_001 + printf("CA Killed Test begin!, process exit!\n"); + exit(0); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_6() +{ + TEEC_Context context; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + gettimeofday(&start, NULL); + ret = TEEC_InitializeContext(NULL, &context); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_FinalizeContext(&context); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InitializeContext cost: %f us\n", cost * 1.0 / count); + } + return ret; +} + +static TEEC_Result testcase_7() +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + gettimeofday(&start, NULL); + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + TEEC_CloseSession(&session); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_OpenSession cost: %f us\n", cost * 1.0 / count); + } + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result testcase_8(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + struct timeval start, end, tokenset; + uint32_t cost = 0; + uint32_t i; + TEEC_Result ret; + uint32_t count = 1000; + uint32_t origin; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + gettimeofday(&tokenset, NULL); + for (i = 0; i < count; i++) { + operation.started = 1; + memset(&operation.paramTypes, 0, sizeof(operation.paramTypes)); + gettimeofday(&start, NULL); + ret = TEEC_InvokeCommand(&session, CMD_NULL, &operation, &origin); + gettimeofday(&end, NULL); + if (ret) { + break; + } + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (end.tv_sec - tokenset.tv_sec > EXPIRE_TIME) + { + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + break; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + break; + } + printf("Token set succed. \n"); + gettimeofday(&tokenset, NULL); + } + } + + if (!ret) { + printf("TEEC_InvokeCommand cost: %f us\n", cost * 1.0 / count); + } + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +static TEEC_Result RsaSignCmd(char* msgBuf, uint32_t msgLen, char* signBuf, uint32_t *bufLen, + TEEC_Session *session) +{ + TEEC_Operation operation; + TEEC_Result result; + uint32_t origin; + + if (msgBuf == NULL || signBuf == NULL || (bufLen == NULL)) { + TEEC_Error("invoke RsaSignCmd has wrong params."); + return (TEEC_Result)RSA_INPUT_ERROR_PARAMETER; + } + + operation.started = 1; + operation.paramTypes = TEEC_PARAM_TYPES( + TEEC_VALUE_INPUT, + TEEC_NONE, + TEEC_MEMREF_TEMP_INPUT, + TEEC_MEMREF_TEMP_OUTPUT); + + operation.params[0].value.a = RSA_KEY_1; + operation.params[0].value.b = RSA_ALG_PSS_SHA256; + operation.params[PARAMS_INDEX_2].tmpref.buffer = msgBuf; + operation.params[PARAMS_INDEX_2].tmpref.size = msgLen; + operation.params[PARAMS_INDEX_3].tmpref.buffer = signBuf; + operation.params[PARAMS_INDEX_3].tmpref.size = *bufLen; + + result = TEEC_InvokeCommand(session, CMD_SIGN_PSS_MGF1_SHA256, &operation, &origin); + if (result != TEEC_SUCCESS) { + TEEC_Error("invoke RsaSignCmd failed, codes=0x%x, origin=0x%x.", result, origin); + } else if (operation.params[PARAMS_INDEX_3].tmpref.size != RSA_KEY_SIZE) { + TEEC_Error("invoke RsaSignCmd failed, returned Encrypted data size is %d.", + operation.params[PARAMS_INDEX_3].tmpref.size); + } else { + printf("signBuf is : \n"); + DumpBuff(signBuf, operation.params[PARAMS_INDEX_3].tmpref.size); + *bufLen = operation.params[PARAMS_INDEX_3].tmpref.size; + } + + return result; +} + +static TEEC_Result testcase_9(void) +{ + TEEC_Context context; + TEEC_Session session; + TEEC_Operation operation; + TEEC_Result ret; + uint32_t origin; + char msgBuf[RSA_KEY_SIZE] = {0}; + char signature[RSA_KEY_SIZE] = {0}; + uint32_t bufLen = RSA_KEY_SIZE; + + ret = TEEC_InitializeContext(NULL, &context); + if (ret) { + printf("initail conatext failed\n"); + return ret; + } + context.ta_path = (uint8_t *)TEST_CASE_TA_PATH; + + memset(&operation, 0, sizeof(operation)); + operation.started = 1; + ret = TEEC_OpenSession(&context, + &session, &TEST_CASE_UUID, TEEC_LOGIN_IDENTIFY, NULL, &operation, &origin); + if (ret) { + printf("opensession failed!, ret=%x, origin=%u\n", ret, origin); + TEEC_FinalizeContext(&context); + return ret; + } + + ret = RsaSignCmd(msgBuf, RSA_MASSAGE_SIZE, signature, &bufLen, &session); + printf("TEE RSA Sign %s.\n", ret ? "failed" : "success"); + + TEEC_CloseSession(&session); + TEEC_FinalizeContext(&context); + return ret; +} + +void help_print(void) +{ + printf("Usage: \n \ + 1.function_interface_testcase\n \ + 2.sharemem_interface_testcase\n \ + 3.multi_thread_testcase\n \ + 4.exception_testcase\n \ + 5.client_killed_testcase\n \ + 6.TEEC_InitializeContext perform-test\n \ + 7.TEEC_OpenSession perform-test\n \ + 8.TEEC_InvokeCommand perform-test\n \ + 9.RSA Sign test\n"); +} + +int main(int argc, char **argv) +{ + TEEC_Result ret; + struct timeval start, end; + gettimeofday(&start, NULL); + int choice = -1; + + if (argc == 1 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { + help_print(); + return 1; + } + +#if 0 + char token[1024]; + int iret; + iret = + dbusmethodcall_fetch_jwt( + token + ); + if (iret != 0) + { + printf("Token fetching failed. \n"); + return 0; + } + printf("The fetched token: %s \n", token); + + ret = + TEEC_SetJwt( + token + ); + if (ret != TEEC_SUCCESS) + { + printf("Token set failed. \n"); + return 0; + } + printf("Token set succed. \n"); +#endif +#if 1 + ret = + TEEC_UnsetJwt( + ); + if (ret != TEEC_SUCCESS) + { + printf("Token unset failed. \n"); + return 0; + } + printf("Token unset succed. \n"); +#endif + + char infile_path[1024]; + char * subdir = "testcase"; + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", TESTCASE, TESTCASE); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", TESTCASE); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", TESTCASE); + } + + /* + for (int ita = 1; ita < 10; ita ++) + { + memset(infile_path, 0, sizeof(infile_path)); + sprintf(infile_path, "/home/john/projects/tzc02/09/demo/ta/itrustee_sdk/output/testcase/testcase%d/b8ff9049-9cbb-46b0-bcae-7aaa0253000%d.sec", ita, ita); + ret = TEEC_DeployTa(infile_path, subdir, NULL); + if (ret != TEEC_SUCCESS) + { + printf("Deploy ta %d failed. \n", ita); + return 0; + } + else + { + printf("Deploy ta %d succed. \n", ita); + } + } + */ + + choice = atoi(argv[1]); + + switch (choice) { + case 1: + ret = testcase_1(); + break; + case 2: + ret = testcase_2(); + break; + case 3: + ret = testcase_3(); + break; + case 4: + ret = testcase_4(); + break; + case 5: + ret = testcase_5(); + break; + case 6: + ret = testcase_6(); + break; + case 7: + ret = testcase_7(); + break; + case 8: + ret = testcase_8(); + break; + case 9: + ret = testcase_9(); + break; + default: + printf("Error: invalid choice!\n"); + help_print(); + ret = -1; + break; + } + + return ret; +} diff --git a/demo/clientapp/testcase9/testcase.h b/demo/clientapp/testcase9/testcase.h new file mode 100644 index 0000000..7ced8e2 --- /dev/null +++ b/demo/clientapp/testcase9/testcase.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: multi_core_demo CA application header file + */ + +#ifndef __MULTI_CORE_CA_H +#define __MULTI_CORE_CA_H + +// #define TEST_CASE_TA_PATH "/data/ebc87fc2-05dc-41b3-85b9-f9f0ef481bad.sec" + +#define VALUE_A 55 +#define VALUE_B 33 +#define REE_TEMP_BUF "hello tee" +#define TEE_TEMP_BUF "hello ree" +#define TEMP_BUF_SIZE 20 +#define THREAD_COUNT 3 + +#define TEST_TIME 10 * 6 +#define EXPIRE_TIME 10 * 6 * 5 + +#define RSA_KEY_SIZE 256 // 2048bits +#define RSA_MASSAGE_SIZE 100 +#define RSA_INPUT_ERROR_PARAMETER 0x10000001 +#define RSA_KEY_1 1 +#define RSA_ALG_PSS_SHA256 2 // use TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 mode for sign + +#define PARAMS_INDEX_2 2 // params参数的下标索引 2 +#define PARAMS_INDEX_3 3 // params参数的下标索引 3 +#define PRINTF_SIZE 32 + +enum { + CMD_NULL = 0, + CMD_SHARE_MEM_FULL, + CMD_SHARE_MEM_PATR, + CMD_MUL_THREAD, + CMD_SIGN_PSS_MGF1_SHA256, +}; + +#endif diff --git a/demo/dbusjwt/CMakeLists.txt b/demo/dbusjwt/CMakeLists.txt new file mode 100644 index 0000000..0c23113 --- /dev/null +++ b/demo/dbusjwt/CMakeLists.txt @@ -0,0 +1,71 @@ +# + +cmake_minimum_required(VERSION 3.5.1) + +project(dbus_jwt C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") +# include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include/) +include_directories(/usr/include/dbus-1.0/) +include_directories(/usr/lib64/dbus-1.0/include/) + +# Introduce variables: +# - CMAKE_INSTALL_LIBDIR +# - CMAKE_INSTALL_BINDIR +# - CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + + +set(lib_dbusc_jwt + ${PROJECT_SOURCE_DIR}/dbusc_jwt.c +) +# Install Headers: +set(HEADERS_DBUSC_JWT + ${PROJECT_SOURCE_DIR}/dbusc_jwt.h +) +install( + FILES ${HEADERS_DBUSC_JWT} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${TARGET_NAME}" +) + +add_library(dbusc_jwt SHARED ${lib_dbusc_jwt}) +target_link_libraries( + dbusc_jwt + libdbus-1.so +) + +# Install lib: +install( + TARGETS "dbusc_jwt" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + + +set(dbuss_fetchjwt + ${PROJECT_SOURCE_DIR}/dbuss_fetchjwt.c +) +add_executable(dbuss_fetchjwt "${dbuss_fetchjwt}") +target_link_libraries( + dbuss_fetchjwt + libdbus-1.so + spiffejwt +) + +set(dbuss_validatejwt + ${PROJECT_SOURCE_DIR}/dbuss_validatejwt.c +) +add_executable(dbuss_validatejwt "${dbuss_validatejwt}") +target_link_libraries( + dbuss_validatejwt + libdbus-1.so + spiffejwt +) + +# Install bin: +install( + TARGETS "dbuss_fetchjwt" "dbuss_validatejwt" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR$}" +) diff --git a/demo/dbusjwt/build/cmake.sh b/demo/dbusjwt/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/dbusjwt/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/dbusjwt/dbus_return_code.h b/demo/dbusjwt/dbus_return_code.h new file mode 100644 index 0000000..e59e9b5 --- /dev/null +++ b/demo/dbusjwt/dbus_return_code.h @@ -0,0 +1,26 @@ +// +// Created by 62754 on 2022/8/19. +// + +#ifndef _DBUS_RETURN_CODE_H +#define _DBUS_RETURN_CODE_H + +enum TEEC_ReturnCode +{ + TEEC_ERROR_JWTVALIDATE_FAIL = 0xAAAA0020, /* jwt validate fail */ + TEEC_ERROR_GRPC_ERROR = 0xAAAA0021, /* grpc transmission error */ + TEEC_ERROR_DBUS_CONN_NULL = 0xAAAA0022, /* dbus connection null */ + TEEC_ERROR_DBUS_NAME_ERROR = 0xAAAA0023, /* dbus name set is error */ + TEEC_ERROR_DBUS_MSG_NULL = 0xAAAA0024, /* dbus message is null */ + TEEC_ERROR_DBUS_APPEND_ERROR = 0xAAAA0025, /* dbus append argument error */ + TEEC_ERROR_DBUS_REPLY_ERROR = 0xAAAA0026, /* dbus send with reply error */ + TEEC_ERROR_DBUS_ARG_NULL = 0xAAAA0027, /* dbus argument is null */ + TEEC_ERROR_DBUS_ARG_TYPE_ERROR = 0xAAAA0028, /* dbus argument type error */ + TEEC_ERROR_TOKEN_NULL = 0xAAAA0029, /* fetch token is null */ + TEEC_ERROR_TOKEN_SIZE_ERROR = 0xAAAA0030, /* token size is error */ + TEEC_ERROR_FETCHJWT_ERROR = 0xAAAA0031, /* fetch jwt error */ + TEEC_INFILE_PATH_NULL = 0xAAAA0032 /* deployta infile patn is null*/ +}; + +typedef enum TEEC_ReturnCode TEEC_Result; +#endif //_DBUS_RETURN_CODE_H diff --git a/demo/dbusjwt/dbusc_jwt.c b/demo/dbusjwt/dbusc_jwt.c new file mode 100644 index 0000000..2445602 --- /dev/null +++ b/demo/dbusjwt/dbusc_jwt.c @@ -0,0 +1,458 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbus_return_code.h" + + +TEEC_Result dbusmethodcall_fetch_jwt( + char *token +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + int ret; + int iType; + + unsigned char *charp; + unsigned char param[12] = "fetchtoken"; + DBusMessageIter structIter; + dbus_uint32_t retcode; + unsigned char *token_temp = NULL; + + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return TEEC_ERROR_DBUS_CONN_NULL; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + "fetchjwt", + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_NAME_ERROR; + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_NAME_ERROR; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", "fetchjwt"); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", "fetchjwt"); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", "fetchjwt"); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "fetch_jwtsvid" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null \n"); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_MSG_NULL; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + + charp = param; + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &charp)) + { + fprintf(stderr, "Out Of Memory. \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_APPEND_ERROR; + } + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbusc_jwt: fetchjwt send_with_reply_and_block error %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_REPLY_ERROR; + } + if (reply == NULL) + { + fprintf(stderr, "libdbusc_jwt: fetchjwt dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_REPLY_ERROR; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments. \n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_TYPE_ERROR; + } + dbus_message_iter_get_basic( + &structIter, + &retcode + ); + + if (retcode == 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments! \n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_TYPE_ERROR; + } + dbus_message_iter_get_basic( + &structIter, + &token_temp); + + if (token == NULL) + { + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_TOKEN_NULL; + } else + { + if (sizeof(token) < sizeof(token_temp)) + { + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_TOKEN_SIZE_ERROR; + } else + { + memset(token, '\0', sizeof(token)); + strcpy(token, token_temp); + } + } + + } + + // free reply + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return retcode; +} + + +TEEC_Result dbusmethodcall_validate_jwt( + char *token +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + int ret; + int iType; + + unsigned char *charp; + dbus_uint32_t retcode; + + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return TEEC_ERROR_DBUS_CONN_NULL; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + "validatejwt", + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_NAME_ERROR; + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_NAME_ERROR; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", "validatejwt"); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", "validatejwt"); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", "validatejwt"); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "validate_jwtsvid" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null \n"); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_MSG_NULL; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + + if (token == NULL) + { + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_TOKEN_NULL; + } + + charp = token; + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &charp)) + { + fprintf(stderr, "Out Of Memory. \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_APPEND_ERROR; + } + + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbusc_jwt: validatejwt send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_REPLY_ERROR; + } + if (reply == NULL) + { + fprintf(stderr, "libdbusc_jwt: validatejwt dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_REPLY_ERROR; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments. \n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &args + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_message_unref(msg); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return TEEC_ERROR_DBUS_ARG_TYPE_ERROR; + } + dbus_message_iter_get_basic( + &args, + &retcode + ); + + printf("libdbusc_jwt: got reply of methodcall validate_jwtsvid \n"); + printf(" retcode = 0x %8x \n", retcode); + + // free reply + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return retcode; +} + diff --git a/demo/dbusjwt/dbusc_jwt.h b/demo/dbusjwt/dbusc_jwt.h new file mode 100644 index 0000000..5f2b495 --- /dev/null +++ b/demo/dbusjwt/dbusc_jwt.h @@ -0,0 +1,27 @@ +#ifndef _DBUSC_JWT_H +#define _DBUSC_JWT_H + +#ifdef __cplusplus +extern "C" { +#endif + +int dbusmethodcall_fetch_jwt( + char *token +); + +int dbusmethodcall_validate_jwt( + // const char * taname, + char *token +); + +/* +int dbusmethodcall_restart( + const char * taname +); + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/demo/dbusjwt/dbuss_fetchjwt.c b/demo/dbusjwt/dbuss_fetchjwt.c new file mode 100644 index 0000000..7762a1f --- /dev/null +++ b/demo/dbusjwt/dbuss_fetchjwt.c @@ -0,0 +1,253 @@ +#include +#include +#include +#include +#include +#include +#include +#include "spiffejwt.h" + +#include "dbus_return_code.h" + +#define NO_ERROR 0 + + +void * +reply_methodcall_fetch_jwtsvid( + DBusMessage *msg, + DBusConnection *conn +) +{ + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + dbus_uint32_t retcode; + dbus_uint32_t serial = 0; + DBusMessageIter structIter; + char token[1024] = "noToken"; + + printf("\n"); + printf("Received mechod call fetch_jwtsvid. \n"); + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) + { + fprintf(stderr, "Message has no arguments!\n"); + retcode = TEEC_ERROR_DBUS_MSG_NULL; + } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + { + fprintf(stderr, "Argument is not string!\n"); + retcode = TEEC_ERROR_DBUS_ARG_TYPE_ERROR; + } else + { + dbus_message_iter_get_basic(&args, &token); + + int iResult = spiffe_fetch_jwtsvid( + token + ); + if (iResult == NO_ERROR) + { + printf("Token fetching succed, token = %s \n", token); + retcode = 0; + } else + { + retcode = TEEC_ERROR_FETCHJWT_ERROR; + } + } + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &retcode + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory! \n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + return NULL; + } + + if (retcode == 0) + { + unsigned char *charp; + charp = token; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &charp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory! \n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + return NULL; + } + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory! \n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + + return NULL; +} + +/** + * Server that exposes a method call and waits for it to be called + */ +void +receive_methodcall( +) +{ + DBusMessage *msg; + DBusConnection *conn; + DBusError err; + int ret; + dbus_bool_t bResult; + + + printf("Dbus server for fetching jwt is listening for method calls ... \n"); + + // initialise the error + dbus_error_init(&err); + + dbus_threads_init_default(); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + // conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + exit(1); + } + + if (NULL == conn) + { + fprintf(stderr, "Connection Null. \n"); + exit(1); + } + + char dbusname[1024]; + memset((char *) dbusname, 0, 1024); + // sprintf(dbusname, "%s.method.server", argv[1]); + sprintf(dbusname, "%s.method.server", "fetchjwt"); + // request our name on the bus and check for errors + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + exit(1); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + fprintf(stderr, "Not Primary Owner (%d)\n", ret); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + exit(1); + } + + // loop, testing for new messages + memset((char *) dbusname, 0, 1024); + // sprintf(dbusname, "%s.method.Type", argv[1]); + sprintf(dbusname, "%s.method.Type", "fetchjwt"); + while (true) + { + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't got a message + if (NULL == msg) + { + usleep(10000); + continue; + } + + // printf("Received one method call. \n"); + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + dbusname, + "fetch_jwtsvid" + ); + if (bResult == TRUE) + { + reply_methodcall_fetch_jwtsvid( + msg, + conn + ); + } + + // free the message + dbus_message_unref(msg); + + } // end of the while true + +} // end of the function + + +int main(int argc, char *argv[]) +{ + int iResult; + + iResult = spiffe_start_conn(); + if (iResult != NO_ERROR) + { + fprintf(stderr, "Spiffe start conn failed. \n"); + return -1; + } + + receive_methodcall( + ); + + return 0; +} diff --git a/demo/dbusjwt/dbuss_validatejwt.c b/demo/dbusjwt/dbuss_validatejwt.c new file mode 100644 index 0000000..87d603a --- /dev/null +++ b/demo/dbusjwt/dbuss_validatejwt.c @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "spiffejwt.h" +#include "dbus_return_code.h" + +#define NO_ERROR 0 + + +void * +reply_methodcall_validate_jwtsvid( + DBusMessage *msg, + DBusConnection *conn +) +{ + DBusMessage *reply; + DBusMessageIter args; + char *token = NULL; + dbus_bool_t bResult; + dbus_uint32_t retcode; + dbus_uint32_t serial = 0; + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) + { + fprintf(stderr, "Message has no arguments!\n"); + retcode = TEEC_ERROR_DBUS_MSG_NULL;; + } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + { + fprintf(stderr, "Argument is not string!\n"); + retcode = TEEC_ERROR_DBUS_ARG_TYPE_ERROR;; + } else + { + dbus_message_iter_get_basic(&args, &token); + printf("\n"); + printf("Received mechod call validate_jwtsvid: \n"); + printf(" token = %s \n", token); + struct timeval start, end; + gettimeofday(&start, NULL); + int iResult = spiffe_validate_jwtsvid( + token + ); + gettimeofday(&end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("spiffe validate jwt used time: %ld us. \n", i64Time_jwt); + + if (iResult == NO_ERROR) + { + printf("Token validate succed \n"); + retcode = NO_ERROR; + } else + { + printf("Token validate failed \n"); + retcode = TEEC_ERROR_JWTVALIDATE_FAIL; + } + } + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + bResult = + dbus_message_iter_append_basic( + &args, + DBUS_TYPE_UINT32, + &retcode + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + return NULL; + } + + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + + return NULL; +} + +/** + * Server that exposes a method call and waits for it to be called + */ +void +receive_methodcall( +) +{ + DBusMessage *msg; + DBusConnection *conn; + DBusError err; + int ret; + dbus_bool_t bResult; + + + printf("Dbus server for validating jwt is listening for method calls ... \n"); + + // initialise the error + dbus_error_init(&err); + + dbus_threads_init_default(); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + // conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + exit(1); + } + + if (NULL == conn) + { + fprintf(stderr, "Connection Null\n"); + exit(1); + } + + char dbusname[1024]; + memset((char *) dbusname, 0, 1024); + // sprintf(dbusname, "%s.method.server", argv[1]); + sprintf(dbusname, "%s.method.server", "validatejwt"); + // request our name on the bus and check for errors + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + exit(1); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + fprintf(stderr, "Not Primary Owner (%d)\n", ret); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + exit(1); + } + + // loop, testing for new messages + memset((char *) dbusname, 0, 1024); + // sprintf(dbusname, "%s.method.Type", argv[1]); + sprintf(dbusname, "%s.method.Type", "validatejwt"); + while (true) + { + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't got a message + if (NULL == msg) + { + usleep(10000); + continue; + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + dbusname, + "validate_jwtsvid" + ); + if (bResult == TRUE) + { + reply_methodcall_validate_jwtsvid( + msg, + conn + ); + } + + // free the message + dbus_message_unref(msg); + + } // end of the while true + +} // end of the function + + +int main(int argc, char *argv[]) +{ + int iResult; + + iResult = spiffe_start_conn(); + if (iResult != NO_ERROR) + { + fprintf(stderr, "Spiffe start conn failed. \n"); + return -1; + } + + receive_methodcall( + ); + + return 0; +} diff --git a/demo/libspiffejwt/CMakeLists.txt b/demo/libspiffejwt/CMakeLists.txt new file mode 100644 index 0000000..f20ce44 --- /dev/null +++ b/demo/libspiffejwt/CMakeLists.txt @@ -0,0 +1,56 @@ +# +# + +cmake_minimum_required(VERSION 3.5.1) + +project(spiffejwt C CXX) + +# include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +# Introduce variables: +# - CMAKE_INSTALL_LIBDIR +# - CMAKE_INSTALL_BINDIR +# - CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + + +set(LIB_SPIFFEJWT + ${PROJECT_SOURCE_DIR}/spiffejwt.c +) +# Install Headers: +set(HEADERS_SPIFFEJWT + ${PROJECT_SOURCE_DIR}/spiffejwt.h +) +install( + FILES ${HEADERS_SPIFFEJWT} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${TARGET_NAME}" +) + +add_library(spiffejwt SHARED ${LIB_SPIFFEJWT}) +target_link_libraries(spiffejwt + libclient.so +) + +# Install lib: +install( + TARGETS "spiffejwt" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) + +set(TEST_SPIFFEJWT + ${PROJECT_SOURCE_DIR}/test_spiffejwt.c +) +add_executable(test_spiffejwt "${TEST_SPIFFEJWT}") +target_link_libraries( + test_spiffejwt + spiffejwt +) + +# Install bin: +# install( +# TARGETS test_spiffejwt +# RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR$}" +# ) + + + diff --git a/demo/libspiffejwt/build/cmake.sh b/demo/libspiffejwt/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/demo/libspiffejwt/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/demo/libspiffejwt/spiffejwt.c b/demo/libspiffejwt/spiffejwt.c new file mode 100644 index 0000000..49a060e --- /dev/null +++ b/demo/libspiffejwt/spiffejwt.c @@ -0,0 +1,254 @@ +#include +#include +#include + +#include "c-spiffe/workload/client.h" + +#include "spiffejwt.h" + + +workloadapi_Client *client; + + +int spiffe_start_conn() +{ + err_t error = NO_ERROR; + + client = workloadapi_NewClient(&error); + + workloadapi_Client_SetAddress(client, "unix:///tmp/spire-agent/public/api.sock"); + + workloadapi_Client_SetHeader(client, "workload.spiffe.io", "true"); + if (error != NO_ERROR) + { + // printf("client error! %d\n", (int) error); + return error; + } + + error = workloadapi_Client_Connect(client); + if (error != NO_ERROR) + { + // printf("conn error! %d\n", (int) error); + return error; + } + + return NO_ERROR; +} + + +int spiffe_close_conn() +{ + if (client == NULL) + { + return -1; + } + + err_t error = NO_ERROR; + + error = workloadapi_Client_Close(client); + if (error != NO_ERROR) + { + // printf("close error! %d\n", (int) error); + return error; + } + + workloadapi_Client_Free(client); + if (error != NO_ERROR) + { + // printf("client free error! %d\n", (int) error); + return error; + } + + return NO_ERROR; +} + +bool utf8_check_is_valid(const char *string) +{ + if (!string) + return 0; + + const unsigned char *bytes = (const unsigned char *) string; + while (*bytes) + { + if ((// ASCII + // use bytes[0] <= 0x7F to allow ASCII control characters + bytes[0] == 0x09 || + bytes[0] == 0x0A || + bytes[0] == 0x0D || + (0x20 <= bytes[0] && bytes[0] <= 0x7E) + ) + ) + { + bytes += 1; + continue; + } + + if ((// non-overlong 2-byte + (0xC2 <= bytes[0] && bytes[0] <= 0xDF) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) + ) + ) + { + bytes += 2; + continue; + } + + if ((// excluding overlongs + bytes[0] == 0xE0 && + (0xA0 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) || + (// straight 3-byte + ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) || + bytes[0] == 0xEE || + bytes[0] == 0xEF) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) || + (// excluding surrogates + bytes[0] == 0xED && + (0x80 <= bytes[1] && bytes[1] <= 0x9F) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) + ) + { + bytes += 3; + continue; + } + + if ((// planes 1-3 + bytes[0] == 0xF0 && + (0x90 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) || + (// planes 4-15 + (0xF1 <= bytes[0] && bytes[0] <= 0xF3) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) || + (// plane 16 + bytes[0] == 0xF4 && + (0x80 <= bytes[1] && bytes[1] <= 0x8F) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) + ) + { + bytes += 4; + continue; + } + + return 0; + } + + return 1; +} + + +int spiffe_fetch_jwtsvid( + char *token +) +{ + err_t error = NO_ERROR; + + if (client == NULL) + { + return -1; + } + + spiffeid_ID id = {string_new("example.org"), + string_new("/myservice")}; + string_t audience = string_new("spiffe://example.org/audience"); + jwtsvid_Params params + = {.audience = audience, .extra_audiences = NULL, .subject = id}; + jwtsvid_SVID *svid + = workloadapi_Client_FetchJWTSVID(client, ¶ms, &error); + if (error != NO_ERROR) + { + // printf("fetch error! %d\n", (int) error); + return error; + } + // printf("Address: %p\n", svid); + + spiffeid_ID_Free(&id); + arrfree(audience); + + if (svid) + { + if (token == NULL) + { + jwtsvid_SVID_Free(svid); + return -1; + } else + { + if (sizeof(token) < sizeof(svid->token)) + { + jwtsvid_SVID_Free(svid); + return -1; + } else + { + bool bResult; + bResult = utf8_check_is_valid(svid->token); + if (bResult == false) + { + return -1; + } + + memset(token, '\0', sizeof(token)); + strcpy(token, svid->token); + jwtsvid_SVID_Free(svid); + } + } + } else + { + return -1; + } + + return NO_ERROR; +} + + +int spiffe_validate_jwtsvid( + char *token +) +{ + err_t error = NO_ERROR; + + if (client == NULL) + { + return -1; + } + + if (token == NULL) + { + return -1; + } + + bool bResult; + bResult = utf8_check_is_valid(token); + if (bResult == false) + { + return -1; + } + + // string_t audience = string_new(audience_name); + string_t audience = string_new("spiffe://example.org/audience"); + jwtsvid_SVID *svid = workloadapi_Client_ValidateJWTSVID( + client, token, audience, &error); + // printf("%s %d: spiffe_validate_jwtsvid error = %d \n", __FILE__, __LINE__, (int)error); + printf("libspiffejwt: spiffe_validate_jwtsvid error = %d \n", (int) error); + if (error != NO_ERROR) + { + return error; + } + + if (svid) + { + jwtsvid_SVID_Free(svid); + } + arrfree(audience); + + return NO_ERROR; +} diff --git a/demo/libspiffejwt/spiffejwt.h b/demo/libspiffejwt/spiffejwt.h new file mode 100644 index 0000000..0d2e774 --- /dev/null +++ b/demo/libspiffejwt/spiffejwt.h @@ -0,0 +1,13 @@ +#ifndef _SPIFFEJWT_H +#define _SPIFFEJWT_H + +int spiffe_start_conn(); +int spiffe_close_conn(); +int spiffe_fetch_jwtsvid( + char * token +); +int spiffe_validate_jwtsvid( + char * token +); + +#endif // _SPIFFEJWT_H diff --git a/demo/libspiffejwt/test_spiffejwt.c b/demo/libspiffejwt/test_spiffejwt.c new file mode 100644 index 0000000..b4a3f42 --- /dev/null +++ b/demo/libspiffejwt/test_spiffejwt.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include "spiffejwt.h" + + +#define NO_ERROR 0 + + +int main() +{ + char token[1024]; + int iResult; + + + iResult = spiffe_start_conn(); + if (iResult != NO_ERROR) + { + return -1; + } + + iResult = spiffe_fetch_jwtsvid( + token + ); + if (iResult != NO_ERROR) + { + return -1; + } else + { + printf("The feteched token: %s \n", token); + } + + iResult = spiffe_validate_jwtsvid( + token + ); + if (iResult != NO_ERROR) + { + printf("Token validate failed. \n"); + return -1; + } else + { + printf("Token validate succed. \n"); + } + + spiffe_close_conn(); + + return 0; +} + diff --git a/demo/scripts/dbus.sh b/demo/scripts/dbus.sh new file mode 100644 index 0000000..78602a7 --- /dev/null +++ b/demo/scripts/dbus.sh @@ -0,0 +1,10 @@ +# export $(dbus-launch) +# echo $DBUS_SESSION_BUS_ADDRESS + + +export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-mE1jFGBAsx,guid=dad6b93cccad1aeca78dd84162f7968b +echo $DBUS_SESSION_BUS_ADDRESS + + +export DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-TdbAmwQsui,guid=3556dc166fba4469e0f7f87762f4d56a +echo $DBUS_SESSION_BUS_ADDRESS diff --git a/demo/scripts/spire/createentry_workload.sh b/demo/scripts/spire/createentry_workload.sh new file mode 100644 index 0000000..e18be75 --- /dev/null +++ b/demo/scripts/spire/createentry_workload.sh @@ -0,0 +1,9 @@ +# bin/spire-server entry create \ +# -parentID spiffe://example.org/myagent \ +# -spiffeID spiffe://example.org/myservice \ +# -selector unix:uid:$(id -u) + +bin/spire-server entry create \ + -parentID spiffe://example.org/myagent \ + -spiffeID spiffe://example.org/myservice \ + -selector unix:uid:1000 diff --git a/demo/scripts/spire/gentoken_agent.sh b/demo/scripts/spire/gentoken_agent.sh new file mode 100644 index 0000000..afda869 --- /dev/null +++ b/demo/scripts/spire/gentoken_agent.sh @@ -0,0 +1 @@ +bin/spire-server token generate -spiffeID spiffe://example.org/myagent diff --git a/demo/scripts/spire/runagent.sh b/demo/scripts/spire/runagent.sh new file mode 100644 index 0000000..41918e9 --- /dev/null +++ b/demo/scripts/spire/runagent.sh @@ -0,0 +1 @@ +bin/spire-agent run -config conf/agent/agent.conf -joinToken 16047f93-a133-494e-865e-033617d33eec diff --git a/demo/scripts/spire/runserver.sh b/demo/scripts/spire/runserver.sh new file mode 100644 index 0000000..1907eec --- /dev/null +++ b/demo/scripts/spire/runserver.sh @@ -0,0 +1 @@ +bin/spire-server run -config conf/server/server.conf diff --git a/demo/scripts/spire/showdelentry.sh b/demo/scripts/spire/showdelentry.sh new file mode 100644 index 0000000..6a0183f --- /dev/null +++ b/demo/scripts/spire/showdelentry.sh @@ -0,0 +1,10 @@ +bin/spire-server entry show + +# bin/spire-server entry delete -entryID + +# rm -f .data/agent_svid.der +# rm -f .data/agent-data.json +# rm -f .data/keys.json +# bin/spire-server entry delete -entryID + +bin/spire-server entry show diff --git a/demo/scripts/tcpdump.sh b/demo/scripts/tcpdump.sh new file mode 100644 index 0000000..a01f5d6 --- /dev/null +++ b/demo/scripts/tcpdump.sh @@ -0,0 +1,2 @@ +tcpdump -vvvv -XX -i lo '(port 50051)' -w 01.cap +tcpdump -vvv -XX -r 01.cap | more diff --git a/docs/Design/design.docx b/docs/Design/design.docx new file mode 100644 index 0000000000000000000000000000000000000000..c76d0359572a00c9579991a630aa3f96c25cfc29 GIT binary patch literal 1077774 zcma&L1CS_DmMvN~Z`rqO+r};1w(VQCZQHhO+qP}K>Uq=iXMRsdyo}5^sg)VI)?Rz> zI4LUu41x>*1ONeGuPvw4$A=8s1PB1Y0|@|t1b_&jA!uXmXk_iEqv&R94{ zY!DM@uuczJ3nXOt*(=%wIp_7VoOuv>prEsSr6QvaDC0rA-D&Vjg_lG}EmoF|IKoA? z7Kg~W{l$@4=Mt#EZ-GY1(jVQLO~xKrxnK_5R-T@r`46K=5Ff3rN!SvoZhiNP5C35`&A9( z`;MEOR76AYtL~Mmr*MocAJNA($uNHw^iEG&e>g{IP!p$$Zoe0SRfa z3E;oT3?|%}im*dc-{$9<+lFYEzP}bQs29CEx;D9mm;Ddj0e+T$=>CuKp9|QJ?mG5H zmJYQ4BK7|T{WDkq2?+3>e^9$X007Yc1)})}^k0ybans_!^a#P%e%A;`Ta!&Fh-OV_ zi0+i~c)DW7E`qGyVnu6Row+5dr55nq#tip|>3C{X&(;Vw33agAy$xmjG0VNG+vKjB zTr#+Ph9Wk$5Lw9BWc_umooXF3KAJ)HHU_AHd-Z-<>^$PBPBL%~Ca!`M)bCa6%^W=ZG(6nv~}iW;jK&rnzp*^JD0p2B5YC8Rk5a z%Kbpywv3%yC%4nZMI*p43gJRY=o3!|nuy-16*ZR%Goo<}1m-P<1pkuQj6_iCMHqaxHe4D zKavLHs^(_fT}MTfjwfWH-|uqmoq@ty^!3H2Ii=>Z=s2)E(qLZipXR_}gG0SE$g@2- z7)_hUqJIYl#UXDmkjnFfSm?qFY${hL(Wz7t=#s|8*j335vK;HKEJ+u1oI00Yy8$=j zOX2)|JN4LO2Z)AEFR~* zH-Z0W#1;ZwGxYorVemu5KhoR(C%}JE@Gp^@8N+Yk&xa6r?fVgIbY-_F0J)bY7$;y; zC^fC8wk#CF7|y8teoZOnM|=?1+L`)_8=Y(ubd=}iG0vRpOBBZM=BT*j%5dZ9s!_>b zt4ehlID_@_2$QbgI>PRN1I^4ysT@f%0yaf}Ki_u!UILHJzM!boc+Y9CwJ+z0NlNR^ zWo1JqY57E?b)XPNdwq~!*z=9{CVeLQeO!ZQNV8o_FqlgNiyiEmK}c%%1||OSJDW&( zh~rm^n>O`BNBZ7>8vUQ1H4ywOeDK47=nn(v|H6Q*y^XEIe?-E+&|nnJZxKNELqp(K zFrAB3p2ecD)=Fcawghx%5Ze`)Bmv1%(%ko!C3N6bRuF6S>sE*PbCu{_P`$#^LXQC$ zNMu7NLoudyR(lD+UI$$#dSx#r&rEMsYj?SO^JO5~)H+5qE;A%F%293QuEX>=*YzEX zxN1{0OT~`d=)7P8>SYk`k=jz?C|XR670}S4?UUD<{Mi9Uqit>G42VNbJu1)0tI#DK zS!iWqxX8X)-wJS|M96Zrd%)4%^z|bW+*Nl+N7KX^t&!HUYo;dEBz0mjlWH)YE!G>L z6@~j?(eh@x&A)dmJU zqce)ajsLiCw!C2?oQa=WlGLeNJbNwJGM0qLcGJ#?scMe!?IFtZ0|3i}s_pkI>8!xJ z5=Vfp4dktUPwYF_7zf4QeGyy&M{fG}PGnb`0X-ocF(qV1ziL3IU@hb6pwrRYC*qFf z21fm}>2K3$mN$A+yM{1u!|fu;L>H0>z9}ju;|5K<)n(xCKn628m^HF_nSExG?+5fY z?2&Gjnq6*p5z61i5Y9tRS&2%mDZuQ2reIes5O&QGb4F4IUxB`&rFLVgK;&P&v;a+hl$Lu1meYx%ztQw5ZsvJcmo{XOz81eptJOC~=`5+y zYGc)yvx{66{2Lp^p>X$FYc`G3J-+KdkLxD(FAt2A<_GTuUkj^_vePTlsM9ZsinN+& z%o0%=a#;uS$jXdi57r>}o~`7tGhjrO0a}CXkdDW7yZdd5je_tPN+J&SGN-$9{+!{ahpDv63j1Z%mwNkiou`bcsgaA#z)@iq zC!^6XC#ZnoN)`690WOvQ8I!LOvj7m-3`XoxvV#7u;P>UOv|vP47FJ7l1+ya{FJw zh>(29b(X@J@yD0@S|UJJDP(G-pa+KVX%#BXtmC97DYc}hMVC&x#SoeCLn&Wb@>)zi zsc=T{eYm9sdlM`2iw!1&oaMeGatZRxS^UZ-jQ&!oNR8xZL@QT+U&bxfl&k>Z>sIU# zjs!rgS|^);Q_Fe}0t8pH`bxLpiiXo8Kg*YuWQ9Fl{?#evTP(9b}| zWwef1d&ca(Wb>DK-@ngA?~7^f`4jp`&f<4wdLfXOn|G3TSNahCTqxsDBy~E|DStG` z3LnVhJAa@gXt|LN)&^2&5-_0~+>1=_{{U*|KUFUpVm}6la1ixe&*qi@M7QJE?i;EI zEp>(+c*8)$#6EvBAk*Lbr{sr};t64PJ=$u~-{z<6h7CmPhw;R$!0Y=F5b%b82(xYO z7;i^*7Yll-CO=$6yFG&b&tBjj^ZUfT4*;NF9_B~V{|tx!F6Y0LzzeN&g>|u}Z?E#J z@0`8<%GF9BjXR_(5{&=^lKNIP8ahs=<{}DWLky;oIF&g3QPMa-AS58e_)-5D1Y-db z#`xM%X_DPZy!s?dp2==onQ~$^mL|ac9nrRuzPPu|6QIej7E?Q5@UrrQ0$}Y)9A=T{G4I$p1>|G4;ZN- zh0kj0Or0nK;v9FN)Oekt4#^Jph>k09=_DS=Iv|{4h@DhJj??7KtP$8OO&HXx5cBD4 z2k`+fc`;z8C@;`I4j8z^9|_syBnOyjv-jl~CZ>C*ScjnE;-!pWot#iExq(b_m|Bs2 z_fbZXQ8Dm1Fznos*%7A?NiwLK!{1h2(7P@ar4Mc2fc~pux>IC>h3%IC>eT!M&u;)uw)|MDU`+B}ZLS zj;x?SU&7)yQsD_%p#gkuOFJT zXL)3(2VGnZ#8grQbs1V+(Ab~Vbl*4Pmv%mOmOu=4;~E4$kq4A41<)x4@GkZ7QMz_@ zL%ajE1M^FjJ;+ZRd^oAKNKsNe=cXVlbN<6emhgQg#Bl!_R_}1ccj0zOHV1*Hnur8I z2_Ar6EuZ{KUnUb(`)hF+o>)kkpFW6_xX}Yfni@w_aVOEe9CNSuL7O4{gC<>b-lc1D zpDsOVEywgz^$*w}SJ)hCbH4i?$H&$30FWIHPO*&zF5sO@aQTZ*teHg4+}$L=v7 zU{A}uNBq7sq!>m>$106lf*#cn2@^(V*)sKo+&0E<<9oSpm+(H-~lcwD) zkSuebw|m`zcR5w-G2b(MSn`U6y@10>z?^6xHg&tJ+y|cW=xiB?8nrne*(EF*q>Fop zkbAp~gyGI;bp&a)!e3;3KiuG*W(m|vOTWuYw(E~+uQiQ>`e{6hr&R0bcl*QjL(?!q z%1sqWg=IX2W!7bNuKwL`R5ShhU^g=divQ zM_C7V`@tl+UA;WR=u*ST;Bq=DsyuCOc5}2sw-kIPn-gCpW8*bdcP+p}3|g2($WyGu zhoMhc123NTW@W%rv$bpD0vp-6Ybv8*QVFEZ{RqTSvDgUYbB6-cE+s(jHRxp19LgXW zL^*p(XZJg2_v0-@q1P7+Z>K2Hh-CIJsDo3*`Z}kjHmj)ixXP{kpp7If^y zf_az^)EMR-JyXPM>83V$ouN-8Yv~Wvvs*%ckuIegSpRe9E$JT@v4sBq&5$Cxa$ZVK z6+UE#p%aWhClo}fp>nXI{Xdm1Y{9LxmGJ8(@#U8u?mhF%if^VYZgf+)?tnc1>fm6#Q*5okjl(DLGk&TwtZFV5!U}4V*H6* zTrE76K^Z07xe-kGcCPB@y1AP8XI-aF@i_e(-Pi@{`UE6ZN&TJk{#C$sAoD5s1AoZE zDy;xm_2P2o{&*&PzPqy`@6+jqa#;hOGOWXXGK$xSC0E`);mq#}P)znd&Wi@}TkNKV z;A(@b>MJnVntYDS^K#VY7ng>X0t9wQEoglSKMw`v6Bz%8pEJao2E=L!G3rx2rz}%5 zDudT?Auax$^$L$;a2|1Q>oJ9u4%Yy-7NAx5uURYoDXu?BYhNnr%&Qvl%+9inUYEb? zIc>A`cEU!EEHs0Pf<3o#D!(TRKw+c85EuR=+%xIsE&S#s5_2BR9HEPzO#u8VbK47u zbh8UoaWhJ=VduPAra6;HeXI5+GQ8|QRmStm>B27Rl9VMQCH3U*BBsc_vs2b%{^H{< zQ!_i8|31IGYInT7(0;|G2TB z1V;}Y4F9;j=_o>jWk)6H5}yNU;+A{zrp8Fs1Sb6UY5M(3K$dzwc@l?T(PU6jZcQ=_ z_qbnaw2#@oFL}`H#QE~+BgTHOi2JkIQ#1IZZ$Z(35{?)!h?oU*0U!rD37 z7K)hnb`}^ivvSeTIBMC<r@)o|GoAT%d|s<^3*-sNk1;3kC_36v$tfvKqpdqUIJU zlHfr8*sf&<_O%pApcWeRDK(>Xw4W0$_@E~782pxu*n#%`>`7L~25m9AmZYAI9yyxwZqb4{ zyO_|qf@6YC8;FrPs~FrrvIYoZZ%Q_S82XVt5Y8)P(P~Hrq+rNBOWqh}xd-fMEV=G1UEQfwJ!nz(aTsktR(bz6kQW;w#;uEa z$j0&Ug7mCaFG*`ETcRX&F!V@%ERSx*@{ElkMYi=QZ%)>uVrd^z;Zo7th7Ln|!M&A0 z2z=BvPi+XvH(HO2KVuxrY69dSN3&TS4tBpxS|5NkRS0%*tT7}0L>UDjzO~(v&&&H!&NrrZj7^;BFD(aH z!#=IY>5V)Y4Nx4$MAGjus%Qs%jn2*1|#Iz9DngE%ss-zkWJWuSlgCqxKUpp?iJ7&`5qpN%nklWJx+?DjfCylrhLBvTu5 zS@hl47bB*+v0#9Q)eh?V9Zq@OW8^Fxc9X3pH3SY4p#yp*5II9c6JTIEHzHqPBjUTj zz9Hzjk^GKdD2KIM0Rv{P?$qhR>3C2C`RnYH=cdyxXdOB%mxhxcZM=lu zkG{FR1hX?1ii;mk@fe?Va%F}-1l*q?CyI296V)(SvpN~Gq&~X1p}!xgQ!F+YP4G_c zOCPqv=xN-oZHIs?6#{SuR3UY}R$#nIrW0(|lcdV}X*jJdT>@%I$K<2Tt zU+m{Mup&T#edG#W|1ozBV;OWd{2ZkbW-aVN(ZDw)t?{!p{<4>+mAH&oqyZ3WKe~pFdcW+tBPVgXuz;^m zQ+NuG6F6DOX;^5=s(SRiuf^kK+qEj`m*8_VF88Wx zDS&C?q$D}Ba3tyVx$|y5;f&Y3E}x9$d8~2Qu$NUd;MIe0%QG+vuQwdb;E$V5p2zc^ zZ9A#oG#>tG1uQY3jYw$C-7V=`>dZ%8K13tC`gShg?V`heV?%TzG_7yL4+H*FLJKLG z3us=-`+j}RX^a#Ds4s~)e)u}>pTh2+q+(&ld-pDSlFi@qR0pwcP8!=8q8KScGu^)U zTjuT#P{YBuT1T&+7h6anOPZ?wO?2fdc^yNr-pobJ81Vp3cJIFv5qvR>l|1&p+-xP?>0ELS7l*syspQ67 z4sHwR)#rT~vNAe^`#nQc+s8yT?b#=b{zYctp|V9o4hdZwc7|!~(u`|GM4`44HwS+h z`tNfAB>imgeR*}i447S&g1D5A2ZZ4FAHlfkm1A;H8RBa3yA&b?6)N_)gA=^xv20^7I$hZ!`WN_??)o&d4HVS67eFd#VXlGDF3Da>fNR8yA=n})8?Y$hQ zeeJ=8@xAyFgcDHQixS{?SVjc76T%VaD~6p*()@yuPw1iK-d*RlkL*BQ@9G6?%(0iR z%@sp)b=WZrtI{I=PBO&SiUEz)b(1D@Rh6j2(+-n803`Zzq!1a4(v~V)U63g|*@AMR zZcd=nc-eLv7!TB0inkH&4TFA!(PaUT9woYqzV-rv69v)Kfd*DZfrCo5dk}0a#m_&5 zm-uHJ#(i#nOW+^9-bE{#=p46(Yc;ZpEirO3?`U6_ z5zeTk{hr(%S|GTRVVYH?IiT;<`ikn%nxQZ?r%2ZvCBkdt)=A5njA{h)Q;FlXo^{|t zl;SOcLen2<`AFHnJF?ranj-;8BfmL&YHSW3b9H)$$^%CaGBd8Wws-kUh+7%`?0Hcz zr*XY;Y-OZi6DjHt?C!ZvDvAPmn`r-TEzn|WOEROg6|nj{Ui-TcnUjysx&7VqFKTLO z(YC>PgH_V90@iA0;Y9g5aOO&o{_2=i{L|M`zU7^;yC-9(7x?=W`w^8PNO!0Dja+t9 z#d~VD0@+AK@Va5T%>h^KDvVO!gw}S42`-=~sQq9N!2{-gqaJ%-ZC*&YQ0`kL&QC*E zzX(nla4A1B4yut?;|2wklk<@h#R#%Mg?YFOJp*tSspBwMnlAu?21)Hyp}Rt5jOtwT z`=dgp`V`t>L<#s^ib|T#bPAfZ^Ar28LV`_kd@@P&%`b*Bna$o*7)KWut<&Si>ECB- z2^bL(#{26p0T5z)wj)Q}rW)=RDDI0KJo@LghuglPzHj|RN&CO%=EI}10mk4Q_0b?* z>s2XCW;9a$?C@Fcjhc>jDGf_U{X@z0*H42-j=l8YC<0{~N4MSM4rmy~i(>xQ6B3Zvj_Xo(@k#N4oxO>R- z%GlBtn#*j9-Es|GoqzG#P}Lrcy{*5!abrmoFl}s1eSK|;-+(n|tHiqg&EqUd5pCTR z-hT>|p=B=pR6C%KqXytw#ev(yRj+J4;ULTd^0bl2MsTOs&-*aMe^CG7D|ublAA79} zo}z67hjqC*R-|l2%9K#Z^V#Qm1D#;WC4LG`Yu9ck8LpD#)u+^h=lj9t7Uf90Ww>3n z#JI6=q1jaAOB}p{ibOR5=+M%D>6hL}4&GYBqLG1q!i2lwm#ca-ssSQ#f>5Mn@RXFL zIngC^+HUHQT1goDk+SxZM`Q|Qd+W5t6|-9w1VGVfG;v|<8JwE9d=$e%+TwOK(lU%s z#mZKLKaG2q(+d{myaLeQ2q-Kwg*gxHYN|PtGOsyo4uVIp{Fc~Vi&zkq_MPjI=$HGH zb6ByP51ecJ+ZIHp(6*&BqFO$u=ahJdtrI4?kQER$sdBUCDImd>Zm}9%L3n^ms+(l( zuX&Wzpiv+jizl{7N01!ffJvzciS`j;^VL#%W+6>#!9*VyeaJG+aOiX z%i4I#F!1ZFpq`CFw%ZZm((RB&Q@?Av+b2gSj{(<;*fr1O*V9f(k)8LSc~_s5AuMB= zBbJ$W8jcG}_V`b)IqkLaODS+>%ZZ3<+DJ6p(d+f_UQi>Cf;9!|_s;`bA?K-iccooTfWet&l0UIJ<2I8Q3?Fn<9)>jx~vJ4WnFI z0nZWdh|pOYg`K^@r_?-M_>jUm?& zo5}+&t7_?M6T^o!2tUYZz4ol2n_k5kw!aQCC#2``9Vq+&7Zc*D4HI2*c{a}&<+5*(c8kSd{z$=)5b@Wug<0P>x@mj{{8^p!%uFQ3}3<-Y6V?FikiRMh)d-0LcdAN)O0>PjAIDH%1zLs%W~Uq~&tdQroa8 zoKgsgaWE3)`e+}OSLFpz^M%%O#lif^lJr~cOM-)ij6rA<+>>@uP0I?%#G8+^Cs;Q+%AhNqhs3Hx;%lrukMUfNOK@QUf%R&bz^;VV6v-*>f-udbtb-%yMh|_n}rEm z=cBS)t88h1V0S^ka86%G!d4tpKzR5JV-@{y2N@O;nxMeK@55Vc0S%Z{8g81g!)9hX zd`K#4HyEEPfW3mhsm-2aYx#FXg-t|%Ab;V}jAO^1JYPOruQO4#b(Pa_PD7>eT|m7Z`nnCu3vEM!)9(M$<2;vK$uONH1K3Q zFpT>i+IpmgrirO_u>u~=tZV(6n=?h(iEvj{Le7XNAruk4-N0Z#TPPslu-4d%lsX5^ z*v9@Yo`E-G%QI~&OC|rlLo?ve;QVf2Y&M?|VG=gHaAheKFF!61t~Efg71kKPdfUQg zG7_Y;A&+sUp5Dxbr?V?_OS?qYAz!nQiB+qk25OzIakhK2M)#6^cTh>_VfHFPU73?J zB?sw5cMy4kUA*75^U6ZtW0OsScj~I;DIc5z(oP+kSi6vb^X*q&ozA zrL{37DlMT4Bif6@Fx~Lm#gES_>^u`UK<;}F(jYxm1g0Kh81n21zyc7&?-z@*vP!8t zeTwf^oTOozE{!_*i`7pCzpd-_j>`8vzoeY9IU~nu9ZzWjb0PAf$OB<}eY{`ifJ}2@ zy?O?PaT;#4z|(=fxsgIQ@?NoBC3O9u_->Xi%c$?P!R14*nduTtd(_y_O?Hdgd+YUH z>XAMwj|t2f0i)YKp~A>@Dx1Y>lkMH?am--DI=Z^Cu8;znLHp9N@|Bnr*yTc^!l-K@ zD9!!9!*Y8s7N?n=QTo0uWVX#S^`rj)|EboWbw4ApG#(#_k3|zoE`HFkLGJ*R{YwtZF95 zg)KcF%!QNl&1J~YgdV80fDJlcFO*g~x!G*_%_3L=lohhfAU>?lE=CnrW|q)gkQVgW z>I83v;xF!MiMD*2BkKb&4+{*BRT0_5fxudb@iGwg7Jk4va97CK+!$_Si?_OC=pPSj z{RA8JnN+s2ldvqq!uF4I=^p<34-#V!MIDTC?&+LPPH|+3LZwX6@}u5^2f*-5;nq`5 zr64kv0ZntzLWe{!;dE5#bX4eJHGnzb*Ddn`$TD@4QZ18}w#PkNLVosI_HHyRO-(uJ zWH&Q6z7RzVZm~tLvS_W5@>ejc*GfS}iLJZ|r%L*OzY~%m6q^bYlN^|NYEzSM6`egE zvx|a`hSHnAFJIQZ_cLB(QrzWQE*$S9BLqXyFvtS)GQ!&=-D`br*=(9N>LZ zqpsN-*)OA4xwB=k=Epds(OikmR6Z^VO0bbi;o=P~JFF916p-GDYjxD8yf6wvKI1~x zg*KXM&HPqqMo~#MHkLF#u+HMj3&~yO66Zo&YcCQ}^eu@BVq-*ph9MFETKWZ?HZraO zy9J>pf4ETW@10*{okaGULM;m@#eXrLT}85Lzw^G!xc^<#u@S4$EO>`Awjg@t@|n_Jw|(XC{S%H96C7AaxBu zVbfdw>Nhs)F9JnKL6?g*6mmLq2_6?R7@K~VWjYlM{N-Cppr?d)9?3AUS@cn*Yven% z*-H^moH5bEJ+uLu(0o_pK#D~kX|HIv+I{x|q+{ON7QH+=>zKWe_hEmeXp*S5HBLn< zjDEYl?;wwn zrdUqCFL5_8t*e=XR!Ji5O+%`%I$U}b1ZH-Pb8;pUpU=}Lz+6{#O7aCIZDb&^hRN3| z@yvhuaCLnLpP%~KIxz0?2x{KQ|=S}i9Q{UOMsPCjpzt`<941o357gTR;StBMdfdAH#)0s3!YKS0#_g7ZD@qGP4OE{DHi11Zp`>^f9-s=^*nlluy$$8>f) zD!*lka5IL_iEno*f{T>z44B=k+--l2`A3xxni;yeC{v)5iP%P;WXh4vxtqgtXrdpy zFe2-fb3fPS?eqBpb|7cdoZs)~X@Uq(0f&tcLZ=S56LG=r+L?^*cK~L;x@8mzC^;x= zqNI`;zgZfC+>H5pZAa7*NQkZk!w?luc-~%%N)g!&F+$nN@jC{znRX2UUb5;aIw_}H z)MhU8!zBZAxD54lapZk#)EcRvwG1Kl@qX$3Dso>!NC?&*yUrTPpPv&ESaXfOpApBJ zKgAQZ+tW^|a{f#Cc^?19VP=3`VdUP#JI|V^y-mUue3Masz|NBm`cPKCwatxIrp%`Ez(q0$e+Wii%N#asxqE5 z%NWV?ZeGjm9d@@r03M0QlAdQ{!m$o0gh#I3XB#gW&K(A+JXrpVYT36w3Ma0IyByuuwA#$I{m@Xj(h2 zKPL6s3VHiPH@|n%go@S1iRQ(pIFeNEeB_R z9*5PQ{SS{r(x}NnAhnrAM}2Flc4SAyJWOwn_;~%?5na@goxcgXPh^XTyHz_9?>KKn z*(^^Sxf^w?)P(VS)+o|+y+2ZBttuA6YrY)GoynfumV!G4D2E~mNnt1ZM{O3Su>tnN ze(O7Y!6fNwD(_tVXXT?*>Zi)s%P;I{52){#Q$3L4_})rL{fn;AVQ-`N7L*K!8lijK2s6778p#h=t=yND$PSJGXB4<-vHsA)da z%+Og{@l9ssKOF1FY~KS&mhZoc7c?WQI~F*G1(JVyV35nw^4qEc*Hg+V3($YO^HR3| z5c%)$U`mNQZ+=dOu#4n^1R|)7z)f4u*C=7b3T;6pJ6FZU4w>d$DKgmABpLKy(2LJ* zI}snPV{!dh@Ud}XvtuWgTYs)wh%L!?JtoGlKUpbL7c!#`)qH}fpU1j+6lXc8xB4Yh z0tmuAeO|6KyyAc-;#e{Xr~GUsi-0#Nt2&7+L65YBn{Iry^A1>a{i6N^=g8lX ztFE5wF58~L#Q?XUu;7pI3c!a3!l%d=-0VT^&Q+_iCo3KU9l z(o1P>c{zrU?y|VpbYhx5q3bZ9R&k%SwEX*_hCmG<7Z4gdx!|wa=%!OYOT^j2A za^Tc+MJ8$n0qMv~;_}Q6BarB>Y3IypG1C+luD83h854G14Uy{Sz6h9NFD6F>%T*_n zkT`{SncE*>f!hum4Pf=cHo@k%P;NJdj}WaGJA#TX1pL8;5<{PJuywn$tlijrwK8*Z z4Uc2*%5=6glS!2sX^j&}p~pUwkVuQB;L47W7QH>(=(*W{NBfph+Hywvmvxu2r!;=d ze@BV-TAvPFDda$!8Gsl?2I=`UGR?i-`thULDxK9}Ac%5~J*zEWO3?9bt}wt*!Mtg1 zNKRAt_mVExD~ykc38d-(Qj1|h9=<|t9MzNu)A>3dd4G;A71TXp#sJJDe>}xDyc-z5 zqV2P3oCDzeWDHY+)q#LJ59|m*LYcsu!I+pQ?V@*HKcl#&#Hv9srXBo^(1Zr;Q?oSHa1Bf3^Zs*B zqCO<4ohCjD$ChKR)nxuPqrLWS3oH-)%t8Dp{i#He@4wq`AA8 zxHcuH2iqOvIs!r*vSaU|D4M;Vz}?Nh6^4|i^Ow>DL#jSrtKkDHKbB1upj5>n=*)8m z;^``o^c<+b3F+gkK0NrfBJ};%#QeQtt_xG+DH|liej94`B;3t)r_QZ``N}XF$AyU_pR@nN6Z9nI#iOpV5#M&r*vDTtQhb>s zXBw8?mB|d*EyS(!(yykt(aVTSY?tcvqwB^HCiv@snq5jXvIK2(ZL)6r+{#4gRxN(- zN@u}BF(+?5r|9whS>@q1tbn!yXSN5yz<)HLBDiA4Po#|D`8S5v7JW5n4TokSK@JwD zRJTLb&MpA2SM-t>ERJ}TLd>cgBO(~Rvbg!2spVXP+wEhHwp<3T>DM{Y>3aDqJnt}ol79?BA`KIH%*Grj^S-fx~^SX=JPYV?RNZ@LCZ1L zBK;*|A#=6LS76gYurA$kT zo-QEW2w+GTY+D|NN(X0p;(d0sovb?63SRUvLe_-##?;vqA0EUsv{!Qm9d|uAN>bjB@;n*i~`GQ}EIacE)^Q!q(pboYNE_r&80yMEa2)K1Zs!x#& z|J0$Clx!&&N*OQTV7C#`j>cNh<>d`PT}tzO#_C>;83>wzX!rdbAmosycz2?Zi+8z^ z{ota*P&v1|(zg(0vidq$&n=a=g2`rA^t&U`jr==z#08=Jz|I}tQ=DD{Ma8PE;uP%R z@`7rzn4DXN<7)1hk)E=jYHvNDUzU&6W&n5uy%e{bU-r!hYc0|#TU%GaiLa}wt|d!O z9=9d|!|j?A9X$%KJzUGdci-V+S#(wnC-xpLz8xl4=)-E&L<&H+X!0t>>sb5qmMHF= zydn4<5)o8=*KT7QFiWS6yfX%0(*W_LU}dGdTjRHrIAe zG7s5nf%CY)R9c3n{qJ*7hjCfu5jmhPPiSx^?9@| zM~O`KxqpE=s1ZhVk8)#sV>#rh@r{KR%cRP~K-G1WBWDtNDr z@!2f`Z2${q`O=5C=cET6!SFOogdZnT85C8No$c4cA0l8WYC1_iUA zh96OIP@-(XkmxdcU;MR~@lEI&0~bGObOuT3hS_jSDH=@*J2E)5&q;fT;j=z7)?y-7 zd06|^6ddF`MQxa`WPo%Re@Ah+T;eZ#|JgqWXBdb9kJ@@cjR76$){ zx3j6XP?I-f&0NK`uk2G);Fdi89k{#>0NEVWPYxz!EI{M zbjy1n)Tvu&g(3MkB=@XAE_`kgmvfhJ6HX>+O5&g`g*aLrCTC6?UKdRrOc<;{Uz%%^ z0l|}5^hFjZ>1=U-BpT>HR zeOlzIA4I{A=0L0fXck|_ll>U|-UzW$3(0B0_KgfD_${Ar$FAH2K1XxXUYXs5lNe9#v$$Z5`q8!n$d$pea1sa5o=aTjP3R(9e&0$%N?a(r9 zoq)~XWN?(PSm`E0{0IB)Sr{oDgL1Yq7kqcA-O1b<_brt7iF9^J@-Ni`T+n>{7@o)! zwj5-DQ2a1DUD)8v=IcVDu$K4Xca&0@>4{J19&H=e$=|9H)Bp)!l(6ZR{@velUX9$X zi%n_BwsUrHT-v}#@66mEjt&oID%!VBO&dn+p8&$s0D&^{W5A1l0ZN3@@aHB@B^Y_K zCmU;!NZEM^>p_K{9=M&Lg$m$U++~Fr40p=;`0g@!)_D%gWk@fnJ&@&kYzF*wXT0BB zeFDH{5`ux`fw8O8#!w)@c#(RXe7WHF2ypTTtDtglf6MZM zEm%Z0vu*G!uUa|4I2MpA0=%jNy&CXs?Yv&YfsuWiY+QTU;GZlywje4atmozA0KI@i zev}7yFB`#x9alf5f_&+Ub06+rJ0ZT{0e@K=zz8?<+9usx@AYp=J|jMLFH7xs!@OWs zlv!t!?l3@pP;Pu9`+n2!*fc!4e|#|>e$y4J|Lw^4-(A1ShN9~cq}xG9-(i*qcs`E* z829haJo?V=yg#=)Z-IMJQ9CI0yqm~)4JQBv=@s)U`jbQ9c@oZdX-~`|Ay3@Oa7N%` zIUHv7r%9vT$$UI1kRvi?rEczb6P4O+@Th&G*O+@8|0gO(;<{>fr z^F(UvJ*PJ~P8{k;A}Z62pFQSfvPFoIcuQlXCh2MXqyZ*n%YLUq#uVBcLw!v18L0%ujZOeW;nmC6=P>eV0#l@7 z@Uh^ICPLEzE>=E@lQM#W@q#Pv3&x20w=#@Mf{^HvH&}O|KTYRjUGA35TSV3s-?qvX zuWy}o^C5UK%#_;(#G=ZBB6&3n_UI(Se3=Jy$EDhadDqULS!otoa&urHEU|Topr22E z*}4KPHQy!CUwV%gp2cj0u$Kw)XND`6o${wP)!BbfUh_YlVw~u% zmy&xm1W?^yAht+>`~4ukaq-#G;c`Z#y1I}KJ6WW|Ev+O+Zs)5q7c zC>#3&e6d92k?8HK3>056j@L5@Us<)q^7=KhkOafc8FX2eBi!QlTOnN{C>>|d*n|z5 z8xX|YVN|ysX=S^V3M7xEM9_)`!^hdDbn?X3BA24E_2&cd-JPYup<&{cN+*edr{Rt% z%YE?w)M5TyTUpgxuHV_UM6dh5cm5nXjr~ZK*fL4nKLrkQ8kM!*ig-OqBJB0HYU}{`)K=Bn~df2l2>^VuP_=w$dKe&5fCEor+p6q(li8`>ZIdV1xB2(8Y~+Co?8C zGpz;6t(0iSRPx@z3lQL4&*C#3%qoSA+gIDTST48-TakAO!L8(vL1zp9l~JF2LqB}B z;U_#e%|Jw+%20luJi~x!|KA11U(DTf?(#y}aM%tR4zvxtcm{e=IlX)wvQ+@ySuyVfx#UHcXxL^xVyW%yX)n7zdyGs)m5wZ&gvwU?ye+z zuf~gtIpF(k!P%lik9#~--Gz=Knx^M|-xpS+l`q@_5m((f7KHFwuEokhs>8zSCytko zq()Vzz~v;+Y;*vgR5bcw&{Gi-20s0K^)Cf}tRwZ-4smDbcRIOfW{8uU+SU(GO0}!y zY#Z6*m>TMaVpW*GlaTB}8R1UM>hU*c{bcbshF z(X#lHZW&&P3x47grCmfIsU3hEVtDd}7kueJn)`nX@Kr01N52!-!cec)L4Iwsh%UsS zs0-6L|MEp{A}jsJ{-3AfrQoUWyp&}Qd%pjI9PQ@>PQeUIu+tO)nug@K$d&oGxc|8c zH;Vik)eSTlC7Kbmv@76-Q~$__`l8d2j98Eg9BL@nwdW?)XNi*^>0e~oDpbO+Fy=91 zK-Zwd91~P+IdS;kSUf81D!|ZJsUw#g^XM^9pb#@F1ZkoxcWV?vE@1exoAT*J4r=Hz z%z|5ncCDEA`cJ|*10`U~DIU}<;W?i8Vum#eg%>d58XjV|XWPHI2vi##bS0E~YXxRP zBB+l#4Qc#L4=BSerFIeMGCKI11OXS1*hE6>-|)qO9R&khCS?D6e`M+T=wC_*hB_UI zm9$cMWCki@ihCEMB`i4ZZ{=#0W8a3JnyrN}yVD#T)iS4MjcqkM{R{*F;<J-*Z{iPMx|m45J$`ZY$I(XZ6h^G0ThYhr002BjZG=J?GEUM z50L$8>nuEXHH85TV>@D}8PV^Ux7yjC;s>pBGED-wm{vm^9|yM!TO1)?>efRp^Iks2 z!aB<_hfN7vDjq!xRf8Fz#)nx+&3BxFymsk9N<(4}WKM=+W+LR;`7~l44qnZ3$0Uus z@OXb6o<`h32|tMR=a?tE*Ei8%gCmFIB^4r>-6;{x`of+I+i1#{3?Q4}&ZrH~_u*D0 zFh3g1E4K6BcSYvGT}%sBNp>v@|hnGM_3-`yr$MSD5bY(BcZXpKF}^iU4a9k z9Xe}F{xvwOhll@q9Tz~v4RM|8EBx@-v;8fjZjg&83h-3^R}6>FZ7;Y2cy1ewV!{Oc zG%=&D5Ug$ixDMP}lT6%><^q#b*;MD>>4oI3D z{(8g(4f~(pPp`z5f@kPZ$$G23a{e{6Yf+pPkJV_tmf@I2i1nSx6^~VXsM!X@d>`l))7#FpFHeW6TlmMLr8f!w z9}bdgk?DP2V%8oNX~JDgMC+~5-ZI8yFea$aUZ=S>f)oAu2fm%|j)>@%iYZrWevg7t z$C~`ukCa_Jlihk`vRgjLM6%ociFeB3cC5XzbTR%;uBD^KwuC#c7R3&67N-6pi|)Te z>7|FG8OPH9T6$oG3ivJ<+;Nl46Q*+2s6|djGxnwbwK6KJmguVcG)_%6!T6&{KTJCo z>J`rY4(7Eb*j!oqHq7lYhlQld32CaXI5*Z-BiF}^JH)4hM1kkj{-E&5y}hu0Lz%7Y z`eO`DV9>l`4Q)l^<=*;i?bFKZeg1m2bJg9hVMvX4NS09dnP*bR^FI76SF6GG0`PQ* zE9&VASblvgILlp+26BHKfHK55O=NjZ%UaRsY`cltp(PmnChzdiZi(j9!YImOCvi3 zB+992HSTX0uJRTrOxW~)@iqG{LvTYlvExqg)m5Q&@lH$8p0?;uI7KMcR7LLgK>^gB z9q{2E_|}CGDjc&3<4($wt~R{VG#mcrRg|+I1unLobcEejv^z~6a7Oob3aO?9Mj6rH zJie2&2G8G1MlG;Nhd+%IK#1An^`F-@eSr#mh(UYi@jW8zSu!8Xpf3L7az~TQMsxH| z2FMr&VH#f5S++jg9shqUO`@3Y{Luc1U~7V%$6QE`;%fJ_!tXxOJn<_7 z`1+}-g`lM`I0CiCAw!)}k3iUPRS3uL^9B`>HKqagVW z2+)q95t+NbEmA5-R-JZhy3n;i)yNxWW&Nz=*q3A69h42dp5^Z6M|f4RoH{x1LlzEe z-=&f@XNIaVX-pXA_`5eg8QHqr#c@n2f)DVK2*{dwQoV!hR*c@b?k)O#W!{XGeYx(! ziR<~GndX8OoyCVu7iem~ue*&njESw&Kbabq)cz?28|MjhbX+PlYY!t8NT62s3Irp_ z3N>o;t`v!Ne?uw-3&zFY$}#fEB)ff*SK98?lc8mPdPkpeKZ^fl{^X!OgkKzhSlvLP&I@-Q+g7~Y7n_M#Pk|#f9eP9WW)Qjp< z=~4cUsY)QETL$}FcLnC8{nQPWE6^dz3z#pOi0D0NK&`1H0 zkWcA16)~X3;>;M@Fc}zG6(+;uV>S<`QRmq>);XXm{AH{?QOIzx7GZ9gU8eCdV=o}v zmw;Z{Jw7wqIaKy{Q)Xch4o&Zoq4d#W$5W+%+?1gz?*Bq|>|8U8&#pXz&Q2`Xie=sU zomzI6RO0F>8B%Xk7IuNA$YZaROmwwzp;_w41}e}bJYflaI@tfSN*#Zr>FVtHx;rMI zmf*~kU86&ds>*-@Z_?TUjdwz!`}slaJhj7mB3uqS;mynBm`#qt9(n z@AU3O@pEFe({&m<5sRhT?suqMacD{0PX6BSoA&=JU4rY)c%ZX1 z_>Z+|Jt2+0&0VS5X?mB6c};ye^hF(QzI>r;DOat+?^>b%@dbVzK()pby>5YwgsWCK z=b$T8=IoP4S9U*Q0jkxQw9FH1M9KScYhHhG$M^_b(7AMN!@oc;Ul6fvX^uwbTJB;- zWw$81dt?wg+f8JVp+}2IaesojiT%xFWz`rXvY6!l4C5>E^{xs+Y^2dYJSGIg0Z~BW z$#|JgjCX>R1obS1oD>(JgSZesfxy`mV1N8mtm6X09Zo?Cu~sO?H`%bd*+B%oDd zE}O1$?5to%Ft@u4mn~m^9rm$a?ikb`9_mR1jGFtIpfAhY+c36FwTnPFcg(6Lcr+=X zWk56JPS+`BX@izj>h6Y-T_thKi_m=K3##1xV`^w(*_id9Yixob0eCqOty#Aie_(eQ zv_yER)kx~--LSFfWfhd{O`>~Wk@@Ul!Ep=H5=y=Fy^HouW(mdfs852L@Is!{m9}QK z*NVX=RUJw&(5_ias2j9YK346Nju>Fbe7LYn<45bzD*Au*p_W1P(k_12m{X}xf*|v; z!7iMmS03+dQTuNkqRXm`Wf#CIOiTUBLP)isVHP8_y1$-DXjODTGX#w4Dfy3s<9|he z>H1JBeZ30?%&?{2`jBCFs8qY0m(tm{=Q77C(Ex1_jJ=fcpZ}tT;3>cu$>8lYJMs&d8QPujsL~n-bf|J(AMj1jZ&YtG)a0XH(t&g2Do>qY}I9n#l|3Ix# zBrbjY7|mAc4yCT~w@zujb{DWHzl`H$0 z7zU`?x!@)Z zl%Mbl5*GTPY!pG#mhwazhcLEv6e*T7JXZKeG)cX>!fzq~n#Edr3ahzSNnLsF#Px0V z0N;_;`#>f(Z`o1H)#jJ@Sb8CW(KrTAnHjFPDR!^Kv$@5CArN1)49`WuGQm7J0$)+y z&ce2h*Sn?8*&T6Q{9y%^BkJwEMc8&I$;XtexI(7N`&aKXlgMIZ`zD-4i+u;6^-s#x z8EVD0N73#2W%{|(YHtH+gRUCy>}8{erRfT8W0QuzxNEc`XnVHGjm3PoZPA4U#CjaW z!uQOec%J^o>xFK4e$_uK{MNKwdh@Pg>z4j8vElpBTYFlb=pV~3Vr^QHudqs0^tgCg zvqm0qHK6G?0k%C$j!gsSO=W1gFud-B6kMv|S+$4yP09&g?2>y}Nm+FxrT!A8L>Vk=ZJrU%dS z1`y!G;IVtPt@G2(>%H?q;B)dC7D%w!#`CfFp7GjA419O^2&(#E_Bq{{c;_5&?Iieo z%sBkGzO3U1yoSscJzRipp4NGn9k*8LE-$@rM>|(9v@ISP&oI{KOvz80X=4+FM>GhygopSU$@A>29La z+HY6WR3APb3$Dj`O*4T$hq9f|4+*@{r0=>9(96xTStA0U*KM5uZ;Q8u&dc}f(Yi@M z=ff@#510wR{qfY@W-4n;%Hnh0du>~3{Fv^o{!n>_a;wnlIJRjwrKM4j$*aT6C+ z0+WnP1D|nO0E(^}2Zi~WsxknP3< ztlgN%at6`z50z1G`9#k~oWaM-%eBtfW9>qmwkq$G$<2s_^wWWH-obL;jH=D7%JTKJ zD%`9TYm%0K=U&d%rJE_VXWFm#7pJPVl2eaT0=#V}$*2PLSXox&ReU2V=hvFE*S%>M zG+%PFl7fmh*u4hwuBIcYt#k!KE5e3OG zQuauh86kF2-^fO|BG-%(n;l+8svetZTVN=>GvxV;G^+_yajpgK*UbCwOwS1T(Q*Ws zOJ3l&2=>9I5D1pflPs!qaH3b$PY4@=LZ!HvZ%JZk2L1c60Ts}868){%za}85%&+SR zDqJ_Z(rACtJ!!C@`)yOY>gw-Lwfu(APy9|Ot>VHVzVUjYVVgXS7@27zMYO!-Knm$* zCc^&P*iIOeTDw?BlES2~n?bFCj0^BW*u^_!e;0)Z99V=;LG|pD!nv*Xbs+p)1ax^K zX2mNT4~7m*Qv0K`IHGxM{^EV~q@xvlq_x z#p&YA)PVn!C^i=Q4xLwAo3(`d!hSnyXm1xVKvr4Z1cvbykTU*@G1o-jByKfJ?ozKm z2I7^pz%=IO*{CoW5Jsq2oFPr$gXnGnN6o(kI#Gj6+VB4x{w`9?U^B#Iq(AKXdGdPQhZ5-x`9Q zvUvyT9c~J94&PAM&Q(7AAB_l6g;4e`ZF76ERJF(WsF1Fo=3d|MKZP~cV4}J+KT+0H2uN`jP3?z+al!kxRk3_s zU;D>#12zjnWCEkDP9C;Ioc9bE?Dh;QOlr=hVAovxi5(ugGkv4G>2v@#(Eh80I4kmd zCRvpL7$mmCG1(Vd}uX7L2D}?<2Fx% zu>(j@4;Y-CPh1!3;^UYzt)Dd723eUH11`%=z=U@c0ynomcT^4D(Z;Wj+irSbtPNOe zLwA5_165uM%V7*2wmXR3?{O5O_4|_opAg1Go4!F+v9SecuV<2&J~@DO5%`=U1bC!F zcpQghrv*o}x0oPQNmAwzK(t|c)9^sUs zL5w+^dwwfhvkBQV3{OsHD{qe)?Po-!on1=tjaCl&9`m96Im)zrqb>b}H!J6N?*5ye z-U8(a074;EKK=}nBeA2zGzAl$s(`>4F+1noK}PCTgnPsFQc?nk(;nOHZ_Zafs>QIM z$WG4q7j+r0zLrHYUve3bK;egbJ!<;3D<}`7CvXo~Z#~Pic30jpPjcMt^&Awot3X2v zB|@S13>R{AR&wXS0lFUMT2qxmfPfVS#5lfwnEP+V*zQ%X$LT_SJGir3>Q&fywP@rUH&^vgus{_)_MV2V~pHF515zHpde z*@}6GK10$RfXJBNJLpKqS#e>^~e1MBA>b8YZ^?y<7ppzt?qRB6!+7QG;T*pk!5DIU(V7=lonyW2puK`D$5MWH4SyS;>W?+&v&&4Ds;bJ< zk6m98w*egD46mE3aeHJ&RTQYcPIHZyf|fTnX7mcv%9a)$G|lxXh*xno1+b_F`;X%9 z4#DowJ`%|;tII~SSfW+>htw<{Ip27$b3rW>@B0l{>f0*TW+B=Il7j-0X{d^pc_q^s z;Wt^)p@d4g3t=vhR@d&fBqD z-=Ege$Gj_x)`0eog=1|$@MGO1w=>}l6i-#{kYkt9tmXVbq?hU!(_^rdg-BJAMGz9} zSBdqaxjLW97g8EDOlu`yj$F5$GO2|=8awX$mnOu!q`(KhuZ;<4VX77!R2LXj+i#Fn zBuQ-^6rI127@#)zm?)xbXtQaOy*f}FQ2t34=_Lb-E~$bH3fz!seSl3Iw+H-j= z9yh)BL4+-3Beo=J8YCz?)Ky;sIxMe{)Ly}m5si$)D;kpcV4cU+E1hr%t^kta^D@B+0y$v00B(hhq zMnWw@6aoXosFsNj^vcYXETA z>2^#o_T160(K)_n%|uwG=t?y~WedF4`9*lqc3ElJ@hNw9w|e~1@}b_(HlpK=_nfWk#VOiR6*fuW+JFqLy#~5e zk)29fk@CGsUn3;}eGlKc%DgjxM8(k+lXp+(92p!t8VE*l_a~kH zin6=SsfTp-cL2^FyT0;O2&$@iw2*sy2_6<@UpmaYJlI=SWf3SN{Afy=CPuqohdWxE z$ugt|gKz8+uIqKhrH4Ojxm);#gzjwh!0`zZ_I*aWLm+0RV04RT$a<7C5J~s?8;6-C z2_o!rLy45XH?KB+1>Oxuf~7A@L3sZZtN-!SjkKpA(JJ7S|LX`0$ z$$?+0FDwd2p@3EOaHHJR#tmk7-W?DBxqNzjuhpIpB_g+r0frIeXRxbM9zn#4#Y%oJ zj$ekQE-pC95i~L&09&ovr$k{7kJzI_r7o>J*vaI(K@6%na}=x@f*yUe#>C^9}DK2SNjji6c?C}G`_ zEiF&YI(>5M%jPCf_j7R!2+@l|Q}m-VZrM(9@GH)E4hDuHpI{(cq&sL3CC>vNKjo{}3fz}F_;p3d6@np#2MU@WG0(4wxxGO0hw)^dbDvD!uA zr_L7R+!Ey7+1H_b9TVCEwX(nupU4+1XgEp-1I8T$`Qg6aR!ckh$JpG9uM~oPog2xr*u94S&U;uN1oCulnx_*j|C=Yz2g#}4O32hX zvf>YH2!{I}jF-LbsAd7iew|;g+3*a-G_i6Q(Cs!Wti@AYmvWYF?(8?}>0aW2echA8 zAk!ASE_46)4Scw#;-D^Vdn0v^7E%9h{~6VvKVLZB_pyVl^mmo^zS)01D*X@@LhVjI zV2Ec@+oH-3i2N=fO}~bD7r&7BP3eLl5N+?SCse+Ht<@@bl(OM_+8Mw9I1^}14}ARw zg6o=hJ5(IMA_T!G(843!{xL*|ImOS^30^pMX&xfF2Qh&~!k7BxSKqK59?k9!#gX!X zvXGWXq>lok?JvLYeZoA(&c!t$%W80}wI?{3D!$OPA&~KD&_R*XP`*S{!&RZTojqrm z;1O`2%TPg}gkjQDzAOF-7v&uy2BBCRy=sgBj^cO^XSh0}g>eGOs!Pn%kBHz6x2@}O(MAx<-{4Z6JVLA`dFw5nXF*CpAgKQg#IB*$AAAt4`w+L&ky zI&3i0g>0Wj5=cLHEsfZd)Vj2Bw6g5Gl?+5TESDHPMbF7T4erT*9MX4q|Rs%+^WJb%R_7{&<1rM^PxNry;G!f!k2P5Tva3yMftGz7zi z%ZWM~^$ELG+J<;C4ap?DT=@|?1H(-VKjolrpzvex00S!pjUkl0c=EY+Q{5GOZ?&fb zF*8K%NXj|Kfiu@J>hMP2F;SO41~GIH78=FlN0Es{P=?HkjfQeY!ki^De!``4gkh4_ z8G@q=d))*Pj9s=^nO{24DG-I@ZtjbgZ$}$xJ{?7!AQ!Dh_QrI!g5f}+5}YN3{aS%V zM^m9;eJ@D|m)gP$b8hZZGF-l!v9RE-)R~zCPL=y-7x!kP_%}fN)1nvr2K%AR9h@uJ zERRX|hvu1jxQuXf7>VWccG{bdZ+3v^pz!G^o~zlJT4kqUr`n*O{`Y+;#-J~w4kYyr zMLs%PO5{n17AM4FdS%-@f%;BNB!rr)88tM=#tIS1nZ$)mPh@?xLKY59KH$&iO-@ac z)$tw0s8@)vhA0n(Hz5&S9oK^7;3VXJimXI_`h?_u z@yv6$IJ-Wa+A~3AQ7Y$*Im?W>dC}69LMPm)A9PeVR`j?w! z*Le}cPGF;$jjbx@{`l9CBwS@QA^wgdMl93lM+yhCvo$z&N1&Y55Bn>@0m&tZv5Iss zK_oG*`p5UFDe2{OUN!w}grdvb6}Lruc>e~FdJa8_QD0ni!68d8CYZ1YgT2V~a`^fE zPBu((9yaCrUk2e|a-N7|W)(+fO43~7FkL79u)vJ$aCoP0&CC^R+Ne%Bs!er=4!T2h zZuvFZ^jsJTIw(|_n#f~7*v4LcpG`e|E^#IR*WQA`0H z%|tyoV%O3Z*TP1f18<bv6%w`_O$&r{@cQPbM!jLo$ z&nVnn32pg@tZ*bc?3T?6zln#vwm)*!GJ@-S? zJxy`d&`dqGz0B!v>S)Z`iBPi*PgskR+oHE28FL1eGn~+}b+i^Rkti8>BD*btM?E^d z*FG%PT&PSR-_C!Oda1gW{UaoRWq^BM3rrTF?1MvD3($NmbG=qr7c{gIL-wUF^QkAB7gR6$O%P)GigTP}!; zyFV|b>wv}pALl3!gO`u9&&?csfEQB8wILW6VDc|@cIecAl`|zZbq^^h zQYA01Ccd4KBQN8om5t{N`ldCREk%&tgCvP|VpqYgfi|_NUnQrVq2J{de&3oq&xxTW zI7ULJBztz>*lpL4*~0usb|6y)NFe&<7l>n)EnSZzXk~mL4Hr9vM<`8+fKU^b}O^ej@F5b%tN*p*8qD}v%@S;yK=#D}6PG`6hzkXcED2O{* zdSEJ7>eqg4JikdCOl4!ahoRdJe|z*&{HfNh<srp&j0Rb})(}@DgW78)AK$wDV$g6P1jo);n@4!no4n#ZT zJfeFkcH$jx6s-X!MJKT*d=Qmg^HNMq1ik#6zNj0@wF22IFQ;%Q^slux53*u!Iq!h* z?{V}`vtmRa6-hV3rqRR3lL(tp^Im?Uno*B(W)Ri#&wjE=CKC$(#<=1GeIik_Oz}(jx%nE;Q^sIf1hyQw_bW^sXLGz{W9g#X(LYy+f4(>HYJ70;35d|K{qj7xk~ZMP zS^wb@N0OfdBdEO$ks{_WbJc`;%c?ZDE8kXe@Get2u4lI*PxAz0j1D$+n?P)Hcz|Kr z4NarQGAdbo?U+4lx=)q)AS;64ZgB z6=fc%>vALl*IhSrmJFM1&!zCYE6@N*`ppgY!y4tOm>{htlrEn;nn8udf^)B(CLo?4 z_}$kn)jIcRIf^ z7b1#%I=;ZQ+?GrD!>>^rHs!4ViFDlp?6!H#J9%cdvDSLl5h7xhxNEp3v1}1%BS9}t z%Baq--4^O48~AXmVNE0AJ?9vJcTCf=#jnT`s3A@EE`z!iqCtq~G?~uTLv!TT9^9Pr zZcT(a%~Qma(PW>r#K9HmNM*lM^(uMn^0IY#Ni~%;lnb8bEbwN<9W3Hi_Gd#PX%k84 z>ivz_3)T`#Fb;=+*=bAx555QLupgf7Y7llDi7uxXMvrpKP}?!tr`f5^=;Qrx=AD$8S=g1>UZc>eMKnd++b*w#J2$$!4CBvQFZP<@Uv9 zwJDKe8QThbW`phtdBmxRoj7rMQ0#>m4s3@IZurs(R=ZaXPI%7S>bRMcLT;6TkQ=qJ z2X6U3crRvautcJU6kWk7nqhkcjDjOh$ugmkS#w%hep9-MVEa=N@TQH9gMVBbFD`h8s-9tM!lPhpQ#kUBf#r1~pwPTGm$7dQy(A7eQ9{Bl;CA_a|6M zRr!H+=C~6EWl-IT*$v!Q4P^}pwBO9>W4~c&d?hZ`om-zZUp%R9mvs#jPVT1Q6T)v< zVRZfStB>5o1{aifb%j^Vmy$oVf`qh=$(@M9{04tkC~DdCXB*=D>$d+bmF^i{F5udeDk!lRL}7Zu@DXMK>jDha0wz@7Rm#(j~k zR)>BAHEu*VBk*V~vdPIQUh1vse%AWeN2{srdJ zR@BFE%W!njA?v$5Yn1RF4T8q!q1R}5Qtfj!IvvTki#5v(}u~1;J&Hs>eP>4S))23&z`A+joQU zz5w6vWv0INgyT-5!|T#NuJfZ~qel`uaT4J9dY83XRo}SbRrGSx>)Pq|XiAm!A-NCp z@sic)@h%%saNiQjjY$A|U(qIER%|b8k>f=sq=|xfPcthd8j#^WB#s{VdkN)ODvWAN zfPx}X%&rkT;~8V3G)1@vT4IFidlv%XQ0RaVDczH{w995uSCtpWKO_Y)1HtT7D??^W zdy=!uN$OZ1j2Wbvtv`sDm<9MM*B$byf*V4qIUV5@A4{d+j<4b9p}z@AG}9R^srk}L zWU19*pMMw;|Cr$UgF59ltLn7=I`BSy7J{|a#`r9Xz$~NZi_mK9I|!-awSKW?cWp&@ zbilc$>XE<(wtef$(9~E$k*5qpX_}sh7;M^>-qGMS>)-qJE0x};&*$mmw9lq7ZgdyT zq0oYKwUN*QnK@@hErs)@-lopFX3_~#9N2!4$9V9(W~+Yh;^+*YqV`xPCqZtlCcb(Ht!8F0t;f+?%}_G+U_UuYEdZkp+?gmh?J+`*9vXnT5bWAQj{ zJ|dkkotKm}j`93zhQ0Xr+2KuM+`;}ulCi9ck43_cxy@LaCTsqv#`3W*H9uFG4e#Ba zu6NH)KJRFOh5hR-xo(p7IS z`VKES0YE9$AQgby`!Tx6_Tyyl(Dsl@%*SDmO6*qH(1Wk)H^Rq(Rv`77v+lP>P_UXi) ztv3C%WEqC!ySt$-`F_ScD`P(r2&D9AW4-y>FNiUYWM{ ze8Ag`xW`Y2M!cfV&#mxipvTLquJ^|xr>ySh?Q+YxG5fHARG#vl3|4_=7?=bLR$D!}I^kGSK_$6yiQwZ45X z%j>S~MoblGQAfhjf4`F$c<8GADj;sy!;thZeufuJ+s z0u!d_lLvAY?&TCNySMeDv%?B68fghcB7T3DX0sb_$Ttb@-9X%YzW{l@A5!H#n=zBT z8`|5_IL>*NdX@a+JNfj!p0T%Q`}D9?8H+ZJ%e%iMiXsJq9(PsY5FMN5=l&r2-!BIu zcD#>x*|N1XGwvfMm5)BV9-TTg-7o$*{Y$ZtPz*a1|N@~OtkKjByQv9H$`JV`n( zvu|Qw`BR1t-#x0QkggkD$duSg4!dvc(8-fSBF#yn6`pi_YTqQXBYui5-q(h`TdyAN zxqB>c|8QFKWYOzUu2aM`w7%d-&H$%ZVq=IwKZH2Rf8XQy?ui;r#Z<}g>v={xx05&Z z20^?wPy?|!76*SjZu7TPhkt#qjJPKaJrpjz;5)Y<-B9jj-q*1J@Ma+?>*L|B0g(Cj z(h2yyYS>Ro@Oj&ByiZ$TD;qle4IZ8OMMn*nY-DV>JmY^;`qNGB4z2#51B~B$hR|+& z#J{O0`xdP13uU0@XED_52B+u0Y@^cWA`>=_O2qpjn_>ZN=e#c?zP?B(^CwaG05=Xp zcT>bwJJg^!zJWCS&rhdN(PNC=bPK|5K~Oj{MW2W1H(|oFsBEX;n4EFqz=%D9k)#UP z31zqK^9sMgaZkKyT}SakkRYz!uB<|f_4{_w{k~bKWPrChE48uQNOnEw5KRJJnPmzluKq+BlYW1d8t6MB9tBLVAuK>EwNFpd*Ky3qo%wf2 zYMQQRE^kp*0>nOe-m+r`E@hESo??N8W@o=P5>Yc?O+Nyq{WHuM)q5gc;x<00H_ReaT2rRMBcZp zKC`*LqG6*joIfgPVG4kMZ>9vNPAe{G1P?c(4d^GXcxd88yqW19qAoX?Oy2i_Bh9c9 zYtKy?czww-H1j(WI->7k)tAU7b<<=o3UWP@r2NRDvbL$b*SXfZ_nd z0wg*I8uBET#-BtmjC&fQ_k-*>skZ$CQj{P`1WtlwOUV^{9%vqHR3W{)zho%9fqhg!eY<|w zP7N@fpaqvLaRvi22Nnl*1^#9w$|r!mf>j9dV;fRZB+6%jJ)6LT{idWO0XM6k0eP`P zBv#~%(zS;d!0B2sQ6nE_dI-z;4b^7PLX2c>X(tZWvgMDhajONay#wTvsU?`PW!Ilr zhiqS`ioL8f@c6V?k}el^`CqNZH?pH(5~Fxbak5x)VMJX3^j$m2sHtHX69N@3qR+kX za3$9C`t?XGxf8-DAjZJ|XstCmJ?A7= z==h$X-A%SFyOY5=OnPEeY`Ic`DB!7YFFEmfIDs@RK@`A;XN`WVU7B6-m!RyS3+3{K z-SdXzYynHzE%$Nwq!|EAQejry;laSa6EB1=FwEZxOD|efbevZdcCl`{kmP{sU*Kk^F9@B&pKfjY<`s*q2O#@0m7+j^g4d%=Gz`~ZzG zn2&aB0){62`ahF#UqR!9K(5TM6f{~L+NKYq)=o8OgkG2rBtkn|KjiP-C5juil>OCV z?}9&pT-rppSZ>H~+w5Q@V=AHfa3>*`s0aSE8(3z@Z#nFGX3pJ|OWU)(2911LQKi5N zH7k3BN|=vk0=rwGinmnSonZgvt?bfrVr9W1UyCi&Qt(ImKY!#7e+eeNKMOt&Tx1o& z|A1D6^pt9V-~{n5Ga`1{&t~-l+1CWOlh=dAw`ZPeS65v(jv>nM_ZUSg=+H@6nCNqsHLjEkcPYb?{ zCKKVlpV(9(QQVvz&xZ{S&sZ+2?>&|dX-e!ZE0$yXn!a^W9qEOU>3(dUjM047Q76z_ z5Bt`_oDDC8EuH;pLvi_BA(%te5mN_yNVgO*>M{jM_?#=DJJQI80zCH`ASRt)<33u- zm>r-cuAU*QB2H=-j!-xNCXCX8I>V&y6pYgvhuQw?z}ObHKsO5DPC~LIl{TbM?Kw_@Vr?Lue}3z@tQn384_K?0QHG8?*-n@F)S!qru{*mcwy_qS#mg%^2M?YgONh@ycJB55#PA zCv${riH|-y^lOcMDcCfC0VBe##K%|}*}=VlQ}r_wOHvM6)sAdC0w&WR@O6>Th!&(k zcWmH+G6L>$#_6}W!y#kp>awTa${xsu9?g06J-R&>tR>|)ebw(v&_&7)J2Ql#qjJTn z*F`$UPecd%CUcIUn6ml-!iEM6<<5IH&!n zFU#%L#N=6eOKw7fcEtv+DaR&h;4X9cyN3(4g#pe_{tT}Aoie_dwj0y5mp$KB4z!<2 z;ii42H_<~ou>+^(X;+>moN%7Qn&<<+@XS09%VfZvb)X5kojSs;#aAcMZ+Y~MzB;|b zAPKHBPU_|i)z0&4MADRjUO6!RZ*wYO$6{@~{JVLoDOWO5xIKf2HH}f(b6kZBSB4d) zlkG&<^R*RAMkGlD4sSX{Z7N{M0;*Py^O(Z1O3*>=3UyA}7z>MvYUar>*i2=`H^kRZyp zvuu9ipxX0XYV>?Ulfy_@EM864B>#CVmpPzt-a426I}T_vuuEz;<4^V~>1Ly_wtO;G zlltLdqRrwuw&d^kuZ8_hkpYIYk9U_B&VxZrc6g28E6O8WI~OX%2xhb96@ntr^0^68 z4S)HvbV_jU6eKgeukir_!!dO=T7O(fIQ~h|Y5D95p+>yC>}h7tP?SodNCZ~CADzX~ zBRlQV(czO_Nm6cf{doeaMs4c%hXEVz;rC=Cz{z`e&O$_p*Z7dLu;1SFu;vZ*Ja-m6 z{#pC>JVz$rEb$`K(_!N(2(COzs>A@JysyD)FwiZQh-mo?5r*#D@HRca!w7Dxv>O1< z(beoC7=i*m-?rC*=Bo+c?pz|1cf37q_j5+@8m77{%Ro@nMMr^x$D0Jl|6O^;*8out zg#U1@;`UdZCWB?exz%?EQqK?21d%!ako`@*-O{JvI1^8Y>Og-FoYGtKHh|*0yci z?$)+#+qP}nwrxLczvrCuy+0>2lgu@D?j(~8o}s@|VOt|9^O|mlouX;cBp|;MVbx5f z#+H|&FFv)%&0qm@XkaXAD}SDvMRjP=Fd)CE&;OY(twn?R*c=G_Q5?yU!Xs78Gdf?b zQE!!dUA#L{#Dp=2BWZ{Ez*p|txf@Xm(RA&ar^&z<-=-mc@*W}3%Ic$G`tyd$vi!4H zuJS;(4iQt+Yu3Cbxy}?$ymja9L_Nf9SyBv;IuuPqeB?cnV}kb_QNLca{Tydc4{3_$ zlj($IS{2Iz6i9^zE!7F2zx*e4sc$@*(8p#$pig~-z?8dRy+*^MM%Q>w;E(!Dj*-_Q zMP;ue>N9saThB>MJ${Nt(t~;0If^X??1KB3)P>!da`0kVAi^*;v6J^qju|(h#sN)X zm-cWmHLkmUCL@~5b@N_+d*Yau}0TZS&J7jk`$=M|L}QTVqG_JEc8L9 z+&94V?qAe6`7HVg?Udeq{y|_3e!P=V z*a%<}DHs*BfA#Y8taoFYKvm5G6l2|YM%0A;)_Vyo0-}qZJokA@S3QFYdkJ0{t$VMA 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

$uNbc1hj!KBbBF;;tXFv)>TI9!=;p>#z?(%(Zz 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

HFaNZ z51tY^SXrlYg&+Y5D)SW$5Kx~MlEjEEm+L*2%sh`Ze@E49x3}Exc87?zawqj4XEjgy z``Jd)lI`%2je=Jil2NeU``V&YXhSt|O=$P(3|N-6C~k=*lg}Y@WP2c{>10Z)=)r?4 zd|_oxxC3Et--YinsHiu+k)E2eo91>d4@7QuH=}cV<&J)*72yu}g>uC`QGxZw#Uz^H z&FBvD4>(kTzM;2 zY(Bx^j0IL8Mw*3E03@31EgGWh6Wpd_rHMF}Ql74rMjRX*R@V2Y)L5{uc7W)UFOeq# zG?`%0vS3ccz)U%r_ESi|YO=IzkhlWsQ2RLYRV48>u~C@Lk2y9WnE*5N;QbbgT!^!o-I zVgQGk1@`*HwY6~o8rt3N@q4Phw~r+Z0i?+=DA~W1nBw8zEB2QTyE54JP%IX)^M#tE zT{(r{$KCJ9cg$tpHSa*~>1Ppw8AxyLDAm(6MMOm0pDrWH%FecMqkn-#P0Y;11VUr# z8yMV`2jPQFh4bfRE0rn70|;>Ifts4y@njY_gIeaa^>2!2adUH{Gn*x}sPuQt&__dA9)UKunOfzknlaO4&l^Y$E#AQ zmQTqM{9Fkg(BH}FKsTfaX{xe&aK=hJGJXD1cJIhkZ!rG=(EMLbkY>~Aw%7;vS#W-S zj>c#Tr*5@*Rpb6}D%a)hMJVUM59mY4&Hep;hRbHpz`#LG)B>P}LOsOb{nvkg)+QXs zr9B(YfU`qiN&Wu3QqdF*WgXrv5OFIpVc;|*AS)ru?D?lZbKRq7*;BZy6o)c-Sj}R?O&E=P6;oq?HvF9UrKf%`v{?BWGOTEj zvz7vV^WOfojdoQY1G)*2!%%bYl}DQFQ}f= zXAgg$VF7p)IX5s9Fqe?s`r37rZJ1i*t-4I;&s+XUFQ5LmzR+_m=yBb{I8@X7 znnn+Xy`cy5b}~i>_ciA?*1h?(G_t8H?{cu*9~Us}QxL3LYE$VSBTzcaXilqEi{=_e#Tgz{%*|7fHCGf>!;DU~9-Q1n8Hw-D zv`IviyMzW|g6&~`3#i2Y47d<6uzi}|vMEMziE;8EFq_W>vR)n(P z><`WTZmut1`(aqb3 zSN~VYFC4L7OK%Um$hYBdnrv)rM{G+imuHLQ@;3zia0mcJ2Pkz`n(YXzn=pmsn(t>N z&^esXb%Tig;rPGBP9yRM>+#KCq&VJWNRFrYDnXX!n)FO`8C2>Y#><0o^E`@Tn~Uo0 z2e90|wZ9OmK4c%KG@WzfANBNy>s z$HJ6{CKY4DbBIL5&@#o&-V>{tr86SDL0(=7xJ~ufTD1@fyaCHMh}UJ$!6N0GuciHBk>yS|o<&y<^PGW;|SqXU|VU0Kc|#OQK|c|VdW_D`6&C%YW!TAY7P_iId*krn&iKKSf`Y!AhDYib9P4E= zKwUG~?;n|}-2=z?XTtGA{lKUQIe|odQv61SL1orrAZ?IOdZ^QMevCF`4|_vUSgqS% zvk_C*!YsqpI5m1-W}~;7#B_Y$svv9?zeMQ#HTV*6X~c zIDC$RXh2=B-xyw|aKHG)FyU@z=J)$eqxy}x-LtZuB0!%X12(#TVYkeo(s|fG6>6(| zBZresJ9aFiowgC5fm2|OctN*9gVwD#b~s5`;cENA#P|8;9!gMzi#9D{8+dvq4)^?jf`=vTv!diXu*jCl!vtRBGbk{{=8o)YSs1d;Ri>fk6QUp-Uj!_R9cyZ4 z2hu4qRU#wx?eqxY3v(1|j$D{#rqKxDN7A}y;xp4KaN7rVPMwvJ zv5mbSiw$VjfgY{3BZv>i42`7^7qd9SNxreVI2>8|=#R(R)L3dWt9PTsd9GU(O1Ar_ zk(eHT*j~GGfUi#Yw{reY@g;5jS=stl#!&wNy;#{GK~_v>-O)%+p#?3@uCjnCDNgkoRHlCN zM@ewC@iB>`6DlD_Dr}ihF+Qh++6wyEl>oYUpKJJtFi25)^6fI+J$IftYwWNAbD~~n z%AVQTKWZj~_}l^E4`UH_C{H_hp>6v0_({frmNf&v@(fdmKt+s zOzG4JY?mdIt>9Jn>VlVF**D95u$kN7vSH&MT(qWc^I13AR&BT=UT?tM~h}NcU48`AhWwDjAAd85h zY+f1AmSn48|39YQIk=MU`yQT5Cbn(cwylY6+fF8SGD#-3ZQFKkY}5*n)q$LCuLyOoB2CaWYT!2;wRHF@cdqsr|C7+7-S)=z^d zNCI830X*A+dA+k^V7H#TpQBB-IqfcdlZ}`z$Q5LiMuV8#{Rgd#YtCHm&el9qDr*oIfZ(z%=J zf>=U0ui>gsY|ZPE$eLIU=e!+;bamhb+GTv#>`7p3Se05|aQZB!?be%*cvn@EI62l< zK5sXUelY=NW2zdViXmfcZTJnH9ym7g0rYfiapOmhjzMxsVY&fpzdj9=LY}O=cFCbd zhhM}`YkC%E;B~p9e?ln21oUvj+PFH7optVVtIYKWk52NgvXHMa(ll-cZWNY&#N*o4 z8`z$2%epMIP?WmZ4>5~Pos4bQB!7{u;A_NHh$Hcv-+w1)&VnK6prFoxP+*CS5$x(yo zZwJS)c{4tB^`^8!==f*wl4EzH`wwLkV+M;t{~62~K-CO##srM(n#A>r^%4^xwAKvb ziQDOk_t-JlMWyB@fbxJQWr~KaM{jXu^6y27f+2!zB@*hnHT zM2Czr?S-Z?;1ZnzR;UZ27D^$tQ$2iG~t5a*|7|=#WM%jy}az0lWDvF8$WBa`pI36@& zMhegbf$&8nGd5e%93@WB)$JDfC6`j;_0U|8lX8ds3;I3$KO!1GPYO;4MHsm1K0)7* z6kp^PrNtZNmDXAG&WLuUwHPS)24X<|ZJ;1mhq-RBu8BGnS@T@n7XcU>tH#8=O z3lu}cB26dV&_uYTz{jhr^(|4%4}F7_P7hNUv3t*5@?e~5>r_ZQEihC2Cgv8J;<$J2 zQW1uTQERtu2E5S*rZGchB#u9cRf$3KqLu=M5#@fP7m#B@gEE2fy>MYYYE9(U*n7iS zP;M6_!P4)g-U==I>T6L*$E~yVW!&oU>?q<36rKB8_WtGX4~*vNFxhy97B8 zG=loHmHp%aIv@P-G}8Gh93QRE$G&`|51+WWxTga)o59wG6k6ZSQO!CXA)B-18KJWQ zG+m?Z-XQ5@di`pl{~U58kdcw)wY0DkYeZvkCn}mYFcWKj&~`oGv|d!1lZ$xue9V{dD#D~6RTrnu z9so5dciPrAI1H!)lfdpb(rH4Eh)yf&cUT?<-&ot6>}q6IT-X`FV&|<>g}2?&WZJF9 z;PtkTy&gdwB=c=d?Hhw6r3OXA#Cn z|LOnhoj{)1Y06g_IVd*XBu?WQ$hLe_Aj6n&7crXD-CAHqe5F08beh=2D9dEI z3p2aZji!v3nv{btrJ|~e)Ob=kUnErmmkaBC!PV{aZ@iplW6!$MNM*(=MlR`>3O&t#pm}gl%V>Ts3}Rz=Q#$e&1yf_DQ0N&=+FjJ zgaQF?$Dev9zNwE>=N-~$f*Up9mgG6F*;-Eb6TB(}7H911;3*xWs!{>W)27>}(TcsP z6p7U#ItP3YP^qqeAqv21anG}F$eEvGdB}_G$F?vb{9-gzo9YF!(&(?uDA?Rzf@5-0R**nFNcH>XOrtk1iz+Ll`L_VCuo1fw zf^uIuoelZxr@n5rk#Kozn+e&~!j0BNo84ck8(E_;{rbFEzK;_Gm($yp>%@Wn$5fos zn2Ej7mO~_@tRWJnpNrBb=yLR@lgz2!pz5Vwf838)1_mC0{R~I4_pa-( z?impyC#sAuUn)%mmyZivaA>g)UkzX&YBv*aZLo9D;$J=lHAYInx|`P~YX(IyRoAt5 zd)cVCOsL@EX>hsuuDbnD2eN45?Hv*ogC%feLuvb$qA1>Q`F-Q$b+=H4-T;4BZ&$1$ zwpNS~DG`S5#-bAiTQ;%gdcO+Pa^<8RHYJTuK+t($P4$F#Sk=1d8xpNdOGo~dg2)n(^BYfy=x#vKe-hiL=p6|cYEiX z*%`_1V^I}8gpKLRnSLbA0zGNCB&Wg*$!%}zPLXte21UN+?DnSN4x%Cj<#d%B8*sA9l ze5g+JmV#o~2R$sB3ASC+mfJGU{eS*C>6HYt^5S2)Y-h}jiNWW?jT(`!|DSK#bIR;a zvYR?9$S!sOPB^@vmwx_#Nly_`e}s-;O4^IunFLohKT49MxM8+}^Y z1{*)(bQ2K5o-`J;csgMA_Rm6=Kv*~2pP^U!B4{}h6E9#sSK$7|jAL!Qk!`G`@;aL( zE!lfWsdhKI0ZLxE^+c0gM}6?)oz`DSFXybBYRGPV)@Y>>C;wtWrXI$HUoccIAtPg= ztg2H|a+IIOTsEUeuiNIc9+xF+f~IM$_iVW?g~QQgX%HH%#++edqvBgD@ zF9HFaVA6s#KCHZ)+Nrhfi|CO^B|@j6Tm*t+Wkl~m4cWaiMLfOm><*7LziCl4gwDu%`YXY`FOl?^!px@Zlr_wAE|ySc_2fyI{UI#WADWST*_ z(7!Nm`P}7TA`LAOgX`ORbF}h5!{PQMDk5MyolX8eL>34y6#HM2LsM2Qj#X;6iAzcK zS+T;ouzw>ueZJ}24R(Fb`lqY zW;seg-w&3drWx^c)$W1C!&qH2k@Fk*w=3=na%OAt&yK zRRd=mYmsrNeadj!;=x^Ezyp+dXoHHMzd=@7O7aIn+&(9p++8)%!q-RJ@g@y7oPaGq zsxvDJwK`ujoG=&9wtO#W1ZGZ$o9ScR7Z2j%Erpz0mTpgIH{4p&X)99vr9^A>%wZW6 zIN#1Q&b;4$T)unaMKP+Xf-?ld`1zZCMWrugY~NsiG@-t!3C@LF5ZW>-DyscyC!%@% zq6bz4+6FqQoI(S}!NQFihT8Zo{*9kp-ZanfiI8jA%FSMOcZ`KS({_Vx}DiEb{Or%1ng z*B>cqaH3qYM9pc%kb!Lur&ql?+(wM>!!j_aJuLP}iEr{mC3Mb^^|VG5C!^C8D{G8} zFIik5)9<|stId4??p#pS}NV>qIBiOLopTCdPVx~Yj8>AS@w0pJP z_ig4nx3J)IQRCl(uT%B72bKx^fAxL~BJ}i=QZ&O~hbjvK!k+fpjr(6>A|f;>7#A`@ ze@dcF&%rbh(3)8Eq&|!0UGh2T9fd;VaQznLeC>ADzLW1;p;%-rO#u$i1@E{gSe@#hWi_I2E!ct%HIZ4! zV@q%BrLH&?cZ!0P%6RAd8J}E{i>E}%rp9Ya;E03y@w@DSo>sW#*O)6!%+Svbs+9^Z-JmoXE*5ddj_6a6&#k}0s1^9cA%en=Y-p^cM zJIe`fsF1|($EefBE zAub;Rw%#$1zEnVxEeY_m9~Vu4_}bp2dn)!Ghes2*6Q9$On}Gonxgu7A%7jS)1Q{es zWx#kkI~I|LAh<*K^JNj6+s&@J?`TmyY1-1t>R$=IU?^bc5wD|{+o?Hy@Zg|28b{yt zZ(JPq0z*jdjS1c5g{|?((o#I0S7NnVxf=CC53CS4f+zrCK%T#o=_D}~m1T7w{Lb07 zd2W4uMC|g6k#3Top%jCx?vExoX`O~mML}LXOP{*97}j5ARnAO$)>S9^_Z?KrOgsS` z5w#;(nZy2VMS%JC;DtZokaIrry->c~;*V|IEb#sFvq7x)NB6;{rNtd8B}Z0AdQ(Fc zds+ws$;_XLP>>2~ei>!ny2S1i)E-3Fv~^`rPuku-yNOs_GLeasoyW zgw{9J7PQ^$eAiD=r3pmu#rEM?7(DZNO44 z39y3DYlfb^r>1P*#KxJHL7{5;yXgU63=|Wvdthgeb0K9YuKPE1GJl|@A~6+Kjt{I!QDN6$^cPi0 zk`cnI3R49q(=M${fr%#4K8ue5U_3w4wfeXOvlW>}0^o>l>{@$W@v^Hjf+852vsW&4 zu-UlMniwotXnTX;O~aS1 zO!kIjkDN@;_jBNP9L;DccbDPIu1Hh??I{j5>N#O>z{=e8g)lnm z%!fArN#3V|S|lCDXW0nfyDzu30-3IciIwpGwf0?`7)Ah4By)#*F6<)-_NeOgecF^9 z^o6*ia?_qG^vAeA@?rVXn@R{5qG$m zrrKb)tXjIcxe4CGp$tTC)uKhqkp~ay^OG%t8B5;ZN3mL|r=T{3An4Z%kBTxLi6cRe zGW7)%>%O0;dhJu`ZcFLD%<6>@_Nx<%&%b!TwVi+;bHL{QrcS8yW!?Ez zuT9hbc~~KQ(*Ey^T^xBWMnKS4rzt90e3rN6UCl>NN{-9WHU85^DXN%0J#0YGJlsJ z=SSuNrq0JUCZnhbVwze1;@OV4In@2UjaR~}`$xz`{-NkrC@bQb6F_BAV&K6ec!)Da z5V~`GTsqV1W~4fj#q~l9*ZXd!Iuhh+{n97Ncr3BTY$mrl3WL_vTJV29jiDdq>UF`# zfFdbDxzH);g1p=m9u(k5OjwV$rH8kRDSDH?qc90dHb=g;#ejhiI54&4+P=Pv&kG#A zwI3mi|LomlHhC`IS-h&d79o>LB|Y7V+D5TnqpE81{RR=$Csjfn1yocPs*m%il>7gG z7V+sK#5rH|W9OgDSpDrg6aXU&vGW6!hK7dw?W&KNd6;Zh5Sp}Ub)qK#4C2?%|M)35 zL2&HDgUg23t&CPBP^q&>*Z-X&BMWH+7^*Hg^#c5~xknFPnI~v+MKF|3T2T>+uH!C_ zTAt`XrBmA8p8iE%qgPhqY0|tMP8TY6qq#1?g_MM{i2r9u-_K!uGFM_`WCZM$X}OZi1>Y>XYxbpQVQ_8fx`=equ*oJ?vxAYDFn4H3*2hAo?wU zo~*X_lN2DB&p&dGig}BWXs?LR#u?05@-6S0R}{35#LRE??Zd*_QF$25Du&gezn&>5 zCqxelAzxDKdrDx$N*qUKy5WK>D=_2H4wOU@^AQ1wD7>VvsyY8j%nm>piDh0`+*%Ng zO+<`}{$UN{%v|4kbWvW+pdleG-LJp!h#~gB?AR7X{C4e>UH> z9!nO@i-kZU6({-t)bBQI+D#Y|YK5d|Y97XR>3(^dDeWvas z7f^3C_`apDq2JcjdAC0v+S)xnXnkznx#+xPqk_*YtBJ|PC(W%{m2>`)w(&mVMU9f- zxM&QxFj3+A1mFCez!J{SH)JaQ)nOA^V)-<0>oett=G*(2$#C-$JVa4%9>b;Te7V0d zu$Zg!==gDSZ~t~}+EmN*;PUZ)g^2A`b3LQ$@Cd*|NXrP8fY@key&S8Zya|9+tH?U%RWM<>pAyqF0|W98hJ%A!Ax#;8hu2+ znD2yd6LyZB&F?Bl<l0F{B$DYEY=udOiLi`WR5z9UVAbn|NO$NTTxFvNzN*kkkPh>M%vU%NdGByE6|f zAj3+#4%l#9i`4YoWWF)nP=YC8QfT!ln`rpxxK2Vs8lQzFVQ$W7hp_yJ#bhV`cZ{`E zzdpBqsU^9%`v@+k#?I4CgVeB8*q}iTLdL(If96bKtU?R@P|1w6K@C%#A|1Nt9Lo1B zHw(9xp;PHS?Gh=_|9EGQt%*qs;!-muwgc6*+;`cYH;X=Eo(sL-_Q+!7SN1-BUWoj! zY=e3K)0PayUocXpT4nO~bUiC}dHY*BGLr@Fvx94SaZMz(k3YLENXGN=Z`~WV0$mT(&;_|FBGv%x8ZK`3#14_73WP zXzVrE9rSb-$#HI0?)Oc;7y_GJMf(2WNqnIjnynh~ol1oUi;)!Z7t%+U;#R=Vnj!Z( z1EE6WY71|5_x%2NJKF4JG_hsdu;W2MK+wl?CBOFQuv%|TXm971I0_Otc)CTm^^9|E zT4dy-ic3s2XtafLm~SeKJzpBenra{W7_4Gko*7B3Ao)eq*}sQ9X4*v{LSVX(u;z8n z>hpTFNa1k_dC_u8N{SYZKj~w24ILGPq1y>NmgPIzI`NvE#sX21E8lu9W_4_E z+BGFAK4Jn}PX9Ma+Jovf%-2Q8SX-S@>f0Yv2RO|>_Zl92xTy3CGi2$}`}ZA!yx0Cxs)p~>g~{TI^fWWG zb~ND}Cgc^bwxz@kU%xRj`5{lRzfHZxTP$tw|G&Ke6R*+qt<@3hV2!a}Gm8=&6+wn5 z_0dk9FT0!ZyeFS-JJ&^OKJSz!zQ>q8A7gm(=%&ArBQYGCbF)(x7p-qT2kYHBLIuuDCit(KOS z+8|_;e(dxqtL+9iG-#h*2tgn^@w)BrzU3<(c<`-zkD1eZwTdEzeda%p8=iPgo=5j! zOjykQ%h1WrEAe>Lph3KZnJqzi>aQDM*fu)jlW?14uA?x-T-3r*=_5)Le9O->uqSzM z$hNN4PtmbnnVW@^*aJaqYa@3-Y}F45zBfaBd;{T{tIvISzCHQKP~oI;5uNSHzMozs zTt4nl@j{wUQx*wSKHM?jea8(q&P}R{nuZ3Ff@g=JTIpk%?gtoyF?jz$Z+~_EOM}}O zaSof(5ujJsi9UVJZ8z%wiJEH3qm&5~i6aPx$a~qNAgYqX$5#bpkN|<00mRP04S8*2 zhwWlBhuv{x(!fho6#Z-k`PQOXOKa(LuGq;0x*F?O&;_d*dXoWUD^ZwmiU9fSvaNl{vOQl$U5?evVfKPGLA__MD4wZDs9uiAb; z(%&#bCmG%KL!^GKE;fm4Yy|I9c{cC7$aS?ee0AQhw8?-0x6N8a?kyDCs`H1>CmBHB z(1Fzcx?iFFu7C47*(H|61Y?(}BC937psOq@?tbce>(hEau4-fGUt}>LLi>Llp)URZ zrjSDVdT#c|uHCo;a7NYh%53o3PI#Oyypx7Dtxab#9PN^M-6d49ThjTo``~olW9B59 z7-#_-@!S!392pQFd^ZOV;FX=8ps@#lw1;p^y&=t*+Z$9eN7~Nh_Ih$o%ZIB2rkEX^ z*s1*9xy%Mr=7V3T)am24owvjV>`xbUw_$(`?u^Ba`XtlOYcfQcY*6mGf9E^v%4y_k zH`YE*uY|eMjQ3pWgoK32T&|VlCjSvWjD&yx`loyzm<$XHFI!&oAC0)^ZCO0P=ESC_HRl`tsaB>>PKJk09vfci%|>@ZI*h{ zRDO-{cKa&d+ zP+mD1>A1n5nN}E^-aTtEYzLZmVgiSiEE|b(Mc>~7^yI_|2wML&d?nV5b4f%0q1>+6 z=PRKj85+EGyi~HCBRlqZGQ)1V_z{g}W2CM3sV22{tJD8mn(H4Ly8TiBY}AI@&hyGz zc0Jz+y;U=WYq(r%{NE%8LH{9|f*ptN^QjebM^t`4`dw=0ybTD{#nuFrjhH1pPSa7) zMrJ>o?=>@(pdPdOOUi?V-da*upJ9X&bQWuy#th?2t?kX5h;C6y4UpWAdQhqwdxqqD z@3If(2ZpzgiY5qh&hkPeTD~(1ufs!Mviu{4pL)gz6@1$bX+N<~y~0#%yN#xqgjc1) z2?`q<6CWNP{;v>Bll!*2x9z@H%>w^7BVXGAL+di%nw)MzM#jqBare{jhgdXrj}@yF zUWZ~ngUH|5>*KN^^Lx>955rBIaL|B}-fk8(NX`z3b&3y4CsC%bl9VF5e9-s-&TbhC z`czN4`rK@`)FV2t{~`acbdz1|@9Dvr(>6`DmpPpczNIf}mmy0Q!}EYXF)^W!r3ik# z+|bliXS2@f#k={X8NVw*Kfkjx^IJ^b_-rx#Z-Sm6u>07l*601jkv8XR*eNM1<2v-A z{Vs22eFxz7aPj8rc!ETAqdzAox`M!DY}1X;J+#o>DV zr$ctqZyKt+qu$=$GB4rqc*hSW(%knGRMl#YAf%FLNoZ)!)755Fzw!V+8xU7x1dVp` zP-lOCSjC96qa+^mzguBH1o;UxIy&mM7b~XL?#2Me_eTH4k+IIIzps-BxdJpwR36(pUB8l+MrP^K&oOaR-}k;ax)VKn-FJHqMo=ly`0 zRL((fI=J}N4v#9Us(asW7@@S8}Dm5(!COH$-OTS=g6X4N2AHh}RxK=afs7B<-j>VHf7@Yx=CD6+!orYHlr5+W@B}DKLfz1y-TY+9Ib*9XRQ{%n( z2PaOn8E~g8U1nw8B9BKKLYZ<%F8}m-5#TuQbzjPsL9fxw&h;0A7^b|J4`=&Hn1W$= zt=>Y28Q%`UuWa&UY|(L4nqtZe6}HUG+j{mL7`JqvI~QP38YdQ)ZJzhB>bmeAJ$xo6 zqz)avrJOqjZSAPBeayH^<^NOc1;UugDJTNDJYImguK9xPj=iP(VYU$5}32^t} z?aac$!r>Y}KEJs+#dqaQ@jPND>H2WY9OV1?>M=N(Ge^FxD528U)EuV(J6V*EYw#j! zKkGl7n-72q8xP6TdxF+@mMwJ@VoRwoD%xa#Xw&NW)IemY%Nh9mT;{7+Xeo%(z6?RP z7l2iLa{|4rs638$G9_z=0yU#$QAW{)#jN=u)T?6YchFh#HUwn7l?6d0QJck~S} zE9Tq}POV{Oq!Xq>x|J#>g0^b+Jce28YC>=v%eD5gPj;4;fze(Ea&@DsppYVvmeKE) zHnL#9W~Zl9H3%K^j@02WW-olzF|77<8iR$L07cc9hVIP^CnK7>(?J(BO~*=auK**T z6yu78<@N!uvBp`ODNK>f4luRjc3WnvsB|oZhSyU7H%?ZTmp*j4CKwNy2(i3&(-({U zZcSskX^*IzJi4YiL|-}`t&_J?YGDA7@>GA_)Oa%+PT`9dVH1|GB^eG33VV7y+r18P z!9!~_HiBGyGXjNh27B&%blCx#MMY-(EVXiQs2~^ME3m!XUoVm@sl5Fuv355VhOGnO zKLAM~=6q|vk6Ki#Yq|{4KFsy^|LJnRf|6J>7>Ut$-n5CESn~swTCKa*cucL{OyPU| z@qe3Ij8!9}^)Euj2`Bna_lb}p5x{?4y}t8=)o z%IfNu++xp={TkBbNY+O>T|T?Gf-kH)$_|(@VN}XcGA@oTg^K_Rx5tm@o)JCR`0U31k_0wXjq|8&P zQPox}mp7A54jG<%_x1_sv|z@}&CQ**Xy_jtG+<2m((S$5cJN3@Lc+qozLa2pfB%*p zy9Z)uN7u={hZCpvRP&*~9{rNyIVuLma^3q@Pe8ePUE!wVECBGTwDa}N->)I%2!*`x z6m{imevP;T0|US+$M>q|s=B&UC-Y?tX%op4CSTWL{_}M>mI#~EDfCEC;wU2uxg+=v z!@k+o`e0%R4q^5LTy|o|pe)3ji>oz8(7a?PCCjR?hT{)yBZi^|vN{t}m}g5^-W0zE zrKJ9hM+L5n~GTG%C+%`vel7R6U-#q`sxqAihoI9VOiNj@JIuZ z5j^F-21Hbv_v2a&VIWO0g$*7!Q7|m^Ahjb|mIX%=c+th=wYB5IZ3Yq(^V3fJ1a0`J z5hpnn`8ZMz+)3|lnD!Mc?QVyl>FDUr6T$~;tQc~)7Q8x_qGbR>sTfn~?8K(a&%XyM zbQQA0zvR3BWsDcN%8=GngfHT*M}X1qMQyFLK^}QEC3o>S{F0HTR^4EWrMlOCd-m%K zRH6ws;{wnw*6e3tsk;x0Y2MRQOhMI+#FITzM>0A!?XJ31Ekb3}gPMCT-?)I%0 z7}TSKRcsp$F9wZO4OlSTr1YWfU>mZXRAWt@Cq?t)cgGTm6_=IeRaQnPCZc}HOEU|L z+?pDMB7lUVB9d%T{KA4tx-40aJb2lB_>5Vk@Kvw6-j#GEA5X(K=p4GuBFp)~bLj&2xqtIR(T`kL zc%I2G8Bud=ZXn0{jHHQ2;B=>-E}^6FPpS#@h9A^-iLf4|Bxe3r?t6v{7woM$ zL=?gHt|qapgu%0fWX2>mkfaCj?{lbDyNorBT-PFM5_k#S7s0Z#q$IP-I-=?c;pe5? zH;V7=Z?_p|%bs_a)vfMq%f6X|$u%QqTDqY8!{;XFLTSrdUS|PPyECQ`8APcfj|XuD z3)gQ`Y>v$WAWo4T+!%CdIe^NI<=4$7p-`eRa0ItcbmYw7eq3`L&*IBUPEKa> zc`YrSot^D{IA49<3V>T`utcknZV*Z zn|EFQVSuZw^iuFvMpZ8Lr~VC2y?1t|;UQSWd&= zfI_&v@QKz~Oy};v1RwDgK$p@9iz~2yObG>u=E2|n`eNSvJ*hZBEXduvA%XwM%U?*- zeXcxLmugl<3J&+_UxbFy^$X8*QJCSh)~NfdcOE^j!S4HISPeI@h$#tx;upjY?XzZ{ z>@VK)5!>#o!D4a=X0yf2EprS^f#d0-2uU=>cBr|mEn#Q5d9&6SV0RusM@HG?Z<`>s z_y@(IFipu4CgphHro%yh31zDhozWi9vo=qqt>UeK?%=E z?`B*~=+YuT)oNue7j~}ypqPPygBGu@ikP93-oE+pMMXt@>F!7O2~^;CPswxypqTh@ zA!GL1!3W~fw+mKSJZhn+NkTFfk8ZHMvI;+;3d-AYu_i zun8)9;*$hCgD#Q@PLu=>K6j)E4<*zo8Lm!NT}clQvf~Uh$YBOVJEk9Hp@s(*JjCR*cM9K>Qs z7jg@ZuV8ss6egNM79Bp0kniGVkottbD0pL|%QWV!sXuk_Oo<@EX@EpEpJNzJbpZJsYv8J1s|usalU7>s4J^`+B@DJdo=v1pucMo=>>x_))37ZlFz}nRu2qmzriyE3E3t8#&fy^W_5(Muu zAvMw=kLwI-LcFZ39T=zct#uuND{$QRsKbU{(qy#+s*MU`6Y?)KJbImG*GU+zUESf_g}6A}c2nHD90ut*%9WwhGS{#+VA%_HM9Yam*zS z-;j(DCy@NjcdYdQ%#8aKG5r~|8myd`-{jE?gv|ib5_@}+o7GqX$oHIHiaP8kC?XMw*t4p9nROzhA+xlqL^Pu@)D4I(iT~}{$QgsZci!Z}^c*ab ze?JO|X~>jJZ_b_Zps>`CDL2}tV9%CttDu0vp=c7Dgc#QN816&BCxas6G@dCenx9}% zg`_(ixLgR96cb#^h>Z~xDc%Sue1ZV+Un*ySu1JL;;N6A`1`kxa)0i-q&cRC!4-a3e zF$DYZ#T&kuxo8xoh?SL~I=B#Y-+6eP9GWKm1g(BU&P!d4CSX9o~%OrrQoEUDCr z2-Ph1;Y?Vlk~-R*_Npk8%OO04!(gJewBqtBCS!x2_m@`r25#jDB>f{4kR!W*(7dQ5 zT#i39lj5q*R1L41a^kgV7;S`EeR2u2sPqix2HX~H@vWt(O5M7@MT~FFM0GR6LC|1A zG|VcBb9XIwlf7H~U8j6bIAc^oU47<+U!C)k?G>O|=$PS^Sn{?1@(cd5;#w0w95H|m zBzJc}J2tONwjVO0)MTwTbtNk(IHyj=l5;9g2?$w%DA5b8LBuQAvbu#+1EJ<^`+CCH zfUFN@D~JxVEU%k?sPS0Pannfps@jbq*(@n@fxGdVW|71PsEiHt`^|yMUx`@g#7ANs zwr5Q2C271eBYIT|X)ztLYK`yu;`AF_zNIb!#}he@saBRC1?<;4_EIZ~&;s)BUEY?h zDz4`En-dR0*NZ-5m8-V4Zasl25E)@c*cEoCY*oO;pR@q3aP}qSenUAz5+82ZzA#&O zCpE&n&?sj;77KyAf$8-C=^4F75qK;tp@{iEDl>Y_$@!{T=(QWmi=z=-nCh%7eozim zQKP6|Sp7vK>F8pG=_Hzpgf({N$FtM=AZEOlVJ2NXQX$gsl z!lI&#=ZY2nB_=+o{}K*dyq)5c^YP*R!eZCY_eaN%=R+xx4Gu{x41q~ZhA&yf%YC~81%QN-A>z_;fGJ=p0Gn^0Y z8UqK1qh<~z{C{88=dF(YH^!O*+jUrZTQdu5u^~mdrY&>M1K!VGE(uDbpXisY)Of7R z-S6ex9wndTA}X zZ@q7J0H{{71CH>!HzLF(k&VOR#77#9mg5Lp&akSi-PzjISFt$SqT|_pcKdC2*b)u7 z)SK8Fjk#()Z1cq>h(!>I#r=sxH#}1|E<0Yq{s0A&6O+jQ7`}b?y299CJj}#^rGMmo zd*I~j?vSMpqeN>5wn?hytZ@% zN75Ze#LN4*j19VZk-zKjPv`lk&?TiJf$@@uM|zqK^S9&T{PoTyVCnS=_G8F~t}{7v z+zTmcYQf=XfM9M+yd$(#%tn`h2drs4)ENszM-8pDfV%q(&*HDJ#cTd zpKRuR06*dULBR$U7-abVa?i|6J=~j=0LFi}K|6*C)R1(MmqRO_elabOFBADXoPF4x?1V zPHJK9n&#zFhlw#8-HJ^*U!kv$m!M9G&gS73v41HBJsGu8MAbk zN^bSUFVV-24SVLo1sejKHWA#n-K|Hj*R=X|c*%-2Qq*vE*DXOAUm*o0*=5~nl}?9m zwRJ$RJ@?Y;lvK3^N0$%KMYrL~jnDRRbo(4SwCl!=i!9Q!drf>Wg7wKAsY>4Imf4|3 zEy|23qJaFRIL*z?jZ92xJ?>BX*Z#7m!L+SMmzKUAiSf0bTxQYtSTx+s#CSuC;Jkn8 zMs~sVp6#_;C9>~gdliKBUBcuM#J2KEE+=X^C5{Lkv0!GF6!;|G4o`2uJPy?YoJ zsXngho6H4B78e*a{!B-^TaU0aaZ~`8_L%E1-8sF$)GVBw#|mVvXISZ0b|PyX56tx^ z}5$;LS#KrZdlNwC=JoT$55pm@ZUc4>nE4S0I@ z@$bR+0W zu@BFM2mckf5T#mxg9aIdcxgzFF06ozEJA<|O-i{E-E{i+s-VoGFz@nqAB9HU@-$?` zn6r5LRW0aIqF+S>8UPg1=Qm)`V^T-r^Of!t6cmaZr^n6f7wSz=s$wBrqqefJHAR#O z${eUpgeV`Wx#_mMOP*3oA82h$sNp%qh@wz;c(!}P@p(NQGP`kXfekaB!+4xSsa7iG zjt<+8WXHz{NjLs~@dKC^gHJ5Qm`30gr`4T~?l2|UWw|8@6^OZya%wD%1`B&Tgyy*U z%ync$a;ggBJ5x(uDgEfRi~5{0GHILPI-><-owe$J&!ZRHm^xIzP6g@6Y9*^hHv`wV z0oP}xR?fql>RPAS1mKU0|GEn-6DGoqf>$w`Q%mM&4<uNJVXuWV5qD$R$GJ&JN=d&O{Ta;}eSn21|IpG@_lg#GhRj+!W2SHLTl5 z(^UEA=m!xmPYG;%u@jXRniVUS>zX~-_Em2dvv{I0HY^xyh~eO9+O9ysh_b>^UCUt7 z5FU$+6m<+(`rF6Mvicy^Su|Lgk~4F};^8fczs9y5I|6-LJKo>oeh&s20HR;du{3OU zlqp`P?rxRinskanY9T_zK;b&C4vEX#^KQ@N^+yyKxBgunb0!c62e}1n%;bzkgU0tx z4(dc>b-_OU0Qu@fvOESbT;-709 zp}jFN&{zE_2oFkySI-kE$oc3qV@$rZK?6cz9&Y=qVC)KJeO7TmFeKQ9&GP}CR=s6J zo6A$n$)|_ahfe1ktnJ#bJgpbezP^17EN#JL4M*AXV?8n>v``*7MC z<7{4kR4Ky;x-;M+r$$JYILZL(Db#J_2X^gyx33~s`HHWtno=U+cu)^QmaPh#o82V0 zW^J14Os6v4Pv&18FFPJ@j`Ct|_UU{%YGmh`Q-cZLw&eL@7NM`jESZ{Zl`+d4EAYq- z-=S3?f6h zq(v9Ag>Lf2j;uJ}VDq(i`SA-IHPM>Dh6HH0xlBlC!tva}e|@IY>p|@Hh7n3jOApFB zT8Mvo^eP(^I;_%!5i}8@d7($MOas=$%Y^#4S$SD-vGW_9e>643c1}o9ILW4~nZ@F- zpYsSKe=+~d%EK127{ywH_t)1g3rxQrS=lC0HE%hP#)z&u!+>;d2h^K|n;NVLi5d)W z7}uMH4%5XEzJ5z#Cdm75dv`9mj4i^sCxo%@()qt zZRI9Kp`JX~~ z)?ByW;P8TU?6J65ab$Wf5yemH0L7W&>B@Tdp<8V%FJPyG8v94t;%{diAxxOg>zzs> zm8e&vcF@Mo9=!z-bRD_u^2%Uw(t0yB@AHh^f0ra z*Y}Jb1V&-PYwH32^fK9T|5*J<&4NX_>ZKDan+3_E>@jnA2rd->$OjH>oFA%^1wRQ7 zg102yOOnO*{KYhV;>VoHe6)8U)IwM;|9gK8M7%4azy;wniT=^2-v26Ga4j`cAZoX^ z7LX5!+sS&VXZO2heQUt`ox1f?p8{$}Z8z=G2HYQCiveL8=^$B@9QjAaIKL&Ih%pB` z5$`0fPe@^C`~;V4EY9)4{0ndC!shUSveXr8R&K$jOywAZ`EbObyd{p0C+l(!eTO~0 z2IErAp-&>1A-3l|b?tiZocgH=Dx8yDAxCfcYJ_P8L76$G-?j>D=L6=w4HVZ!bA0LA zOuSGANl*jZdRVz9l@w7s)Qbdz%+h3N!P$A~jr*bfk+Z{w^AeJS=SsWR>xYvMryWqYe ztgxrvVNo!#Qo3~Kx{rgjP*yxLJ*u2s<_H)r*Pb5lbW8RrJzF+dRf;y7Hv9Ux zeeCxs@LsJY<;>B_n>ndVa`4_O+V{K!p&b|26uwbAI;X)$u%M`RO;-hQOBg-#a$DSew~pWtOlW zpst(VY*LBTDe;X5soyc7;_MIA>{Hj83|_O*aeGw8Zd@&bkW5j?m1(c}q%q(qTlQR) z`DYxRIcKTyukyCx*DU3da_mG{{_h>k?M@v~BA11PeYrGqv>4c%hf`Yx`&aGq5eX0( zBKD=pV-viwN9sOanG6US#q0YfhdVVIdrMR{uRT^#*^WuaqF{(X!Xw4_I_P#HpG#c&H27#hidmUl(_SXQ>!&QEJTn2+vMte(-4<-yk;_u~_ zLmTMYU%#%*FjLFPNOhyYIf3yU{-|bW8W|hw z*EIck$Nt-@pGL(fBPg<+`zCb9mWfD;u@N~5{NTHFG*obD>6fkF264_u}Y z2|4A5{*q!IPHAGqoGWkXP2+|5yY~GS5hay9;zT0*gpnXC05zu#rTsT=T~jjD! zFV2K9FvTdv19c3H3|44PV?lTC{mC2@KXgCw$SZF%2R>dXK|{sF3^zru8j^7|WJ`mb zRR~z0V+B*cj%74y?Wtl~9v-cg(Lf?Y44*JBV3q;Iec-6h_jj?7mj3*|YC$&&!y$3$ ztY?Y04suC1!HIM7R=z|2FPtm*U#ut{;*QlZcX@2(+*J?KX$F@uR#OK;0neM0NhN+z z-j?jTSXxq&QYCNH&KK@ohK$3d6hUai!luoc>$$`v5>3?uCiv*gHfML({DyVCCz_=t zp0}M7+uYr#h;7E{2xKKxC>59nn=n_@jOzh6_Dop`rL}Tv-mJJ3)FLvrhnEv3C%@uC z51C%erQ5dp9a@Y93%COpniPo<(@#9v%_#I%EM_*Sm%j~bLa(}D*TeLyC@{UyKZj|ltte0aGUhg)7o$|RFfIv2_5)2cE?Hm2+VhiA1K7LBO85NR&_i%m}>i%so{ zY)}2psqBq+1Mql z^5S?tCT%Bap}zN{;sNpAb~qc8T55L3a6xV_kScbdGCEi>v5|*ASgvab@cPt4^Q~zM zm8+aczq|nVrw{q=t$vv4NuN?U9$$0h^}4!w@I7VT=6VULCs7*fyVUk8O#v0d{W~$L zyOGh*ZpU;#9AsBopAXWWlYF0(ILx88%5>i;vtHK@zskEgF=)87Io3Exs``ZFY`_sk zeNmxh7s+aLvd3aB3UslM10l(YbhgeR<#(4#U7giwMc%8{jQzwvtM$IDjf8*+d>M{s zxt4PuR$p$M5c7v;m-6L(tMN?sR;Ds|(}g4YRhYJm^!h_H1eg%1)Qf$HUVjGUP{&HP zZgFzfO>Kl<0?9Ky0bniL!B~huJbAJQJA0p}(Xymp@pNkftI}<``;hqEa;v#YKKnR3 z0~|eTReR5yishdSIXmoXQJ>|E)R0oLbh0z2+cEfo8S6~*Rij={l9H0-6cj0!HeTf4 zLl_Y&xr8eEFqSDP6`k#1MRa8O828(qSXQgfubc0@85pzp`~1nP z5l)6pW*8m33*{(7Xln>@D!J4Cl%WV6gYuSO#DoEY8E_uk@ACjnDV*0jp$cAT|3{5(g>TSGah$ycnO-#y@MsdcnwV4(NiJh*w~zlOR3$*O&Q zeQ&pXpG_+m<%TU+?PPkne#D~p|pPK-1Xh@b((t*`VP zY{)gQl|Q9l%x53x*=6Y1?9PVaA^!~Y-@K~SwSrq@^2)3)i_czg)`iVsL+Q&wSD1!+ z^Pvm4{?B z(btSzIZ@H!D?n&CVpzT#o?-71`FPYyN|=oHlpGmh%8AFv4WCs82uz%I{Mz{g7_inY z#-}oN!fq-gZ%%vVcu_(M_*h=0eO;1lw5bMsc+uG6rM1@yZ=@DjwXq=qmhL8M^pY={ zu-p%E*nS+4n4h`nVSEr3aojwRz}Elxx7HE~vkz(eS&7R?wPfEF0oBDWZGGC$%h6PB zayWrH`F4eV_%he;u^3G0vTmIB48b=5XJnA6Pb~F{HRS&K2YusRU#-OvBDK)|W1aS2 zvd1wQcrS{Xwe@}v7+!vB>-U-^+}y%fc|7;weRLbf@UV(?Xf_LT$b6^J*WjL7YdnVf z^-l+FSeI$xfs@%nrqlWp;`;kIB*+I?VvEPd^%6ZWAyfgHc$In+8;~yR8lmsGtM?y? zyqFq0)T^13c0zbX8)w~Ejn&5+Bu`V1jLbVkoV+xpL;|zD3u_vq z6S}3narFv>9pqWgo;UQKguglztVovEK3rXIM!>Ytfec%tN;Rd(bu2nlZF|#4v{J@e zGnU!0v(*fd&&f^CFV-Z`vKcM$N{z;}6UtZ967SY>3rW9Uhvu-X`ie%|MXTlH zN}3d*(0>T?Rm6pF6Ps@^2?+_e>rsyry6dBtWtu?4S}Fr*K8b?ww$WF6X+0FLg*G%q zObb&Z9$c1Lcv%HGl4u90WGI#K}V-)0AoO$zsDz`b!vvx56%N? z@B5JK>*JRn1&M>f_@$t68~iTHoVBZ5sVEdcrGkeaq?w=ASPDj^ybS?U-W8$q`_4{y zw=%0f53SG+j4T?DuJIidF~&i5x!$v|ae=52^6zj%#Xyl5v=`5-X=)F#4$++q!^88w zP?fL{!J5EM4MA$Z(`8!c`m#a)PR^2u?u3h~hyay9Go(fw8QuS85@PAN(<(j;UYUsLbEF_%kBv@yr>^3e`V5xegrR0h>`_YcsZ8yr(JuH)3NHYA#(*4&GSK>W3- z!xT<>%-#HQp@MBGy)e(^!%z+{c9Aey8X_8NT&WBsBSxl$3b&$t!VJ(7Vj4L}MT%g& zd_uf~g<{j8qRKlt^qu-xY;Sx8M^h}-frYH%O=3~%c2ywd;kchPEeND6XD+Mngp0ZN+~%y8WZ101IVTtEbp zvA(hBCaFufYVnrL_lE2Xi}VpsOSvKING!6>3LbwlJJA*GRB}UKdV~VS_3(?9AZg^2vb_-nDonUu#G}d&eJNp;cBZ~gDR*xK7K_< zuN7@+7qBr`&Li))Up$9i^{hc^O$1nr0GvB$nNL~{$yo|5i@x=hpdvW&j^4%k?0$CN zl?m@h>npxY>-f8`QA@K=C!hIX?$p2NP{^Jl9i z&2VZtn9+e;NH8Do=!=(>Tka;W_Vk-54knu^3MrA)xkh4%qbSaB6_cB8-NG3yz>udL z+w8RGOF##_06c9P_)*lgN5`)K#Sn%sYJQGR*Gj*hG4?2>fSfx+?$Lo;waB&W)6&x7 z=&@!QHezIOzS0obw^Lb(KVJ0q=GA$VP^DK#QuMQB-NxrSLRXI&6HSKyvOf%I$%+*c z67rypN;PJ3_@)9R*_&vt>zn|aarVlDPwEl1j{EaxQLBGhRD-onc`h}tO9X)C?6Xpo541u!*<|(gA zbV*%WlFpIQ5|UWF^j_lF+~uWSKaaP(B>~f_Q-1yt1ZxO7&8(&VDO%%AY)nC3yfHLr z(80SlK z3x9NGMx__lb#6MNZR?Lp)>6feSFBFxjIKu=ZRy{;9R-p%MiZ#aZEc6P?Yy=cZ*Fdy zuLrRXvsLqKnzuo5-L`-p&X$=>ttU|srm+A^OXAwv>t3!x@PU?deQd(a{))X*;kloy&36n|@fLCcaAtTJ)D;(6!!k;xR=jXAI;-Cs|(873{299zBbAx@^7 z7Y%VCFwY3;l$P~zKOO(Z?9vP|wE{eSwo^KlMTK^79@n}c4bKzhBJQv#iFocD4B&mhtR z;1%ALV5>3rl_@V@KNeI$PTbHDybUXqA1K zS#NsUm@=mjN;eO6Ty4ZYs}dP0p`UTBj{l3fCoL4ov&vZ0jzQ=el+n4kiVlD5o-|=L zZ&(|tLZqr3^_Q(>#hJNW%OSH(oLsb<=XOFlKs}}>KkXXSnH_$&e~c!*gi8b;Uhg_2 zI|wdbwup$u*=F{yZP&ZYcSnIQY14gpix5FGZXmaF;t)4Cr^Ne}pX07g;^`uxdLsQWIDvRJDi{F@TPaj!#5nIQSZOr{%_?!NT{1Bb_DwV+#~i~AV2{Osf3u8<3F2<2&i`yiaI`5Te&r#Kx$fOQ zSiVEI4&_S41$UJsF}((hCfy>dY#tlzd4XF~gVWQx5%Q1XnQo1O$zkE2+9ebzRx`xx zQvpUK0W%tW;;MCVYdLS|+dd$2jt=pr4HL30JOWd9*gOs;#E(jJbvBxUy(~?0h{%hwfxJ0B zb-9W3uI`|m_Y&Hj&GEy;8}Jqigy;)A7<}i>*^ryA+m;e$Nqv)l-c@e2Gja4tuC{-C z-L{@7PKkP!ff1*CyHb;UnQzH16Q?Tn5~nKpQ<u0ZW?KYRrHugg$>m9M?6(^;&jF6h5_|1=H zeUBG1#^%zGJC%>8U3X*?Exl=+=JAKSy~+^*1+l-2`GzXY%piM8SW-=XhbR5pROEyrt zV+!q9u~gn+Dc=uHv9v*897JQ!h3n}&6s7f}?EQqX_b!dCbXXOu`rl2P0qZ7$5Fs#J z%S!)mFMt9Wi8su>3nMzY!9E^};mKtIFY}AvwTlZqGOfXUQFt}o=<#l!CWMp8r?ULom1BoTR z9&vnZtbm0D16HhtHELfWUGx2XUvr$|`IneD`6!j1 z+t!wbrsL*E=leXScrb%>kWxqjHd=e5)-)@*nuc}-O$Ik~=Fyt+;n`I4T!}2}<;yKj zyt|?^un{?Zlsh3S8=M(da*7hn*{j4`AKPGQmHsr(z}Y51B7VDiPM*Ua4%)2sN3?o# zi2qdtgMC>+$=d$2;_=4n%H>Gc`%;$zb0K^R#H#>s>yZgXl{-l$%@ZwaP%EKK_Z z8+6omjA&s+-1>I!Q95tmiSC@on7S<|Iq!8!r*^&OXCGABhWN1G|d4;DCXF?;an?YRd*c*B2HBySsnbG+{}^(Wgj<{fYX|3tpcYGybDu@w7&b`pAj1 zT*Y!nA&$6Qg{qdCEO7{!!sYcy;`8Y?kSec~a@!7FL;*ZVFl^tAJJT&vm@sT#jXLoT zJ!U9OG%qYmoH))6I;1Zw%Z*!BQW6pa1H;I~WXGYUxV)U0iz}_XoVvEQc6fZ8n2aoB zZEX#NC#f)({MS!E^}|slUayZ09i7)Ai(oqG(dO9q_D5T?V?Kb)RqpY;|2t0m)wEiPmMBZyDU!t8D}O@x;Cj`U&P+qB?d3 zZ~J))5xkhsPb}G&HsMCrb%6jU=BqQY1w`~70;Vu%Ah7Z`W|xm=a!XV6CFTJkjaH$& zBuUi=J?Hdn=k*VVHfp0+yMIGl1jmaN5txsojqEC1Gtt|JX2@avL`2Y=0xXY$+{9@` zeFlcO(H=yvR_M?!G&D4PjPDhPkgmruN#}Kx?eshgKo>xDdtc>?lQhOcW&hzC}s=1tZ29lZjLjmZ0w47{19=7R!S+EJs4-or5K$i@k&nB5Yri z7mEZ*^1){`TIuq?$eeQNMUG~_Ngg(EGoN*V^BlVselIZFKx{=ic2n&EQ)45CCY4rv>fG47cT7wu8xgZ_E=&`< z5i}XtHYqI?OMkNfQ##4+At1fpoguDMkK@%WvWwTOt|4KRyCF)+Q_NR_a@O#K7*g`^0dqMg^d=iXOARe)T*|FRgD| zeB6->Hys-;Ic4IYA3O0YLTM9;$!Lpa%%qHX#_EFxHG1@slkObP_U&}6X)txm+=gA1 zVqf_F_OjTOd1<4C@Rg1vf4tXcm0l(vNvjl<1vhG-JBxciveG-+8$E)TKVz7FDakfm z@02`l$_O+kvNO?Gy}N-}+E9@eQKPuWf?kuRS^Mw^z#oMC&q?%FvT89tEv>D%*0=JX zY*F8_lTS9sPZSY}UmMIaX>m0!9ILc0*PVEc*U+sg(vx;=Zks8M5^;glW4XU;zTLZW z;+zpnmRVUhlm~-(Nb(PtXRr!QEYK>4@r$SvHVRYf`0FHplWT3amhRftKZj`rvpg zh0J$s=0&If4x#s+e4@075Fi+?z6OUFXc+}KHacCXSQO^Jtjl^o%f%w42JhWLf#?qn z+%YQ+M$CFAB*0asZHYlt4Ewbk2wWre(O*=7PY50%rJ{oB`%>il?c@q(bK3cOu{)h3 z^u7Oz@AG-e+{!Aw?%^P=nGmT`U4weu@9-mvmLx(6u(VDiLx2pP*R(<}4QYzU^Te6( z_=b_StiWuUHaPdwMyK@9_if$qt*Pr>YT+=sa)$~&Fz8V6lyO-*L9|ub%NzVlh27uX zZQbkW%>2~<*TNXFHVsa54w!1;z*{=IiK)BLWQft4vYRdlPUWN6H!uUO-fXU<}!=o+=Dx}TSy6W1EPVQqpb_^3`4!|x2 zgeK4o%YhAx4LjuJx+_FbIUH!2SU6yAX4czsPHIz(DYXvcas#k^PnC)B$zU-L!{P9K zgJ7I32Q)IRX-H|#i55CrxoM74UaZZ@xi!a3Hba{^rB@7UHAJukQAj80SCvARmJ*D$ znjiK~D}jiBsFM*zY_~6xCR(5=SItsnj2@_bK zOZKA4XF4|Cx}&4t(#@mU2P5An_!XCk9nYwiPTkcbJLS$6D^Wvz?}ay-)L7eI8o!+k zMjRGNgL1ZJvsdBEDJylk0~L}Q0rlKZM&16gq|WI_@;d#_aV)t`9+S^6yG>$hV{x`mqhJjwXnSU{y1m#K9y$A1Lp zVe>9YYHa7NsipI_nidBX`P{I}Ex`W9q0>8MyBNUlJgsssEo4Ac;aI{vU^9J7$BRUa zG%rW!YX%WWCex`(a^3V!!m?@JPE8iGt%--`OkZY&mV}nG4OROsEIpWF*=L2xr9aJ_ z>qp+113tRsGw4J`ff^Ot34hJL^ia7UUq+I88o(}DC$8$jF_R=4G(Qz;)sG4p-%#^! zJSuOBE$QI5G49TYZ)t%ob;|IOL-nyAWa(#T>c@!VACTbX$MwGAFZEFfgm@k7vSF5R z1@dpEdz&!&C}BfgLfInl_Ans7oU)L7MWk&YsKWG5tQ+J45L-oUKwJYXKcVG1;wYmR z_bnV6dQ1qW6~)=xjwGh8v&N zQR=bpo(=DHXqxYfiQ_CQ3w-`2PV#k&2D>0LNt7p^%8QvkiVre6awk>6^x?9&Cr;nE(o9zUU7eaf1;A z9A6_$QdJgNr_Z02!V&!pr;F#13~DOIT=GAKJExdC{Z+EJ51l@O3goYHn$LMO3_fr3 zL{6^#e*xvqcLEPx^CFoO-E)nmP0k%QR4>!?IP-X`9tX3I|pwJf2BP{ZAXs9$0UfT zn8F=qrWMp9QQydn}?W2gLsE)vVC>(L6mo>oybJ81QF^`uO9oI)kJH4Gp@xghL6c?eKRI zPvJ@=?(*tI2{@c1Xj?B5xej+dUmxeYpd*o#3uACOr8&PSj z`VOh$SCmPkmk(0Y+Z4^O)rafJ=O3c+umS2)m^($m22Y@Zzq}#C%l&b7GQkm)dx&gP7!O71d=9W}EzO%voL8Rbi9`-_6Q zom6=ThKOa+r8x~V1W6$WYa?^N_efp-`V(D_lF~doxIx7d-NYB@OC0D*99}AWmZXp( z;Bug*(ttR`1m6!p>%P=%PWcn3(9_xB+Sz6=6UNLH)<`o>&A5Gn@Ljj04Cn1`s)C9v zUOdj&o^naaLUihXU~SXSB!(b7Jj^VuOzzPZV+*rdfDv@rY`a#w8>f6BRP}LP>E!lZ zUpI}m4iImwS~0T7sA(Bw4)`Wt+*>Gmw#sj}S+1-T6f7+1*tbUShx|Jl@ZmLVSTIY5P6Ib5Mo2Id^^Ssk1(OnMj-fB9= zFR;J{yWKsba;_uYZr(lTI(g=m57$h(^Ix7V*VQ*PkW`FKP8K#dv)8O`ZpukXNzL-c z5!bli9^^Y;c06wUd-ysuGCnR%-Be#cy}6lHAJez}?W!GS+_gEiTxVKT-(WFMS-ucP z?_+IE5ocnIZ#>UNBmHl60iwPJQ z__FM>OtoszAmxcWgTpackN)}RuER?u;CQLo-q1i@SveYqi*?^^e}7*>h%7ZV6&)K} zdS&R?sn%+_w!e1jaCfc6QE^41&IHEfwqJJ#P$Y*0Nn+~0cX04qO)XjN;`}`0rX_W( zvnW4bURgOo?ZKlXozM5f`<{o6E`~%ZkvP%wD^#|&aw}q0i*@>a!Tq(l==QhDM%;uY-Q&(JnHX~}kpQR$_tUlA zRR~P^%eqP8y3t<7Efbu1y5NGseag9&?D3(J%pZSkDGAGx-RV151|azWM3Bd%T)52K zPQ@JGrQSq2)YlQ#0zr`{Pt-ZvbobK7PFj+plw{fnJ& zNwltY(DyZ+#SNw=;_NPA0_voo88!iCZNv3e!Q6kg+dhY{q0hIa(YGYP_N*`-b*$8; zeel^8rDQ}7e(5z6<)Kh#HCTVge(|Qc(%vBDr zMj@TS+y3suo*~=$G(h(~t2jL~6I(x_M_=u*Kico0sk!=3FHE**H&N3@LW514 zpM;MOug%+lbiAjhhvIer;D8haETCtr-nv4wiMFJov9XZ?h&69!I2?rvajc@ELUCpG z^!{w6fvTpw^rU`>ik!UJX!G{wChq0p@wLd>^8Mvr@x{mf@2C+Y$$dvli@T(zXkKiZ zZ6`-fIr(V)kY=sX2+6CCy!>C}rMqV@Kx4yKGE;bWv5OnmsKxzE^W)c()Fh3kD7n0L z^IF+OK|vwGsp{&=fV;c1w}+eB=M?Nv5?<=;N;DgHgUGr z!c>DDF;K{(V{d=`uXAy6k?dUYtH9=5ivSWD8kn`|=?K&kh@2U)8M13;FV*agXtn*g z`}{Io>mA4CPw|4KjFXPkv4boLljTASN`xC!Q^#?UoO_)>vhA}GTIzq8&j`$tP1^UG z?fxJgBIA0wQ2>AX;`H5X=fBNhE_BUI%nX84P{7_u^Xfc153%5k15c~Vpz|=K!olg$ z(DW{$CEpKbV201EVwtWMK_2;(r(`a^48Lzsj>_WhXnCVA$A&<$+43&dg!;SZ{a&Ee z*G}=%qmD|uXxgqgHC*CBFdCkq-+~h!cEKp3F`_CkuHLVd&NatalSeha5~kaz4kzdn z7%)L1`Q12#6hn53vu4fdyM4y)tGh!T~Ql%z+8PTF`DT9}y;z=!WP zNjqQh@d^EtX*cm3g>Pm92vZJ^XoKTH1OX%4FduDf#ub9J(vf*3MDN@wid^SJ4yNwr zpclj6{fEh@YNf0O(dh&_4gFS%$0LIPl-=C`TG(HK`;R0udVc0DqK>Ly)fkBOy=MULksMl!i{sH@*Xf1v_u%;lc=8rCL#S9kUjRCS5ap>KvBeN)>bYHxph z+$LJ#>SU$VUxe_zA$;D<$vw>&HZ0L%^1k{mw_RQ}k1}2EZaNmC-ESC=SzL4&7=}k3 z5Agf@{SsV>Ga9)Ft{x#x`}O+)Ce28F7OI+`oInqJpwJL&ZJ&0m(Ze>6HFab1HDoWC zWL0mOXzcN@wYmC$`!K~bdUX8lfC4pO6sasc1R4wu@3VQ9nX1ai{$}gvq1dtVe&BJ7 zsbJM&d~9q_hU<{>$gXtix2xN{;IikoLd+8`)Voz0lxrcg*V+95o7Sz#j&y)d1j+%!t} z^6|hSEYbt$c7Ktzo}DQ?jo|u*4Q;18rek4KZAos*$+Q)%X6)dH&^}c2OAN7Q(R}G9eyYT7;>qF-}V?Vnj!DRI8>~ELL4IV;onH0vLD(`bk zqFFTP_Tbjj%C>L6VzKh6SVF%{^g6)}lipG2N?muV-CeNFz-EgQpQ7*q)eW~bOphp( zvXHaBRrRUhMq*wj2K(XNzM6iMzdXE2F$=bNyR8!W=*rPqZe`n+8zW_HoHJO^R&J+J zJvdvvW)vok70djq)==VnBTm}(9}-Qc&qd2MYib6D_dslPcy@p#G)|lTOo=LZ(*=Fy zzU<&IhSTXXvJY%EXin?Gmbe1DhlhA=g6cK_4B--9`Rg@j-8)kz3AX;ADOwWs! z!+dM69&le8%c3zHVxooN498iyl@F`eG2IVA2ZtMXjH47LLyGh?;m1ayyW>dVHJuZe zwiJ%CKkZAXC(%~Fvg7LMvrt4*%s>QDRhh2nMUo-cr}|EQWsU{2o*Wmr=z99d235U zdUGLL%E=slkvTPr!oX~0IS`c5dpt5Ho=rBXSZ6xLYXjP=MtV8dpFFSG5i|U6Od{s} zjtCMq(L0dSp0>a~%j&3#fie(YMUIz+{Z^Q zAqj@w`q3e8qv0_t%v|W(*htR-cigJq^xGrvVStO0-aPBVNcS`rqKAb^73#@i-(Nn! z@ahVidG7x3^({=~mHXl9d-QLLsBn#4l6HzDXU@Ooc1aZ-GVzVMP}_!p2_V^Qex!Ij)L=^_|F)U>*ApWDTODgvWeR~Gi~ zw~TcA3GGKqT|6K6tyE{{!xXv`r;>6X0Ix6O^8;pOY?OYYB|f*=5Na-##ho|)w~qc8 zmu8E}4x_<-lhe3l-RbkmnOY@P<8@4cjZV3pA^S+ts~|YRAZNmC8Ke9umiyx}=v&C* z6U(6e@nS?WH&@gI){7lnrwv5g&$|Xs_KJ~|9Pr5io-=JlDZv;&;Rz@xP}pZqkL9kq z=vtVLyFlk7*jBxnFzw{qGj`U-T$qDj8C(z7twIFI(?=V>$G|WnKhK=7v8awQrE>lh zZXY}S)?Sd+Re`i9O0t{j#wy{D2^nmJEgefYtFce!6#DCFfM$;*&2GVE4;$TnsFDvYcOEI*=m=E{0*6$vJn;&xHV=?ba zd3$#YN;XfUQ_W@rK#ew=l7^~*_4Xv==`0yemdP?Wiwu^d1Ic^~Exa{<+b%oOcrw{# zPchWe7rzS9COxxiDrz?|j1^nwxe)4Wtd$&@G#wNsnwOieKF5O@q8`caYo$-Kq#Yr; zzvi^yl3f^^_DU;rV>!zQoEGiAcVsUzSpvbsDqKH_!rE3iY$f>l?!zD)?MpA#e5Py= z(aF7F;hb@|Cn=EoC;saW+=IvKI0GG!p7H<1`Pew?m^rn2y0$w0!b9t!v3~ca50%jU zCKAs8)Q0yQsvXcHdB~&*!~>88zoV9(WRw3ifC}LgdSIKoe%O{N?;{`-MZy?>^vpc{ z84z}6K!x+_!A@sNQwI6c&s_N)o~i0njiK8kEIDtY(#2SPYMo!^R~!DjvfUI?n{Qp< z5I(G)fg(8KGEI1XCBrG%D6g3)k|A=eX4l-3Xz3ETyqmvzO=TtscuStnc4Bfnv0#@X zKRtl#)ONb3%X;T}1=~b7v#w-=+z^t366fZIEJ>eri$y&*pfal`8Z)i`|> z3f6y&EPWpN>b^|@fnkgEY-Asih3%B3ng8tLTRhhGkfLciwk!1~85y^8u~O_nAE_qg z%w2fQ9~7IuMpQ=%WXKr+ARw2Vn2apzB~SsMfx%wsLe!O#qs~yF&2w3Ey`A-QzVg-dnEfcQecTCm2|#NTw;)E+rQL2dvo=G1H& zpxDiU39o${->%b`a)6Y&72H#|v^R^-PYO*$?R^ZA6I;x;7_MEVXD;Nx?(`jDfm=mD zyW>+_-inp7KSnD1Ab@f7F+`kJUS0`Axhfk#kq!N(J0HL>Dfrvp?;({}(D0c_0pt!9 zX_t;FH-B1qAIjRv754Veyx)CNgS;6&{KAWUn^S)xy21vqOi^E^;o*@(3Mb-h6uZmZ z^~xk^#`zUjmJuP>jAQ(?QcoQ>x@Gplg$7q>rgKOQEUy3xA1q;*lcHiwB&?e1Z- z^3CGW&Cja!8H0{2ZxAtar}8|JS?hK$ z`N@Utih~V%7}~n2KzUN?98+r9BU-59C_e8i{eU@nkP6jGdz&gdc@tiA7Z9vxR&l7;q#f{cfGvkGpiJeDu0j4 zu;fb{%r8iB;?@qar1x5|z_$7n`|Aw`Jl@{=Lns(QPCm!%ncZoG^F<3)k``AC|A)Pz zWAeZA!-TAVGt(ZpMT0`WLn&koFHC!E=i)i2k|^qSkF;F>G-Xxxd5%Y_tu`AKZYqUB zfhdYHCQ;YOe_C+N|40o8?*K~N;LaGsF?lmDq3&Qn+KsKNSi344(=){ZqwL6^2pzgS z8d~NKb}>QNf&SJ>qobo{Nesjg|7Z1v4$_g>rG}sOki_S$p2jOI}7b9<;f5g*MN{LWhEEZQ6U! zk_JB4#~WqBSO!}oNq8t4_Xl!@=#-zVhvnMSPn*UCSCO(kN70CD5?WIfP{+N_(?<*%PT&RcYTwWZHX*8gey~0DJ94Eb zUWiNoWTgy90w12~)fDl$MKsAnjqE%hX5GaebjI>$_uhBwt8=S|n%#Qd_;LD8lQZo* zse2hU?)mZ}IK7DP|6E1Et8UB?_Wlg8l*?hrNh?a5>5UHbYnZ=;C7F;6{fj zMQTkM5MGN}q-d0`lr|{3h|s>zZMS#d!Jl})`vCO_K-(zF(*Hb^|B=0Qe!qDPx%rT$ zizk?tp8JXx+Vv%E%#wFtf2vqi*OS9>q!Z#anfiCmnph_$KF8vCtTqWNxN3=d^~2Uc zC@y!pl9oqYX=y3_`G`IpJTA8_r16^F1Sh3tYob7i|Kd;bVZzCOZj9C&9*(1M+4Kf& zd{}qO(Fp#$LQQ~{b}wEQWkXe1Ge13(`H${w)&j45t8~9ugyK%`VCcl?UVjUnbwd+) zwysqDHkS1w$z>m?QB3yT<*gF8_5$8Rlpe7fh7)&HC}BoO`Z}CH z8oeXm?=-KqzLAIpczGm<3)SI+@qZ0-gJ6zP_#6&cz_Q!4bBeS_;g;LczQ~u{~ zi`52@d3kvR^Bcm^zy7_jgx056TN?THIO!CY8t~d3A~+pQ^8I5)*dQRdj4(p&JujBR>LT~919pmgR@^Gh`%jR{;%gg= zxXq}hK0DPU5U>FFOtT~EMBCvnD|-63b70CQGd2g@`Kq$xQ>||{TT%bE1WK%6CMq>G zbjld3K5Q=YI)mc+@Wx-b9(qIa^EMMqT~T_K`#oJ(?&Tpl*z?}>@ zv^&Ypp!Ygk!|^n!@zn423U}d`1Sq`U{@y4HW`kg2V#0AfNI*J#NpKPB8W$%gH?E`b z3G6aMtgQO^{!f=yj6yvez%bl)COu<0z(^XDw2s*ARLoJGlbChN!8d5AJ6m;5Zihcj z`BRbxa*sgftuQTnegKCs;`ng=DbR2P;f_mA#yIcz_!AND<4+rn54w`_WM9ASRRRQf z+(PBf+Yg}}0ovI2ch7at7mHQPha$|3ZaFE=zR!xNKp3;p)(}~X===d+@o!oPmd{#k@4$~ zfRL>XU3@qiMg;gR6u8Z3n-LW~AN=YV%=+_@rK9DkcHx!daU(-81m$e&6kmssz#Us* z$({ApsXW58nKdIeml)ArHiBg$Hs0xt%-b^+Q-?gC(D$L6aXs$0BdMa&(ojcqzUW_8 zleb4RNn9STwIiRmo-S`Hy9vk$n#XF=p!EWzkX2r8jgr zpu+w^)|L*)I8&A<#(9z#X~`+U-=>^49+f?}S9qf?d}m-Zj_A?;DRgAxB=2o793>EB zjlKQn3u!DTE6#f_7QfR*-aW`5AtJ0U%q(~MUeLum0c zN4s|mT0#XgS4k7@#LIi3RLQ&_;mXfWy@D;#kSY0_Ybm}?REyzZv$ z$%>k92Iv_d6HD$-RSb?5<(rc{)b%z;;%W#$5^L_sS1q(jNu%i&`S)HARTn*af7pG# z?&RWIwwiLx&`~UIaO=YE{XxRToseK&;};hfuN7nMTCOvrO&QZSFc4^oMI7vw{MR@d z8XB*sM%+6G+#fE0w^@81Y-QE{WcWGWU^Xxg7Ny%2A6M`f?JIm;b#hI6ppYt_a>VN% zbFKFUKK5VW@X)}vodUqq`nBcXX5~vgVCtH9U^+&g7rf4E(UQwQQOdcxj*|0%J8l} zu5NBNYzB$#aHxNx*7um;z%mz306ihGNJ&j4JUIo&>nHRg?LOv&ac$+1Jrh)v6bmxt z#AGtp-s<*~DdPd)Q&aww=6vUh0d(tI%+|8+;?rZmsr&1#>*@Q8VEe~IRzzJz$tLOv zdAR%A3GzfnZT*{Ii(wYMvkAx!m z`2vh~yR{1pwp~F=pe3NGiB<;oA5PWJ27Vh3e@wfrngM@C2gr%it8>s(RG&>!(M{P1 z=ep}&Mwbt);)g6|S=bc>KpK^@hlhvxVx@PUSi*2$_zIj9?wo0> z0@EYJ1rkqEGGn_Zaw`b%{pyp)$H&TbrpN{c21qC<=`va;3l#@`sG6HoLb%vj$AZ-V zlDytTI-W-xe!W;-+mJL!@2>`cBne|T_kbHXd$;tBA* zp`81pEamU__T;#0qv@s}By36vDgAd^SW;s(Ze-k>_=RbC_7Ni0Wm>;>C-b`3hsB$s4potBdilog zB{5i*4d5aQo$LRy`cXm{et*U|D-RrQPro(Js-BLT-#jhxn0W4>$o*3j@`j5$rV=E$ zn8ZdMimf1Sy!njbF5^bXT{D@(g-$|3V$r;w{+xoIK88pvKJ=FY(Edcmghj(zzk-qm zqpn9d(tpR|?=d%^IL^P_F4~xv^8j`W%xA%*@1Vt8+qk#sL>|d=%DbMr`8nFe76#;1 zmh0w40PPvJh(z(_*%^}FiXtz+>aOvZ6l3A-xy9}ox57@?ydHXwJsWmaRaJqdGe&vi zHU!{rF#Hi@=bkM*6o^o1M-<_IkV%mRtN+XqD0DHz;_v-xQzrJFv!m=9W#P3bg{)RPr~5$UeTFTh z)`oqo)_aL=ax}^SW}t0$;lNq<`tX=9Q)4#AjM3byPbyk$F6&CR;jYcQfJ|u^s7gou~g?$UXj5g5VHl(*YP9wCB4d{2}o3 z8$;c)in|3&@V?PTyeF}Snz*Y!Jd_R6u4e4^nZwoYsh^F#TLM2#ktN9j$wiAfndO7Io^q$kEZmPFXk2YN7uPau{9R zxML(2h>leacYI+qVWxn!I4{s}bLpxKF<*-YK~1jxJgt8!7?z$4Gpt!rkW~#^@$uL) zr&hL0Ic)eItR8KS;gE8&c&|!;9scFoQ6msiC{-YD1NR3U#H9Rs_jCm^{oS4_jHOlI zN1BVcRNYJx9AEWZUy9W&e2`<8Zttq+%bC2QqF_rXo=7H1KZimEoxvXAv;`iy;zf3| z!{zU9_oqlG9(XCc&e-1RTukqE(d}PGo81ul5PxPK3Tw#>I=Fzx08c=$zm^r{XD$0s zk$D3z97Lm8{kBeA=PNUJDZuu!zBEW%AKf*B9Gs}hlw)i?<2-e)!wImXL68p>SB{sG zF`)!W^KTjIy04SCW$P&f;~mcte<28>=O`7#6(5A4Qm8iplGA3 z^#(KIAmX4;mzG0V34)TGs56ZPfu-ISG}*9qW?zwl3rM6tY>`2aIeSCJ4vGV)4DOTH zIG!gx8GaBmhf#d!;n0ggF~rwREn^TnTsvE)r1e5>cw}5hv>Bz?4`5lgbA}x=1}rL- z>kZ${421=dc*=zt*;~4j`m%V3zs3oupVq_cv3f>lk6Y&LCd*DEQ8><6AEX4<9UflT z!GkOpuiXNVCx&^rhaQ=u-!JO;}Wh-4xV+Z#^i znFTZ+bGp}9UvIBy35g3sN0_b}v`z`?2)!S_b7pFfg%LQ; z++{9X5U#3@K1P>uds8ydmC@Z&RFm}{?TrAXhh6|bURNi`hECCdpF2<(UWXCQ0#knb_qZIYw9FuqFQI#dtfVn1D%Zye=^p5p#0Is)xNhN8SJ+4=mgtU zND}Y+uf+I=W3m&GA5N0QSv_58`CCVaJDqNIwPdt}M&SeuvlY>_>B@GA!@*r0^kJN{ zu@0NZU~u-pE?1aVh*xHmt@DHTMpBP__`NCw-sz1$NJ%qENpaPnDqKeJG#@j34vi#s z!$I?DEJdhPtY)kCyz<_GnTN2Ub&g8l7zD~TB!{5yEp1&@s zLnI(cS2p{Pzw)AJrT9B-;H5ijvuiv%TRt8Uji$#-Ty+E8UPx_bt5ws0z9_%EJv>@x zWSj!4B&NLT|0Flu7Z~DCPI2A?O<7#Y%(3>wSobefr~8{~?8pzQb*bJ)zhB$_JcQ{m zJh|9gdSSNR)U&9QPOMktE@ZpK_3~yW-G-fR8Id@gN7|P4_I2MMt(|@!C9XfUwR0{i zwf+%0afDk8$^cD?UZs3T-lmGCWXC-~<$z1inqkm@EX~3BH3ucrMh^&=qah^-k#sqV8Gu=aO&DUNxj$soq?kPic{rf`t=dv4^%X@o?N9sYgI zD4tT496KpUcFo0!{+}LScD;1ql@?bDc=-O@M{K5vTc!nmE@WeP6e5_O0PR@+ zvyUzO!2v^^zpAe5#%^MAnbtDEuqq8mAzH70{`~nyERl=^c=-b` z*48E%4!Gw9Z3KU+8^ZeIb*KB62E(hWQnEB>kI2$dd^Ejn7RL5c62=6lPAUhANrQpa z;{7^bk#xf#wxZq7UGNblWU6{orqFqF343)@;zg=8y4qS|u-Tu%O{HIWeijNEQcLt$ zP8qK+3!Z(&-2%gMJ{Wa+`n>FSoL^TLf8%wZdFn{g2zq&H%P!*u>$B#faVMNTTO*i7 zqWO<{`SUR$lpE}2Z%^5-I&%y~dFWQphDCn<6i^HrS{JGn5hFLuoUT!qK@m&IN|8-t z#KlNqk1?&bWF^g(KfnFin*1E!cGy*~|Eu}(+638r8}4k6+XUnF67`iGfeU#&ORr@3t(rYHW(Ozi-3f#)S zR(_fl+4$fsiH-{((#FqSomZHF-QL4I4J&|swQnJHtNvq6^Ue3j^g9Gd1nW!D8vCV` zLV=Lgyq;8*E*+L#dv>&zaeCT}0mN+S{)gC(T=T!-t|3Yg8) zggGWDAyZTGhc%~-z*~o#F=o3ZgM=_)tuGPW?<`Jh4haCc97>L1yyZ;>uPRJ{HT~=B z8coLaALJAjU>bmIe5FXdxAk!eTug>8eKf2$6|nEN?2`AJ|P``05n`5Fn&@U6b&d&JX=D3s<{rTrHWXJCf-S5Wv{`17lOp~i0naCG>nN=7HB~H@kh_@ zXUT`##ir{p`IZxg^5qyu{uskm*FD@)jGc(QMybn!cQi{n@J-q5nO+FzIaaGb@y#TFDcodoH07kky`-9@$*| z;)V#ZZRhxUf;dC|aNdZ|a+AysQ+b4u>>^!#3tNX-0_n_QBYPvhmcn_5Q6WLO9unCj~{O1T6< zq6|VgH9Rzn(B{}BZlnYsJ2Uza12wkur&%29CC0e4Z=@k%wFzJ>O#+YA$5@;}=}$K8 zfdkttw?hadjO6ZA$p23*03B=kE)+IZ0IzwlpKwQr=aaq=fWwgPLkc+Sd(b1F;q34B z^K(uj9%Mwai=$!NB!MfRN+Qskqs@W6x9jCs2y~x%+K^ndE|1l=7}XeienT%BzM8SA z16#+TZY#6Im{+p1RzhuC1M+zEfM@VYm(TH@$pii~YgL%*;DmTmuxEYOF}itdB~`E` zrWRPULNl0TL;s)>0 zwfri(lgtuyGdivEm}~zUTMV@(C){^ZLF|2PxG{5Y@44^b4i0h)csl8D8NnMuJL{6J z;Z0 zxigi)Te#!66uGKySmjXx5*FfMw20FFefNf9o0UN z(%^3H;o9fk>ohO)}tC z7uNJkI0asMT-O}fm|vJ)jqUP1+G)C1V>4w#hB(NTy?RugZ{H8QpF;qktRy+o6qo=* zcL8&POyExA%BwSN)gfevaMFy>bgq4O06E#ls#k4P{?^IOq|DA{+sB%u?L5N%x-|dO zICkwFmL?oE|6NIda!b>R@5|xpa)_AHV6O^o>mAR4iDU~loVBaTvUT7BWcAa5mt=Nt z=|GkM*j>xwlQ_D<&w<#ZE7^@>V1FDugyOT^UoPBAqY?xb8Gb=ac=fOOF<_Y>47Jvg z$qBHPP1zTTH4JR`x6n%&aNCHcrn+MplC7+#kkgmblHnTNt25K1?L8eEIxe29_(#%<|U2eb_y6F6pv7M+o8o#J2!*D@!&TY}dF zB=1I+=E3P|zv5vEqESuFd8-9;@lg}hR1`ligia(3vg&QZ;B*bvI~_;!WeQ}z%mNPq zQ)p@xiFXd#{W3h{oo|feV@<+*V?KnIJt>;Z=JveUZ~#O_S>f->Ns{P$Es|~z6%(hX z&j6zCM2wotdBTgy3GQ>KwGrycx;cTTD@-1dO@R}$1EcxRn`p;3hIp+ge%a=@MI?$K z)+!{;R58`(fprXIeY>YK7yaGkAhCM540N$0d3Kg(6R>Av%hRp`^hq`QS_PKEwX@8& zuCNtkUUn1JL!*h4GGmt`_3I|^!aEDBLd-=@xe~L2G9@8VPv7ui%VS4}N%gge5#%4F zEt+6>{e|J-FgTu%I?XLD6O9!Knyx`1)a}jyT`8@sENpIm8hFPXt?!$TW{02t<$|Nq z-zmK5EU%)?)f`gu{duZ_xue}^(DM(c#_L-pOCd0E(Ohjy;ubBo!Egx}$yaB&96Jf3J1wk%){~hhZMh4RRjI%T z&vxXO21Dy1*a~e+Gj7QUL2*;4=XIF$4<5`ji-FRC0(u&QIS#59-N15U>SkvOoA@6q z>8lbN5x5@#ckV3AF?(97gO7e^wYR?y3BGb5*I}Ke_Lho}zr0t3 z-RFBB)#zA(nq`!3?Y9_R$F-^_AFuXG3X?FFXOL8Q1T0HA8~DL(^Uf?R2q`Gc1>Sug zKtoPJ@&C@>0Me$`%klyZ8dRx93)8;_xM>B)16z8eN-5lf9@I&*G zaw_juEx-9Q%^4_LA@`z?l-uTGzXCMJyA)?`Ts~daqGV=E1Rv&#iJ9#V?3c#J!ztJz zPlBLqKQd*4uj|hPT*<|$w@qK37q3KtO+604TPFQEsMfulDKuuvuw3iX2|`Nv8B8@v zcVIC~NY!HnRHKKpxGi&w=0#q#W5O56otd*zgwX&&flBkAX|u}iEgEcWY_za`;{^PE za-Zv!zTOVZM?wk}s>n%>ZB@KrwZ5?rkX?*# zoMf4ZaZ0F3(o*0fUkheN5pjlj5J4%lY@#HI6GK2i2<`<0Ktn?}s#Bdhy48xYdjEGp*X6wFpz(g$EQ!_5 zuvQGdKp@9WjmYas7n@7~oRAn3%)Z5#^{^K;T7$?BPPdeTj7;ZXJdI#_VYW!_>3N}p z3*Y0by2G5ps>6bYy4Tws!Tf>nf7TL1$s#!K(a6Zi5DwFf0Pq?f48xYK5eQICH}j<` zHHnO7ivMs5b_xI7Fa5EdMVP^M_>%^Ni>xeIO1NFIUeOl4-@6F}2ZQBZ1 z_)sPHuzm-E1oOPvorsiUkraQfi7=$ZlorThXB z&W;7K`w#>n3%`Q^ae9acCLU3B;~?v!j1*)i6Fg#!e$F0JffX0)HmpcBmxrlTTvv$I z9NB^n1!8-gY<#-EN9jz}=pJ2RvY^YYzm`=kntu6-Kpw=kCBbwkEq!3(*=e2Lcn&d!e~ z&CbfdzjSFh6+4kQ_@oLpFO4VA@WdnD75fPC^^Lpci&v7TkL*8ibHC6(k>1Tya4(^-r zXN66MCq~BxH@-(0!~bTCPirP*)zz{7vA0cn3YQ04TwL4~m7egw^Q~Yu`SQ?xNa2pi zyn#}}Q$pDqf8coC$^ZMm{-H}ap-btXU;K!KUtL}cx6MKLe-^9s$C4Qfi-&(UtRkG* zN`}lFeXjB`Wu%N%x9)*IQW$tU;f*UL6SJ2=z)JuF1GfUa^|SuoMvFKm$k*2wzRGO5d;u~3KP%ZITh^C5xF2XaQ_kz(U70uB{~k8{uT;i2( zgk-SU(eB7hq?I_*DoYS7*@s}puW(A)Y(^JDJP^ag6F73?1W~6T#~8mN&3;9;2|k|l9^v_ z0;n3CT|41R)zL%fRyg7zj2sq{s%9FGd_a7lcT5B-F|wBn_0#jLu8OHLP#|<-F@a$- zh*zM8WhXgpJBJVbkr+ZeS=b8LXdvi^H87XC<9`XZr|mxGgB2F;E-1ywC3coU_alvgq$kmlYAXc^ z=^}rfdh8QuI-g#`CJ#q@sr7aTfz)$8!%%;;oiw(0zu~yLo$ltN6)w*VH@B53({DE( z&ZE_TY;YZ8aO}3c+Mk=~9<*@f=NU{@TT;6@!TP&=$@;-qahmmWGk*iyTM+hs#gJYv zDMKmUG~2>1QPU{!Rm|4d{pknji3SN5X<8a901FHfdZq7n132EDS8M|8EHlQil?D)D z_`ihxo)LRl2hn`?dO5rotTY<1n{z^)x$-J;v8ns$eV<_Ut5rc%ZYIyL5wKCFBv&Q% zZRz0~YbIZJD-KTova6vuXrYz-8zTsAilKY`OIZu1%LBDrQ4uDa^S4Q4L)$g4QR1G( zi4ZNdiE{rOkuuux(Q7X)ahqg8mhb%Cw+*bUkH-MQ?Z%G5W_uvHfz(fJd4udB@0mqiVrgVZnUJDr0+j5tUjGQt7f=u8YAcF@d;%se<+osy2dvw za~%TVWvgan6I*G%S{Vgq#}V~%t_yC^4%`i)n3uzxcWim^>co*bjc+Bp<=e*8M38u? zL`W9shB4|?hx?yx-Q{XAB)Q?H2O4QXVtO?M4PSH3=6;7TEQmH|)UN;XwQ?D{u$)Ts z@qFd9h$gb8F;HP6W7r7F6X$8mlcOC^@R-asUpDqJB*<5P7doE9)Xyj1DzmgWuln>I2;Y=!gm^fX1q_X!HyrBMwv zMoB18TjowvbEnxYOA#R7TUzZIVORIBa3t|=W7Xp!!YoSNa)J`UhjQa!XtAdbvUI&* zmu~EYzf`04RvtX1$v61YB-#rl_x1Mbm0A@vo#+v4)`FEYkyzBV)h^smX`bYEkcell z45cSH)zpl4?kx~kzDcPqHMWDQ1t;z3G7I39FeK>r4FychZiYx1?a#)1w~L~AnOC$e z9F`hxv=>}KSb9$7r+OLw{@QY){MHs$>Xnl;?}|Fcj-m1~K&SX|{=>q9FBJ`D`jH2? zh2o7+LQ=qL9(oGQ9vtO*zhFv3aqM2gQg%O-z~eCg%Okdixl5b>du32AnFztnj|n<2 z4WKa??4uAw5G$EM@d%=MtlS16sqyVZ0t>ksJz)`f6ZXl_30$;S&clHv%09c_W6KWr6jSM;4&b zpey{r!By2iRJ>YZ6(SC|585?YzVNS@fsb5DtR zjOL)b``z_xcowU+pLktuL8v?QDwq6sF+m<7u3KeFo0Zpd(fk#~_27KdQgcZZtk!WS zN84|*BobUk-9Y+G|DMLQ0_6*70LKBpb>&1yN6#%N5cgibVlJv}($GsbN~bUH;!0c(ACZB7|6H+8Y_1Fd^$T1prdFEmCH zIx}G0_1D+q2iZJ7mB%n|)Ri{{i$tYxg0j-o`t%>h@EkCx*vaXen}Z|*Uy+bCnp3h% zYA!7}dPltMHldAuJlISYm4z}NjKQ)~B85auBO{n@5iO4k>RS``cze8rhi)-^?soUvQdEAlYWICsX8M$v;3p}5$%uoBlzhC=n`6@YuyKvf%0*vZsp z0_|u{z*0+9N+rnQn0RY_rIHV~Bc+BAQ<~{|l<`X7^pCK>J7v&`@_DWg{RKdXpQONK-Nb+pLBz}?W z^h5g5M>j77vA&~(Uv-H)-Q4w{S-^$pJtxDHs>eu^*(nGk{6>NefZBPqV$ zkveuNuKzykeMdF~+VP}I9#saiko~r{1Oys`P46R{?fPnsC!FrCGq_7K=t=k3_D}MZ) z{s7s=@-GQ;Ve3jm?LJIY87ZQtpaYf28O31YsZ9R3Fb~_7)p9n383_qEKNdbb;o2e- zT6-90S)U_0$bs$B(oesmYI#iyd&^10)p3)>$kE6G->|0(zIE5=gPX+d9>_~Ls(}APn zxmk)aWJvh0oNJw$T8S1?@F{)RFn(Ozegp0d{~6HW;Xu(6qrp`c#rFmU-imVn1>9Bd zfurp5!YJaFj!>n_r^N$H9lm-qy9+L@J zH8ChKO^h$Kl0f0OY2$sJfzp@WR2Vq0aWkdpazbDYdVc@`mm#jREz?h1r zSU>a^lmL~dvJH=@=RQD^^uq@iO?AtpU^_+e8U*=pp-1&fP9q-GU)vaLj#058#-vG_ zwt@_V>Z~$#Ll%Nb(dxn|#L(gYd7b$AbBMPhrS;>~Xsuw6fssK@&C*KbHzWWejYJSP zLPfODPicJNc=G8$-e0MG;W$MQTzLxMJS#r>Vwtdk>MOYi<^u z9%n6U(m^l{gpMm)e$!AZrhpo`ysR0U+-A}pgNuRW@e0TrB3-@Z4B=q#I7p(ugcC>U z&LhUnI;JD#{d2No_l2fFQ6rry{gKtS#Qy}?cFXx(z z(oo`LBm-dw$!bgJ6SWYLbvdc%c;LW6G;`o6qb4t8VmYuw?hof5DmI{`(v`0S$r9Bq z>ldq|#Sr>c>5fSMj7oC%O#Kcz7ONbRLA@eVwqy#uGmF%i0fI}Y#7nKfFU{>3ot4?! zQ^ezjq?T?M@YV&Zlt+B*Y1-pw{nh}8#Y-OabHomERr(oE zy5F>jJ4^R*e#BogBJxEs^8!vTZ&E&q6qLNY{N-+pRQ8ndH_K3+$->90T*6|Ev|Ro} zH;^s^L}Py#dkI}^O`ngJL_MP!RQx2o%cKgoSkE=wT(Ur1mJoaEsfI%6n>LJ%=9MjOZZB;aH#X3}P@v$iMByUlyZ%oREe&Hnh>qqrBP%Gv&?U!EAl z@0hWMWe&w5Xr&h}W^f*{Q%Gt{PbwiagIZ^?Ou;m}+3G^7BBOclsTh%0wC6nJue#a* zljBvJz^8Rq(A+h#sSy=5+==AZ`oTUN{}61G;SOCqB_(R~UW=6d5hpaW#Ptg>2%byk zOn`LnBUu2MIyqC^=%i{3D>QHCPQ@spw)5u`S#Dj+qv6agfd$;sC0Ls~T`=ssV6ymt zfq_?TM}D3zR{4~cmfB&M0qo!UcE7@LGfKaPq;Ww6-iEV#vsA=tm{)!@%ckiMg*a6O z(ZW4ca9PVQ)N>%Tqd4}5Wfx1pNW+0&ofD+D^D z@7}?TAFE?gre9zcKq**ceg#w+P-@ghfvK%<*YAU2o7PS56W6L@^C~7s_*`6A#f$=x za?5s|R}>Eki~JB&2+J82HELf=Uo_nq?Wxo)t5u?Eq1F|ww{ z7qP;2p~}5|Ek>lnm?WTsb-zJ(d}>x)q6*mz^l64Gr^k5wr_o9Hu;LKM7ubM!T!UVp zBYlAHliNzG>E^X}p<9==`v(h}CZ9R$i*VxkHvW)EWx2{$;T8g<08A%8d79wOp^1qD zA6Tx#df)YOjh4ZQiHrEE<`h6)h#XMpZ|SJjrLIcn*rzPso8dO^)|6e~dfF^8x~rz9 zbxVGWLV&%swS4)dvLSm;8w(~INAb>ib$H1CF?Cxpj}~+ z-(GD|JeY9UTcR-YJW)Adva@5LwMqFPr>S73bFS|6fZd zNN&aL*WhRbf5D~bQ&SHwuS3GA(ZrKv{!FA6HZ-}eV^sa@7{Bq-LWI`6--MK*h#u32W z@KQ)-`q5mpx>z;6! zinBtK+}3`tl!2}6>%kyXVP*vvY;K*gJ?PZ8d942wx$;|!@Lq82+&oDV-ALlF-+jyn zmrIP^Hnq;iDZkabq~Wkhmi_zI&)P5TqcjJffBv1Ccec_Xr@Yw32J`ugLq>lnbY2k= zaF3UJ&V#Dxn3&J)EX@3Ky04E{rJ8NcEBz;u(f>}-fAtFpuv@WcsB*sA)()69_&iw^ z*W*^EvgdD`Pz&cwdHMKS49c2W?e;6(pRO$fi~Yt7d(O_&TF8cD)c}v!fX)c$Kh`Bz z&(bFp$bxa?;0>%nKt}HKcvxG|!7UgVDF`?*u5=4zGD)QWQ5=x{_lp}@M0lkDY}~2) zpt}0$%*grfcaWQ>3+~P|K_TlkFa_6gXdNV^gFjSqUz<{x)l*hcYQ)C-?==IX_AJTe zM2e=ZXuQISWB-f@|7vwdEOH{3POxVp|D129VSeTt_FuH7zvRP=T-v1v4FB;s<&+iJ z&ZLDBWsqz1q5%DN9&eYbOK2wSMQ(R5jjR2UgxDPeN^5G2F`kU&Xfcv=2T^RQhnDmP z5}A(Xmp`{-S#!LG{iSsWU)5UkMos#+K^!Ou~m}-C?YJVtc*~+v3 z5lDbyEeV*Eckw;Qa1JHdvUAaYm5<#Sz$|Is^V@iXy)W@X|B-c&tvw>d@m4{dcz4o4 zPbxWZUT1ZAdkjS4=DbR^3J}m~FmqSl$O?2$)NfoFoF5%nq*ko^H!e0U>Y3A-bE&TG zKIN~-KK}VKN|(qVuWNQlMRmpzMi;G`)WOTb_qk82H!*!sA~2wxaOi?(^G=TgDH%6| zIow9ZvWF_1)V%72@_3fr`$Nla0P9d$1}_WQ+p9-tSbe;|jb?CXOmMw~j*gDnVU)DC zrsfDm(AjMFS_YRtMEj-#-2B2fyAbSxJu2h z$J^z^t6o9W%lQjeQIu;XbLFeo#TN3x5kc`0^F14msw>e{S@^lKCwIr=U{4yiS0e3E z8KS%ahwGT3=)^O8 z=zyDGE_6TGtgD)CP=?JA6d1igMl1Oz~Bnz)~gnfKN@?01`Hv+dgGa9xE;~L_|FDurC7-dY!nBxU zaXQDk2Bi1|gh!_6XvWSYI2tY&Z`lSX@uR142T=$jHb`Yym<5?d9FPa|OtH;HIV~j@wDTwdx?B!!^s+ zD?wXZTL9zIik@T#BKJv{j7lr@B5b!KPx}Z)^DqQz*H?oTvcr*f_k<0AsoB0E^<3c} zVA!%ujcXof*Bou7!oW-c3^*w{W0gqJAtSk|RP9Qz%H25RX}NKyqQdVoo}QDBcM=c@ zw1l<$oZmgJsg9*6Vkyu}$!C`Cn$-1z6ewaREv{jWuN|)~a9;E+%;h$=15W$5-4c%AGf&v!0kF_d<<%`|@)b(_nZZKKPoBkB84cFJU=WP#~ zwW>ca+FvXydyb+D3rWR^<^Dpmjdzu58KqWxYEJ;HT@N&KWLzBbX=JZ}ID)Iju7&KD z}st2qdc#zUk=z~%fg=5lNpWX(z`|XmF=&aSpzn1ZKtjWGB_W@y;hzt zAHorInR2VG4^16BYgntdbRDBE6&3*Pij;z!?z-zKuBwpoj=ZP&oF?#i?r++@UIoiH zY%ZuTWSyRO^X0OMlYu>zlpLAOVr8L(%LZ&FAj#R}0i_rt9|6NdM+zPOpnuOcDkCF8 zl7#tl30QrV>*bUlpxD26icz=q5=3y|k1z&iMp@-*%(~C=-^eu0tYAK2nPPMZpSI?F z>C`C6bJVau!1iN7#UoRH@xi4(SY%3fwnMyUG8=OtUHbs8s95qD1KtCLG^U!VydF~m zV=koaGXxdREE2(F3m{^a$h;GEX*&7nvr}tTcUr-|ji9eJE!vqA@)}uM^{<*wi1sQC zd>jFR+u(7~eA}vUz7hz@K!Fw5*q?MqSvaSv8@Ru@YiLUB4w$CCs}%@S(1F53X!wW>unCww<41sXG{1v*Iq18l9LpxD&xGDL%?dWp{(^ zd_6>Rw9;Tz@#+-+H>%GIBD5z9Y2gfcKF${k7+p;)OY;vGX-la(WBU`|wTnpmza_3! z5k8?KAa(1~qqBOtr%2E;xL9Q^o#<><%A7IvJuVie&gG*ys)0KoYYOHX+CK^|B{rlr zP~1P6Ty2@x>s)j-Ecti$xIg7Vv{I4ZI9+9YxbyO~rBhtA$3=mkQIurI%mfv02)U#I z(YaEJ3_l0~`zbdyn+f?$w1Dy5irE8n}>(#*NYSYbbRd+Y<=SB1HmjT?Fqz60h z;p+rcRN-zHZ4GMus*TooHAWNX@l{_mJ)aEXDOK>nKeuCltG!Kg<_xK5N;NcEF}WrW z!-*Ll3g-4)erFKiv6yX0vV76Fa>i;*#pCyPP;WwEd=|xN*NM(RK@H&YN>SpzPB?wB z+%0oSe_6o#;F*f#vWIB+(1u?a!||Si zz))^?cS(6b$(R@zj-&XTO*~q-Fh_BL-vF*z3SBaXaYW}yB$$TN#%58@_2+`wR2Nd>&dK{syrFTuerf8T z#0!S2c%;60!n)QrhhNlV?7Yy}Z1Z#fbd(ojPVK3iQ2!{o*ja$|_s;IthateH3%;C$ zt2OPmLUN3v9vxtqVhg26LG7&t1=V{F0JV=T~!miw0&r zr==pc<`9Q?AB*MWVhS6kPUegXgN*jGd^DmkF1iVPRe?O7vhuw8aTgRLP$6M;@*aQa z6I(B(JYYx=C_GM?8&WEJ*Rbxh9fU%2`)CY2E#prUvmBqCxNP~MTDPoBm;xN7RJATx zAOt0C>VRfSQAGuPg8PHRX~TngYN~qOO-Y2eB4l<7=JxG)Z=?n88ux52H={qm-KpftqamJ zycW)sLA3tk>>(klva$#jt=FOfCqU>7f6>d)B(v;sknXce+Ts z?z{u-4}(o^c9fPkJS_VDdcbWrBf*?z$NPEq@y_Rw?IYA3r}2x=4;NC(%E}F)b8CcI zP9Uvg7^RrepHq|gi?f>e<&;p4NNpJtBAV+u$0K5o*+ZS(ehWHlcWe?zZ^H6DUpbI2 zHac%UNV_xrk5dWYqBo7OU>Wy-8CF7}jx!|e?N`3b8wa8Yl;Kly{5d?FPtj$W$}qT6 zF;<2cBC9%mzo)5Nzv@-DMsFj&KU)zJ?*BzMR_)VrnAoMQJzFS)eJ_JVw0V23-FP>z zhR$rM{!c1OuTiFKz3RurE+09*dHTG-`f&@^OL(K*!;OY*OUlE8^XchnjcFYa;X;y< zk_}-CX@prMfE3QY-M4oiNoP#H@P26tQtWs+i0PQG&WS*fSvXrb2SFYO5eKndO%k(a zM2J^lF?j62SmQNdN%@?0J8_z1N@wAWqz4MSn{t=JBJIp6M-OFT7LJ6B5e6aw3JxVO zH!Xym8IrA-Gi7{uD_EYLIdA-Huj5=qM!t{{gF&O6;Iv1fK10GS1)a%+K}JV5i-d}! zVbvD$KRUG6Wqi+;*5mp1iy3i7wqi+@G9@Qc9Nf=;n%9U>80 zRd>6n)90_3_r1fWPe6=8D0R`QIxRvaEv?$QX|9@`r`@j?&x|_z@JPTi`0=2{HhrP$ z7@RGb10vw9*P?hmJA*6j2cph2d?uov7Pshvto|YsG?+Z(K(BOjI`FYItip#DWp8>0 zCFjh&zcyRpbHhjolQ>uh^o^6&^f^3*Z-Z(Sj6ooe&aF%0>q-xzzxAGkH$uo6qvG!M z`|(|`lzR7Q7cJ`U^Y6dXYx^~8;pAwc0+%hV{AQf9G&A#ef4|`9zT|l~s5jwfRhfIk zEJ!u+_%2Eh163N=m$VEhSz~*Q9TG``wsv$RU^#K(8besnTm6Z~=#`$eQMAZir^nna zrAr@a+@USk+hMr;ag)sb$Nb%>qMk%fGa941+5|RVG0VrVZjRJDc}feHlWhy|Mr;!^ zTIFn9UN;-3)zEtl4WmS|6mu@wc8Vo&VVKO>vPF%r*CRgIk_oL(`zh)!dvT#SoNS9( zpJVd-(VZ(fIT=9d6UPkYi*H_Qbf{^yJHI%duP*)6gT`bEbvth=Py-}(ZZ9sec*?Ef zlJetv+Ln;d{$-3#8m%rrfHfLI?B{N&V^{EE8^;6(GL*ON!E{J~1LfPv z<)fypdtH<1Op2G|+P?-|My+1HMIGQ=+wA*py&f{dRxvK{`pgN2lHInJ8=DndbtZE9 zXicDx2j;FjCCJ=LGBPq!s?|fKNjj|)-U8SQ(f0QC-{{CzTQXezc z5tTh1Nn=e32?DZry*7>%Gft$G3(5{WFgI{;gqR!2HVKeOV9yn#6O+4vW0PD<6L zbL7J#fT4_r<4vW<)wXl3WaD69&C~r`g{R?kxyh3+nKm4b%|19h%vMkZz}10#iIm5y z2(ML%sXI*`kwbul1C00h@hYN08CM2u#e!S^!AtI|!0q?AKX~#13;VrC@e8TOGBPq< zD^?w2%?>A|l$58JR*4HIeWrD?imLu)RaF{p;^I&sK3Quv5d(ZSHa0Cg)P z&jt@}bm~-1jEyhd!n?G85EJK*(E=VUAptE}Fmu5g6%}>1ZOeisucY+iL5UIOe|UK4 z=md6hasrSgUw48-L;2TCEvptz@|v63wAHt^wtW5l>sbM&EGjAjX9**~!^;}G0Zw&q zf8|6;lN3@{S8v%-P*7mOg6UWQgM=iYq%8gWg(@mZ8}Gr{aM;*u=Zs5>i-CQ*S8m~g zIe1i5p53JqEG@!Mj(1?EWn&y#xJbxf;P?={QMsbw{3 z1lOjf&npGeX3!j4I5!g}XVM=3%*fD5A$S~+=<%{7`4CK*e8FujmB3n2^QpUh3CQUe>}r@}czW{0j>48QEryR<2+PZi&weFl6U98~9?OLe>o%9So?T+8 z@9@tz#KjBRQoreyFMhv5H>+pTIgJ^t%wn@$NRXaEbB4yZ(fK@ww;SNN&9e)-RhQk6 z)R!+CAL~{x&2<^pL!~Nb;R$hZQOU{6=g#{2gmrawXW`tJoj|RR+aaD6HUJiI{dzOe zz|Lj8`Kv?ZXPf3k%>>s7wo~oes_y41QyTli1>^Mev~q)`Mhd$PPDB7nhI_QZNctTvj*OM}f@Uz7#A6C2lM-S?u(b3%=SZ@8n zNPr)6KkdeFyg%-ER?u3lb7*?p%`puLmdp+R0ft-%JXSN>sbOP42LuMY^9-r-Sh2k;pXWeqk+9#vBc$e zN=T*I-Xvwm!NI{(OKmdx)#KysA&Jw?F=eNs?H=QEXW@ojbxq9@fc~W9hV*Q0e%@FG zV2QyScIPb@T(PD!W6IKh{3=FZz6pA!f>#a-!3#BSOj0@^J4;VWG z5k`H%$hid#8fKU2Zs$5r*L$85O#tfkSvJ2+2or(BIXtJNHRcTj`kD@qB^TBJQ`NEF zFBxT2=?@`v4D}x#8pGgnty1wcm@m<#yB?EuEGPp6*5~ETEjx(B;+d6|m1{OWU7dCl zoD1hpdG+=2Jpr&8N|55zTJ7rX@}Dkkq*;;R^?sA#$t||#_3=jX!HtjqXRbu)LEkt# z01B5Y74SzpU`r{2__kIR8;^K~HB85e1(3Z+gQxc;orRjGD@yc&*7+r#AK%sOthD6E zVAOG>k&G#e4d1ldb+p1EaU(gbzAS8{i`LBf4V>{^JsA&D@5CIm?+tDleqo4$7jLy7 z-6S?|C=Ly4>`lHcg)=v-5{=TDyh=|BpaqMrH z9SlHzZVBe9QyojB)q4#G{s}%dDI}vQ9nQZjQU*XK`Bm|lTCJj5U!-U%D{!op+JMxa~#g{ zWsHWy?fP-MEoT>XF=#N9$V`~jB?CKm8mBw@BSq{f=0m41S5OH zr&uA>^Vn@QQL_(7$;;+^Cx|}h9>K-{FHCD-tNd_TBKY!YAd$rY3*Z=gJ+L1={b87I zo}`aMQl8z^UQdvUWzT{6`NW=&J{O2C%Sb)H(qC`nUhgiv3JMDkLvg|Z41+?fCPl<+ zt*Bfcy>vIEXtgTS;TNG-|(KM&^ApoYX{#>{SG!Mpe zWd)W~N8_tF6jKdON4$f*-=3Nc>;KBHI`Xs-)54;-O6Sy& zU+LW%1_8m5H9ajJpIh)I3ubX>OI62|B)jipqychKyd2*RDorx z`qRC@xVHB$sMlhC@*}!ERO-fdcSEQui-dgicgd80&vKoF;vkK-eCsZ13s@z%!9cBy zxXLQ-#k{)Wy9I6^3hq!2NagO(*HG-p9xo=fFTi?<-Q^!ELj$kE_2x_6B^B-dnia5)%KxswD&phg zOP1#?xDL#Gz6*e-KLm-X45L5$3gIIONrgHO0g98rtEYf?m`x)9lsC{q24NcZhl#~g37$6It+M*P?Q_%sH|S0U8-2KIKZ;A8U# z8FT~z(crHQoW6Jqu!dlnw5C^2p}FA;-TU#D62JoHZ~1}5pwe;^@83Y_b8>@EcxRe* zFQ&z)?^+Pc{@sV+JZlP|7Ix4Vtv4`g4VJ*F^W!g55uUS_G1Pdj!GyQ`)cg6l)i_%G zD0&I{TT4f}tH?*r!zHBVb;NlChI%I*?S?`{LEuiIM&osS=uJ6+5^C55&&sAMHw)NE z`;2-e7X9+u*sk2HVuWHrEsi2DRJHJ zGzrA1b{(8OW0p2d`6%V_0;QTr%6u;7OA3}HXN(E|H3%Ntraha9c`XQg=*@B{`V2ao zJ!xNGAEl~2Crki#K+i;i+>}2+8*y;pYq!jq8oWK<0aS9@O`WFK+nwdw-o4w#3yz72 z$r_!a6F?0gwz)&7hJnOEtTM4fyy;#bGPWBs{1T}P*i*n!+numSbm4@Sl{Lucp4CJ)wUt2)46~g ztJF+G;vbW2sQWOifkk$_`A1;ybj@h5+Qp}FHBa~8nQfF00iCOV^!%X1z)J`9J+97(5|f4MzpG#1(9nCyX6*xAJ^^Sn+P^A$ z;5oIIsttB`ckS0{!3eWRT&e341Ou=u$f10;v#P%0gBnyG`fp*mSy52DJ3y&v5Fi6% zU|>q6?(T1zvF?Uq@H*zFzXhaJ#xcv<$cN;xPQsu_wky|%C$Fi5rbTs5KG~33qTcl> z+IAFX&QHIGPES1CTr7j+Q;!n5h_iV>Ps;1%y#69Weo|arha3& zVQ>2#Q}N+Mzs~MYT{nk8h}6o1Wx1gaf!hh z2fY0!{=_p)_fCq*7QH-Uu0QtBnoCal`&-Y&)Sz=Pq(;(E3uxhPpYf@d#ubd)$)jA2 zS5QiCM6Z*p+5KMVkS#2+25ya?Snq9jy0_LpgYV9{CB;FV4<=5=_RjBoE_|wwe1MHd zz%lC13@{X-D`MAQiPEt9H&_b7hKro}()0?27G_Q6hS@<;$b{mv)$i zgn#Q@zDw!r>sRu@eTxM6Z6C)N75OzL8k+&(!Uw+pG&%DWUo`q6sN-ARH#6u)Yv~#1 ziF(wId0XIqSI|z`0;1M;$t9l@vVS~y?)tgPXg$Sm5{u{SpiNM(7C<>hilg= z1t#5+TRNs-i}i7w)YyGMbY|E7b#-UdaHCTPUO1{P(}Z%xll%>dN-< z{?H*JEX;CH^+~)Tsaq$ZW$GU1Dm?o>Wx7S{IU%xZwo*-;%3{NCce?_p4|XuzTJh4J zfmd9}LPy=Th$g+G(}=H`)&esd3NILZ=l)nq5}kqQztujlVp38a#`9BgpEG5*KQdsi zPt-X&a=fV_&te%tmP-Wy90}JlA|kC%(OeQ%2Lw7t&TS(W{ckpe9CAsSEGa5FvLy<+ za29G#tONgLUn%V(I&7X?^l`CZZ5vgTW0vXft$}=T8fx6vd6+e{N8c`v z?@kn+EVdyCy9>7#5^|?WmJb`+miD%&F~t@&rk~=eZ47@tObFxAcPhg)Bp5NpRqiP- zpv=18H&bTw)qY*UeaZa|v?q}kt~XumZ0(4lQbpWxW?2!@VNPkNrgLDEbZ2^=lsp=! zU$fy@FfanCl~6@nv2OKpgwsx$)&-9DbtU7aIQEX!v;K)IOfav~UJ?Un2Poohc;5Ei zt&&Om1)Ml77*|SE*WER7!?9stpk!s_X;)gKK<_ID4Sigdi8rEHg(Zd2o%i_8w?;Qp zIyw3tp!$xsmgqRQVs>ny99d-!;`An{dqByN6k*?Dl0AgWyYjkV_WG&RppWK3$*6z zQ-{DCySbKIW4MNfaCcvT>C;p%|1)C4i%vlT@ExQdcv2l{nySO=3L92 zZX1s2)?b~ki`%{ZziIP@=ZOW?(D)?dN{Hf9%zL#=9O&73a^jwr9NCu|$N2jZe1rP# z+*VmPxqQCC9rKt53fqinae0pVH~S)4WWUtDiS6I^QoDwU9NhpR|e{5)l)B zdoMZtHpK0URIw1ESRznzr)86+2wKhr&l`9iiBpazB_p$j)QG=WDhD=GLc_LJ2&V2| zsz^rYYbp{pnZ{vQr&^_2Mo2`|aFl|UFH{1PiX~45hgwX)_zQUB=o=DSMl4)D!QA|l za+TpvRf)|mdD7nG78E7jM3^+_jX=r(_3r~!QW_h3){gA zCNz%MXgLxZUZEfs12zH#FQc{iHnxGFZEzj;RKar+Mlqf2&mB|CHUxQ-R)>+=e*gRmZ67ZiOj^ zbsNqVi8-7pkophkj7&@%0OaOrz3=+@TFcPL$Vq%v^NLHtWD0{$H+sg+?Z$if%n>1B zudn9Chfkp-sLPv~^Wp=ICi5ln$fun8)J$Y2J zvT0#Tmncq=41XZ0eDP82tDu(H6N*7##~#U40Q?rNQlmiess^2Gm8sr`u3C{T*%I<{ zh4o0owSAV{&y&_0H%B$^@&>(Vm8<*)yN$uruN0<#x)|A$jy1?EV8EUYr85&IfAHI@ zwJyFA>`|d)m0va~RNw=5-lMPDKtDY@d-Y5en_D{rxgXIELgGqS?c_XLh}l)5Gu03T zhelmp>0+nNS4u4SkzS||IX^WyB)?D?&5|!lFyV&Ex&t3v8ewLVj`9H$CT8CGr5Q9{ z(hPiTiTTh!I~IVpTO8XirgI{=L>(O+|DjS*g`BPFs7wphhi*3_5e%CS%rffABF?-B zTg2F!R>&9Jb$=?wDh%%fW3>Y)#(xXu@Z=po_FGn_I(-&quxK64LCDQOiHkB;>hqIU zc$gXJd8ZZU%MDe0uSuQ?auvOEOy=+wGquM+?ul9Uta=w+32Y}05b^jX1$oOJui6($ zMGV`l>n!_F>XxNQhFw15n6GCr;E=k?inw;?Uep{3#U4}j+=p?rAo8c6{kR3&VoW5{t-**=@T~!&m z-1b*Jwkni*-Wx>k3<&c|*<*?vrhScD_p#AmnAbw!Rc}O6Ky})^aw^Zxl+jjh4IeNP ztjg;h|8!-KUVpj!efWP?GegmH=o(LxSI}(SBN{w1+6LW-ia4x$h<=V3lHx%fV}=dL z@Tzq2=#s4VKmoAAdk3-OqI9m6N1xy^UH))4cIZ$?Z z9DW4}A2Xg=?+Rw)O{En%bckBW@6s^)WpL<@kp#EheNarZZI`~XoZ>1W*0dRn@=cJySs9v>r(fhqF{Nxbo%OoEN_=8x3e>^5w*e z7~*5UL^2toENC!uT>e%?1R|c;YfdtH;L3&wGI-47>Fur0XxcU}&S}hq3lS6JRRsxx z7mOW8DQfS8MyKr2fXrmE8u`5^H$^Z=K4@VOGFjj-=tVhI}ghSx5PM22nTo8|lvh zpD0Q@#WTaBG_RfF4(=grIeICa2PTxu(VmGa#}yv(Q&&3B@ICL1k8tpzwFZXKC*d+h zJtilqc7yR$*3l&T&t+I+Q`7FXuI2qM!q0#>Bm#(5<*?I6kE^RKn zc*=gSob~Sjhbj7~&Rqq_SFHGrE&Jwm`K=VdArzBPj{0hru=Q~6{5>>*3TnQX4gx~5 zjJ*stf{3-h}vb%J2xCZXU0k6ykVG?1R)Z!HymA=ar@O8~OgoYU%04qr1=Xe0U7 z2x`T19Xr2dGfS+Y&E8*_w9bV;$+vo(Y?s_>!>>g_sgUrq#c$Ih`yx;b5ly0D!~fO~ zJes?lMXcUU6-m@T|8x!PSYtYp56EYm=Xe2Q*JN+6ilqu|a^f0}s2JQoZAhM`y{*2u zNohfW%Lm@3+8OsdX?lv2I34c@;_BJiH7sEv_@^xW&u~Cnds1|C{|>iXm7+4M;Z<}p zieTfF^K_X?*3i+{h=5iNqSA>Onx|mAuZXUG?Dv(YS5`w+CPSx~Jf^tx8d$B!9cis~$_d{)~y!+WIk+ako`v!Je3%_~2vU?!~J+G7%g+Iml9*3W*5huirp; z^970XO$cV-E}``8nEVM*Dw8&}@}z%`}EUW?G!R<#db zsRtr0l>9>JY73N)F-d$d7a ztA>x7-Jn{f3*6%m4f%Hxf}g^&bZqQ#(^++b?`o>2uv?p)(9esoMsh^wi~CrqgS?(XRc3JU{wMBCQYnMSlw1)%=1gMGi{^9-yE#00{c=3_oUbCTtHP{Y9E>9YunQWpglJP{s+whQxh=b#j zitd9Latu8F2f32D!@FpCcuxL|&eRK{nxhQhSC=EzU`yQb)}SFmLG<08?7xv^332NF z!0P#OR+Mr^E=O2X-V|rDH1!iZ`DE#FSZ=lgmfbZjdrjj73dK>>&y+Y5{O9W3_CBa_a}_rU znLeAli3@y_b#va~hH8@s+Ek!;>z%@(QJe(-ef*A{N=QT00q{TU)!EKiGdhb0fj+KFvO5`go_!QR_?pSEh5yZEAMWM|(l;^YrbyUl2f^!$BX`#p6WYr=z$3FmF)aoSNC50L z5%j@Z#0$KM|D#$!pl9smd9O@{)&n8c}{GJx33j~db& z*03(>+y;i=XE7Vz7HS9l_?)5$6SdNxjOBSX6-L_XSntHt+OO8xfQuK0fps+gch0yb z^SCwS?~(RS!P(ttNxek$IbCO&*`nkNe{rAxGA=Ie>M$olRzm~(RC=7^A3z)z;=;v= z08JQ~+vjc=0EJdC-%#O+>+>EsVPD!ufmVG)4#!5Jv-*tL*N{M0!+xXTSaADGqY{~vU1SVyU;qc6YGsO5d(!FYsdm6W7lWil{YBiV5;Qc2 zH+{`_9JH|K`>}o+lvVbSCd-PA8b()w!@1R~!M)Yl$zL{2aml8j&!mV!;8DGTXfkA; zQpo>qog(>Lu*7>y4x#D;Uxp`L1K~5opSjQU)=hATio?TACjWWL6+iW+o!aB$5(!IU zV`2ss*7Vas(na)uq>Bpl^Pw|-7=}9+wPpouoa&g1*TszHXiWsCz~P?^n;BoE*|yiO zM|ZB()zy(=S zmz^5D)l2ydrXh}snf@uDm8IIVFNy)EeEb|hAYt0Km!4>IUmR_jOLfNHx8o7zRdu6l zl3b3Ew)wslFuGfU8VEU7zo%GLF}Q$*N$5N-20;x4^5}7n@;Uv~8?AUBmLeXIYj*>} zwV=>Ft_wkjTe}g9SuD0ye%YvNL^P!H8vhYm7Gpin8(;C5sM-Q4J&A^o&Y=Ub1Cp1; z-Of7_H8!$jcJcAC)N*l1I$R&IvthAh&eVn~{QJvSUeYYl1pGFN9}>G?PxLMzbbFo` zHTyKBi@ya2+aFDXxA_zLMhd#FnWsHONFxY;H(-RTm|#uiGc-DX8#9+Qd{}Oo>`+r% zRrd)BBGsFhDmhv>hWQ4y@Stlfk<6eokF1qxq(0&7NkNn(^t2n6^y)~78aDsC zE3-#db#y|NnJvuCTgWm@PzwAdfl_}R9@X{EGB}^qM`8r^W@q@E0Od!f*eHz6+92esj2+&s;Y1{2Kejzu||1GJBaIV_CYbHN)pCAygU z>z!-?`;<$Lq3M8`Ht&d-@uO!{OiVFz zb90G-M4%y11CFLEq zqZ_D)O?$SeN=+;9#YyH!FVOr5p4~342>WS)Y8De_ z-)aEmvz+u~al<4&NBJA%_i~tEnd*)!TZ(y2-LQr_l%}sgXw{wcbkpbpbx0qttu39R z+1vqsF)=XbfA@sGmW@7<5$=J&BW!B6cUf*tdcW;H-sM@P{Hi_XuCet=%iev%8id5B z%ce@eQMJBD0w+N zxh=sOtN9Air&4sPdW~M;)fVQj5kOyShepBe8dbqupsQqNGGoNyksN>kH0r%+=bMPQ4Q7MsVR2jwU2i9G**2;-{0ur~wG5 zMmH}J8`AYNaWhw-tg(?ji$xEJTMA>l?xxTr-u;((SJ90s|p@q3LD$Ns5~7!9~Ef?9x(<= zQZQYvhg@vkkLouwfb-=jR<2Mco_TqYfj0aW_P0Olr4QlK)kwyP9s=z6HYqAqun#I&XO z=djkhAKcuyF+;vx+J#4?pQLrl&3EPpxsPuw$06F+-*|<>^0@3}>}dlV1A}@IH)ACcHJ+9ludV82V-tAH3t=rAo*|Q+ zH|$F0O|Ktp55N4wTf>YD$F@6$I%e`kupwl3M8@lBT>3%fPYDZ(x4ri4XHDjVODjBe z=0VRHz#(-v3s=Ay)4kO3PC7;JO}o*jn|1bFzCdr?Vk|};FqsqS*;*Z^nY~3+co$Fa zDB6LOp%3vpmI^V>JZLcE6A-9W>H5j#!`eDH^i51mfENt|Xh_icS__EISHb_(0?g!z zp%&B~Q6{5mI&b+U!~BEI?`!)L84+ui1!@hJ3#;>G4eP;E#xy@U5)BjOY+9h@Aij`k&CYDiQ>fasz44Ybw;6kF2P=E4-t<2O&a6-_@vZlxd;t~3*kx1rCG{Pf8FxjCy&*f>H zJRg3Mu1plQfi@EiDg0&s+bs=+;f^UPJ}OMASEAMw#s9tgQHdgn1o5hHA*o#>CF2Cx zIUU2QW z!UHXjrBvQB#hqhS4{knGRMhUCo~a}Ig;#Z2T3SgpIH1iSlJpa^kUuf>Lz!32RX0H&?@jYK@LbGAs%<^Ad4V_#nZW*g-{RK(XBKQ4YS1%O+Jlp{<;+GR%^ zbxA}qb7BoPavM6cH!(*frW9oV9#Z_N!>kJKO9$GdIywX6-(^D|*^AbW+%}-jG3F88 zpslkI5fISW>`9A?iWXMm`*gD^D<{E=%DtF7#VGy@8kiaJo&K~8L68%Yjfr-)^S z|EE*D>OtA0=1bLnPdBKUq@of7@E^9a{~kQ?cLwB7cQGFkuhTDi2mn;b;FRh3-0zLCI|C65_LMe3fq`HEq*j`teTVGrW`9ovQOII)B0lEN<$u!yGWVO1sX2v!S&FA`m%qg$8P_A*hShZ7q_Vn~bsop5P zKiwiYG&Cfh$`W;Zdkb*&9)IXnw~IDOVTZSv|4JY>r*m;15a@pmmYJFP8$cOgL;7r& z^c-8#F4|wh0q#8ai%upkH z`waO;3ef(Kyi@5ltTY|vrx?%VkKvvdOc@W3jJyQMg3Cz$ZBnqobpDU$8WO_<?K6g`zA#107PqnU!4YyrrEx&!g*;j(`np#9_h<>Y>>;q#>>R*p~v@xS5x zU(;UQ-}h_N{1eU0jj5?v^W_?DTShTM{DOiY1_lO{8qG*KQ(& zsL}tr*k7C=!h!*4t}gty!?*JgF!sa_kPq`GtfQ^k*?ujg3h^cU64-`jruTkIt&~3Irep ziUG7Q`oG@&xgylC;i)$B=}fDe3>eTo0k9uES+zVoJmP6=$aSj26kZAdY4EV&#l611 z4#>a&fLW|FOF)#3OQAP{0S5<{G@D4;WtRNgv{`Z$6%`~@)P;Yb?U%JR4I+tT={0Sf zXy4CmthBYYeeM>grVPjH<^GSU|NfW* z0|VQw0^*_4#SFnXmt5 zwfri*0R&`Zh0l*~H|tg@lai4Y9icJTQfaUuVq;6Fs$u{jsK>O9B~MAkqF~PS>J!M( z>cWw3|Hp16WstC7+$07Xvs~QVK2IOAy*;E=tv3(q*(y8|X8s<)w~zM9{(t8!wjlt+ z3Iqa`>GknmI47HHi_)ekwbLJFV`EbUNE0IB;<<%|hs~!tq;~&FPzLL*E~o2lE%|z% zqvH4N+cz*Ms8T>vL}Q307TesI;o;#IRuxC$f4V$w1pq)|H4=|cxxq4RX4#JTDC-}y zo5oqSKlyKNYA@GYsLjayoqL204hth z8}hFH(jWW}MqFQClm7hKH#Sz5pY!>U^d+&S8hb9t`HO8DH0?SS#z; zN{=a{(Y1J~k03d8G_?cV5H&RcLBVR}|TLa+IY1Ial)Acq}EP+bW zY)0ij<|;t*L;pbqMb<}i>1nydp^ zEpRhD-Z(p~RQm@YnPpXduFN2voSfJkjsa?;algJl6uqb2<0Ta^i0PbegF{0$s&3RjHkDFEa66A}W+mIhJ>!LS^>Qd=lb{sk+am&sf; zr0T)CANE2dbAT+qjN4zJse1uS{^M&S zOTvq-vAZBu_QqHcRIbmVjX@tNRdF6cIbb2+#YexHOSiXmname|nH<$k2(x&-y8{T| ze(d&-&cP@G0JpIgRU0SHSO@6_#7F@2CT! zNX*&U`7g1QF=H9zX!NTKDj*w489^NI{Qj#-O@vNm@okM4W_L^2K|z&oORUasJM6qNw^zS8WZu4-vou+M5sBhBBK6}rTH1fpU7V89kJp0HjG{? z*W+;L3;eEM;@e8!bqG9i{5J^{;_;oYI$h>5ze(fy!DjULz|Ej^Vxc{Q!u)w+(Rb73qW73xjtU) z{`mM*G?i(#xn9jFX|Vzj*(lw`zp;_!Gdq8Fj3p`UwWdfv_2>Tf_8A0g(2K|*d4Kt9 zQ++jJM3joTgJx^A_g0@4>ur9!7zgPML^;VUQi$N}FHGTOkI6?B)Px16+dCwR z9ervc+oW}I7fSA?%x*K{2jNA@IfqbMt@kXjTo1J1Pw_Vs_UBFIsY9kznT3mrPps82 zm%Tm@m%|4XWVP~Mr*VnX4_DW6axQjTnxbc3dBE&V;OtM9T^#%4X>R8mSo@<%cIO{8 zPaC&FO*iQQPfx#466T>pAS4kQ*r8MSnyk+#KI|gx%qcp~S$yAMsp1)rn9n`Wf5N0O zenr+CxH?mo6aDRnr z*H-zbzEOHvvvz50_1VagxW~B{7MEG^ty^lF6;4csb6R8Vc1bhuU;piXg7OSYeBOS6 z3Mo@>G@E~bUw6|*xO3Mi;h<`~BVG4;v1w+w{UFhW_&SIMKy?yY11y8HaZ25mhHlwN zkt!j*Z?`Dp#Q8fIINp3@{l}PrG6uR26IxgI2_xV~_9Qy6VLv7_i>k*oI!3okh}6*D zrsQH%x%$0lezzrVBv=uf?s^@DaFoStKnXtD3R zQB};6HQ!CIpQ=+bTP^fbME@t!JlT7Vx~rY4(d|sl%~=V#f}xGK5jh#I>KNIhP|VT&;eS4l1Ur?yz8C-uobPpYnX>v56Q?fDcP4rmJ7AjEyp}WRq#0L}A z!wG_?Iqx?#p<25+tv5)=cgDeTu?<6p9ond+javPjD6w&`;Rs2~bWb4hLYBl{6)CKQ zu}Jgx>3|ZhLFe6E+G@xBXTZOZ$P&;p#tyD37F034?q_%l7PFVW0$_oEc)!29FIK1t zXK{H{j=9`dD*XcR+yc?B%;bHwnu)fpC&5}`by zQI-i~YvwWw?h~F`?hak!6ZUguT;NXS9DL49QK7Jo9|p@-mtq}!vpm-#3VN#-<<^pF z&joO@CSB5yumBV%i82a?ic9=aE7uEE&qAs2d_DUt^BgitEnN+J?{<|hW|K1)5bnri zF$yqN9MS>az%||6uxGY9q?A8}+n-BPsWUMEc|Ke@Pkv!qt1MmmzT1b2J@^N{Dw5p; z3pyNJB9GUDwGw3YiNDVXw4W{#PtPG*Ym-rB&*$QrJg7%DJLE`-+qF6;cmb8lK-pt* zL{27{`UW^-zNd6BH?`#_8{v}Y{mSB@e2WaYndW5PtMCiY$2ay%-M%V}Zht|J|BP#{ zPy?F$dezTl`;*fN2+bc}43Jjh-CS|Tnj+)-L-}@U8*6WJXDczLiz^HpsWSf|z6k|0 zm$04}T__SYs0%Cd%QZEj18pYfh7eeMU~nWOZ5ZsbN3BU9*CAQuAwm3Ljev9cAsG5r2i{ z4egD)n*7GKG?gbK5sBCf`hem3bf5%E)zVaM4ObO*jskygx>IdDm+En~;|ztYlaWLA zx+2et>$AjTq>b?{C8`+{&B-tK@7D_g8!ojDCrpaS>gtP0Zga7bwfeDcfBb$n+hzqO z1dD&R<(0UA#qWIaapep`GRZX=xRCPfj}km){%4KI0E5#W3mYWY_;bYuP7#&Ik+0D8&OsOc01p?4ZNP)^X>tbZ&y%Eu-fbG&INY0 z-srFQsU`)%4+fpP--cCGxfVgKNgYI%nwREkoyiu6jVZRjpKm9a!CKvz>@raUiWVaR zDcNSD>BP}1FrL7Q)UF~A*t1sLcUamQy!+ZBx99Q+9XzHoHVsTDFp?Q#km*)wi$wqg z$&qb(T|=D;C-k<}?3^2`VyZlYiP?xk7s8G**ol%@={E)FO^LQTSg>G`q0y9_a@V%R zKXN(Fv2uQ*HLTlEFHZl0@75OVyW&KM8J?bn(q5JN^|F#eB> z`_?34qN2M=TAntlyjR;je*Hs3>;;rYf1d#Ln#d=;XDgP;Ag~|Ok;6m;P9Ii)J#cM( zi1)a&rNo&gi9xtJF1mj}aHpu=O`7e2F=|p6r*mKkpM^xtaiWR8Ar?JOZ;p~y)8l&|W#3^pM>~B$71PK&3V4~3Cj;W*O5n?pEt3HvECGFf zZG#ribS0MASlu<8)~#FVmKm>M6k~zI?5X&uyajG1Gj%`hr*W2tVyg(O5kIszrMq@*gu20wmcSQ~tA{wXcPd$2`M#Sv%4?_4*4sq||9Op*cP~V^$Utb@z~a-~ps3j{d&5;rbkq73nGX zO%dnU`<;NG;C~n#-}<&Z8DeRvE2BE--{%O;Ord_Yv3!$-M$wrmy@Lwm!(uhr#35GP z&QWz#4$T(&UhVI_BI$3WS@8|M**_52*^@jb2Xiy+&sThZAp@(KFs&&~9G+FAkSIDi zQfl>Q-g&WyMbSE`z~K)z*V5=91B9d@*Ag@!a#Oo!f<1-RsVYmjm}@op`kS+_Lh{@0 zv1G^BoCQtjBMaB*UapTF_KhKz;G7jXmZn_x3 zD}VMmVN}}MYN87}Vdesg!1V~B0a{2kp~?AP`kMqqMR;Xz$l~h_M5K= zTag5C5)8_gX^~y(@+Z}M+h%iSyV~3cJMSBFevZg%f8Y2K$neN}F6Sm%dMA$F%=l>(G$UHZMz;L84Eh11~*G$ zHO+20b0>hHCT)wq?z5g;_A8a4$Y_QTZ+9XYKq62C{nL6coVb3PN(5|a{rhD7&$rGG zHq*z~>BA`exH7Z#SdEFx5R>m3feN$aS@FqAdAa$0T7Nb=-5GV4>;dnBtoS8wHy1pF zg1i>;3t1WgUD(kghsGRdDx8VdN{fFm5`8S7b!-OMy`j{bcW(&Z)lx2a% z*DKPJCcKF!UQD+&_pTBa5qBf%<`M_2C0f?U6DuFKM`jyHpa3~Q#=n-!Q}-W`a1@OT z4A-=8)_~=7V2GdwF1$2BJT{%K7LFK*TqbYK=w&ZU_O7-ynRK-knN-D0hS(hFupQH8 zc^FBZ7(@R_6nZCm198IpHpq3*XS3j0e|8bns+%O*7U1upw&F$?;PED9y=*{eg_SG z#z7bBC7=o$?xj1qJQ+XH2%!pIawo%oMvte*v?jNBzWJCcWwKv2kbfq}Zbsdvh6&e{ z{AC%(zgdV4%@Jjgyv{05Cz+cq0?kf`&8?|?w^tPUaq;JErNC< zuQd5fQp`T7he64V#s2WrYD~e&OK~r^t9?n;=92Vr&a4!=v}0S z@#2{#S7jQXw+z3oCTglHuCpSGkjF__)gs(xIi+WW?zQNq?`Rpb)cOqr48t+xW1Io` z6{GRgSl;*qqMs(H@-x1mNeBkJ<0n!QkI$~?+$878?D(JES|t~I7y8T&D-@kew(Q_? zgn-a7WrB0n!NWdQ;|4SgKsf7Dr$elX?P%4gizaNAWE+2nHM`>({2$jq6`+{tF1L4A z=r@@2$XRxM@e?maE769A`@^3Uo>q+6(QznIN0fdh2l!3exSv$)j_2JA3kku&!Q@vI ze>EEdIq6$t+{IjMB3$NzcvPM?h6WC3$dV$^>)#d^AR)U)#n!ePeo@A zy(`&F4XTG$M4a;ANYL{+V=cb<<5$6^68FhV3Xqw|t+|lB zcc{WvyReM_HPO~8_+AU1IxjDb5I@bUX{ia59NU&>OSmI^RzbtpOF0@Jd-&k(vG^jB zS4htUP$|b_X^DLC!l`LsE}Nfk149yL8PfIV61faU07Ll6fVbtuj7jO)lVKrE8&pG^ z86z_^=fhf~(b#NT^79K(XXX=~2D`rxXH=caz)zvTo1nAvQu$-3OK0?Y;{{U&G)&he zJFD^9vEiB(fa)WCS>1cmET=07bAti|WaO;35(IQIdp2mYgvepdJlYON;;o_j-JZ{g zY3+jYeA~Q-wfj8FG2Pp{hG)=LB@!NTge-}?KisiySj^V0b4wT;x_}92RUnwgjdn

jV2yob~9@i}gU|IP*2 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

f8oU83)^2LB+8U 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

=2o$(3SM;BOG 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

%3gLVMyjx9ZFf1APLKmDQMd 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

t%ws(Jpd zQ=&*zXl;_rF_>0&Sgaf*qhbD7D)onVb(19*zjpvnG-(Q9$!s4xU#2O3!TQBbM5d8u zx5^?>@Kd>+;jF25P;(MaUF+O^#J3;TAn;K5IAFdu4UVI)v|Fih@(L1>ZXzZbEnRJBTWdiG(gr+J(Mo&DYRx;EtkB<8aYea7 zeZlK7E{=X8b@2!Pu3(qm&QG|Nbkc%e;is%z0KnDRiFTckT;s7s5U{=@Ay1^8__ z2{E*&gq8b!wjY!TokOnN$b50Wt}Q!M>$ZMCm%N%vv2({uH?2vtR+ZX{tNlZtd_0=y z`e|vd_{N-tZNBQcwlVqPoybCyFY!@}4Q*(gZs(YbuZLN^2PcXSD~gTk$%PuVptytb zED6_|6?a3+af)6F=4{R||0`y-Nz#7c@$Q&(M_omAN(0{9S_TlVwzQpr7B^}(;1WwO zfITDe4j#;9KC4(Y)+9ubfhx-)VZH>t?hw!nA81K89dvAId-MY>ew$Oy*L+`Xphbw9 znw1sK8T%$$I1)zpJJVg0QzJ2WMnQW?Ivrd)3t!ck1d)0ELbBAJef6;xQvHNFEU@Lw z^kYLZC|1WQD$WrgkESmtHt9#iNi%B3st_s1rNNCDu4bHRUu!}ij_LU2Jsi~zEmEXk zRRe~iBa{gF<@FthFT`6N6NK#rS*lryM7gvMx-u2x%KQ>^+AIOn_|^WG4*GuLJg~uD z9I42%fCN2mSc80`dP+^_{y<9Io_)OWY?y6=bOciX&dMw|-7@!#DjpI>^LP+&yKi5^Y zwzqh7GzJ!GX@BVg*}&k>MC6-9JU!>R{@GVy!NpiffxY1z9qfRGGDpCAVL^&51|PO^ zjU9N#%sRN(R=X$obY5^f#ZIV)*YTY?KPau|xZj%b;f=4>ve$jPn!ex&pQ};X zE>B5ax-jUp&11v6`{>wZZ9P}3qmI^j!x6TyRq(~0T?40tNlGLrLuBwI4d;Tc(P0B{ zQvL_a+n{4XuApO}sZ-fFJ?HHQ%;DrargEY%tZjX300P(0s)5gz~L!#5aJY)jc zG)Dlaf%9J;_4#Bj=@T*^EonIQx`7Wv+YgQ5!wy^+#w+wPLV)9R=w!lhwr>Re*CL07 z1_#ex3^&3jtC0Rn`yE`XU3?W&u}q-rC36|9M6K*1$)oAE@4w!!N(yk6lAJi*Tumo% zP2;lEcq6>sdthWb&`r7cIv<=HNEnXHVkAmY3|=^%>Qf;^pG*Dcj$>P2y<8nZM%Wr8 zJ9zHcL~_Vw@=ny->wUbWSHQkUaaZoNa6Y*1%eaM?oKYQeojyu75(5Ubiz4Vjr>BY==ojiU<7$NHf&M?Ec{*4_jp=-$ z^HfO3@bD&5wAz9_5^CH+18Cfmg!H7a^kn=Is}Ls*pg#aUc~ZxEjs`_ ziWRHZAHpDBsfcS{0E@`7+UVK2D$ju_(YnM75we_~u6cbi^ox|FU06`8vN-3PxnC&# za2W>2N!PG4D>9lIEu6^^nef~>WO_{6wX+w5fiixlX|K3Y0RZNP`ikm=0H%yDIwDfR zuSHPGmnvU)J=#zZK4l=&34lck!s(2ZJ>s%9#J)R!uMK$52Oj5YAOrII1r8WY2QZXW zG{%>;4Y_uG7E3>F6NpNqjyrQ8=$X7M15xp$M*WeP-5ocm{RDtV=W1-w20%}7h#NDf z3iHOlw&TW0vBJ7>9PN+9-?RGjE1e{`Q3bQE?n?m3F*aWRIl$E>1 zB%@F)^98f%^fru06YcyLSAXXeBf&7=D+T2<9wPw2T&s6|j0x6d;5x_Fk$n~iup(nH zEYulq)U^e?LI7GpUFwLezL7m>KSWbbw3%jw2P<+y!h5AcOalaB)6&MCc0S+Y5~q^q zn&}wg5)ME@f{tT#Fw8j8aMFp!A18=c2|H>yMNn)7cLz2twk>ThngGur)B`hQIJ4Ea zcVB2prnw@4XSoxdxBzmwX8&w|Kb4PhE(+TqOFTZ2q1OGWU@q?&SG$I-57qI(4r~|W zD`NKS(pm{&`ae*NTGGR3{(RblY8Y+$ObD{|o}}E${h1>#!+9<^IpuZ)69_-g82COEb3w={NKVZfJdL!Ed1DHMr$UZ#TXJ|r# zKMhZC@(~#0Ugk{0b*@O_CE&LzoAB)?>`@0IL|B1r8sJBi*{6aTtvZ*Tj_((qJ?2Q$ z`2ZIBo_a41+$&7kS3JHOAbIE8%@ww_KAS;CT$fvx9#oxv71lEtql%LAu6O6F3stP< z{Q>pI_c1p5hOAJo^G6bOEF|rw{?KCU>-k$p@KcQ84vavb6)c0-U96`4il}6V{k3E( zF`?ye&uO=m*VCncBqj@Eahwd$!2&qWcPD&I3uLnK3H8_-aFQFVb3$a4=YS_Cu{T8O z9mudKQ<`2XM}XKZWN90<=;2}f5vo(aHNTPCjO8Jbk6ry{dXmI_*_2@>&f#X$=V|11 zAmj0)6(4U;lkt4SnqSBmn&hs^X*G>>KK<%_bp1OqQ6_SsTh2IrqE6YXtEI$9yj>b~ z;#X8aX#>(BgMX|{nyACe&y0_Sk7@?zuTo=VcKf@YqZ!T7NYdzV-{tqrP!(H~*{gzO zjK{iBE^ADd%p&<-zOd4!iI`@@Mjg=fj-HR%lHp32HaO$0Ir4c{`f<_XijuD)CY?_x z^YqeRfkXYYs=y~q@2$>-Lg!U^-{Upt=b90@L3W#5Y^ z{)`*AP?C+o$HPqn(RoBe+}RXOqj;yoj=`{pD2+W|4dGlaqZS+_)rE>B<_U7dYLR1RA*Dijb zeYK9~HFlw;BKo0A1kr-&y1kz2x?i7vi^CeTKWA;Tfn*K;!l_jwJ+6xxhw_4d2c`w^bJ^r@KNktzi+^ZO>IKWpIDw0qs;@BXUt9!%6yb3d4@2mb zKZ8j~sHd&udq%~#U%a4XI~UQYqk_VGvHZfFh~+#RU8f$dGZ9$R~VYl8FSlR$XuQR{1?#=LE`89mzuJ#nQ(;n zkE_W0;Ocm%ia##CkEF|cyj!foMh#$voz1fKtJLTFxU3S=jr3=&cY9cWy6|b?&v3K4 z%V|A~MUe^drlZ|W^V?ChbtgyvsnPhg+WXy>5|A|JhMzpyt*EQ}!LaG;Q$T=*$H@cw zPi&wr`Wp%-A(c+9p5QNZS1mLaMbz7~JwPe|(itzrR8&YGJuFC0ZTl{{(E6D9|umfMJ z6YJGYXL%L_^1&a3r`OYC-A_XyBm|o^sHHBWsUMyJs@1`fPyGo4_dolh(%2qNa&n?t zU7TT~aAUQ|FXiF?`MIVeBfWlW798o0`)Y*@gMG^+hijqMUaC zBSY2R=;qQ7PM-S-df1l~UiUc`?sBwj42QF$`T!L=u+W>Tl07yt)7_VnDN~{_?pmAA z^S2Bt^;Ul8`k>dxdnWS$bz29$eW8r;)%IK;hzEr}MyJ<1j#1|W;>7z4lb)6GNHABg zXnV6@YV#JeV%lG;%r=9jcr(75KB}sfdZfe&8u7UZ@DehB?m25~vECL8cW+>itL^m* z?nGn*sbYuCF!OStjzqHQ7F-g2sc~;Kaciq?#cQP-WY@mm5pCPCf!LfRS7v)YEKT78 zl3_nB^=Xd4-c|n?{1)4u_QA`X9XDvm|E41M{Z3i6!IRAI2h6sz3{P(GlX--L{XH^dEVXXF)Sn$IElqoe?f!KG*Ij5BRa%?3P{T&?B=kGNf!5X8 zuAZ&fh!PLUe`IP9*7m`66i7Wrr&CNo@R9rY)a%Kuu~EFGU^=gp z8vljfcd*m&p}@b-8qY@X0qR4eg6dCbn<8+Ps*cn8&eND=dY$TXAUHXiW zQx4xn^uACpkCZ@%0vDD&v!C+SzB@Y3-u6g z&Iug>Zn`$c;TD#M2%=81Cw_xh}?u;!Q%5H>8D z}Cu4Bp4v*wBzu^z=rQh{IDY6is#rqcyJZkT&NCs}tIVmOZ=6wOFZaYu{_b=uDZ zo2E-+6y20a9!H22%#sjcLDLr~0~B4(wDK48qGMT2dwrHE(VN8i`ZlXMAtI?_$3VaD z(hLPpdyZgWs?9tMk~b13Ks9y}^7m+FCEdZNT{s&s-?>r2G)z}QK6Rk6yd-&yOP$v_ z{4}%N)J|x*>ddb>ZO~mbjIP6Kf)@pe zXS;$b-+TdNA;&nWg&6W?ywI8JUu=S&7&nn&RB0z*Lzr)FVnAIl@vEqH` zHqNo~;|z?lkycFgV1jl(h08dv%xxz*b+OsicDSXiO-sXRMV(z!3uwFgoBYRxQ$xiI zaXxKh5#NFK$Hyh;HBhjyVB5=U)MDGOAE|G5`>Pk+f=*hMJTFi;7YAN_1+0!suI*0) z^)k`&vK__|{dI{Ssr3@;V#QGVadzj96EU&c2^wr?dzsZvLn{=HT3)z`?iVP&93(@I zcpcC7^VFV9`Qr{vP50-jF78W!lkHA;rKs)F>dJ2}YU22u#>ajx2_Iq6(O-cS)iX%w z4i@Xqg!0U<+;DCwEnMM70T`z=Yz$-9xHXm!T)L3Aaiv=%tkiWoA_D03sbLEG6lK&# zgfKnK@`I3ettz$O+Rs)qe9ZR}@Bd_5}I!c_jC zwBd^3yE4sZ*z5vLQx=av$($+!`mPK)>tZj)phylb%hqTGQWFXdB<^TSHTyK)GDXPdiF+=v0)6t@nBmT?#&kJ4m#oWiyFWil~Fyg zdy)5*^}gm8*}6F>CH5&e>JQDj6hbkpFM`V z;D}qUHXBn+yWtCprL9*8p`3l2(Lt-YiGMDvEcA@r;6A^T{&l8 zd}kV57een%(?Ll#JI+3D17h?!Ic`*q>lpQZ+k?ow`#o#4tjBe=gq3SNf&TcYj`OF2 z-rugis53Ll>`E*;8GKsP-mRRA-})4I4#?{Bo;|0|o+HBnmHA_u|LAivQfOZ_H9gE_ z6U$HaPwTswVaiF4=Rj--LRMq>rosDb$0sh86QDm0trWx0mQuvjVQJoB?>rzc>!P1V zF5KL!-ur(Mo8(qoCF(`%OH(A9SGAh?NQgJ?sggMYa zK$Y=){58o;`6?!VN9FI~0P|_g{%fvRw2i1fy;!E9>S+>fG*kT({a zMbV(Q)D}-%S}~QK2ZWXYS3^a2j})TzwGEb=HoX}Q;6{%17{V?yuvUp3(7poP4sEG( zb<}!)$G@)WW&H_+an092wCiNEELR-pP#LppmWJvdM<$dPR%Mw)b{~&qV|&vKY5(up z6S<^+MB)=1&x`GZ6~HBY2ddJx6Qj2rnSI-+VN*$yH{AT z?QIAa$con*hzE*UCgsn1hh0)*eNM_uW!uB|dqSMcXL&xuzTe~a~ST5M^XOnBuE?+_wwU(E&Rl&+49aQ3+thOpd7dX>4 z^@%T$!(ari=mhRlvXx*9#Xo@O6P_p#MsK=3aAzE`cGPIU)6U?yvv{>!{0eZruK!2Q zOjA;NskLiK0Mjxa+->N>ld`J$DTf_NJ)dzLv05v6&;zdnAIU~tt_!{gsOR_xKrhQy z6!^I_KD(=j4hHg)VDwjDj=uaOq@tlvl^-Z`^>@iuy-IDkY$JtlN9H^O8`>!Yul?qo z^ZKGKsg=Bbo`%VAN7*DrA3L$u2A>^gGt1iVj+fq9JA!gO@dI>4zq9-y}6` z#jJH6`!^6;x+65w05q@8%geB?7QYtj!|JaqU~?hPf;@J*8JfT2i^l9cg{hVNELN~m zl`b)nJZsw1cAWA{>zA7o;0#HC>$GZ_N^8DEC)})ZPXbKxx!wnk?c(oog#A5(r{?1x zBv=)qX%R>$LH?%eR#QOI-u|fbrxDT5+*}w2= z;+e7h!+(D{(HVP$`ZwfEWs^iY!R>DT*{f`jU&bwot@7-W?1)_C2_o$8M+LlYO3zNb>(@gs)N7D zN+7`DzySb&Ao)d90RY}7#(Fp5tAtQNN0bkc4qh)mlXks! z(;@82+|qBodEGrcJ^j>)0_82?|No5d#-mgZ_vhBWRG4ax*ePLhybmq>GUd$owKYC4|!5hTE1IFkv z&B=PJDI{rve#{syTACVjE(odn&j{QkkrgDIZ?HL~+338w-X0^9Hmo!cv9A73#MbY3 z0{QR|fN#GLNHpw>Vaw4)WoM#C)X9L38q5rg^g6zHnhvK%0APUuY1+Y={FRN12i|=l z93(J{@4rzN2MPOcsj2(I0H7xfR#<$yf@{Q6L&v_NXTKxkYa%7)B8h&h`FI^Rd&00I z9RM&Qf`y5yRdLxlqMc&DVbq2l`ckDQxf7A=3rqMWOyy^g!9H#~UZp>_WZUXukO!=} zSIiMerVwLU2OC%NC6+;h2Koh>3|owFjfCcE!JHY8PD7~nd5+r=-y0PMzy@T51P{b7 zD`B(VR^*VOs;2;(j~RMgX)EP8k^e;+4FZtn0Gm!!bfG6bH7%fYIt`>$wThs>+)f0k zdWAn&sWmuIC$=u2PWn5OSu)~zED`f9eyB$b8!;?k##HD8m=OcMW{@CvSkjPdW->7m zQY`$nFWeFSuDhSbg;eT^H;EqPGa$=!glqS;#nu-O8P~CB!#3cT`Nq`ovGdcs*=`9R zWZec5kw7X?42o-LTxMMYgFr?mMDQ1^{6synLqjIq>gL2|!Ok13btg ziQDuU7F-wBQSuhXO~}3<&SO7-#?dRm0){Xe^##` zb&yaH^hW}#G(-S$6~<~V{MKFma>^yuZT1*pOL>jECsT+hZI7n>k}4ln^-8&;UwTP; z|8RqAtafkeH4>>mm03>G0AKtt$yR66W<;p}Ql0yOwZ%SU8;(FLSW7es-Fl+Z+WwANNWYiy86c?T+ zkD?{sUqR*_@_x!L>y<4o$YgII0*&}II&cW50rK|#pJdVrPynMMcwVG89IxW>O1Lh~ z8oPG%n&Qp!?#D8yRbD@L#2m85D{bTHH{ms?YZUX`@}@MKYD)ig$H)%`fHDY>8xLXg z9rvWBLCfUfV3kX3B8%4z1)`|nTm-`fPG(O`XX zedajxM?oTehl28n!AD`z6yKhJVSA$Sg_*d@BJ|J#?%J@Xbn`vTpZLeYccR~|2d%#8 zvWLGYeh=Ll*v$ujwv+xVN5*NGM7y07^Kld@l|xQYG(R+<_@WuX+9ys?vC#OIWfkPN z;iGUSO_+dh(mRk>=JWg?(JpNPpP?O#zVo0k@<2~va|av2yBRli2g_f4>M{K{&@ydx z_t;C$kb)Rau2mv$4FQKCx`@32CxPp!*&L_+NI*vIs#HJ``q54uiiAUyu3mGYjfV5A zb4+LD$w;z(m5@3?=aUrfMkprGMv^_VuZ=ER^NPRpC1_oyhL%da!Z)tt}isyQO> zO|sf}?p_Wje9kP-)<);PFS49^*qanEW=;_Gq%Ix&tl&K*x|TD6ve&%3HiVginG>6)gjeg)Kg|Lw~QK{DM((2b zS3kSPEeO|OnXCl>X%{ux_rN3=4@j)iFyA&jV-P9!>03XY-KoyI6BFCr;rmE`v}ZHf zaSOE3$2wxhXm!dBf~;PVL2Ha3`cz|*-d;3bcgL@+rz>D$G5HwSHgxj3|E}A{%ORa1 zGRXC1FwRj_Ml=cuW>BlMe_Zk0)7sj~=c7hy+j9Y&9I=6v@Co{a2RU)b65iT$LX|rL zG<36W`KhL3Zwxs<3I)%kxF~64X!7i_dlUQQ z`4&m|mVDc)Y&fO@i-sEH_S$Iwu;g-is@oG(UlUZDXg_Xt8la&_ib35z_M>t1N#G3{ zG^(^A;4Cev^A3dR^~Lcc#YeEm2cb{< z+?c*WQ>uEeZ0jZx&XDF2-+E=CPR!hk@tIzMLk+4)k+YvcfIOi*J7$?h!eWP`GWEEif_$lS(C(<7nZ^ zVb>Y2Sz1$@Z>JKr)WWI50(w=9JnujVHb1y5R51B&U?DR*KHu7VOxWjM@D|cxw|n$` zQ;k`;IPol-Fz=~Yw1ibHfLJWGoY&Wa-=dJxDxYC`7}rZgn`lJSZcx`cxNU4Ek8BkAwFA2{ zXjc0!?aR%>(q`bq$*0le#RcZ5urib<>$|59n>2Wt{cL z7j&z!tD>7q!J2>*+h_eP{dZ6dXw|MCx2*AP&d+<3QX97w$Q7$y!z9| z9Wo*cN(vp^O$OGHz{6VAU?^rlW1X6j1KB0|_~oz2B7uw2gOld(Wflf%3X*%Ml6&tm zUXC#S%M)IAKmx*sZUcHd>u{V>gkM`WyYo=nC0Q9AEQV`eA1cI5+8)FMWjso3SIdfV zZC^`|s(Re6IaBg#PkpOYBhq+_>p4wHTW{#Km+ybr@I(l>G&L-2;Mvh~(H%qx4KpRT zyB%06$5{DyBBs1l&0OcbR4*~`?_*a6`YGnv;NSl+rVGy4#b=<`e)vXQ1>!5$XM4wK z-;0$&7`@B5u6dO;igV-qpFfutaRF01?W3+2&skqQIi31xH-)`v%H>LlIT10jtkzTM z?ZZX?yjRWHx4LxKi9H??rAskSdz?cJ>RYX%V{E4RGjxk=Oxo-7E!0mRuPKV*9UN7S zkSkqR==6!?nF&9EOs;3zIHus%(rB1l{U7Y%w{!0bN_}_>C;5N#ixf+nqMB&Va$*R+PALzn+sA#35-%dl@}_-R99yf zco83u1IFyZ87818&TNQsse=a5IAJi5?J%y}^-=LAdW@d@(Qd}bQ#nU)uD)LA(hH(M zfF2weogIy9EGJc0e_NdE0x=0iX-wMwr6_ddb?_5VjR3}A)QBmYLj~Jp?=2W*-c>_^ zaBPK6t*Pe66dub*auCS327^U-{bX3<_tJ0>z>+EWnFsvL`u2KHH~c1{3HKH z0#LWU?uYb7KPfSTd0yf(IK{;~aJ$3bs9+wI{$oXv_MxqlxY+r#H7rkC_a0nA-nfJ< zJWegWiwQ)2upV~|O&*O4>0q1!xC>hn&>(B{AOR;a$w4qZ@h6z!h~>=SyVX~;iVuRc z@p@9K!iXf(2dVCh0&eXLf~+7aV8T!5GKVKU3uztxzsQ^#F~%~mCbn@P;&b5~2Qq3t zoN9;UA^~m&#>oFBw^<+|6rsU+VG<8a&-*~nvryn?7D({(pO5(YpzQ8*uLTbx^dDJV zvJCD?F2UdpOtbC4G&?MZx&CA;kPOo=d|y}(22>$FA(4ufroK4>BN4cMZ+3wu<{j9) z#&~ZF34d8p!eHJ;0dvj{QfzMN-c^ROVH*$^OcejC0F}TW8w9eYZxWb(=}pk5S#v+= zL^bw;czFlo|3x@K`2y5rO(W5x1O$1S9GgH)5ZjP6FsD8th?D>?-$Gy9)qU(j0t=Ru z_f2REFmVKCH==ZXyz6Ry1ckKSeE|Cjphbc?3H_gSDn_XP|H{+H)$hY#z<_K@2IAbH=95Z_nzsV4+FwL5i#M0CIOLu>_*UbO z_#A%(F=G{;^o6y`UxUWf;ur!A-O=~+sTGw3Dwwjo;iOq{8jbhsqSeD71x0Ys=r(Eh zyXB4tP?u%6|B=81iQdKQT!0Y2dhQ5~Yl|Tx{eVd=XzwMwKMQUifff;@Srb^Hjz6F- zwTqXN7n%eXbQw=T1>Jd;xe?Gk_jAc#IeY68>8;D{!pC@5xCYUy`q9xE=e=Hnr-xMs zJVXi!2Tbjw!0W zy+x4L=3bz|X5VbyQ_o9AOJ|3OU>?snCzt~r9Q4{{75eE95=g&fa7cFe^WOG-Wls_F z(=bEAHtl-u@?ie1BW!#C1xj$d;Mq?6U7?p@b+|K`8LpxY!)}(w(d%-!@UG`SEh1M| zbn-1g0w-nl>NP$~ycQg@SI*Nm4ox~$j1wgti8REiffMgMzIi47^|j#8kLBc`7BY{>Hu68j(BI?fJq7{0|ZV$bSqQ^WEC+ z{Kh?9O~l(e?fyT%qo5+Ev@o0MsE26Vkf@_Is2~6dW%28+&zq@MsXMKR!^4b~cFVOl zX`$bKMAx@^*vX@4Iwy?+GU?FI|Ac$zFcruN&JKe>y&EHgZP0*;ue?xN#T7@W%pPa{ zwj{WQqmQcsvOwy>(@wV6bm?>&RDECEM1W=v2vmP6fdjXAGq5NKn`bO4X2~Clw_s(# z{!d~9umdN@i$`qe=QO!Aka47okjZQ!Leww^3_O@ni_V-HpRdg%r6=n?* zr+&bSfue)ttzXzOE?9&eDm2=mHSTqd?_H2k6^Vmcpudm)iU)x z0I1r{;pMFsNg>W$)!>$2Dv6iggVM0rV=+ny0O+~Dxe|ZbXQi6t@E?n?`!2_oRJ@3V-I?40Gq`a5y_i9u%I2Y$Ie?{WBaTow-xS^&6;%aj^Ieg(-OcFb;Eg-S5r6wkwmMgS?~q zt&a$K3;G3J?IcZ?OTRI_vTu$=j|%^)#z0kCAt0#J05ng0;J|D^QAMVHRynTVN-WEZ zoE+Co(p2>-ApjfLnjdW7`msrCS}rw~(x2d7l#(>D;&B>mEo!u=jG90a+roo0SaoVy z_qU4rst2{!NhYY9Wl&uKUE-7=d!&HpBeQPX(JA(oNO!q-Z~~v4WhAIHbCT%w$-#&rQJK|zx$<@d#PxEEvrKkivO2Z0zND?v z#(rq=1Fx%b{EO|*a*LuNh>&ihBj#RkK2MyP=8|`Q-5`S(+u&+*P$IbQfu{IJ zh_-zsahQ?o52GKiN{UJ+uLx^tiMbVs;Wuzc*;&ndA354NpMSi{2Cu2a#z~jtXZFe1 z&?y}pFwBIN)R-` z`{7oncWpC!56M`S_O)1n?g%FE0$$bQ{EWXSK1!iZ@0uNnAkEaNimHt0Wn)~ z8Wd>qXP>8?(P=vOI@2;wYxl8KHNtx>IXOA@&{TH6E-IBWuNJ3U9(>gdlaUE560ae0 zZ9g}I=cC4G#>(F^bq!h#!o3CCzC7yGwDpHzOuehG+tmhQLLfrxL z^AAKhPYR^M#3vWZDVr40Flv7V8G`%#oJ$&Mj_zI}9lLaBhz~e#XYN-5a||#=S037_ zMU<~+%au&aoGwJ;ipl_R`Y9?Wa0JiDQ2 zL}qJt+UKpvi0#!DN(Lx${Jh?Yt}t^gGH7o|it-)1G0d8Z^Nlx1UlSs{ru|4l0LNF4 z1@(05b4zyN757VM1`)^$|Bp<_sEr~m*V^iJsy1I#pbQ5QHEa+!+`KvM_6((EbLDZp z%kcCVCnZuPaoL=(IB5X2<8RdZ{rMnW|xNq49aJcy!l|0z9gQ81z0`qM{EQ14aEa zFxB7sjBg`w_I)S3H1`qwHfv*8+d%4^Zossj3xvLFX_$!UhBc!(_i7={`kz(=95^p zP2a^_*tRN?nQ0p-LQ(-bblKOHmd|@`zhrEA?uB@o$aC zwX>KIR_}1gnL+5xoU6bm9L>b;p$Z)$6cqKNKG%}FL8k@`cxG@Wmpn+ASj+wtj1U`- z!q2XvGi3*nGNQQ_+mddgD#XM@8K8$_mF8a;x#Neq$>o88BCAt*I+oSL223iaDwBU1 z8FYhZi%jb@F1IV#oJ2))!xY_Wyx1yfw+x)L%lhE8aQnFw*w$UgW=f2D?cLKn<;RM! zlluFk2e!N|?GrWIT5K=EegyTInm$(C9o-Byvr9Jehvd>Ju}~(s_jJ=XFY5jyBF-5< z!Fc7B6BgZCAHyB0a;tBl`l$EcvjFV}{U*1+7+5amMaAnj_Ayc(BMvjfr8JM9$Ah6% zb>69O)rnaU);e(VK@=!`iIcI@uFgfWm|~@zWUH%950th#mqHSlzV6! z?`fMgy0*)i%q89QvZjMbQHhZl-JL5RG*?;j6GTToRQf(dU|=TQm9VnFFReuo=%uHW@T}BU6ymV z`{WJOl8&lrybPaCwPjg)g|DDi+dh_y+>46V-N;3L-)%-TqG+%3j{13YU7OLY^1*u4 z(=#Uai|UKLJW(r3n#YAU;ag{{Ht2|Mreby>N}2@oTtmWfDc3lb)P>^4t^2cBATyq zj3_@Da_EIio-+%t3}K8XoytJNvY%!6+XCI1KXCEPpd@qifZ4x+k+NCdCb>t2v{Q}8 z6y+iJ;xVc=nAcK`%8{F=rs3hpr|KSEnP*@lK)*~Ve}A)1vMV9rDy9^a8We<&o>*6M z(4mh8UI2v6yr78GdbZ|gJX~fC4yw6_RyKS|`_`vz_XYXpAY=^Xgm4owSH965V{XW~ zOc2jA@b?O#KK{mMoy&}*@(Uw`#<)|4n5tk)c9pBY!{rf^oQJ(c2H`@4pHa~$?)rHM*soZ@_TXb&1EI+%Qmq#0V6#d$sqviBCq zAxpAuR*Dv9yp?V1i7ONVL46upEiQ5~Jzqs5CVZ5ua_}@tSL<}|L%Ezat8boq56-KQ zHPb(xXsc`U?S25>%>O=n5z?RT9#I8)51n@T4!j=$X^@C6QApiDf0|r+&?FTKzdE7<`sor7S zjhcj*SOvpr8(c4)5cHTV@)V_%+=0@4T&zUTKg~HSgQ`1uqzY)2+SPr_J2%1n&3c4{ z#Kcm!oC2na!QjlA&+snGVhv6#;IU|Ph8oK<>@4;}Vi~OU&xq5ErB^-_`J?y@RQd9} zA~QYc)BXt{BR6B@>Hy$Kg z^Joi*zT8}r+~?3gD2NYlqC{0T(7HTv9OhK>&>AkKa0^g}vBtTJ#a=BC8c^z1#s+;^ zWp$!yQK}^B6#ahmlo|S1S8kKJ3dt2-uQOtfJvHlF&G~$@n5Pw(XLNghqzFzizbNjo zyfy!L(~#Y$7L%!Judt+Yz69i5?#|%~@Lqe}r_zavdJ0{i!`ITp>{NJ>kd7=Asa#xK zqu!wu219y6i{{8&hmn$xseTpxUcDg3o2-`rok;a&8j`?a`G?Y`Ej<~z=BRxQV^Yww zXJ-DDCYx}S$L6pbqt(1UAoG>>ET|B zrN&(kxee9)0Zs^;s6BmPP#=+2Vr6bVBg5#_Z1nmF7X&eJaoNQ)uFHIo>-`NNC$s6Y z9UU&;b&630qdOxf`VTXh+;-+3RgN8nD=eWmiFA`eN{zN?7@sEa>O+gniI`~V!bLue z>>=+e5PYGty6JO-eJhAHvLUvZt`yWaQS~_2=CjWgie>FZtVEsZ%b~9OTIc_G=sy;y z!dFqkzFQmJv|f9b`-y=r{FX)QZn=_%Z{x^Wv4HP_&k@po@qkotfTt_BDX<#vq%h}BXtsIbI zw&29Dsu;v*;bm6v$dskGN{NTGHtw)??vPQU0#(0FM3NYw1+=Cuhd0Y^5srtQ1@nX9 z!8?=D`JX>9?A*N;GhG%D{lL^{?>yhVX`AMpq2|*OT@WUcw^7ws=Sdo1NG68z-}twOy%K!!K{~guDt_t3H>1zE z;cg{Lq_@OtwW@z+!uIIC`r5t7r-)}WZ|V+q`r$VA*Tap}sy1!Y1=O|n{ep1DL3Ara z6SqP|j4s?IQ9;|4y%9~+^nMmgk&EtKTk1clQqgoBJ5e@oofT2hp8WXpP!eJ{OM{P* zeG5;=^QR@L9_b2{glcZ56H;8|u~Ra8u8Aja4hkRIsgk6*OD^=q^ERY3rRCnTAg|_$ zkU=@}nyZ-C`0|wGS&Tr|Z)eD`H}q!Y!fpIG2gp!xH!u(bA}R-Q(8%C2l}f_e9uRxbo1xrF}3 zkiYQqdGW6*Xgi$MMsxG=+>I++sJfl^&)h%HKcCiUxK6|-u%L1#yj~C56f>hG*uY28 zV0?(AMkTOUW8=dh+)W=k?DN`L6f*gkk+V@1#EYR25f{|ZnlRvSc_o_LuE$s!^@aFJ za(la4Ob z;5Ks9q;bU_1ACfVL5Xv$)u%uySG%qaPWsT)g)RvJFBjCbrY#5U#k`6;p*A9=QUXKM zL?zmb&&2UxN)qK_1v(}4syRhPX;Eflf`U>Va#P!AzgO3Na(hv9C4*rMr;u?YBH;=t z5STI5#@vvMh!~AXJ3ya198Ud~-Y70`w~_kdCDk0k%RbVUN6$npM|@CLWJW=3&)RnT zO#eLacp6(7oZ70D!ATH4YxD>gWjS6<6aCnZb{EdKpl~4|@wErXwls9RFRPzwDT8I? zvw$ulO4JBviNM|T7SpFfV$5sj-8jq!oewf*+udCI@_6N8(1Y!qo;7A$n|G3uxEXLe z9Bc&7Vs>Jse*Yk(bfh8_&n;!>C|(nFwGP+(#cVwJnZFGXd$`UZE%HB0t*@jCd&e>x zZ7v}@M~uaZVGu?|$XfP&iyAGk#D zRy&aRooVhX;z6uS|27F(BGDGyN<$7g^RFOEO3yBz?m(UEKeT0E_V{$24sBd@dEKmk zA|&wgHPR9jW6DvJCX3=tXtAqDzw@k{oR}K-VXJ;kP777GN2)p;)a7*izLxg2RMrOe z4Bd?r;UT^f$2NR-z|9d_j&ODuNvnZPqfC@C`Tk#4v2L1xT&ErT48c>i)iv{Msfu=Z z+*YNgPDm_B{8sOWzmzruy=XXPThX=E2A_}LcdxX`_BdnHpB#T!D*1A^y}(5=a{6re ztagkHqt$95vw)it{ZCZEj#B=)cFNf*bi3#82gOqFuaX{-MugQN{+1wy=rB~%8{tMg zBqunPL*?nBN8Bf0Q_OWUo26qZc{RF=^?LOL>w{yk5nteh?^RVHCMVj$b(?Ec5(giy zo#(@ul3-GWrrAbBa;W3OR4_X+WxLV-5RHVQPCZSrqJ+e+*t`A{%B?K4ZSK>nL#RMh zW3KD$pt*}2klK|lTYWHT;?lfLC=Rj_4+vjFJn;IpLX#IeN!LGqGx3>wKi=&FWJ5YD5LqX*kdt`!{HkS zgyMK_+?tYqMNT|%w0L`8CXZNF>b{F*w8`6nZRpym-YyG!eg2uapse`H#^mBc+BtoU zgN@c{bBXJ3zd%y|q>uBK-{`NU9^-1hpde1XETnNkyouOTFI#GN2qZ2!ZwD)Hhi|F8 zMpBO7Qa#~DkivqJUj0ns_=%C24@X{KTH+1Ln^YB@i3J=tQM)H*S;R)Sw`5+PDR)OI z1cP%nSE0Qw3523jym5(klNnBV?e`KzFzR;V(SJBfUN{GA>9*rptS2%1+i)bi(;vdz z22IU4{jt!b_g=O|b3SV^hci;rl1x8W7?D1vv=`g;&dQ5=wCgpM!nd8`51b8y0(fL8S#dsqIX;r zUKfR*&hsdZ3_K`wi)Z&_Tine2XVuGXCee1|$<{jwzMoLKi&#-OUwHj6AT|-{x}7f@ zz{`t!xYyT#peAN!JHn^<;U2VO{UB%4RbPPQImXR;s4;CaTIgvYjb)#DuAk$TyU~8Z z6xV*Jz#iqZ#PHi*Sb*vdxXhnMG}Lt#x?MIrg~v(i z|Xr8$CsT>)BHhw;LXaDZ>#cMddS4Y#74ql#fOeIsw?-&RI7rUWf-q+ z^&ErxMQ(fr%v@Ic3Q1~zjk)lQWqJc%M|d<38_cn1B>7_nr6xOL&*R;V9ZH?oTJkBpd^ixWOB#NH`1J&0o1Rlh8<%YgYjpiQVa z9e(-wAyEo%IDfoq>|LP?!NXcgz@jevHL--;wPPyIM9Ptmfb0F?WGSLaxmsWU*GrQo zVq@@5%+kjuOp(r&0T8K`eLtD7La%an)v7#I5$3p{hzwoJ)2%0GW6LlaPTOMcolg{Na5!yw0^sw1WBR6TQvp9#OCN!4*Y~ z>0*qK0b;MmaP(`C1>bG&)5bzE|3_4MX{}m5L3&$rhI))vr@Er4DIfN91H+3DnU@vf z_(^l?$0l2UF^ewsQpmV=A7FNV+3tl#aV~#tOc`F7MOf~X^7g^X-7>TFylYeUaO2eN zE74ckm78SR-MA=r=49@&M3d9m0?k+Nv#OQvCe^&wgWq^tyvx+~ z@*6v3GT4C*83&P{-_*7?n@QfcIb5fu>?JbluXYQ;I6NXOG6V$CMBi#0&=bDM=%e|Z zB&%W$fojGN+6@BrmkbHDd)?Q-BbPEQ4kMLUejbk_MElmd^o#tz%NWXeT$f$BW(W7UQKy`64hh@gzO2#UILH-Y6LeQUC zF3*s7w0w={%{?w5yvh0MS69vUwScfK)!AMxbI#k7{-bQHNP=*jc^_DI=)lVMnoRluq}>eS$am zeq$uZkd2apnE0`fCBwPb=BaRCbkL75x6jp3#9rh%ssP^N@qOY51|g@*HIqTc+~Y>{ zgeNI6QbFh3({+HzD;`x4Vpn8HpC_@sEZ~F{kLTJfZkX57Ra&eYkwFqedaU)=>FTQ7 zp0_n6rtSJefLfl$>#H!USVHKFo!vJL%!}TUn50V^-JNcXil89TbT7qYl6Wlic2?yt z&WgvYqknoCUU#^3a~?stYl=>sIJrFf#nhoefoa1;^aT9k#hUo|A17!Jn(6!Dp;6fI zzJmq`2N6Hk+2=!(01e^^-ItTxgQ&%ppf7mnoP{usB$Mbqb*-*rw=+$*8csB%ZK7LL zv1r<_1+Ac%8yWfevo#J@tlF<_tx5v~$*IWtN7)SLE&h}d+Ecae((SwO|M`8^r=od1 zof7VxUCrQGyz<+9Fn(;CVN~0^Zcj7Zc(HGH*FBUEdTYu|YL(CK<{(tTT^4_yM?)^Q z_@DJWKG%p+VS>xTsS0Uz5NX*ctGG5Tg?2T$)IX!BQTE2YjzJ7GjVoo{=V2dh6-#NI zMk+0G`{%#6IB*P@2%pFihus~7GAoH5`~Q9zDV~#J@T|ViPpotaGyk`G^MFP5Yw^)n{h5_Hn%`BcA6FGy7oYDcJ_O z%WShz{NiZcf;M^P)-vCtewjRv$=ehNOv$O8ytwr{NEJpvfxbH<)F~g5{>v5v2520< z;-x(G1=;Mczpg`@Mn>%EX`3n&?vm-C8hfoz;r(f6(6{02ImcFz;mAaYH)-dzb?LdHL7 znKe{#6^b~lU75U}%dR==F81>j`KJKkX3NF90^8m*(lhAcBhSg{dZl5NPj4u(`A+Jz z=)SFH?-1sC8|4HoRLwc3du~PJ%3V33Jm>PFFLvU|1KeA|L}uYWELbsxIuQ$23k14esnK+6tK@%Z zA2lwjJ5~;6Cff&38r-{B@0UYuBsUMmHMi#+sU9g3#OxHT&31pwnYvreoP?$&AkBoI z|A`+sILa7*;6U$T2#wqgyE0e9ttQOa8+{?KSV+qtu)aHb6fa)x->f*%!Du;-ME9-SBy7kY@Il6L*0q9MnRMh|DEP}D` z<*u^;SI;uy@Ov&oPsWGmhZ!^m#BfPbL=m0qtd;}Gc!is8ub6|$Ijy^qJ*QTeJDXDk zPnLdR^5UnX-bIOKIj^U2Fp?B}y97DVj4V8g5qUqzfj*vny3Lm103QcoWCH;{6M=G5>ee3# zo6_Mi%MXv9MxvtGz6h2NSblsbW%65oUsW-y*tGaB9w$PFRc3{AaGQ3zFhWMWbfPMB z;wp5yT?UuA06pVRrr9#0Ujud{*#k#a^-uS+z*MkoHtd5ieR9z+m^|8lenH1B7DWdg z`=2<3wvM-(Cgvw<3eK_*4YgL3=>FmccI$zURBY)X2%`YfCL+nE0xjMrO;^B;%!3pc z_|+6ZtNFj1Svg08OfpFkJ`;F1j=zIsXbHOq>L*%P_;eM_tI*_<(PL}K+|yllIe13G zs`VccveMS`xRd7JYjubPowpd)~BNO;P(pgN|`h z9HCjPRl)RE(Ybo&7y<|@nDu+{s_LE=U37v^**-Uu?JD3x7{X*%e!0A<*bY{_ryzVg zdpGqzhhZYybRQ9%oY1U@5BTGoExteEuP$BIRq7d%WeJh1(!FX($<8U zaz7X`zM@a0j`}i6SyY>DJ~B-O30L*X$l~v$5HY*ki0<9mNr33qLGn;jBi1#iWyA&) z8wkszgaCREjFt1<362j!gk<|4*_W}0*GzD#jY4K!NkG<;{`ucSIBs1(fA@d4kLC!) zW0#s8dt{|kq4>~q@{To%Ni=tu|Ni{kSB%Gi#85Py7%?;m53zXOykXASTlM^3!LKm! zl$Zuudkv>&?PfYz3Y1WHx*j0}`({hb_viClH9S4o`91=txx92_^0aGizq|CUC(VL_ z@ML*V0#jj9#@Xm!hfX-qKqOPEks(m5)j3C9Q%(C6Ed{;nQ%%xPMUHrb5nO}tc)*bq z%AjxzhlC_Xb|DW3(2?u5fG@X-RjXfVpy!a)_wBsva2IAUKsv#>^<`DHRw9(Ahmb>( zptW_&k`|*@_+ZE>NfEBjIN#H;$0EBj|vz^_PW@BIC}Lh2ql&&JMbb} zSQwuzCv^(Hd^`!if0Qe3AGUeCuM4Uzd{K1OxUuoROrhe%2Re>69j{dIO9if+y~SkH z!~_QD!vN9N)~T!+?YjqsKn)7`c)k0je`(8#osJ(^e%jt^S|}Lua!c`C`*COfd!n{j zHufPbC~WOCO>rwFex%G$Z@%|78sm+4&X%>nxzc~eA0+V9$os99QtWPgQr+CIP$!Ot zGT24JtmL_95YTz_r)V~#d>o&9ksR&vub=V3E*k}d;|%L35ceqhS#Uw6SBVF7{J~?F z*sni`_G9BaR%~c8hk^AXw-8z2wAn^*qj)_JtV>ZG4O2{6)k;~#`=66S!F6?vVp}Lb zIz3Oh>{2i(WnZ?`>|R5(85n+0sv$oU3Y#dNj8F7a{F)NGuoc=2*o^ag&yERZCw6UPSN~K zgB%=?O1PT0&_FsiZTEPst^CSAeetiSqVF5iWS$HbIH{7@LT6<^PlMmi)zHhg56I5s zbQ_4@%WS}HqCstdKF9Y~03l>t0e*GQ?SpPXn@=cFc}+VSRmdnPp~rL|v{4U9SUFmC zY(Dw4e7-yRH+BElu3Vm!xU61{_Ik{SaPf8=RxE474&0ShMuFG?-!)356Y4taBQ z0QiUp?0*)LcZB}DAkCjLYIl{4D;3>WU2zJdXmQMElYR*8o1b$%I$N6~L32Yv*=LZ; zeGeDOP^WQ4vSMT=z)J})20e6m(lp1rQTBbOXLO{7;NoIEX;GX&5JdJu+m2P`S9Azu zi{r3L;Sw;F5F%MroJKxO-_Qork}(gD->yN74rLr}j^WcRUG9oEd%g?+;AI1&?EBY} zm?To&=(WrJ^WE%-V=Uf=rh`A%pr>;vLqD(jP9#(k+RZZ)1_ZlY+QSiGsGXvwwfKTYY;0 zsznV#pt-Eq@^@@Q_?>{tVh*>`BPM4&zSnXj2{lZM(>(&i$`V?d&AP{DzO4TJI?k@T2&5)upoc_sLHyYTekN?q6SG;^JR|q zQ4z|Y7RZhBy3(S_@hv$JpW2nENS~#qNwZiry#IR^fEWb@WpH-{BjuEo*g&d##ak<$ zg!2rE51qeXMKbgk__O_+u{~jL<{QQn1oCY0~ zEVqW`L5Wk{vR)@25{+0+I%F3ms<5(DadGM?S-c2!?ywm_MS(vh4nuINkn83tDY%@X znzc5^AAyLBP$}}gC8CnjHyaXswLLNK!FT)9LQ7&zSG-MLH^^K2hq{Lr63>7D| zvKNY6yye-~cj0nCT%+xB2vU{h1PzNDZ)7EbFhakH66Wm<0ek4I37cue8f$3sJ&liC zJn(QgD#YlW4Y5ejZq>m-{^uX+mlvHw&y=SXUD1E_bJ)Qs@l+cJFkV`(!P1?1B{QLISNh_@^ za*-LGCT0udY0SFY`Bsb+6X@>%J(Ybkj`XLBtqg&uvO7V9DrCk%j1YeB4csU8zkjwW zse-kdX~Y~|QXfr5Gar9?c?JcASsim!el8vV^3OQ*h%caEunNf(pSbekN1TA`#H>@j z*rFkk-NK+`6kJ{2$%V@(VezEhzpr9{ z@2=ueXxX!Op@=dGvM{1r?D7lhTgt>gYfYOfYMF-C1l&YondB36aTBImi`e#0vXbk{2ILWU@tFL z=^XFtfRL6zVSTI^qHe}mOY5l_4Exjh(%Rv}lWvu3_l_$L=Z8_JvAQK7_|JgDAx*BTmm$f`Z{=mv&rnj^Nj=1HVZerIQm zJAO3lo!G?^yGWKjnxO6b7!%6(9JHWZ7ESwL?)e>1`~ZHpj4ND26$D4pR>MATIUAtX z^Wsyl|1Qnm+T=J$EHlpjKaN)Ten~z5_FHZC>Dc4Jmm?^s&zRbyG_$xp^5@;S<_SE; zZ)MGkp~~zJsUxmya{{vO^Z4*`AMcLhf|IAN9(~HzewRK^lFZ-xS$i&w7S>*UT;+Ab ze%=r91iygw_X|IYU3Wx0RBfE0F;R%*!V^h(U1Y@3==gka5LTmIxW8q7Pim7jar1K5 z)Pm>Dro%94*cjTq8w^@)ubVq6in`-2`I*wI&&>%>*|Ga0;hiLZ66x=Ekfc8Zg<)xq zaY0^#*xc$fi)I61uOpY7A#@3Uv{uWtTy{ozfzx#rqwk}uzseB zBvNlV`~k)m4IQ27VvOO%+yY}mlq9b(8{reyk3xQ<*}9PVKitf;WaPk{5zJY(u|*1J zX21i24j$Y7vP5rfgQB}JzJDjrg9c9mzL1YNXqsD=W!@uAaSKEeU4II#^& z$jJ)Wfyly_-*T$1ABf0cvV=^3vV}Cno$wO*!2x`HzcfUyD}T1MxIL*6g;miRLM|gv zXr^in9#`FHz(*8?$Q3c6(|u{P3*P$0moQltF*8Jr@`wuPl}sb1Bcu?=k@es*-yVu@ zARHAYBVu~PaV6xx@(G<3qW5J*XoJy#%%0q2}ibTwu}-7pFd0X%3-yo}X9 zA7^$f)BLkIC~HYQ-cza{E9epdp}0>NR43Nxz#f}=s|ZK?r*&#OqiE@2i88PHdNJjR zM&=p6`XIVnLkPiyd~b4-a6x#89wPs-76sjs!I!#{HnrU&VPljK*6&@XKmAjM9Cj=I z=n$0Y$ny)CQQUgX@NK(%^wvL~K!#IupUOz(N??0ApR|A8R)9bP034_Lyc|3hi8*0; zd5t(;F}!BFL=ru&W@1(r^U@AtK+bt$1>E-s}W$VdfGee!hG7_ zGx6}}jl#S5CULH5LLdJ48n8s+Y@y~TSAQaU^P?QktKc)D=TXLY<||wWhjuqjL&%C@ z*R_pKzlUg%Rre$BF+chX?eq5zNq$bt3sM4K%TX`pc5X1;@1A|uArcSyd7QSwl9xAm>~sK&L^5^lc$SU1P zsfwm%ArVB5J)()PHsw|IEsPY=av@KH29%JvI#~Z@1#1aV&aXsgGf*ZGu9DrVKMs!0 zQZkq^q7$VYw5RcZL#a04;yT^7;P4o&On5QN!-DV>rURjpf6F>Z~0TYEDWu$OGlAYEhcPYw%KXry>#LPsFiQmKx+`L}vd>k(HY z9sIS5s^_h6uou0KvgUB1f?hS(nqKFe& z=3Z4WEC7@=<;<@V;NPV^o@F!oWS7@+JtL|9k~8yqd??MiE~$3Za-+H&$V7POc4q!} zX2RuyPZ!RSs%eFweZrw;Fi>2)j}q`|{VppSttt1_mjmHJqc#Z&VRl(P0DryB8W<~7 zGF(JXwg(5EgPK!3yNOSdtd*@Z(IoLkUh^iDL!^f_lajaLudyF>8!M_E`fz)1bgmqKwpe0cB4AO3Ny*k)F{nDh2}xOu77@z#r%Sx~onXX_HWZkOPsY+G}t zq96D*X@XeO6XD_o0CTiA#t^{OH2dzz@&7P>#dvk zqrxF!w9b#N#QaPvaY7_0b)CV-99SW2v)Z0{hyd!Qgg`UvX^O-JC4qJHRK*>Iik&t9 zxO-4Vvz;s`mXZS@te%r!>)V_a%W>0MDPK-vt9u!SH-#emJ}@E@`R}CjTeNdarFdj| zw!skL!la0sME$a1V^IU@IR7ozZlud-aoagyg;HPHVt8*Uo{v_Wlxsi;whY~vGQHe= zI^ml0&m8n`)Pzy57sa63Q$iL%4bteqi_V7vXns_Zdz zm-!IF)o~{?III67H9p{L%>XqQY(p0rE#D92a;~>pz12y^acZAGf99Lu3(;{Qw~+Vb zY{N0OMKg1r_z|eiIuS+6jqviqC1#J3f&lh7(5ZGU9uvap(1X#R?v9Cwp;za(Ge33f z#QktCSKrVunAs!6;^OSAO!dda-R?SYG}H|VA$n6wuFJvr(oZAQTDknq zmPu)FgnU@I#(4ZHRpi^wADr6(@wny1?~y*P_3>r){&}$xDjPA}7qS1r^8q_`Orkr< z#&m5l>^Uhcs30LQ2m;U;)#3Dk>zFV+?4!JQvX2e>`s>A7S!RaA9N(6h5Dw`o?;G?6 znSgTfiUmaVg=6yRvnCh%=euGd1y5Q04nN=+f!Bf zw#5~7OCHj1bAxLc{PoN6b%5N zEROm9@*VJv*ePjW^caz_xiLlo^vWLFFLxOLfVH(?^T9gg>iya!NseHOfGw3nuUh2C z@n%u$cYvTtPwgqcH3aa@Xm*bZNr1u@LhoH@mk{6g00{?=&QO!dLx{|CWWU?Jm~=+sGArt)p6o7>~UVlvE3b%I1MV;?X!?s;ABh5-Op1)=jT3{ZT)ToyA^jVZu= zi>X8>iFiT&gGS&bAa{ikRBAL0dkWG3z)*WNqH4J}1_sb8EE-h*;$?1`6~wUq?-(|U z95ziGG5OO@@+gDXH3r2?US4IEV}0JaKnRizujloiw?y%C5XqAlpeGuZ#bO2kN~4bn zHq9nu=Vj8px4bUbhwk?Syn*!{*A&Ic1+>4%z1E7go`nm4ohGwV#10R?blQ z9uvE`(bm@FCBQph9;tVk5P)f;>zCczTneZ!C9sQVDS7Lr@$Ns%VG=_(m-_%lhGQB+|cyW%+j@aB=~me!Me~kN~OiK+fRtetaHds2k>G48y#)p zjKZ$A*p{1#au46JrtcWb3e2}RTDTmLR5IPSVz8p+V>PXv`xjLEVJuelsw?JL1WRax z{E434*RbT};mAxvieP_|`NboiDjM~AdydgR9|jDzj*Q@iXOU={ulPpFy3PDY{U4iS zfDQ$1r-w&PIY!<(D|!6Sis~f!nm}!C$(b-e>|z@|)MQmy6EJ zXZw6Ff206m!uxf@x}^t$IeT*5*88&GnsOIb!;PzQd$^_m(6%J;1rlI9EJl*OD{=SIjYlh3rUm?!}kBRgCo^kN!BitR)%LqMeL=~GYhSM+eUPot0|L17BDgs9mzuO zKG?d;KhJY7jNk9MZ@P0P6F~9HrfS@z)y+8d{(gA*dXCaR9}%pX<#*6M(H6d6) z5IsG$j~L3gHfN(XT1bxb`MFLUV~^5@tlm{Efl*5C5CH(3yi`-epnQA^MbMYID`^6YdTi0PN(4qH%iaR|I4awUUi%ZiRrLKUt5! zdm?|#uqbU>WZ^z8ki19FMjo%b-)~-+hlBw^b^PMr@*uBJPI>99P+m`g`)cKoFCV~z z`F+Uw%ta?buC-NOJxnsNwiSH*X+BU2_ZqO2lCd+n>LEZ zo4@S6eO_OHG1UUDbDq4JI`0po9{Vg%3HF{|!0&+j1@RDS zo$_(DF6+)DqOe)|6;7~3Tb`ir4g=%1cP$v95jJYw0}H&;E$em%Mmd(2tZ98tJev?} zUTGBqd!&{mzq@o6jj|VDmwE|iS5bZkOpog_U}p}?cN<^1$iE0e{9Ld0*fvDEy19Ww zewQW$sijF{G!!C{H0{BLE=_CN&2~-nyGFA08IHU*j>Lt0Pf~DJBP!zCn1)z+^WpK zmrzO2+W8X-aW@}6FZI>4nL5R(sxIB&3Y5p&Wv*E1^(MP*nW&FBO3$GQoKY zXEV;qf}I%tLGT?XZlvitaNXPjV4BT)CeQgczia^kFvp4IRa1U1t}Q5|dh|>EA%;Bc zWa8s}F?SyCY`EHyhyA@mjeEMbQP(_BH{`P^Ep@m!WN4mZ;a86x&z(Lp{KrQa9IPR) zXObID#GRe^;?ds zM$`MWfbYoYSMvn`@a_5FrNFy$&4=Du=k}xdFfxqY<{e~5yqZ5Uj{nrEz=hvOBL94C z2?y16CgpQUwwuLI2;E)7X*~9c66HeET#j7MKetbNvgeGy*)lR51MG`~DR6ae@EUk+ z$A-ECZL?Ez?5_JFO}~5X>>OntkHs-R3L3fxefrn;^{7BCJXy%$bcNPq&MQz?K)=!| zi*#(7z?&QQa_k+7l5iAt@CvcZI&+VJ`+}$EDiOsBewN!#p$&-J_?w*cw`&SQX@eSAwlAGm9YZUq~;r9y>Z zWkR18bKU8aHlBy;Kp4$vbtEX4{1^>@PF1X zh*(L;d41tzK(wk3Bm_tc)^>fo55p>jv>@A$g)ia37Is{h;&YM|98pHRzf-)f9IgZ`4$2dftS3-lNIcDYc-PX1I}zh&7;ZgdQNO`E2{H zBu=jPWv^?h4}lra-#1^pc^VGzuYA~Ck8$3+)fu9ypWx#o_NgX4no+^|p$icaK9DJD z{rh>3&?1^J^dGIiC3iF3t7P$~i^KC|rU(hsk>u9SmrS$i5Z_? zHZoIAH-!c=L}#0%@JHxfFzwcvv)Q44m0a|G_7_*+aD4u~BKTVpDKA8TSB-3qDPHX2 zHlzIUOmF&8Akxv<304LH6b?kYnbm*Jd4xg24~(qz2`J3x^%@00+(j#o-Z=#F#@;wh z@8QB1OO-h$=b!gzz1ku%5CDuM*&zp2`A1FBy^01#hBpJ&r2_XRM!RbYGu;fjJ;Wf& zjN3MV$8-_c6IHoaN7xFB3IM^aM(59(t?Kwr3Em0m&s$AX7^yve`x3Xfv;aU*%>M=P zijhN`w(U+m+?t-e)ok-%AGJ~^|4W?St1@e{4?$Vo&9#jr=2!olx>;?P`}BS@`qptf z@&Y%IlQ;~Dn0^IYl?yFREPMeSyG>TZQ^D)G!agf7TgmL(UeJCR6d!5v_YVTc<7q=L zFYsyIpPZK2Pd_6u>?capB;7G`A_m7e-@)08eDCqml0Pf{IYLB{81A*Yzo!%>?6*n&1v-+4#0VI0e*6{HK zLH+MW62ruuDl^IIg-7+}3DtKCit6R^I*b(v8W&H?SCzc&MO#^y(jf2%#AktSRO8k1Y6baU2ly@mVH68 z?LYJ))CG4NbFT;iBs)RRe!L-ZTv+I&pvCfNf)w=0h!Z9EJv#g}7#J!-@wGy!ShhV2 z68NHq*WeE|wpdfZ=%Cl$R>Av^BE9n?X5i0X$p@VvdOAO7rdkRJ-s)*+Htmk#a&F(D z$}UA9zp6oi(jI$t-f0ZUG;nqYW0C!5PqYx}Y$Mh`(y=NxjDZiil7=&Y7eXYCV zVLO9WSg;O;pjvHmNwpF~Qu$LQY(VOawwmkKb&*{;=PRr*FDOpFqWO=|zZ*t)9GzyX zOaA%KGO)Pyb(9Z6z^8q!qx+#5tyRpkXDA_X4E^sL$hFL(bPdq`@6s9eYpUBw5s&+} zu!ToJ|C>2`nAq4$=h~0+)g$NFT6>s$ z^(=!7u54;1w-D&ynV-eYY|pOy0|}^2aJuV^I3ji@8;QbsKiwcl{X9Jq9!nj!WIW~5 zh6i397hHzb%*7m^3V}ev8lFNNep?ZR~-|YzTnH z%&mJI{>G1T(N9>I>$@-iUwA!KAG=r&e@`4x+0V_sglxapXQ-qBRz*fEZQ-OM~RKp?E~$c7nMW59HJ;yV`IQQIA{nRurUa_P43|9n~fd#?7Q%&YTkoKj8x zv>%%GK7EfNZT-WRlgn0ILPzA!5wlIiT5J1B#eb}1hmd0K>FdRgYBbh^%VHC`SIRNP zuM|iC5Y^Z8q28(bqQ|sfWrL2_npMVh4e|S4N6H6{%TfqAVeU7hz*ieD#rbg!t59gb z_iyYACzI*aBNLjACLUEm48+4nm}_iaj27HL z$-xW=`dE11e^34u)aQx_4P@rL=yCYwf3-^akw&$!RpEoxi8@a%>Hz-|@aMYPVfCfC zyDg9b3&fAyLqf2OF{{`rt$kd!7j{vZ;IsOvi>w6_3JfQLGc2RS>=K)4tY)>_Y#nYI zKT#uQnfZdCb{3al?wXAX>EZuuGi~;1N;mxXEWmYY@-8eKF7SCz{zC=?Fw^r)fkaTl zc2S|);-VUa+}E}e`rTHA?XJYz(E5bK#zGo6a~k8z2ymMOwD|tAi*(;cSXc3i>!(0w z<=jtHokSJ&-j{%4#Z+R_df3 zd8_6B7wTbA_$;i5^tKzY_Fp_Ti$qh*eDF{LfB*P}p>Xad*T9IJ)JCepCXX3RzUf}fzf7gC01I{)skU)ohPL>{X;pR;6F-DQ`Vm^yg(|bNIHK0uE z-u_R8Q_p6g^}R&}1=NG1%>Ltp0U=rg5KOg+fO9w;5^M(zSd_|kue%|bq$`uUYo0ZgFjweV&mtXI#&#Ff+J|CvaWu8dJ`WmreOysYMV$jz2TT;g%? z6S4B>gFy|G=ZD=g-G8{wzjg>HRdpt46TgWTEM%~{bH@Q|opl0xlS`0h)|(kCHu&hW z$&1o}As;LJ-Az1}q0I8y@iI9LfB}5*x2lYa4{M3&U@HUscQ^C~IxoIJr+ftTrj1mj z^9%4C>{?1g(<;~JN+mx{#VNyOz!tT#tU$8?zGYX^I5u3`aW`%`RQh(bpdcwvvH9!n zu37p45ZpTMeeX+{=q?TeM&2>Q z02R;Oz=5VwgTtRLxhV{q;wP;B51;4S+Ruz80YG{?`7p-K?Pi=G5Hvc2#AmZxItt^s zacYngeeWKVS+M=UW4`DE7v1}G$Ld?x6DGH-jA;)7x%GV*g{VKjayDbK`h0mu&rCS; zx`f79Sp83DsF&kTm)dl_(STOM0ToPiQg{Cv(Jteo)br(@B^I3}4!q%d#gLwl&t?}B zu%Mz*E8);L^Fc;a*)aah6mT4$VLX|R)~x(RfMz#)kPh#og6Q?+0`JAwvT-ZM&GIc? z^d8<4x7jHH-{sTf_xf8>W^CYU%{PzO$(;`X$e79hu`m9p&AC}CMJsJgdQfY85B)`} zuyi)PaX;Igx%_uCN#y|mt8DaZwuB1Vqe9<1 z!G!sZ?cwa{(d!Rj__>we(UI4N?GH-2aBnGx#u1b4WMyq{_(wOzG${M-s!>+mERz3% z!s+s|&0s37Ey&`!eJ=TVAk^A@Acfc}vhrlv=l`1(xBWo8%c zCuMw~*B^)W!nT_Yn!FsB&xb=#UNHKazv6_QE_dfmEGiO{C#u?B4dynAl9zrm+C{he zrc=v6OaI(;cUkPFtCc~VP}eXV^deYc1^&vkr1dRXK;sB8Y4)CA_6H+BJ}6{KWZVW4 zZ}fgxzom6IRkUfY+PTPpv)Iuq;F9~q;jCG~+PVH91xw_A0td{F~9s3pr$ z;inpxaR56&#J}D$p^)c*9!D1^KHH32RCX#*145vjD>d6O&e|E@w-rvz|Gp`%sHPsy zf*V4IJ3R)q{rH2f>>tZ#3gYQi+0+4h+l+b1+_hdCB=tQDWD@@|$2YuL4@-^Gv>*VY z5Es$prxgmiv+GA8J%;SD$26%&lH^u~{cSzLcxGmWql=rio%qEkT7@IyhlxwttE3Q8sKE8NT$m3gfG_NYqy8z-CyPje6A662cN zEA}oXSU-`4FY(@HPJ;YPC(YAO)jMSqGl!dm{V5m|Rn}Km+6WgiC_vD|YR;VknZ`ZV3_L)gKLaqZ}rAN9e~zacRnMQx%k$x_cF z#bJpYd%>ZO31{~6Tk_|UkqJx!#c3=aYj~l0L$`|ZQkI0;oE?i^78g0FV);b`AnlXU z{wFk^oa)Mpftq+niN1G|>BJGsm_sNPsoLCmUK4y)SfG=Z!?7YnNX z3|Q_K<`?;=I#4R22}8q{F&&>Ps_t@eL{O4ZPYmk+$o#lKXG;3a_13Qlc%30@U8^B1ubIRE z)Nh_L27zKySnEic=>u|!Xk~j_TdwC7hDSd9B16=lQC2nMryiEz|Gn1;D-28YHhaGf zLHa#K{0_RV`fFGet$0B16$y%NL=`l3_wja`bwcP87!Ze9Gv8=4IPcm#q6Och2=4>6R!{Rm;J??`>og4syh8eiIGy9A?QzY zR-J7q=^(xfvb7p`=rJ`A%mEFZSbDJ$a{#LH4y@?%xt`wDBl=$}wT2sN9JS4f88+^f z%T6=CHk%vWUy_~+_cOaG`h5Z@PpnT)p3@E@=rwsFXa)yUU_OU6XB0me^ko;LbHp=J zyB`ui20Pzu4j;$$2%X}0UKsv{5L{JYGsn!f`%cRZ0Esw@A2%gR=7p0#hp923QQiGV zvb#6Q?m)5LD3t#tE;ggQUqHdkl##oc7=T?l`;l<|xKUi7A!A5L3Agy5flL^7(5gB) zftL$+{a$&PNq>d)*J_VogNAi&?FY75{5$Orz?XF0`jNEGo4h60^&v8ZjTNytMbmisjm0 zj^8^~x0s~;@13e~bB}IEVGuC$F*UTfg{E)CSD|&w-oO4_;sqjuH8P&Ni|HcN2Eke}A+Z66o7x zRN@p%q*2N}pGqCrorv7=HG!)8>Gj6qA3KGuai)*VSL~@Y(@7A(m97$7S=fz!)Dk)~ zQ_YYPWeV~e4+yD+cq_RP;B+ipFPZ!~mK?UYy5?Sj8h60hu(%sPtAV_=j{Ms@V;T&g zLlN1A&Bf{4b`}XvL_TJqWB~-AT*D@t>MR2V=pC>@RRCYM=Bss((!>yS*0EZ}PX4Ct zaDZLlE!_*d{KE`62z8oYjR$3;RPB*t@R=kZyrX3$=RLmR4n|U`-Z)j}^0{6_6eyCP z&ZVB_G+rfxZV#3o4r7kyWzryoF|eX_!cq~Z7e140K-u;L#lz%pPF*~)Q0M<}2Hu*{ zwm8n!U7E_N{_~%GB}dHZ`C3paXi@~{4O6%v^rzvFtzT8~Pb6{RQ;jOg5 zHCQ#!T!A+|)A*jRK^ag6;%%JnJJb;n+ebj?0r@A$OZhF@t7)3(9-6!uVmarmZH|*r zvg{5|opXG}T(HR(0_h?`B34XCe9Ck4(R_P8xX~)iDBBveyqIG;oGQg3*9nGLb&g;bGfNnFpyRjqdIy#tS`HD4Ffe)M43gi}MC`1EF$7<%BBE`yQ#<O%q8nq|`RhKS)*t(spfj>vwRedE_2kCOhqMYRDcV4yN))&vd87xUob zn6O+BLS)1oedvYJ6D%BXk%b=-dKTMa52Lpi|Mv3#g0c~) zz}mlK;dbH#4XY0QHY|b=+22`c|I#Sxw}V})I+OZOpz5XsyP+kfgBSI@mT4J zyyo9RvhINUMX|&1X9&QT-)i_r!a(gGUr) zEn_M3Ex%^_S0?Iz4?8o(&5D6$|2>!}5K)kz<*s3PU!YgM9nsS&V3$5eSm4&Y;GrH> zRWijp!Mtz$AYv^%yZA8 zq`j)%BP3)-_o*SwIinuFww_PXY5#0WD|RGXyd)u@9A2+sWNJbZysyde=7u!CKPYq< z$b&AYc=lUCw`%jH{yZKw)sS)@ha3f-l^?y;H<8nm(kVCQolUzU_sLJJQg>Yw-pg4- zq1OPAHrC>iy7_qxw8wE(=Q@j`jkcdq4x#?eeAzFtbAJZ;n#Q*`Uppd}K?VWY>+Yr_ zn?X?a%^_5axnDtFu4wEk83)Y*+YXlTpe!om)#Urp#m%P5Pf#UPe`>yf-8)-9 z6E>IMu9eKuxIrEW!f@8`@uaX!uwb-^`zG`8e-i7p6TVwu+35XI*yvwSF z2W5L!jyKTQ_~UT1>0*Bl1jlBPRF$+!YHwu6%?mCAKsjrbfLP(|4IE}QzI)3mWOxu3 z_c2T#ctk*vkC~xlNC^pmvIK}D7K9xh34@#Pz2(glyLIOHx4laSetGR!6(i;w5M-kG zjFt;x%26qh_oxxo7GNn<_1~lz2pIe__X($wsp4%(#C+YKm{};gAP5AK9o|+xL48_- zfwr&%Zkky5Dhg^XRmIg%I0z%vG*Si)avo1#Fb>**qV_|5 z!*1vqN+7)L#OlJ;oJ}QeBHuL&O*!-R&2GtW$lUbh^Z$!|E*S_=CbbMFHE0bR$>x58 z+m{G$X14k74w6=!yvuWiLIFExbN1raUn7tdGzw(z;%uGiz!Ffr&8$Gw2L-)o8_@N( zVKcu3Cx!<>P~nP?#;vwpb26XQv2Tr_3e8)6KsiR2DhjTn1$^B)1?5o z%bL&sK?Dy5+Am0P9QHV=+7VEmA1JIPf>?$2-e%)J9Lf{|h3bwNREXHOju?tZCb*mN zc%pt1w)2VRuJOEKM))^p*RcJM<7l!SgFqCB#CXkkn<#@~P}~X*-QSh77yviLduy7x z)NTDg71txv^Op!p(&zhLxD99jGqTiA%~YV=#)|sZaO^*92hAlwTcCuNzp(B`qu|>4 zKfCwV@H?<-lkOy77)K0_cx1@`>_G3)U4TH2k%>)WSgWEp{2Sf_A)>N$dPQ$LQ0u)L zu=5gq2d|{LQSySU2&!`HOw&pM#N44cRRaR%ikYBPONJ#1JIv^!s$u>!VJ>tZWRhg} zHx7m%WFo)m;xAf~5SLNj=&d%NciI>uC03FEy2jO~s7jEDSiAn|4DFsI@HE5u=R<>4 z5k?$SpZd?r$6YS>Yv5NysoPvxm;X)jq!j}|lQWj~=BK7g@8W`%KEvx`Wwzw@^L?{6 zWsLBE1K}4n26*k`NHE?SI|>B5=osh!a-<|3P1{_sBk_hEZsJsn(SwoB#7EVjotnr~ zo~qLcUy&gD`=_|HUzm25#WatvcSMvH#EZ z*wy(&w1fFi(S;|$FwTX=c`>kF^-y5X%UV32JuRQ%s10pd^2Tf(dBdK<^}$C+kf3kD z?fSUh#soiLQi44Ye4hpV=C|N`(;sh88TQRT{*R`qrXDKaii;^c1|qs+@k7Oco<&Yo z;waf0^#8QjA+*H*PY@Z+V`=_>=OUZ4o z2`U%ow5I2d5mp6mSuS`8`O!vGqBKz6ewggRh&XKUb85C-S1gP3fu~Bz=epw{p_y>; zad}Xxfkg)!+>G4+Y#v!~@K2F-WyBnrv}cIdrj(J$ZUa`*;YPwd>5xt}coZSyU zg{w7&x;U!*S!3!v<{o==@Cjx#?C5On#!dDAafK-ZY=g~_U9i5Q?>uH9#APAl1;4H zy0j~!uD1QEVqT2lcG#Eu3vErxSfk~}CdZ;fBc@wg$01F9ZP+OB=*qrqn%!Wxltdfo z^A}R(iJQo%nXq78+{xjbf}iFbA93;ETp;t~nr2Y5tdX5P6IZ)?Ao zGYq6(FaZ_IBu}JM57B?KPBkPP5ERjC6HjA^@#id#{|x29l%Tl=-2Do;#YnR`hC=2~ zL#8OW#zn}pG1+1tdZ{;^*l_XZZ1(?utx#P4WJ9njc4VSj&2*qVrTdy~-KItc%H zqf%yk=r7di(csvcv^^|QL3Islot`d%|1ZT?vi5ug-%R+E@ZdVDuR(BUWIt*po->9* zn0N-E1=?KYQBx3SCR)RfZ>)?BGc4wwqohva-jP2dzE<}wN{N!OXnCpx?+PPDM?B%N zQ1F{RQ&@16RL@#~-?{4v=sMkr`$OA$Ez`YR`2YfcDcW(ky zM-co=(OwX3(_fJxBN4B*^?S!;0X;5-tA%V}g30l2-ez`__r$i*h79J+9$DwVZR+#Hqo_il1yxT;v4EZdScU1po z@;4hP+KMF2mdDa2Y_@O-*hXRy_pNzG??8Lj5g9Srt(?4aP;j`2e8;bc`!jD1XR*%jOF@yU4H zq+YLRXK!-7cX;JfYB`5|#H_$r@5P)Up-_fzq_&NtzR%b~fQ! zXV&?&x!HPOJLb==GbN&b!XF1jrnNHb{GIf6+;ISaOxK{l8PS&>iz&Etz}V!%?&FuQ z*%X4B7W3omESl(vAAvF3#wG~hiw-|t7XqFrEAC!-AN9G(f6oH6U9Z_liOkUO;vY>J zd0kt{zNgt)2}G4RLG;)wWc)_R6?@w^f_*EwjJ7$ZrKdpPz8;KKCib)*n8PFSJQ7zt zcYli}CHHimrOR7&Bd{=7Lo9w`PYn54@WTbDe~_@~Y0FL$n;*}vCU=RVhrsmY`b z?Fo%;)VmhIkzmjRt#qo&PNl47Rpnk1y2TfwG=T45Zu;ON_oDA;PGSiBDJ49_m%6)P zs83z>Fz#Pe0?6ay@xAjlc0MDmZ#Y4g>x(c#x^0lE|I8wLjFW1-_H(J|%Fs>CekFiN|<3s4s=L9jCI1U)qE^Q13s0#LcZ7v_%2wCPzM%#p^o50Hm zm;LfK?>obV==uoHN=5Fx43@hrw#EI>+t!C_foaRT!F`8Kj{C803ta&_(kF^V9p0zK z@Y$ldl)vMoUw-QYOhke~)S7VH`s`78#kXKgA4RuxVErQO__&tPb=0N<8= z@&zbhaSIv$`eps#)cg7@#&gsWVW3=#<2x89-rQXE<$FYL_H0a(k9*!!`nS2@(~_V{ zz8Vb=9%`K8V(AX2>knJ!ErnV>HoiYN-x+Inrl+KBX?T>f!U*W#OiE4FLISR5lz^T& z8&ixI6a>JzLQD<4B#Odniydgn%AF`v$9J30n`mjpsjK)+)I}et*&l#kYWWTbUe04< zCiNX~C7dr8a37I#yjLr_<$K;U(LnAIF6e~Jaa?EvaUWx*n4Q0m46mhT+o7*6M(07K z-zy_7!eO=BE>|h|bXQ*P+T>mw9cN$CyeD-iK+wF9|Eb(%I>#x#8FG!gdiyggMbhFW zg$G<`)Va7P)qyY(6!3f5RfjqLsS;L9u>Iz5S~&KBrOc|L!DH0pSGNqtFzbiV3aWY$_-=)Ru`cEUq|8%Lyu zZ_y$@+0yX8L~QcQ^LG{wRu2T4r0{4~Yt6zo68pod1I8Y1ixl%tn&>zg2mJ?s_+C@+ z;y(Gx>OZ=^dkGrmEwXAXF^66wf3yc#a)J~Q%@=ij7oPh%t;Nuke6Ji7d7)f(Hm~wG z8-qR%XJulqbKG&qA|NXj|DwqtIF$CjixJ6@4*#aA3Rhz6h1=1mLxa9vB;bATJiL6$ zUIPI}`7&8{JcGlQT(HBE&pBRsT-+8&0T~riqBd4m)lOQMS0B~4#GwG7sNP18`AT&P zQyFNuypI?u=u36cO|=|htrd}c3us0F zfE*g|6?Lf$uZGM-%D`-#l-9wIPW-|W@4|@XW~V-8;&dI4R%Ad!+1%{A3E3*+0ml-U zYB;E**Vm^Uc|I{#lF9ILWfJKL6M6jHD|>e)_PZ=3N`V^j>0t90oxo}u=_jwKq7Pl1 ztePL9(_Jk~o(WvM)Evui|Ga+qmdhhBs`Wm{GXNY~S)VA*@r!49_{eEPwB3%QH~)O6 zR!#R7bGzgqeznaSfBA0w+vYPN&=Cg# z2s%3;N!JBX%mi&?4kH9sBN4(h%*ReC%BSn_a{5IjGN;e}R>W(=HN~9RZMz+VB6Q-d zy4|x$uw9>N84y~0d58x^3{pXAJm3AoB+tevC5Ap;GOjs;S8=o@4zFv_@jBlHqtrE$ z&(q9yzit_-0OoOUL0jF8##!%f62TrRO9|3nSq8% z>_?TR%KEFK!fuwuSRmeXP`H(jj)VCM`SS&mkpe`=n2L8}oxzl~M@{A%gV6K9w9q;9t15DG5CHzx*?{B2!ac3~MdqX-ZJRt`!<^8? zaj;K1z?d-f=4fz{@KxyL25FT$kuQZ_=VhslaK`I)Af|YQne64R+=kDqSw;*ya0kZX zxlMw=o5xYT1j#BaXJ}aL(>=n@W$bChGjoqoPlyPJzjHdnW>qG6P`-$`*CKp&3)usJ zvZsIb(HiB;fAD#K=2uqomZInp$MD0?@}C?}Oh%uNB6hyt#6qVwiGctXqjKn0K_*MuLc|{aOy-gM5WWp; zaj98~EZ#p@^rlAaO=qf1N84^XCf`5nKE3?)L&=d%6+91`yI*gd6KVI}N{B3Z(0v^~ z^?Vqak!0ZUw=<=WI(g}$$Z?vlZ>+TG4Z#w5z58eknzO0NTGl2C{=1{{bnPu$Q^*cB zo#zWOm-``0W!PbM5sz8~VfZE!1VGTl4Bp?pVeER}!l zBHGN;*B#KS((VIt9Df*Aw?L|M`0TS_s-!+>s{7^4f6_{zUByK7r%BnBsYO6z-igyv zkU6Lg(`PmeB)4TdqU9(^j1AOr-EbQI)t)|()b};n@qPv=@}Zy5eeHDh)!q@%IorrK*8?L+@6*7DPQ_Hf$@8oofSg~(^tgbx{4x495% zJX3_Rj4!`Yu?cFVa~tP$jZ2SrRHHUi1Ws`>yvvZ9aL@FdM7dTAD8 z3|;W)G&n1H){aZsG^fj3*{|ypcYdKTm8Q*2!vsn=zs)|TdzDUmD|#8uc#t7#cpafx zVZmjnS5pOukz+>_G9V5&)+Ubuk4++DlaA`e@=nPx#|o=^`=KVkA$+?~#|2sT&93x{ zdJ*+a8o7iMeDX$K_eXES*x&uhYwYBc-!Qgsh@pQS7kE*uU1y_Sx4p$aQ-mY(|1A=K z;3X&U5KP6dyuN=2h`ey<>RxNzPJQj~^J<}!@7k0d4`BLP_b^yFqro)tl>PC$v8H?->*-1@yi!WwFNmh243OLsiCH?c~jyNj}4Fw7bJw=Mi2LM#TK0Wu|rK_)KAKln}VDZOdqC+g}p3M+u>qI|JzWD2~p3(VIBbd;r}0`{dG`X%M&$#Zrmlo9fG^NLkMoco#5{7K?4L2?(XjH?(XjH zZjao1f8SS6s@|)5Rp&1_d(KSHboW}ldhZDpi0(%_^yg?`j9hS4-UO+Ak_YZM9`a8b>6x^?1Bmmq_qJ zfd8|CWc)W~N-D#}H8_kX+OA10S$;}Qr}b}i?0jy?$=$v8SLP%BDB`!9NNz)@7ZAhR zH`fk^2g|H1?f?Vk2raRhmBk#)Nuj`mMa!vsUeIFmH}@cG=r~*%UR#R=<5&-R)3EDG za^M7ynEjJdKaEx?xB&V)@BHz$s}LUqbl&~gtSnECh2<&(yh>>ev0UUKYxWsvO3M>uHi8z(j#Y?`!fzYaP96-BeocF$Gut zrOu}+$NZ;@G&ej<2RsQ^L(e^SkuWg)sd&7C;_-rEKI=2S~3E3ImVow zoO0v~;OE`Dz`}E55uU#W?8dHLzrp}rjC_CWX{=FW)>v+hwH5u_F?p@a5d0)EFD+7B zR*i44l@#0%0AK=4TTB(T{|7SH;U!#uIUHNtZoNmoOjNA*gMC!V{-E6&XKW?|BApT% zsC92z0RDt>9X)Nf^Sx@>{?Td_C?ABF((Ia~N?D9+h~d5EZ?B%^!xtU;*Z!N|e3Og( zVQOeRENT8YX|9GjO+$%LWuh;)GS$esxJk;sX=|3^nWtQds2wLGlK#lpv?6Q0s5UNd zoBo|KpUPg(&%I^wTn6mBtJ5MMCBI!LgpP=k`y0{tw$mB)q8n>yx$m-@#zzMgdk9Fh zx8AfT+n;$(_6HB!NTf8|iYG`csXvStC+baO+)M>ahPSKk8)TctnEWb3n^=QI_D&g5W0XIf-7sr4eAO>w=~j4ruBYVNY&gnW)t~ zBnThSXtu^Yv)2PLF*j2LfKfFl$>r99jOh5pVcie*9kuUi!xu5O6~OiEzdQkCl-7O` zo%_COcoKLKkP8!9Qm89uWcUGiGW~qFn;nkdP&csgoYwcfu9^_lOhxmHvgstt?9Pf` zQ=KbvrXye`i6rM2ITwVc2WQN&5O$R^@oUPmBFgj7qIE|SmjaI2T+3glgcm7da@hYE z4l1P%?Y&Xwap02gpJCb8+4D3=qp?pzl}89wgZE`(1(mWFkToMgXC~%duDpkH@?43Q zLsoK`ZJ;}c+MFT_y?%Nz+=RJrR&yR0y31V|I>4@!@-3^_I8ZR8!|B3U-!{rOlW>3i zwwNK08LbGi32oy(5eq9~?>t<#MgKkYaOFY;qbFbzZjuN1kmL6gcQ%%>zrwqI^!yd((>2rin{3VM8=LFL!G?4?l zLt_x1n8tB7B zu^UGF?&-Q6O1R%)K;zxRrH>{X!Nquhti0lctTfpBqR7Nw|L9qpGVNv`?%LE}nZI6z=N zPKA0%`M2E*Y$nz}{TG=(YPGz*pMz`r+q?u8&c`8QF|M1l)$a2M-jBAguKbq$5U223 zcu$~l-bLX2!HRU&=%fmDc^~?oWkr^eymb91zD^B@I4)+%Bd`#$p#75dxD=d)4yfyO zR#U*(GiHFp<#r0m-xHv+_HkH?OyuNu6yq?3=M7e>^|&5%=cmIyF48Y$zp#0Q(RbTFZ{9|(OI&Y&gznocInDR{}Yl-|F4h~ z_kV<>q}=}_BpFfuAI(Ya|MORE)-x#u36aC^qLGl|@(tM9UoyPE|DJYnfcf__EF{tY zDLmExSK*=gKVlGz)ji2}5Tto*{;4fOah5J>w)TuclbYp1z(YIK%v< zp=^#vRNDvte@?z)g6$ujXS$l-D&>SOBg)e~udnwfXB|ZNrzF__4P>9BJ`+SYW3M_B zV2{f|)8hV>8CE9l-=X(B9E&8fr|TU|5VZ=@Pud7s`u@8t^T%$;4n}ouUpbOak#%Gd zSv@~=80~*E8esWu{cvKk>th|Elw=w)QS;AMMVgWnz8@^l+`rpbD&*qL2BcD*y1%zw zOx72Y6cXgOeay74{7_mcEVb`e2p2uJJIg4p=Hnyd)Q*hJj2VY|6(dF$)QvZpQD3!T~(cok#@6p$r=Hl$8i(~!7pz$3~`z<4FwQY`D1R@p?RIR3R z86~g|u;4SG!{}2VJs-ES_z^6Z?#faspXRPM%8G&$&ys(^Luf!ALip$nNfRs3M~ zx=#)O1frji+S@EPl?XhOi{_4i4d-?>6DbAg%)^4B%Io)}-T=Af1tU#VmXz#$*x!=BmFX@b5bl#Q{@On2 zTmJizA{xL`Ik&8;V1>-iXMa2;KfW(&V%EjMg22XO~;r%^>=Yv2B;6Twd zh`Q> zKST^d_El!Db(((wKMh%{#PgADK;SAix}~b~Ia6t7AUus40F3eX2WhX#Ge5SE@oKh^ z>SG!y#nx@Pwsvj*ceqw_tgvD~$kfwUX#>qA4wzSA=uwB){EpW5bVv%)jMf=_t~21Zw`we z{ykHwtsD$Y3kX2SSLwb=!tCn#Vdg6{fRJgy@^-63{Fp%K;4IRu+gOwuWaH;oXJe>P zHUzl4I`I(OFSmi?;Y#85=g8RfA7(`OINV+6ItPnt1@{fMXvC=!om)%LnU{AprHAGAPkPzURH)Tj?F=Ek)+Kq|%Th2s2sAA{HZhVQhBWSGc~+hPS)ySq)Nfg=nN z3z?qpNxQ4(8lGkY*_^BNNd;-+r=%?#2a_b*ohbtKO~E6CEH_eMg~}YvCx0GJ6<)8Z zIS@Gs?ZiT@eZ9_PqI2C^!@zhr>CfBW&I)HR(V)Eak0|5aIyo~l^*U)$Q9pX+${`3r z#A3@-pLSB5bg>k(dW-f?ZiRaHk(LbIyT}4P0SGDkC_7@97gq(L zN4X|5@%xgNiZP(R1#K;f{Ov&ra+8?H3jPJ354jmfSp^`rRFWvowl_40i`i|tS9sgYJ@1NQ~ zJjxre_r__r&_qKjX)_Oc{5G{Qmo7Y%LB^aPO3bgqm@4r z&?~nCdd)xkL)$%G3$IVSp#IcTC#%vd+`7j{yk9FOJRW>(JS)yN^6gpx(tDqbf|}!P zx`^Il!@92mr-Ph{(M3KPJbvgOM+DEGRhn>>JW`YZWfju*Fa5aOLTi^7r_= zK^89y5vvoC_e$DMg+@YdVSkr4Jw*S;PR+2%$*07AAj9}jxcXuIQI2YQ#7jSRi_J-B zAg*zK>=%6VzB8z@+Sn$N*{t6fEsV}7ne=O+py{Azv&KN*{i~&Vl9g9tsAQ#2>E_>={u zIY-U3M=XcW8M=AI-a(|<`#XF=Fl;^5)VibY=StdM;wpx$OLnBnGRRo~uCU32M(QBzN!e+LYS4hi>KEq+Qoh0h&OcsH zHK0I-_MfYefv=KH?pyp{zz&oF)MMoK0NX0+!y*s_7A1^vID(Y{LkOsH*Rscs{XT)5 zfrpB375)8b=Pc)p_r9yQ$UN*!{)kkrYh~1?(_a|Be4HBQxU!v&<#mX*WV;ABw7Qmt zjTmEswwmqk^?Ulz&)kXs>jhv8nt*3+-illmX0-QLoNx@jPvN$IJv(bDOf?+W898|7 zGZ>Bl@c<4NcZm6K@X%VS+#Fd@{-h!xINw^JF;`cEw3y3AyM-@LFILf`()(OiJh_I%K#(H^|E z+pPac;*5}a$rQSU>?pYMbgPLSS*l`RwuZ|G*Z5ena5nKGd`B{Fxowk@VhR?1ph!DQ z7I(m)dD=Mlie$3;rFR3ytDC2xsZgm5)8qSGwS zL3S3k3u$60^E@ra46qvJYqyQ&7OO9vpudoE35c;f9E$M*k=W5h9&WYg)5_q|<;sBd z@|ESXPgjO~A%N^Kj-%`c^^eQ5lr5E=uX#}&9<Q; ztfj12DI2E+6%r^haiSr^dl7mpd*|}pTk5%=8KAShp91!Yf*iR58lHyEUXs?}w{dD8 zwdm;>3sSXLXVmNXx7F`5cBLK4Pb))FPAnHaA?9w2=uFi&13Vo)vl+2%9Rt{tr`_yj z83FJ&t4wn>apzqy>DNQBwTSnzVDb9z%1TbgMB&$2`#ju;$%v6=;^xeN!2E4J={(ep z;n>{yi%Uk))5Xo9)bJYG-}oDblzMU`O8<&`xBC|MCcM`x@A?DB8E@r5UBR|5R|gSS z?9JBOF%+UK;R&$O@`4C zfpa(HeDBCb;lGEk#EgGx!1UgN)XEQM0XlQ!6KV2$I4kFm$9C@c z+*S6H+wa=gowQ{HB~w7_3je_J0zhwrB#!vQ*yy18K%}c2UkJW~mq5USSf)4n2#(Dc zsSh?pXwZSjfdfA2(?bBjQF-oQOyudVvDrT51{r=pM=gwDwdXX0wEUAS5!PQyLSgj2 z932Gc>EV5F^I&3;FZ}KVB2qYO z$IIri2LcFWSDu=p`bamk=(H<2vY-Fc(D|*O%VOAC)EUC>_y8IR569o0`ry=KG{1ze zimu75$`8wANi5whOw3_d`?~s-;u5HG3ELC&vi|s*{;jX^9*|EITEr!UTXNZU?n=!+ zZ!H44$D5E0BZMK}(wx2?-B*RO0t*YU#2GXg1^3^^K4C*Sa!I_|9jfbSK}l~fo@5&b z@j$1xUx@IpE^4qt%GOu^dTn|fp1-s-aSK}tIqb;*>Ci!^(v}!C_j3wB_xWae2BXr7 zuYPy(jZVP*@T`d2<=ekV<*egl)_JBRItct~V_q%ksrVK8lfEux!KD%EII{dP+N>jn zrFO$b+y-^dzM+*ZzG!&BuM1UfeKkleL(3%_*0Y8dSMI&QC+5-`_2|Bh1!UybDO+p1 z%*&GEd$w%`#MnOY1AY!R2k;Ws$G#|o?fAYw1!Zr}X4*J_KztH-MrQ>)$yry(Ka(LF zDhU&g5x)rP$*q)v1r8j{SSJ<~^$o#VC5n{_{&Z`L`rp&YDYCF6x`XP>b@*%@p3Sv( zh-p({JAKa3bh>`MW)I`_FuXl70qxn^2_^gm0s!KU?}K)8uaNyC;XYVc@P28v?3%ZF zE2kww{~F+%`CK1SVE_3X-;ycK(~8c$0cWdKjxFYtZWdjt2>1{C1XRGplBbzjD+lDr zw;@Q|t`c%WCEoMZ=y3yaaf$m8biq!z4jk$M1ptcbrp^tG(mLoS!}VVz7Uff6fVtmi zn7PV-WWzjV+`E;^&j#)Og>}*?ix@#m$yfY^8*B9x1Aa1@1=RfQPIOwc=PZ&9lq4OE zk5g?wBy(Jwm;hi&ss6kIigz=obX65k#<{if))d2>P41A)D2kJWZZT!yIaSc}+3Ag+ zsVYYpN4?VHG}UKJ2Mf2lClD0SHECD+&XX}3DUbahXs!JCX^Gy)pO+D?svtll%YG0_ z9q)?sRLHmLx_tSL?%veY7n$Ih87_3LQCOfO5aV5KDyywKP9@IVEC%x85zyAg@t#g| z0t1hLXsiMOxC~2$(`Cx1%*2b&U>tMGigUR7Z^rWL1e@c*Z<}SJG;GYqGXzO|jm(d} zOa3-GouI%k#rPi%N3pu=CGxrmq~%GHP*(0iM6SzyZ%;$;06J(5hMz%j0Z(_yLFZVq zYGmNz6bk^P9s9M1ly30qTB=fLZlyx!*`T;O9TrhrT@~)-TdQha+6@k-vEVEfgo*20 z&MZaq7kfpmOspOc<>n&;SDz7oN|2VDQ*wS+ol#M3Q78r11p~rPyM3>P%WFHdO7XDY zCfzm-IRE7i z;&-iff&du`Q#=+ipBm^ijs>75*y`%k)$BP@TeB3@DTWqwm^A?~KK*QXl}|(EULu(jZd<{-RFQM7w(nw~ zf8ML&?~~V`tzAUpJtAvglrnjzGs+4j9u=%w6V=B(_~PM!qPcoq?2u-Qngw?vbm2g z#ww7h3gXjNclFFJ0afE=vN&yC%56Oyw5W;xufZ$XHMWqwVI1SU?N>vA>1%KJ`#uHzV-XWuQdm znl_bQ`BwZ#_&G>xS;48s)yp3W3V4u_mn3|w+8r+%aAA)1(Ep*x;3qV3^2Gz?i^sD} zw1i{mC3VyM9mKHmQgw;qZNJ&CT|P;E?WHWmdh~iWt>eYR0ug1$qRJyF;jph@#*Lfa z>J^b-ZieoY-p^>2+1D6nA&J}L8IeUrvh*qD>GtczUN~=^gD(87PX;oUww8Vt0~2#m z)X(08m1qCnyOAXJ0o250(QoGR@~$30H2jG5@hmW#=DMyF(ottApx>Gj&@@u~(j=gl z$}G#RE$JGx9F^Rf3zgQq)fb~}egH>6xW7`Hh-`)KkIE=s-)LRtG}C?r4NMt$00^tI zwx3OKmE5ZYGOp)F3D(NzK>*~JQ%Sb6%3R-APgMZQ4sBv~El+uxGDBhT$@;6JrmEaP zD5@L?Jk3u$O)Eci!+cFiIl*-@_GV^kpKock$MY`&oxZedWB9n{WWd4fl#HvE@T7CB z9v1L%9P1Yd>9HXkrnXgN@#Q)UZ~N-~v@{X4%qFl4c<_m0q6n$lzZ|)bw2WV|{5;(< zhh?2;Y_kZInf<;BasA@qiHWMEa#}wxqeBj2=e;Dk+SF}-$v-D%Uu6Fkyd#ob&QI;X z*j=;uIS7ERt2giXR_;RxMTarNmL9B>Q8`%*9OZj7)F}&?C6}Y$T774^*EVJY z`S9WETV4>KKXV0xApF1UYE-@Rs-6hG({OqC3OH`Leh|P-Jn*{@67E< zTu3)rL23G0=CEv?CsL>WVE4kO5rjGm>@%x+DSC}%$e0)L4;FWQF)(0a&8p?Gb5svy znfkw)j?o9cySmZ3O(7RGXDEmbLqnL4FlJYDMqozHH04Q7^+5ly6#F{&*x=~+Pj!du z8^(_)WRih%>$J4|3TuxvLDeLeV4u~L<&KV5I5O}qZe2?hOz}!op0iHEiyaFJ08;m& z=wta9Dy+VzDLw^Z9*}@fCad>DlGC=#w9A*{0T^G2b9TAxsQ42}+C?aM75DK+d>K$2 z3}b8n2pz0Fe(M)5`u!-TaPN2&mIfhasZtDC4*H!%YuWJ*`{Mw}@P(eb;v?2s5L%RQ z;tpj5J{48@S;ubc{(FlLwzV>3_XgSpP;vgYjj|rA=G&zE=EuFtL1tHwSzPnblWeFe zsk`U;f9q$2EVCQdR0iKHWfbm$?SNk^8|R$!u2s!`Muq=R+7>3?2@NJ*lAgo7H7<=k zoVzL^>VgAO#Q{r5(Oigv>*69Y+VZ!5{8L~{YH+lhbc(9+ayd|lQl}%eo>dHUo2wB| z*rY@kHwm0eP56!+VKHVE;h#;3xyi}osbzcq>Z;+{|B;eDLNpTd$%^F{_J`+w_wUff z;)g^+`v1HYAn%9Gff+=2tqcufYUTv|YOd}KKOC1JUO!ii1EgqnS_?!Hv@~2!91WjN zs<#A*wPKR#obtNu<+VnAcwAuVErRx$^u#ZiK z>y>Tbj+oN+#Ix=P?ZWUsB4DcSAuHPdr*6|%UIg{G7GzX>hqM!odLpNzq|Bkon9zyI zgHBmp!#JU)i4*2=kfs|4*2I z*=Wk9C#A;VbQOYfLu-!ORO*rOiU$Z#;GuN=+<2NKJ|{N+ZAL>4m1st~cnU4Oe2i0m zZ85Lv;}dFQSJgo}`jNb@;>69A)Vo`3z6Ounoor1LD26v>!0{5YB*8+~gf6&z-!N)gEf^KN6HX{}=H9wEim_7~Ol7nM>N9ZapKS;NpM`=jtM zcE^JehFy&;^jZ+R^rDdUqVT2myE|08b6w$7+hDtE4v9sn^@6$%WHQ?x?^lzTf1Wrj zS44N{qoFO)ANz-x|Azl_)owq)=W}uskf{a@n30-E(8Lp*5=qgOMglWTDf5AWB}vn> zMU#h6wYd{`3Gh@V@mDgff2ctK-3F^*Db+(==}Ge$H+^NsgByWd)t}n)hJ>pAX*oeH zwciV}s!9-+=saa(Wqm)m%}>vlW4v1HKX=PXa8~t2APIlU=8DJjRX}>)JoR&s1!&%$ zX1`$WX+S1tRa(54)zJ?hZST2$3tGQ--jgjy52O0D$h&ta1_daMs?5V;pTxcJ_LXH) zoi|I^o~yX1LO|a0AR&Xd>I{7u7HLw6&5nn z$JIvV5wm3(TACWKp8Hxh7*?T3>=bV-npM1XW-qOTf`b-O`m=xOZLMt$em9h;3C}-= zNYlaUAzUsO^P!i=%I%=>mn-oqbw|g zupC`Ebh~S{SBZ-Fm@=dD-swU=d-3x~na4FdJb-4y4jMQpdbO4(_Nm{MZ6}!;?}lZ$ zntJ^VP&{v>TovXPt1K;u1X;R-dL7*A-IH%Uuo|ivYXo8q9uBy_Yii%mr}#(21py`^ zhN5qpE7n7q$4B&f5O*I0-fjoVC!s-9$0^e{@A9Ug8o7Hmje7%MmKuXnN--L91%9B; zX;BQWrhrESiW}5NajtF~l$-^BCu~SVRB~9s{5B_el)N9jkn}oQ1R|gMb(=Sv4a!by zVf*GQ^eXS)XC)?fcxkN^xt|uOw}SYX!2v+o8q)cvi34S1D{IZ=WnQw0AcnD>imcDN zUdRF4JnsR>DwhTGGZ!c?C|TX;&P6P!0FYOF8R&!eGFv2u0~(!j^6p9XnAIC$G!6h2 zo4wv~HPAj?6GgEAqV_W1wGYv{Q#*{GjTS}=GB#ljPLo3pen-RBFQGe`*<-Ua&^*a4 zW4cx9sGFQRN$cJW`N9k(1uX)dy0N?Oc6RT}UfM!>_mN|9aC`HW*ZF`4}|P8z)SXnYgp zDCI$Ge7eH6Sq?A30)AdoidIF1H1%V=T_$UDT1+KE24mMpvHMt<3ABK@I0 zS-f8kuc~Jd-(YO&!z|#rx*2abN&WAQTQo(kU zrc-953^@~;E?C07QBt;a?KbU|ciSxA0ROgJ#%(yY_8@YR_Yr6B?jSE-ZWKav0HBB_ zyHoDM?3WEUzb{m+){nmM{Bl%m&t4tCGey%C- zN|q}{y8*C%-?G1Bjl@tPtVOY|gu z{_)$q$BjRpaINPagoyc{4McBB279NYE62!f`EvC3lxa9_wF6p6;WFgHZ1!6gdr+mX zR=B4NX@1=HEIOXe_+162Y^T*0I}TpOTCF-$Uj2I@@`2$oSF11^3zNuK z=hpd$Z&}mP3Q`E$0m9&_EQ>=`3Twgfo1@!+9s`^sDrWr8$ws*KU?hz1KR=S_FZc(} z(h&n@!iNYli-sUcFlr|UF<SrMAyEo9f!D!wt+{u+biy4 zJfV-nDn~KO^?gdtL`^OB(g0q>D)Z%lR?sTb`8pXpv+|!;F;tiAEn@LE-ruaXXc_5A zOqtXcTj8|-+Ngj`Ar$A8OQ0bWqdqnt#%E{blv)%41u%bSqXfznhMaO&^hQVK-t--J zmjxa6+N^$VG(d}hSaqy%m$&>tI`w)%t?8(9?ls1^kacwGqVP#;Y(8|kxt_%HbPG@! zE$0VzP#T~>O)2}RXQWgs`_};#u@IBAAO4j_V2+{HU?4>v@=qpb&EVd@F6N3+JF0YI zFCKUt?_D%xQ^A~NmmV#>0pn;CtL}Yp>YQQIa z+0kojG@r+IDzZcu_!*w)xD{xGM0faM7_Irz>3 z=GVPW-=;@dj-fmBUo0j55y}A-nZ*p}9qzTfmlhiaoa-As?irVwN{c>P`I;)P#1aR( z5P(~(G90*{>2E5x(rCrOpa`Qj8hfGwjMe$Z=jn^GItu{UaKC6KM<_I8H|W+3j1&>0 zRddRv+y9!_BG0+#S^29*!s}n=_stUVMq@{20y3UL&;;}!D2F>EtvzO;WK2E1gbx^q z^s>=?a%f^+c1fpdPnfLIH3bx$b{`!+0Y39vDh;$)>gy!uKzNSDg(dsya2O<@dya{% z9(yHa^%`eL1WeF1UwOEp0XH_Ei*Hhh!K?KxahGnAEGeK;s3d)JUv#dVk zzyJX50xkeJURSU#7Puj-u8!u_x(N8~@>wA&0~4;)*FpEkjsg#Db#{iRC>?~{aUL)G zKhhWfrv~u4kVc~o&#%Gw91{O(Tb~X_1TxTOb8xovD%eE}ca7%LhzuYLN#PWV>}38p z*CF70r#yXN$I$fkp@&S9GsyP|5|F?zES>)xbojXz4!T-lGE?S0B8q3Oi00@?8=uOJ zW&i+8ic6FrzAn2w`-*`BtcQc2?pv`9#=+LXL?RObZq^pt}BW2N4_K%`Onf z>+(k9Hfx44no1eeu_>LpRnMf6E&Mtw=v4AP zUMy&BvaWs)mwD}Jh-r-@287V%uW&^M0HzaQ@LJhSRck(ss`q&BCXw~w>uJ|jq4Ve< zj^&On40r;>;&d#`;?i2`v1(iox}sNM#DjiF>dI~6p?}Td(5H{zKizJe}OF$qd(HMVs3eqEv2iu55=5KGxfYrpX+GPd+#gMDa zQm8%L32HkynNzGK!&YVSqu?`FXSY~&yUdlIc9aZ;2Ovi06;2u_)v~CIdCPY?)-2bl z>Y2%iYgth(Nb*WHc(3FRMvJtjuG-=|vyd~$-_no~;U3>km;B(={Sf9k{Q8mI>8WTc zk1*&8`(oLGSuq_A_pP|RbUV)b*q@fGT}fgK^{F*!YSktS+jE$vi9raUX@{#GEgc#q zmMZtV^~&R)Eu6N~YUu5d)Csxc7;bBXG|u^ITQhptW@9(STnPwWPbhll1)oXJetxdR zMAuyNEg_G29@*__LF&&sJl0M+OPAd>p&t73KIN6ae+sH;n|sA%3jRiU*Nk>akzs=a za`2RhH5qNL@B!3)w7A9|NI6QxmI92pua4}@1;fSVNfdpnt(nLLidRi>(Zm5Fxn%v$ zzXR%E?v3Ni#A`CEI6=6#xQFN+>8n0Fn>M{8Ff@JwjD}PQXR<#Io_$seLvF~7%#`=6 zZJx53^_ybSwY`W*wC)+CH@t|6=08XQnvrqStEotK+KvU;yiDtK*Bk_?6uqon)Xj4L z&|`6e8%CrrxqWRW(hogFZvOHV8YnC&iaiGxFvYKN$afc=k2@BwLIxZLzPrcaVBLlx zB6QpDhoH$HwVW1qmyu!(PZ9xy_IJuq9tX$xpc$t0YYG;&ufB{%CS{E`Zl0&q)NznU zM-fJ;l5y^5nw4GUw<~b$$y3GFY32njhE6wM)m7Cu(J;2!8^XW<^`h4zdKEvn1WVP- z_nlT3>g_*`2?Z4Zm5+?}12C!7!9UE~#FM)_N@lM*PUX}VGIls+6F_(OGvp){UO@31lI*_Hd?=Z13M@Yf#H zbZcp_2Gfft=P~Zdu>Qp0j6+66*U{nv9+a)cNCXJb&!Ii`*fU!_M?HAUGU+P5)i;)=y&uD zC<5T~S6*OED%Bm0)M}hKy2gQ`0+>}XMao-qK>%^9pHtLn(jdBHFj}n{n>V*0@4vBl z&?#|>5i?As)Jey=)#Rg;*>Qa3yxpec+zRt}YUivoMIYSw+kCjMSfRuId0nYgMojIz zYSYkHySj<<*B}xbJJ~ zHd$&^G@e%o&MzsqoIkNj*4Z&hI!nU;$!n6h$y$=p3pbov0^L zOFZpg&M{26Cmtu$-eAVY!c!aXHTWO{j53z9>NG?pdlQYQRmU7YmKdk55vNZ5+csiI3@huCh%w+t~z{PF(NvC)oBe-6fg?cAJqyRpZtY z8Rca)q~Q3!xsP&V@Gt<(J4T>;bs}Q)0J&2KqxuR214mlp4a#)BiWRtGrl;!C2@ege zKzbJbZe#AgntOFje!LUI>RR?(TCvxQVl$G(`q>GI^y|YXw<&>2Tg{sYu~{F2GTwfC zpd&;ANbssz*4YUbMu&CiY8+QVYb?fA<1Yvx<)Q-+ zqXq+{Uk~}eE4SdBZGX#_!;%RVQn}GF%bRjs+qKU!EzXona?HueM5ea5`ScI3t(Wt< zi6g9+doyr`8U_C+H=)LF!^pt_4k4Agb&e}nr{;-6#cEK_Y=t00*u-q_@*5kwt#^|3 z;Z=br1d>Cr%?^NKS}B;;EX|}`Vc)TZ7O3OY_B{O!eL9beP2Wj)nUMr#jfo=wI5hX( z$+V`wJUwyPg7_TX-egT&nFm-pKOs&uZqoOSz>$;aX!4|Txv2VmI%u~L^@)$scH5m> zd}Z}i*k-wExgYxj`9$x|)-jw)y?{!)fSRjRgcdF1Dy`veD6BqoP!C&MjRq(tn*U&k z1i*h(b6ETkYwxDvCZ_|C$ISKp`=<`uLouQ)PqhFV_n2Gq0=TWY^8G0Xt*us(rP5Cz z+H2N%WYpX<+%C3||d3VpEcc`oh-HRb{! z%^0ADS3o|sdTtf?C??>{yk1~xhq&%VRvB~s=R4mG}n-bTA<)RUt(-L`+tJ^fyzLNG*Y z0XEh(5R25j#CWqr*9uYsU8GzJZgYWcRHf+*7GnL-?GBB-3R|=B@B{j=H*6mS20av2IVJ+y#3v(hNEcXkbU;C(2v9A3+%Js%|=6nKj3J0bQ&!1~+j#=*Q~ zsCJ%j7%VPkS+vlmJ7~wftb6XSwFdLy9&4o5vy1d_SDJI>9Bgu>T8S)xu(9Z6{^xly zG6+C@ImDef=G)p-8Pq{NeGbL@fWjkjd){V}_^|95gM1B+kD?K3>R3g=7tW-@o19Fh zR=)kOjWt76o_~z%^RD8U35+fvRtiRc`eLfU{xAwM_YeHr=gcyFpw5-FyjyF!>)3ZL z^2pzor+wcdJ*ZSX)fzteNyKlsftS)CUqp{RoO<0Z^yBs&)`eyt6mhPpC>yBsVJvypR<-5c5_`> zBB6LD*;QV5BbOeXkAJ^s?L@qVSKHh>9MR=cw-0(oZY;fADP})r>Ac5Mh~V|^#37pT zi+0j&wnj|A5ds4UxsSpf!xlvR&wi(|{K=nN<5H)xR+Mql$-^>@<=IVVZ=gH*FzMT6 z8fM6Zi5eC>*-^|%^ZP@OGelNMJNUwJPfmuHOY#PM>Q>a@#V_zO`K6i z|DhsJH0Z*4YsUFTqI+^CaP-nD8D-_0RoI7r8RQ(ikFoYW(Wq|rU2mu|g8(-nGNvM0 zZz{V+$CiW+YVOIo_0 z4TfCJsPmd;d7&i%IdL>x)O3w#T-eWVM4AUceI~M|GNoZ9VT)a`mueVzF>4&sVo)V?xH`3{x%TBd*lvnjW6(8J3wO zp3ik0=3Rmb`WJSM$h}t$YZy7xN+XYfSAu|L0%Arr@*ARVwCe7L2@P`}x-=kGjdu}PmnL?-RasT&ns4iCX!IXo z(r`F~2FY5`TLfm$hiI6aBX|Nv_e7ycnkHnBJij@JE-68Vw@WTq9~_04s}c81b~Z&% zmj#w;CSul-5-Hko-1-~3!@|5bxVh@8T<*`8CrVLDg0`+CNYyt4b(?#6QZDbz)qojL z&CoYD(!uH#YM9@PKgYwOy%$qlOdk}?&-;fAMYL+q7;P2{DfnANvG-&pEY5e(9Z_TerT|*vXs^MFW7G13#(F{Yx(o?VI7K z+i^p2AGGI&WZEBcd;94g`BPmu%C6`}ncTt``j1V&^WM(w|LMuJG?hhXnly6BIY^J) zd=^eQgr9%@vX3u0TDgIJng8X`Tc}%GhjygF_2T^q>daB#E9qqdFk#C*8%;AKy6mLD z<+2Pe{o1(QCF(Vt-^lTFO{4$|fP1Tn5ej>pvRM6O5ea4{Wk-q^D<1Kp^UX^L6fzag z{6oJnwv0{kZ$=gW`v_q=+xqq80it9riZ_XPK236xO+w-dhMZ^=761wmSpY!ve$?Ck zWIpe1ioiOA=8@85NJ8Q@wcErkU}tJ%Ab9aGziXtaIbb1zL zeaLpcu~1kRdq~0D8jm)Xor=7f{s2+Dc*mG;WTUAfn+@vepDvEUvrkDJ|2T=5u$5I* ze>4Mj_dGRQ)`65&JF||qjJx6PRZqd_q+qH8nLIUDEq8n0O3;bcp$^(X_93l`nMnlQ z!UFrY3~}iMu=(ePojfoG52XfgBjKT*w4-XTnVAB>dFy2Gq{r7cx12Q3aJP&I+f#gN z$@hv|KOd4=dteO{8ESF>X56<4+!H`^s_v3c%-O}+BIJfxfWPGoGbm82d4gAkPd6i6Tj4~vd;b_UyArTt3LIuYw{Ws*3 z!Q;pLAKi82fPnEXqw)2+oBI7rw~d=OR^_q8(gpJqX4H>sh%M%GWmjHQtX|8eCY71w z;==pBGW!@!tYKCe6N^aoDu&#m3n@~_%tXNt7Wwd4`aw8^RUZAxV4#=Yjn7BGlDMvK z-$}@y@ju_OR{53qQiL>=*Q%T6mri3XuZ^ABd8gJ*n{r!Pb35m$Xq-Cal{z=cEEi5! zhR!LMqB|ph{R9rO2m|vRCjbg#z`c1d3R*=RlI6nZEjZ@BcFjvp)H43O`s=Xn*OrmM zAQ3EV2$qPNwu;@K8D-@d1?Yj+tZgZ@F_Pz>a_niqldnqZuufnX{nx4QT&fyS~UPexJGD~Obnfutzaw;JJG0@-?-mh%Xi-?kiWszQKn6JLu_ zF?BMcw`{s^>pD)%dhinJuKS~P;vy*tp+?Knw8B{~yD_K1}2H3Lp5+M#1S zqT=m=)U+jBFKV_mqmj3o$Dx4IN#Mprua^a%eG_d~L#3SEFJE6hqf7feW3Wp}*!G2W zmyu<&srg%V5CEPF2KnH}la=f(B#61U=6w@{_UKTQfL`1*$uL{~BEnsQ6*|ZoHHsE295qc%I7`eGrckHJ&yW z41XI1M&`MRV+==8uf5X7I`GbDGd}sppx$?0YnXV+MI@^p$sEv**C!1pV z6P=^;mLE=la%p9Cb;LN-2ur+9t`#W2HLpOjGksF58O|G9j6aMC5zjq)?<|VUN6z_E zm|VJOoUXt;b8T^;{s#NmaDPCTlMjy9m9yD7+~ivCaF&X^NqK8Uhp%rwPsPA%-2j)L zCX5tOgLv*`g`jm0EhcFszkAMZ!y{2wp6WnKE#2t8Kz$&%(X~Zvbm;mCg0XCbE<0~n zKCN@k>%l_?rQ@?GKNcNFRI--PtXVpwn?s%?R1wwGF$IyszAl^k^<5kWfqWp{UFa(E zNQ_P1@|TdpplD%KR8(e!4_E0aZDq=zH>%Xpf_i9c`}vFgJp(Pm4d#PgNF|EVkRIeT z`#U~~1!6%aBRJ%ZtUc@;rV!ui9vqsG&wNYi3mwtf}<^3EBf!hdtHF&K z4ok7%MW#Zk@nq-Y?<1{bzeN~K8$RjD2DU*_Q5lt1Z`oz%o1zxc*ALG4JY9dtJGz<^ zg>%g>=?@Fa%UhGsn5>u5g(E(k+dPh+cQm~E^@g@DI-8ZWeS8Ly*r&Gq%U+8rG zFe=t!MC<)a=dp8w35mwF3yv`=(}T`f6)v~!?i|VEoz^2=tClQLvfgpeigW%=Y^p2Z z^UuhPn4H2~-uKs)te-cp?h5bMUX-aPN^Oo=9pqM*TKIHKka$kT$~td@8Q-{60#j$L z)G-OVesnA~JYNtQqkb7akID%c{F3G~NC-sN9Jr~|Yw|HpxXjpc>7JVndr&oxfC3=n z<=Tlonc3yr`8D=*q4Om6hX=<)BTLni%ii=~PjJll0+kI zC$)*y;Jql8g`zp96O)pX_<>;D+0!AlK?TxtXNN5a8wJU48d>VVWI;R`dxR?2<{X)n)BIna`1-VDz~w^ zlLr9iNk)4~!gjxd8JX{fi#y4?>8E?7{8ZAkMF%dxm*{!+O4#j2x9dJ4 zpR)_}Imnf#kz=Cw(%N@0jw?*<_6#?`Ba(_3I!@|+C*6GbvJu9tybCaZu z3XehhjD<)4W*oyqw>7R`&fvUm-aZoD8^0~$uPprrr8^u=&Q|54y-SV7sV~J0D%8Mr z8;^8f_-@;#Baaf53Cd-nsWV=HYPdaU+jT}^g^FGKwzX!bboQ%bm~!*2_uaMJ;5XtV zqEwNksVH3IptstmQ}!i+@6MNimskz}Te8~vvQs9_>pBX= zFT`*7t(TPEh1CbxVMIHFs2T2dhXAzD);Xe7C7-QV@6WN%_8@q`J&tSRWo3-#M_&E- zgnS+6ybl-z>tVk>LS+Y)K$Mr08$pE+tfOu|_sltj?5+8&xfh;S7?@ekU*}hMvB{vL z+#RJ7$W02l+4!_g0s_SrYeq;IQOVge9sqfRbxnWzZeFT((5|OZ(hi4UaKD=`YlLvg zdYR+px!1H5^R6(_b4JkjDTse7x!SU#+K=*5e~Hy{(Rv@XHWZ^J4mVfVXX9ZNgOWpq zW#DJ$PBT1n1hhA0UuHlFLT!E>T4BuweQ2|LaYTZ!J`^O~de%~XK86WjqssNfb{X!( zSMf=4opeV2Luw*G)GQ3*A+zk(3d5R@@DF%?784kNdCX%#15~ir>tHuf3Lh`>*Kv8> zTZ?@ES3;73Kr56EeR3ihip67jK`92fnf-=gQ7-n4d7JtH{tcd%)AzMwxm})Ok?SAPNc!Bc7N+yrcwk*tlkO@RU!L zA8tL1h=^w~Z}|4orCvSZZ5qApo2_Wbz*>)Bak0d78wjOE0zA-6UWjuKL*57_ezU&$ zbOFNP+I^!`>UJ)Zi{MiyiKN^1>l`{_@_-5wVOopjh6e2dX!^PXRsfR0zMn4rv-~*( znt>O0*Hqfk9Tv)>cx9c9y-yUV5PscKJMtK&;r9jwXi{09As?N-o_WEXogpdx@uG{8 z06OF})EYF@XmMCo&x+*h9F9Ci^q{lKzaGQHNqhxZmZGaJW%0pflb-BCEEf7+HdcrL z6*qBlmG^+Cx93oa&@sBtAudi@+Tu$xV^`reVqBs(;?f=M?`x0fz-clE&JBXYt7lrvs|M!tCL>- z=4NLf3~t30UhuzO0L8(>O_o@bBng%);48ScibE!^Ln$`PYR2UAOD_wwNC>7PIw;{6KXAYS zf;8p=;nu;ZMU58GAQ7^jIf=vh7tOM5-SqNA)|a2qfKThQs*DlX@XCrg80IiK&kctF zHnlS@zY-)sR9>cq-7Vz2T=>qR>3X{-uLN)SQY)7odHas2mCh9c* zl6|?P6)LQdwu8gYSNX}wu$P=ZKCHxv!FYK!xYMCI?{XjG_(l5{BI1s%Dob;(9z`+d zom1o9kPg@IdFO+_LE+aSy-E{-^wRz*h2_ZGyNM7cVJxr4gvNHaS@WLxgzAM6Y2oZS z0#EM#UKP}8J_?TBc$wev*W$Lv|FB=!5F9`6j_9D5oEMlkyu0)JW*)+Q0zQfjP{0(Y z23j`nV;i(=Z05zGSMDWhg+`=Un^ z3WM1qOywl|5+?9?*b#O}hw1=TiasUSFa{S^FNO&Sm|g!7ww7?`D|eqWt8Z*)3I>T} z8T2enJ|l35C5qi;m;i$n9~L19$6%VzVkC|P^Vw@~R?diLM=)^iMv9T1sXT~{DStMa ztcSlpiR#EyNW{8UnL?LB3Q^AJ5r_D5R~`#$t5g zj2zafAKC@>;Y{u)!Ei^#Eh#@+9H}y#XPi^t2>HFeMMj=7KFBh7OoCM?1)0x3L$ zyU769n=alHm@KRYGA>of_&!l((*_H(V{5>I0L80@Gz&#X<2s`fQKT3!0N}s{mav4I z=98c8kt%2jXps%)-*U$3+p74{;9&A|V zcHXq+_|`GMXbjJ60;fX`yzEu@Pdusv#(aUHTzU&v_aBV=m#wUA(Y`7OB;Kt z*G=^^JBf*U%yAF(g!=j~PQo@jLx2S8>d=413nIb;K%l|^Tn~I@5(LC( zQ6n~uW_qQ3?}8cl)U-{4hE0U$NxWR_`9&O+P&`K3K&IUbGOq6tz24%wuZ0;SC$)S0 zE2(;Ud4;+j&n&SB2q2#cu%Uk(P}_zrhbXEK%#+fIJMb7Obaztq3k+I+dC38EOXc2L zs`V$!0*KC7Yz!*tAvC>&PiK(O4J|DT+!;W8H&w|KsE_Ew>}K~+$him_WnooW7tNBL zLU#H)Ps-sQP0s8niWk1ZfWIZiebjKMd$C?P-BO4=1&ThPAj`y6h! z9|^w;23b6fY@vkrQy}TYeaQhMY%b<2sRA($cc#FPW(1M>dXZ&Q%M1x`@WyEAP=V9W z>8BJ^iocsgbG|!F0uC^&vXS`j>>yYf9Z|LJ<wKnH5 zYch34#elgqrd*p^3aT2i|2@8Zce$3g^>f<00yW!?qE;hpFUjF#Vo1cyAAFU>u(@E- z^=M6FLry4`C#Be(H1!fKuypn48g7J4E!#NcE7D1E=jO)2g_F(HJo2#p>FQK>Mv2{E zzj_HEwQxDQzP{z*7n5GV7qe5EG=JtxPE__!|8gF1%#ey^ZG>CoN!=-ombA2K5-~Ss zRAS++HpYmX=`<)6z*LS? zojB=(_@wh|eET1;re<@gFG*0QoC<=rZHxSL@;%NuG}On{YjkBejr{8QJepsmwZ5QT z9#$;EBhZQvpra!EVyIq4oR~B|!>Wv0QEWP=JoPm;qV{#=!54%&K{uCm&o^^kTLj%V zBvSm<}sO$GAfc`kFAj8ZuaKGp7V3`xaC>w)p@E z94!`a_oECItS*2k9%KLo{{`%|x&CMrT_JwWj8v`8*O%ZP6JYUjyDDxeaFhjapbuMZ zV41V3QXfSZZtjI`APFdygtZ^*F@V{n;R0eR_jLA|sz!Y@M)c2K?#7O|)(YHv;YBvC zjJsZ1Fz2{tD^*}MTEXJ^QTFOtob=6d$}(PhniUQsk}ff8TLbu&;&ByX<}?g#J+2uw z#C(8`SaGa|@b9n+NS_|ILJVQ%Y5j0rdUMFGKTb>YkX3CdSoNg(g}&kB55t`ypM+-L zhbqP{3<@i*e`5g*bW5YdlvPmeTQ@VOGyu;@PhjmuV!HXo^@VwOJH1jPEN9h-u|^}1 z=2rvm<;x?HhJgNO14)g^{Czm8BCjX^cAk>Q8;n;^-6V;2Z}sMl-G+;qg)qtN(x#-@bbTQezjsWv%h++@7vmlFK;G#%GJXeVymbe2-oy3J9gf^|fhu z&o0-^qWsuvNIj9a&3pM5QP^Um_DEJYM}fyVunQWbpg@qUpWs08?LmW$5s^NM$ZPGR|qx`$I{<@T%= z4K3GS8+{=B40Tye=_uCTT^N_A$@TmqbTZ_=7{l>^Kh> z=WT_9|1QS(*)x>!1MnyrwWgjVTWRDa9yO)8W(olp4#7r5?{iVpR|EbWhz4E?l-nbb@eXK=MvCOU|Kdy&`#{WfcIzW3 z(ddln2~8p2ZT-^G-Vcl_#Wv@mg_tI$0P|}3S$A@Q?798(a=Cpr1)+hTn?ZMDxk8j6 z6**DkZWyO6hPYqBbZik2_z7&-Fvt$(uV9QIg}_8H?_P>3I)lW_pQBzhOyZrdT;8S>j!urbvK|ZDE_bfOvQzXAExEK; z9A5fxoS7L6T3u!?WAY5XO0LQi;_&m{_U5zCyy~qlNj|VeMtpWkjI;k>}29r2T&2y`E0;tVW~uEPjjIntTk^BTGja zxYDka**kd9eBTwhRZMaLtBmoSHO46#XQTMctIrPE4Am@EFXBw`PqfKsh&APVTCRo} z{}u=i=K`9qFl@zygS|A|MnhF#6GAjKWejytp>eZ4r-x5YX@VUo0?vKJucpC7HvRI) zSC8d`)U{dSw@yQjtbuk_}S5@g~MdEhn`Vqydw@AwEX7iG+@!n%U7H^40`tDL{b~Mr| z|8FTuJL<}R^vB;)6x)8d-@i1Yo()}kZR~f8ZO}}+`%TQ|Ay+n|*Y}ChZ|+y`cnw2o zUrf zqHr8E*cNr#rENzx5%0=6jFa=C;hc{bDk<)~_3YB5Nq(eiWj~`o96h9GGdL5K9Z_9} z08QClqw3jYwLN_H-7NRKT;)-^o)#4~W-nXkg=3XWPEHPfGx(fMhUY-JOXg0=m>m_b zXs$r?+u(P(m9+t|p2=fB-)PSR@K|b>fco}AuDIp9F0f8&lzs`^R&_}|*zKNoJ<0+*|w41tEzc`$g}e zF^-NiX=QDHG8wtdDoDp(cTw~trHyZcqqkDlG;*)|Zo6(}w#@9fz7?XA+eBytPJxwn zBSP@B+t~_Ocf%;14MM(>aM!!@RqHuM7Jg*^l;sPMC%#se-s=222g9|?%m_)`mdjO! zAMW;>K@cKE$0u{J0(CF1u2!jz`)l+{TGr<(ur~)%x&5>MQ$7TCvLu|qBSxRIteq7hU9_&i(nlbw1zg}ysAV`Ra>iG@Dtk^G~+MV z1H!ud|JC3(WfU7{i8xIzlCJ@{^%iE@kb=@;xJV|f)7WQcL}lJj$?Yg`Ai|rwMgpIy z>WfmetDH)^rKP zC+@_(^b@M9cardk(b(Qp2VZ(=CAK#+Y`rEiL0Yx2S~e(*Tv*y#nn^^aP>LglFV7}$ zA3eSaQsdu#W-8|)5u%A~VmgcfSMvPh%Cx*`^JPnAh~vPrG^;TLd|M3#rS^?Z^UdTl zK1tvgn@8r%s;4gN{QVfG>xqA5vUJNFe`JVWF)?a22URsYDZHuyawp+m3x52o=&Ni0 zacqVVx6KAnK(m$I(%G@CXRiwI`B&}ia6psnbr5Je)AG7|H`2l1IYu6VyCBDzT4zLN zFoP;pj&ZX1t&l-ZZ+t)YDNGpR>=PVBu38K{UoxoJ6yMq=9}bLwlk8TAN!LUM<>QG* zCq;G>?D}Zg9R_1f>exjitz_B-6pdCa0sGy(Q!K6aW*1@etT*-M3n%Hr;Ks>(QJ?Cc z`a&+fIsSI0oI+OT{l{VH6t(v7P(=N(Y}!Su&y~L*q2pS)F~-*fL|E9Ct|3+hslkmL zHN5A)3ANGL%3JgoTE@yC$^N6#GU;?>uyEwaPKAdtsVp2FGgUqNop)`2@r7|0zP>D1 z#d+UpemEQE$H&zd)LAg_u-Ghmzn(_>lY3e+Dc%yD4u69jejS-06yPHXXxrnvcs14B zBZy|tVGzhG8_q3@7kz?;=yi!yt~xQW6miqC39+7868JYmYyF#{M>=L6P6OspzFZRC zM%U=;rvN6_EAJA8_KI6AI_(>sKDDpOziTG%-|=j=&yhlHSRZ?koUJ%W(9M+}@=l3_ zBN+ZluHEQpUT@E`tkd-}x0;vri(PwhSKYI*q{4`icYF+(pml0WAR}0}np2pcYAA;k zy)v?Dy0)nF0iVgK$#N-hjV!Po1~lq%^BP~@Gc{`8d75HQ2fLeEuj{g5$Lbi+7M^IG zbaR(2q0uw@u(a<#bImtaVO(r)kH8VRG^X(R%hRGY(sBJgv{qgodG-jsF`?B}%H)$Y~ zl~%TMPoV3jsqyeP73U>|W(`m6i%62MrQU7#I_E5g?S-G9>@04z#uV9I%HB9A1-JrV z(ris;o2@2W&aDD zik+@W&1L&b7x8Ng$W)FSseXcqofwUz^x{MXiwj??o~K-TW1+B;*%zM%cJ>h%+7w*{6U)K?a!i0w&eRNU+{mYH;a))F<^n~R^OU6YmEO%S>Vpw`r_hI z?=OI%Qq#(nB*&Q8FK+mw0e1Cs%j%W~YI-`==4W8S(8LD&bA>@-!jCC5uYx*|Ci>XX zYrWQbIteQ7RAx6wd3$AT=MGq+)InVkU}Q8k8`Zr5Mr*ZDtK5a@9bA-$0i16ciRhs4(evPRwZz=rByc#Gcx6=3j zj$)jA|Lqz;oLO;QbdL5S!T^)elk*A+QKmwoK~E6i4GhvRlZX@ z#@xq(?R5$5yNwc?6gdCdc)k=@+C|bYb?fg6=+*;()bX7#JJrY=BQq(&Yl#O`zfQ+^ z$d&kt5V+vS@5z{i@1O1|vP(P9P$Vfkb2~Bg9 z{=Rv+Va=xw&1Jk`35~}t4srx8yaEY<@fTi)=D1Hb!dv5Fb<;d|2a2xiv zcax(;_;S%ZV_3;Dni$QTK7aelWEfohm(=U$+%yD#1tuIbGZf2zMS>ERa(xC=*QmWV zhZqmxoMJiCf=+iHM>whDNWshBh3}oMXCv|;-9y{T4|eO&@y-*LlH0W8cG)oSi>xRK zED8L!WWH_HUd@V?RZ;CzI}R&B5ms-v?2t+me-=Ea`2eO+l2tri28_pk{|GQ+ry&1j z>ZR%NS9rpgT1P>ECRN0nYF^#us1-)`q>NK*dX$m%U6I*NFa;F}Fe${}!ut%pqW5)V zB@cx5&-2w!kost5DtMowtL%6Q+gXOQ;0QYtB4N?a@M}&q^gtxfohl`itnZ}<0tT1ssYj3rzqsryG$o6lM(grNWNoc|joa4e zHs}w!c`A}Yj5ca!1}OmkMmMBm@V(vJD6;vt;@L>_xhgIOLHn-OdFc6Wc*$1jFcl8H zg?*qN`Lo%z2HhF$e8KJC<~Q2lvcnm#cG~e?D^1k37WV57B*+f?TTvMNxw5$E@Uk`e zv5kO-5m=+_Y~JT_WBPR~5&Ha;I6F(pMrC}$G<%%{?-r<3Om_9n@c(+Du$9GBDNuY0 zrDFMy;xaotJBMvS@`k#tXKq5VglFq}m4J_BS#L~K=+^~N$tV%1heJs zJqf(^Ni7JG53>SnrFl2mzo#Pdo+M;Qgg_8vV0s+=f8MgNbW`hX$DDcg_69j2j;>-f zh(0;Q8ccLygn-u3xjtBV?(XN0@4#arN0}7y@Dj#!v3s5T;L2~RvHrZ=ssJOoxd#GN z*q~XLc;!^m-k)B_vx1o8UvFfNmy|qh8V1>qe}9~#eED&><)SuoO)Z>+J=WrKDFLlP z7$Mz3`BO6i9$;|Z6RI+t+`?q>N{n@~`nB<+pEBpRNa73Oz&NpM{}QI7)?8>n5fKx}5Ad%Y-P z2@rFfeU}%P_d*Ba8@+#B{lGe!qJpKv6eIk?6^YofGHuguo(aNY_BvT_--G}1K`%Nf z+x}2s!~Gk#ptut1$_f8l}Zx`cpl&wGIGwzKas}1Sk53D>~Az^d?4ie-q;NO9q(WB}qkzPg`nSG!iVfOvg8Fe<8Lt2DtM`st5dbKu>N)eQR zzF04axqhoL9OBE{6+(M*R7spTG~iR2zfAMT&7Fjw83&Tzny91*gcclt$11)oR|~MF z30GiP(B`YW*HlDoXawc3=pg!85iks`r;$B5oKN4@ zbZ%U`^S5LW|LiiLZQwHWYUKghu_N}{DD{{4d5bH9bYAo~Lr2QCWI-xqke?84MTgCH@&=)jB30~5G z1R-@;C~it%ss{1B*VeGn!c+vJ^Wq3~UcRL}B&|4CNxnXs?B$QIFQj=-Rd#<)kfv0&&W4x6{C$HsOK@3#Ky zV4YU{f~g+egsYV|ho;z6?h2(lc@#3^d=_}^y)Wr&3L(HhXHf@!c1VA7nh9UBEHopO ztIE$gIe0HJOq*!#wQ&78>@WC;aXWEApnqzG*MY|cMx+zpz%i?Sv5sL~?h9v>UHhVF zxtV$Nk8YOPP)b4lun9rhKao2NdcYcSS9xA&UIPQJCl%WN=#&=nRWrtF|q+%z*dc?Z6Ku@ZIdJP%rXd?YU*8{=foP@N;Oy0GSbc1<-JUzyMS(O78ZjCOuOLEs zG;NJOj|Fd8CRnVErr7Rjy3vh!s~K|gU4HH`^E@e6MFXyZ)9aA9KbAeb>+Ch4z4F8p z@t$ok{QsrRH-W~>obUJ5Mn{?XmQ?Fh0ZvAOJU+!UqgW+w z9n|!AagI{vu0j#dC06rQuOU4?y8$!kUs=SgfAV-b1qqaILU;^;G^(eT_JtN_qItS!mbnv?aU^l9rp|#A%uaWsd0cP6*L1c`nx4sIyKF zBX8c$I>Wr!ju_gFSe`-PNRLfbG-0QrBeSyv(*}OEk6v)A5Wr4mE}DB@TLN^+-mK zV;qgaTXdw3GkR;9ZQGmrZvwT2*SUOA<0glUqMd}Knl%b%f?kAg9r28dz=NK%z{fr` zU%2X#;pn;#?qEtH{-oWGULrbEE-q@ymXpIj!P#e`^5d(_3=3lV6tL zsbcvWvDoA)U&cs3Ug-X$$NWo;j|VuILqBUJqjk8B9F;_#VnukQ%CsKo2+bKKqGbK6 z9aj_kf@LWAanp+o0VfF3iP?dtYB#$ChH*NNtI}T}f$#HE+gLc2tc}FX)lFnm+*B^7 z)1~fCrkz)IQD8oWSzPByH4~OWZM~`9>qApi*n0Yb(No4LD#G(Ji1TL-Vqc_wy;2yAI4Q zuae)gqpf=!9Ue-9iAjIkq)i*@YT)kDu`+)w%22C-1|FmaBez@knYp|19fG9-nrN9i zf*@6~kx;dyd+>$(oO4L;>t>1vDxj?wQ|5i!rRGON?a)a3>7L$p62TMwKZt3FH_O<= zY*JZe^M-)Z|AZ1NS=FryQR3_`y`Ug?6}K~oO2SW~+)b7e}C?!6)@N9&go#K03s(Jr8Q0Mjzxfuda~5CrDWa zpc(U<*%X8qsLYdqe|oi5>{`?*2?b7OcXg~3xO7k&#yzRNW+Gp5V48lLDK`J?d*IW` zecaVHjw_uDF24NzOUr>z=1HT_ojIJ*;KA6VNSS22>O2(Yc>3#^J|6b*_4vdVdL?%? zINx!CL!|O{BtM>$jpCKECQKZh%)(7!d~$+O{>(kAp!(pjDQj-O(gy^y#qlLw>pHA6 z!TvAwb(zmS&1dsq;jyBFL}m zQ$_4H7;j2I#~A82K9rS5wb@IRKVW{)TnH5!Y8JA({_(yW&!G==dhaHM7I9(+UE9}B zG^I`2j5t24-T`suX)d<3_i5p9U3qf znVtOoX}Y3;Ne9t8E=V?GVK!pedAI6hjxINm8gjyzJ?2*Fo5trLEH3lQwQpdWi~bB7 zMB`3%zd#a(itN9Avp`JO!GFzAWDovRs{tLR?rm$`NOjK^deB^Z5z^qSQE?o5l_2HB zp@QAU#89n!Ugkx6%4)vqJ$@HEUH&_GlRk|Woi8B`4)A^8&n5A%hVuNCaDv%J(?@JE zLE_5+Fn$G*Z<7mJR3Fkpe8gA2Ct-jY4ocNmW)bsK{PW`zs|ml%!6YTiZW zoW2H%uUlKaRa$RjSUbe`UKld+1-lu`2MtPpasJ^nlV?qhGrz2mZp&scd^74_hu)XSg!Ey z;^6#p;S6&P>Ofvi?rc9TqY#|;5h-4CakQPi^0pg~Zgo}o5ONxMvuW-d@T)=h--kqp ze*97}qUW1*$$|&iFAt%E(5vcdcD&^$p>2EiE+TbBUr}B7c-J!nPPCeatcNAc3EQce zOw)czGxSh0noDRPrsAFmd};{lTAGS}77=k?IC*p)egIDh@qsAJ4Pv&j-KUHtvAIls zqXQ${`YdU&W{CvWW z&q4fHHkSz3SB^|%KvnZq>vu4lCvT>n%TMNYO?Ds$%hl^tmLMagsVdhw(30+*_ayLs zzT2wc-9p;SMlih$ijAX1D@N<8&Q{U)$)ab!0iFN)AaQVvTYyZ2^|*)w%`7!)@I`VJ%J#GF78`vgW|<}O?G2U zqOgMFO#}+!7Y;UV80;9IRk1r57?W?`)=XquUE5?9)OZ_K8mkeaa*L5G4#IMvB7lj> zDTBD$rH6&v_Ba406AV@m$w`5FQpNVSAGvS*@$0XoIS5y@q&N4XCV4S|U} zZF3~|zm?YxI~^W4@?uDxX=RPqSGagb0G26H@c4Un0w9S?D;PMIcWO4BbUOCavvp{! z?yXvr;KufEQ;XC%*NY>)51XM;`g;=ErA0+fh4$ zO*WE|*jaop2i4yFWoX+KXPoV_7qjn{)H$EP`8$Z;up%BZg-btJ&pIA{EXiUt=9%mQ ztMs9@;v%4mJ^e z&oO&YA(SRAt=1tbDQp|V!=xQo;pr$R_!#UQ+s!W{T{g4B+(D;MKLqj63J_rJu0 zV^TJ`A=dfIt&=->3gB%t5B_8$3H}NI?w;;%8M1k5%Wyz2Q&hL}%A^{jm{&2gV=D~4 zrq3oBoItGGgb3~F(oez~ZDtq-5Qc`aU$vD9yW79BQ0Ua3#3bH}{j;md!_LoPSil4p zbA7+x&rqO4hdZM}0a8m@pL8^1eiGtpf&WG?{M8#-rP&}N(yz7mCOBZ!(Uq{(l;%w1 z=eHY2cb#lyZ}s`VP8|o_0ZyhP5K)cfPxSVhAOKAsFhAQG(fP#!9eI1t9rKorTR=3u z(YS}-BDT{2%=(YD-jtaM-?RK~^mEHmEmA3j>sLC z($WU#igYf&7p3QctqLM$76Us*l51TOQwgf8+Jgr)Scr+;u+*cmv&<#<{RmfRVm(%+^!B+kl-_g{AnRs9Mh?@inx!jE?m@3z1v|%_UINSlz z{=pcvLahV<^+*xLy)5pA+2e|_y$K}xB*P|kn7m1`0_xMZ!6@qGxabDO1T$DQo}|Bi zORxaJh_0mFRCY?m9t91UGIMy@%>3D2I01C6W+UZs_xM8tqp9*~jb0ZXNh|@w%8tL+becN3~_9Wv($+0*h@Gzr@?R|NQlFu|?t*cj4%btCwZ!h+4rRME1%@xJl{xqwr!5#X6FPKThmawm z8{r9EE{$@|aS9QVB<^3`y7Cz(yT6pZjL1FEdeD3sNI#Hg%X_!Xpoq)8YDHm%0>j|P z!rd5->U*FMxeOXD;dC`!Hx3UwJ@dV%f8>pB+3_ZB3||ye@T?=@_H3eDumTRKD;wwkI z49w3zCoOiKMI5mFM0>Vf9{^ez%c(Lj%PSh+1=3n`F;D@)^>zb_=jW+{g@Q}5JvOIM zW&my$X1V-@AVRY6Yi&UPOP@rA7!5_cUNx7B^IXdi3xiRnqPF_SS8oQ>yZS`s@@5C) zG0*KEsCrq0)ruDnf9IPJF)N4l#dg$^lA+ooJR&DBVlr})wiwIG9hfhm7ss^-bz+C)Wu1Kz-?9=-i-mhX`^cqvW{2ePmPOV=QY| zOPTt^RH@U-E7sgy@ARzC5o(zWN`vT(G{knn^Z01^T_+D@n^#d=L{ebv{ngaO<+cRV z!=s`X-d!ty=%CcHeL{L?UDG*lL;wox^3R02oh7zqM?fWv?|RO}o3snqOH}1Td&9mU z0Wv}>WC{tLrM-U)WOQdiS;;k0PIq;UN_u#FLWi)!460y4k)Z@`@Zih2XwPkhCWrkl z&8e1K7lcyt;!sR=I4X+K`CK^Q#SKt&4boZLkcAS%dM??`wKS)q6ZasVUPX7o8aFSQ z`h?(Dy-`=a%-+M+zQy$Re58NPQI-Ms`){N3Vxg}I^1Lti0gax7txdG?+rE#f#q5?v z@-40o-*v(CJjWr%ggTGlD*k&Y~1LDt6VqtGm-30aW9uoYDm;w z8B>|ZxKEwVt2rIxE?sq3w*0(slz$9;;XG9|y5F*4M|lqt2PqG$+W`8>Vq%p;`~iD-xj0hA@94Hm zdiUZL1SSl9S}a%sTn=kfS_*ZK5sPX79e_@sbG(i8n_U(Q#drXOxWW#3CTHxiU2#=| zj-`Qu%9K>*FvEKQ$&G|A9KP6~ljG=cgwuaC+oxX3rUM;>ph0jQSA2ngd z1xSlR0NNEi*q1!LKV%{WK9%(#GuB4`VsU>*kk@MW>s#teIo8;!#~Iv50iV&?^6XL- z6nu&wfN@im+23;Cq>ahgoNM(7JKnV;dK@$8!iO&uJ#FPGEFs_bTw?W68c%9Z0^0{t`ul6?kbXQFn(Qu|v2+@xDyc2VF--N^S zRc92;H}Be=Jq7TiSDasL8|!I~dr?Tp_}#OtTwKlvUdUsOKlz+VYcXpPjp5j0+nElK z>kL*W!l;|hL=*hc$oJUt76txX%M@=?NxJ^p_VgICRVpv2y3$R#92_;6oFWBt(i|Hw`gH^(OYl-SWw!6A#H@D-t45dZ9?um3(BpA^0i_SJmyRHf zt4p(I4t&z%xUPHl@);Y-iDTI(Er%s@z$g{od2Pv7w}k<`|1m-;9@`~h)$dNv!c)G) zs`viwmLnBw)BDv+2Z%2*7r%1I0ShTR1&|A=*Upy60KY6)aT({~a+z1vmeF~bpj!Nt z879`N(Nr?f1K?^48{Z5reH&~#Ogl0OFynu@8uQfYA1wr^B{WSTYS3dwaeWq4)w!50 z(0%b18GiUA36J<=c1|qbw~>CqyXHi<@4&Zq@^-HHB#s$~!4e$lbH3@6`sK|xe^RzC zxuKUC{2%949P1ACqzK9VB7&SWRAJIqj_o&bA?{xy?XQejuvB-3hye<7Y#~Z^gtZ4j zzndz%{k?9?unBfGMuoca4}8HU2L&yY_|9P+?^boYO~Z_fI3MJ7H+L;g35LGYE3dY( z3Qh;mB-kR^!LL=~$|A=%-c4fL7Kpi1xH1_a`#j~1uVLtNe@%6}B7noB6Z`u2vXA|R zUNhd~(?Q)@dr$wL*Y@i661v_1eQH5tWuyCYYi@$hF{cQUr~tRg#S-V-$HVc0^2pCg ztg|i=g<pxLj5RV2 z3#|M=6WsjY({8CB(tlB-@nHsM6fN&`3eC`Oqtm}qpXfO~j`~!O84#8$z?l!G7(%|WoJii^ zyQQZzV0EpL{6g1D;*g)eYOX5}j+kt*9W1}#LjnMRQ@eodI)~?EUzOT;&ooRTuZ$V) zoMd{_hNWZKWU{fvv|rLOo}egAxD6D*^6cc~=}NcxU2}6yzgK+h@Cu6gzUwNj8Cct8 z{f@0R!2vc?*rRd)Mt5CTG}{g#bSu7gu$FTRsyu96|e z=g(*KqRC`!wC0tq9d<5a@h4YoB~nm;-=j#WAo8zeF&=LZM*jO?H^^76kTfpT{h4hd zUfs@nt)7TGU&Ql9*Du*Vfk|a9QIq+5Z+nKF}ZB66GMn5YXK6#uUM+u0K_Hg>%OxpAT?BICha@;%5h}B2cZIYg}#}^YXUNTi~w7D4N!x zp{g$m5RM3{9ZpUs&8ub$(kY(;rC4aB zjuGe^)2-hUPTk7Q$J1+ORvpS63C8>O`}0 zz2%P2BxS-@zgRDH<3^&P%~`=?#pG_M$L1IHS_{nDEqV`itVes&m9vsvkA6Gf1C@*m zFpDve8_sw-3!%nDk0|h?qHeZv8tZQ~c>8$YiQh|?K@!Bj9;KwB5mOkz-wAWb;B&jR z()fz>X2;1;53(@g^X(2YHRVlllN4IqPf4nnYc8AwB9RW%F$`%_nH*s~-}hd=s%kFz zY!|Z=a?PW=`l5(^3LnnNK0Yb+KCQW3US~9&*P<2@-j5U+!~wmat6~{!9d2OuU>aL< zoRN2x#Lx&25snQnq`0;I%JZ^?5=3oxd#eXDawS)PUB|*TYY!a*>|p_3=v{4YHgl?t zt7`jWCJk9!l~?B14PvDPk2E}Gyj0^e-lp>_GfT=GU>2Mvnh((SgAm>@sBkeaG6bIt zcz9s0>5rZH=n!$Qo`t)E)hH<)QW)!|RZvTZ#W5>`-Cq0=CWgyiX`D+-JBW{GbYJ$X zS{<4TU>un_<3Z(huPaAP*e&2P@6UpCaD!gbo+tMym0}2pL9VnXp3HnMLSCMY+8K0A z>D1uYrD##INdD5&lp&-_7wmLkTD^5ipZ47OEPs$O(ar-<-R+gZuEk_{5~1MlGLbAQ{8s~lNUJvWaURJnsl0F0ZV4b+xw!L-V-g4M8Z z;;^B7Nuig|@;RzR^cM^?E4l9(aqbybv$*p3!6|HI{!nsb$xBW8!9W^J$gq3dl=p!E z71i`Ud(V!YOS;yVTU}m87!mVCyE9GL@SdiRO|5g%REeS>wa`{)MIy>dvLV*mPg+Qzlu%kX{+aBBzW}hya+mVMlzl# zQ;3yyI_I#6x}dDV3i8LGinr}gHG{)aD@qcdq@+dglt`G1GrUwz2a5<%^9~{R7&01n z6W^%YgwN6Li8r^oK_ri>XL{}NX^>n(_!0l28VBd55*){8f#gq?Qi6jTG7A|G7mUt7 zyoFZEVB6uJjK2S#IoNu_X$2l0YuIoAg#dOuxCOKYu4TdT`N!(nx=pSL-0QkcK7ZuZxwh55N%zXgY63MH8?iRTDAJ2vlKq4mo+^m^~y% zT&8qX>(|s8$sRjX{sPQ0$Uligr^H12>;Am<7B!rC^=${QdBQ0|v z!c&v~I}4Cgo|#w6N;wxFaI|xyy-g{b{O&VqFfD1e5`sXKnE{NTr|aw9M#{4&UMgi& z&}4L^1`vowra?lYxCAp&7RV){^e$D+E1?wZh_xZIExs6{Mey2rvD&XN|G+co`5@$O z<$%M0nBVlV&&WT;D!HG_?fkmDmD?Y_VF{(nSYggQ=F-q2f<1Fd-FlBn#up*1p6zr! zw{O%!GCdLr!vg(DKHj}VM5}_p5EJS|l<}5oXQUc7 z9=RzxDxAn*Be4TD?pOo&3s+z;>d*H-U24-jPp|H5B0@@0NeDwrWOor_2$q}X5oq}t zB~$U#HRlzoid9zil3sA^4DBI*7lF_ln{Vu2s}!!e8wDo5xTlxtTNP7HL`n(wo>UD~ zp~w|z6)8}22@4BBU4v{l*~V>H8zobk_}N|b-+doP^y7R7XcZgXMnPSmOP{-SzrzhK zCJc%Byk*9LK$f>v`azizK5$S2Pg67}wr|uy(b8rve|TtYlxr))*&|I)0)UEo?M(Qx z>71+_K6bgR+{MqmBla<_S%rEX6;)omKh4UwcieM*E(k1OZoej|$`S!uBIYpC926uW zL4($HF_9WN`FIm}H{MYus#9`<#6I!O*S+lru%LMC3&tMtP$NtHz_cGOh8G}Jzh_&t zcU$y8w*JjHybDkAbleXq3=ci>Ys`*pvK`WwGy4@3H5$CFiVu?QWLOi^GQ`#fF0fbb zzW|fyv_6OQ360b`=>$8+f?lw14tYmd8zm;ZRdJ1u zYCr98PyW26YZ0Mc<@u3^>}*%&fj8k|ws(iAao+v>xM=aE-F+mSbwmtHptQB#AaYD`CPS(nL_zf3IS}{|GPIO`kE)e3dP1xK5A0_o zy-Xcba!*1X9oMe2$0wb zJjm85GB|zvAmW&wkbszl`myi$!4nd5qGs z2-@_bc9XX?ECdJ|8{eP@F-cINQPoZsZa6{8 zJJJxOP=v!WZu30W$|#`O_JzN2R2GK zWzprJ0Bo^33pO7s64Rkv$GOwug*y1xCqC0lR}v!8vYcOqc26G|Yr2U3^i$aAqt!$9`ec>3dTh|BLv5cHIrklJmE6qp zioA~H@VCcU-*1!P;hsosdKUc&RIO}%q2%43?Daq)cP%DFhIAvDy zJK!HJM9o}a7Tuotto^KNd}-0Ln6ig;UZJ4 z2as6Wj(E-$=P%_!jckvo8ttpOxvoHRKHoB(Uqew1NG^6^q&>S!A_xRcxsu@IqwLn};;s-E zC&vzHZ}#aZQtN4(j;YX9x1<_bt;))luNS8YyuCl_cFSlL%BtgSQlh(ou#*0k5h<2C zW})_WR#SWR851n(&}K&9tO2aEN*!Kxj23?F;u}&D$4eNQ9atO71+t+EG}PK@pPi=9 z&WT*lU*ytwqXHjbfI#u2s8NlQQc6rAn=d;k{diW7xDgG)HnOmLVUxjrj`Z| z@2%g8Tw~9Jp!ZC;S5~MDFVQLtpF9naxbpV62J$t^G*D z7Vv4UZOyH556lq|5XjyFE|RS4bgkv9qs-&s{yIW*E9l9}^l{-F+2eqYgH$`{MT;M0 z#<%WQEKs}*Q4wVyG)j8|HW5-$!O#nG~89~>;(MD>b+WR z`IalU)wB8GUNXB(wLbjrmt%9i$;DCksHo9uMKT79edQ=csIsjV6RdPSYymwdOBfDJ1p-BB8h{#xLF?-(<2}hUA;|7&$k-w z3#EP-lVC+x*EgAKLFX98;JYCrKjVsl8 z<^Asu@{14icgPw4Gd^sV{{U+tgu9 zfD5dw-67fy)>fp9f>{#i_Q46S30e8F;c~*VyG*E|z(4|31O|@98Dd=+Q!Vso!Cr^>T@oBWj$I9VjXo$drW@`GwLfi0= zo574Xd=YZ1Q~PFBV};oNK`w;MSd2UYg>yJSOL0apj>8!fxUe zMm7JXIvv4F`7)H1tTYiTU1ZWq#Zh4&1U1{kxgkCIw zP9-5BfyQ^$slb!uqkk+2Q-A%gGFt0&MD=79^fgUD;C1Djy2kRsoS`+CqNOaqRPANrR-q?9;8Zut4XAsQMd&cU%GdO)O_ISxrO=Kt@vE@d+aM;^0;>f1 zY%{7le{=j2(_6Uac}NQtP4<8f+xM3Ls(c3K=3Q9!Q0E%?IIuKqOaP7>ZZyCl`a`xpQCwvbCpo@ zxzR#KtTDdxMK87?)Pm4Mi>ZsR{XPFvSQz3fRqX-SRn2d!8L>oOO^0d>odFx)en;HN!UOlJQS{hYS-gChg~FE)acslA)*>tuW7ZL z#TRCKy^S4C>zFoPJ{sxv?UK-2Hxf@nFy&ah!Juvu@!P(*c}jAxCL7adthehAiDZTK zm{1Y%EIyj-|7}Oq&zkO7v#}_Qy zxAg7eNff@5DtuoWyvF7)w&q=0KXx$Dbcy;Yw#8KE!!1=D3kEU0+Tf-FsXmd#SbAJ3 zT{?*^`@CUsYD=~^oO%W79Qp7Elv!erdN+(%G}a9nY$~bu_e}ELD+f&Qf&tdW>l%5S z4dFQ9+8KcWZF;Fk43;b?EjHsAtz@z}4xG`Gg30uoY2=$(jCz{!NV9@$n^_gf;|h&n ztro>}6;S!eRQ~_&O{3g3y}9RFok=?XBmkf#@rJ#8xckQSx$CQ&cFd}$>_ZtZhNdWb zFZ(SDyjt`Fi(@|@?VCVyYSkE0QP6+Yv$QPdEV+%weV9j(O2tcltCNaQ+~2Y}!5iFq zyD}s&vyCH7O>9CKU#nWZY=3mQ6uaohTZeu?oxjdZV@PQ-7cbK~i&Eheqd{%VkFP%T z)Sv(_>C+TZ)1{1X+nW4CIvNB&J~^d+{oCwM3Q;1~XrL$e{&C~=RpvU2B6MKqIHU|s zE;W&sJ(KHl;AY?{W9Ws-!OuwJ z{bP2F&yjpt6?}LcGTIPsi20m?4XU*Sjt%^>I2EE?i87z__(x zne#!i#(H=NMxlRNGk*KZEKz35lm?d1goP_%0&wztO&>ZF5?)L!buLZ zXCufzq}2aN@w(+G)ZWa@QPFE51>=OW8*D&2a*@fR3ds%@7+{HyJ?K(xEd zsyedYB{ND#Q}I4J0`nYO$00VfKFnVS7n8cR}D~&HfAxwGOyt?pFfg zGiOqoMpnx95-2~Q<$-bkw*PS7c&SJD%L|}fzd`zq^bL-VOzgZBe24@TwyI82G5<@) zf!lx9{_$^ZW2->SOzbyll?W_&wEhzPn@8#q8YNTSyfdC4@YB1w_y3sAYd2A=3?(tZ z7TJ@n&wTxzSDn|lgbAJ&to7f=tNnY#23gPkPadhE+&t3h1hXn-0+(Y&bq+1{Lyh}X zv0Lh?=y4Jbe+Z%eLm160;iEdaA?57-W)g?8^`4-#)bHFpbZ?TZ5ZyTzT)XlAXN;F0 zX8TnH(sOK?;*N?+>89KqX{JI{i|3m82=Om^nWy+V*I8eE&&Sj+K*phZ2WB%XZc`07VlhOCL2mRND&*=Zd z1AE}m@3N^k_Oy8?9a`72v%22aE&HxSJh+TO1fs(K3fm0%Z*wl~cF9~rIh&W+Z{D8h zqmysT}iv(LDdb?xJ{>dTFos7)k?G-{%4(d;97D)=S;iwtLQ{|+4kk*40VJeyc* zxhs_c3!Sx%(N3OQp`ep?ChXebKR(Zh6#~o_Hj~vg(If@RX;+ulD!5FZso!vZjpUo~ zH;Ilo4k=-h{)R6g819qqPe1It9_~(zAz1a5EZ_ZvCS;{-^*80n& z!gj9+={6SbEsDgd6yh*ArqjG@@cAb+zXnLzH|L$CQQr3NeTyRq1bODj(KNzu3Bxf# zj1;z`^k2dNEWhm|jVQK3LEEvWvEf%-O&y!MD(&MTY49@=wmqxyJ zkq1=&^A$iIS~B4x@f!5dUG#?%(s%WEb@lLn*-lOA;(GG%Ke>iXe>0RM?|(vNicc3? zOaTq=GTabQ@87u41F8}JEkrTHq6cnm>v4Ycb=@y<$#*@3_^&3I3hUdIx9Qs7e^e2*- zAvY<7A0;lksUW6&$YuV2;%)x{Wy+|`j`Z%~vaSs1WPLyC!4}!YuU5i1b?sTt?ziyW z`K|nbCw%S`wM_(6uLZm=ND1%54a(5Qym=~Mn7O*=ybbgbxVL1P-7R>FX=wJzcc|*D z?bPxmGxG5DPAR4M5x<=tvGi>xcH#VdYUleMA(zV5D-7=dCaX8k^n6gW4dUl1Y2)Wh z^<_ZVgo^_W8Qrv_D-~o;w!)?r)V ze_Iow%fwq{eq#Ky8JtXV~5nH^NTdQl$HeY***3+4-UIDnTWfIrTu?doC~43 zwnn_AT0d0$>T>&;9e!71)*t5v2Y>q z@r{_|VO5*E80=1Z0M&r>A8QBh9W$ncnRvPgwm)^ZCm;Fl3I<57&n*}(*jHS8%)Pfu z|Mb@|0W-BJtyBj_^Cf-k1*UHOd!uC{A!Vk{fI0Yo`y3D8hC;R0$PPn59epYo=3IEQ zfnu=w0;e5V5~?ABbA{m#6`=WaG$5owys|GKFz;s5wg=qOom7&b6A?5pUZ1nu2-lNfze%WEZWHa;hl-v7xmS1RqKl|QqZNUEkVWr z@dN*q?u+}N^U>xleM9T@8>tuHU()zDhu)m&5LQx}tT`1Psd;?eNzW;hz#wcj&CsG~ zI{8bA_?HwjP+#D&d`PR__wqzObcDZWlpK4>m8g(}#My1_+0|qj`0yr>*7twpm?YYZ zZ~U_1Mq+Vz;9I}8jN#e(kSJ7!C*WZR*R@9a{*6_ayOOsZ?LV*iYw;%v3H#pf7LMBF z^m)6SFcudal4X;tABf-<;i(h8Nvie_Z1vj@cppr(!W#*sV}G<=;q%x=f}$A8ToL#x z?8UIV50kjE_lJS9KjTV(;eIGQ=6GT>l10aoriQBHDzVp#32N`mU|_4WspxOPoq)fz zgnwyaGl%Xwpc>1T%3rR3b*UtsxThDMqL6`Sg90L z33NBcS*EAOKJs}66x%uFrP#crP*0i)0lJXEPoL$wAXi~ zm%1{rexp!-k*kat!tvfF> z4t`rerx51N98&%o*vvWhdFIn>_E7zDn_1QK9|O?%qbj=@_EPbP@DCqb9@oI?4$1wY z*MF*`KSwfv1`C8PpPO~#vZd$`3w59!kNP(O`&s@4!E+?E)Fi(4yr_JSb{UpsTz{|_ zQr{Bvn+8e`25jl8)Q&@$mHvcqz}m+*4%%f7!fm}aj?wfy>{-KBr|H)xe66lr;1oM_ zCuD4rL@ehKYBxEYEgJ@2S8dt!&)HrxM`(p@zX3N7#UvJ0lJW~aVW$JDg z-e}HU?E6(OQPN#hN^#D8O&GbN(WHIc_4f@e0{sAh3C;688}&uPo=)?BX8}5-@-0JF zEcck2>OSvBlAH88PM#hW`y6(!3l7a>#Ac?}?nlEG>Tyzh2OZ`jr#n$>}R3WsER=kcis&dc0sd96s8Om%SXmxXm#HhAIK`Ex2npY<&C1@ z)=%D|J?BK!UX^zRKi6GfPnt!0jn^}av3U@tI%E`qB)a~#!$IUnt>?{`!{OE)2h`DNJQ#kpU z`|tw_8hT2sq?KcA&UCAH@L73jhmn5Ox52$L2fx7HDN`| z$lch`m>kv#t-+|EXP2==5p<$WxF00Y!@r%+JKK^o(kXstNCmvwH8tRy0xnIu6(A+ zCXyaAqG?ryyfuR`Bfe^1Sw4QGHoEj)U$Eh|qOitkPU_m*b$bwp#PYPqHP1R$|9_2j zoK%MYKaO?Ss{_%=;NoPk_|oXZchnlkCuWv9;bAAj_&%w}G?^LuMG2*FzVeOfn6=OW zW|K>Wg=H^$5*BI3@>PUI%zy=L(aaOCcLBXS09McuO=GMgJR=JOq zTDF~8_*F}#S*V2vJ5x=xuFQn@TMEOsfao@-F)rEc9JD z8JF5h@w$C&ey4IxzA9B5v+e>rTKGpPNK7!XI)6vX6(na=R&wpvx7Cl;E7Cp4hb2ui zptSm|5hCS^jgGoaX3_a0IE*jgR7v`xshf+@xBybUE@DSWfLoKpTA;p=bM&=L_Bs@& zaAbH`B8sSB(vus{G@S$}CcM*o%(nSj)BPEeA2s>?(qZrMu;G!)Z&CmWiF#m+;!0jQ zt0oSbCILGMT2N8Wb<+jyi&$81*+9-aN^0w=NF{$S&(q|KF5ja4BoZh5GMi;8#Hm9h z?7`U`l;}+EG4pxXr%)E+{ringa0mc(;*0Bj-{uFDAO;WK$+Hz))uGEhmX*sSK~^gp zpWC|=K2e{js3tLfb>S-aa=H=x*WX^mq9`j?f6kax&*P+Y#E~6cGCgz8hK+?Jn2u~}pT3%FDdFtD-e4n^thH1|OMpFMveYCMndx8Owk-_FMd5Y(@e!?Q>ZHxZVug}x~!Y*d3}4k-u(x~<>- z{%r~y_#xEwDGSrvqO#*Y> z#H43Kc}Unr`+3)p{*o~4x`725DOfPk%0(njU-R@A%jZW;+Iy>z;Dd@sR4)9^E!6}H zP^2T`Bk?Z2#9BErXvK<4!udHqp*3{i);)xjN6MB(}^K_vEueKmScc8Rcg%xH(O?tp8hVb^d01EG4B*=wV5l zM#9Gt2b>^G2?g(a@r|mKaJ1{H@D6D?Ia?wr5F0mh91uv3^1i#Wpt{-vS>8@u5D>j! zp(@%{yHF|b6Jr#G_Rri>UH}SCYtl|QDaj#wES-L zyO}{G&s*4CdWJ+ojcz>24-#vgg3~z9*P@OtygC{cxI&FSNPc>vgSd7%x<6@fi%oCb zK4&sj-ydC_-7ghxK8s&f0petj`{BeMKRo@`yLrR6ey3Hw8WTyGc(l9k%ST{o?NRK5 z@805)aCGY#w&_rn1G?gOVQPCW^J|!=9q&uH03a@VI@jfkWukZD*c*T(xdjzw9gsqy zerA@K*4`hm2<%^c5xM^IyZEb~^f6wa1-U*vp>ET;Y`*1k>0w&JMhIVzuy7jm<>?S5 zD4vto;OQC4$Q$!?=CFyteynsGHQKIWYzBi=E>wdupVp&QrW?(o7kiEH=Wv2F{uzr5 zr2RFwVJzvVb383M8JdXM*F#u0_S-BNx^%I@+t(KBN!7@bLE(OuK0^BT?AvCUj_4)c=dT}W=cGZ?TW}8Y`;0g5Tzc0PZP0ZU!PfH z8$ZuS0)f~*z9-9zIi`KGW#9(pG+5+pGkaVOedV!|#HAaGvL zAGk*mE<{A|vP5h=8Y^M15iKk%OyYYO^&HOmcI7H!Ed?#_isT?r! z`2+YgXc{5|OLJrUCzf{=cTpn6ap}_lPf(fsw=X|(TyaJesiPr; zjpk0dAK;7yidy&uXp^k}3}Ov6F)F1PIErlj)}IUfHNH0*2$oBz)d;@XyLOfO?VY$t ziUoG{tpM6z5eeKzu4*ro59sT|Ff>r=**y&l;rq@IC@@5q=7Kb_P(ew*_lx$TvUbY3 zJ^BcI_mfW0qJwTAj5m7wFrE??HB7C(rywL+g@{N*hi+VFYO(g6(TURP4x^d_4}jBU z{DfFjO4!$%cpO0St%HDG#BiWCugzgxm$Q*(b?gkj0|ML2elcT2uZ<4QmVSQS1D~7= zxj?m3CX>nO2t612% zTk{7N{4Wwc(&*7@TpZqOXE~H&oR;BN#cJV2o)U&T9D zZI%4`c}fp!wf1m*<62Gr^(%z%v2eFZH4uoF;}2 znJ)WdJptMqWnjebeV3cT1)zPRG35rLY89UgaNTtNjjmg^)pmFvqg4LvB4c8kzz8>@VoX*jcz*z7+Vi`@v=ZTp4j zbftYKgX=Aj0Bq34G&S#da*Ob?ZcgWzcIeF>yg)B}Q)6cXF9``K*D{1fXGG~kMgyhH zM`mrW=i+i%Y45MLbe`^Q_kTwGMTjl2tcGlO&ZY~w5BuW~;EW15)C=3PqJaIrIzL~P z^3fVoA|66h2Sb8^@?+cBnYDk<_D}ehi`yOUh*SI~R2Xd(PU?7m{B((3y-&%@Q6bqV zh~;=uBlz?w=3eY~$k3t*Q&ueJH{$*My~>4P;9Yi-`DPT;?vlO_J(M@<3v;%9s<)uk z=*1f*Q}-z6gcA_o+sp9!PIs5mofVoP8?Fo=0Lea4;cZt?-f%O1=zKC7drS8`+5+)b zp!m*B^ucRGDJi{Xw9$yQ=dEXq-K4?l)G>%LIWYJi?1x99$;&OBh{-jU1#?-*tQc0x zOF~5UkvJ?On0V_CWYqVzeoTJ6&|c7}Q(S%M@%_l`OGxywJxaoNqr)&4qs{y=4P~^V z@~k_eE9)LvSu|M zVHUUDmX06ED-m9Bzmn3O@9Vb5klxlI^Ti25{6GVKAO+8T4Pz`2NIB*~LryGzwA)uf zxn%m`md?BX8pM?RAVU&7#rg?jpn5~av>^4h&hxfm)WIb5hndl2;*{yoq0p{5uIRxj zp@ey@{hzd|_Yj%+eCIlXMG|ib8kn|o$BJQeXA{~sEx9vZcW*mVBKd&A?W4JP^+*># zEmx+Gm|>1HF8=-ZhIqEg2l%Kr@ZpJ=ai~gR<0VaO(7&Qqe^{%+gBsN3pke(3F&xHM zg)2*h!Sm%=PTYFr$8a;w!ai=97|h(C7W^H1aqE^4U$~D^guXCWa50fe5HLuFtyZ^1 zZPr3&xtUpwuz38pY6cH~4{p!E7^AGBqi7()`9_9%LLzyElIn?13;iqH_J*pesF$0? z>xsnsc`C!%wkWinW~DnVeRaHT6jW5Pex6r_%B{xvGax|T5?opI3rJV?DUH~{&PWRh zRXxa~OqYo8Z-^6AyiHClPjc*p3hZ*6eqN_VE7Qs#*Bin#KP)^Ub&wnQA}rjoI--fo zH|_RKRZ*blI!*lXTTIGggw|)mMdtP?{@RN}}!HFG^TxU7ukD zagDZUQixY*-DQu|xZ|Qm(;bW&3n`Z$r&2J4kY4Hz!PdJHc-|PPRxXn%+?hT`5=O^c+)XDI|_Dco-3 zVJ6a}7#*_B2UC7(PO(3W=PoAPGFo~%WyWRB z&#}A|E6OS?<`D%}7fHRYYiv8pN*5&Ir+38ne?s0%*DjgQ6+>x#{1dCq13?0+^UoT zFPVxr8du=z(U-j>ON9CbWCcbr*_i8U+*0}QLp?nq= zf>QRS<5e-r`?VL(m@fuXb@y>5I~Nnwr`sK>H8)9k1{ENy=sR;7NkC(|^JHgkljkRs zw$>BeL6p%VEX;cxGEzoobozX7MQQ7#(d~~LX_{A@#&YPgaJ`+A*^tM4N!n!f5iqI^ ze_8d;ibPXtQs#?|)&#Z=lenqSP z;Uy}9jQfDr)~%trtF#MtKJxrvV1rk3*+Fc+$IOHWc$%_s7E=YC+VEmG6bK|c$}+s3 z*;XVZomsihjP4Q(UGZF@#Yx@b?KkM1tnjvPiHSgg`t0UmOa*#A-n`8F%S0GU9 zS)0E1BeLz|pGHMPFaM7=>4U{d-}U-{+6gpS*YfqMyuH#PLNFCMGluVGY;kfBdKu#% zgSQ`LyhQ5)0{aD=p38qo%$0hcUIjDYp+-xikvJZ+$3VnUr>-akosHDm60Z0sr+j2^mGw5)Gj+tY*=7M`Bv(Nm@o z+%`CXMchD-&MjWrJTpV;W1A|T*_5_p`84(zZE-i$<-4k1fzEi)I^2z-=$k1VPeiwW z!oahz`x`jlBfKL;4q`;Dgd~&%A{Yac&Xny@$&Gh)c)V;v9G6Pd`!tqyYbeBP;DP=8 zb|twkomh@beTq(2n;_2*DI*y~suU}iRqSedr#w0v2kef}K`(meCqGVj%9O)IJL5Gy z1ceKJuK#>jSdgb5!)+A#yKfN2@^w>?h`fn|t8|mX99FklO-MNJAvEArdZrN7M6r&Y zBu+&5=HY?ygU6Au(Ggc`3+)b9E>I1^krkh&8hrsdtyrs;L}&y>F6F6{fE_vrm{vLx z#Gg)KW5+J`6BY;zGaVzMVMa%F=J2uq_MGl%WVJDX{c~zPcvT)D`6EAXt#5ra5q;V` zvsLrmvTD#G5J>Y1BEN5$|3nh=SPWzc_r&_svE|^Ve|tQ&kG1dl-0M9Gi>v&nL}35& zok^u-6XcYCtTHY8@JvO&Zjt&IY`Nhh%1skkl|?qhl)0`>!1{nA57u zqQY?$TRcFVKq=u~S?znLp!45_a>mA@i0RZUg%}DJ7Pb+R;H%xAqomjr$3>^ut=` zLo{ua)y9TP1bMyYvtB!(9_porlwpRyASn~*;4hZ=t(p?LD|p;eJc3#SkAQB=rvw9}$B5f2<;bB6Ji zUoI>g%Xr4=5o43Y?S<*naUiekRh-Q0|M?pgQmm^h&`G-u-yf)W%2%VC$Jp+x7j zJP#9__GiZ}+ltu_X(e9M^CiY$bi}BIz`>D{h@A$!k7Q&JTn~ZoZs|?lz6$bbaNW8w zv*pNRvDzM#e)UV})Q0J0z%|xP1fvh4Af}F{wHRFR$#FK1_n;cg9e*KAHS3H+KA~6K zXlyFye2>RhvvlTI&CZ9$zkmXk7K=Xmi>;v(@+bTz8zPO73{6k+`hIa{g7^n3uQM57B$6r)orE)jor#X0 zD*2wW*nvG6cXXm)jLKH_a2JJJcmM8fx^n%TzY=buV^AUq$K^D{?@C{-2&`Q1BnP z@ohjokEMq^t||tYwiC0OPERcPWbWfq@zQ;{8Io2DiIQ>YN8)+q{meI7HwzbC_Ab*25p zDk-~#)1+jMsEwb@D?p(pIf^0U;pHe_+gP;{hrp+Kaf^QBIF}0Z1b%YEaHF`$tQr7&(q07zFJoF@-B7Z}D z#l1uJ07HdCuE85P%IF*-Tod7IGE+~fJ}(v8#QwTLmjv48`5>l0G0Jhxf=qnV!uO1q z%Zx^SijckP>^Z-AwU92yly@?~VCrVSijaVUiio?^dy#Lstu^tbIKNg)AFH7aKIx}p zJLiq5vO0JclNt`M(Q>aixnrhbneDjBv}>o;e~4qDoIEy?KeX0!7A8?bWO9JWNllBu z&h(0TMsSXeA2G#tnQkQ}O4*iX9$~?$7Wy@_g(uRoc<>SCg?LCt5G^L^OQ-C7RtY_Z zq?8m#e(fxSjiGZ%#FYFl$0l=V&gSMFC;wCNu4EvS2% z?Gqu1d@b+(UTo-kQVRCYI!_9vom!gSXnZME`_=Zmw=d_i$C;YI@70Dr{P55+!wpDj znq?>QwOuu1LEbxU(D-~%oO4ubJ19y3Dkt~$3?_@R-EgB zmiS2Ldicu@h{7y(zOlj1yMIXIR8_ z@1$Nh{1C6Uc6_g0N~yg%64(G?*F^coI?#SQVPzQ@@qG@iSb8+&Eu21zT5BW*P!+7K z_+YN)U4y~oZBZ5#!o}_DHA9;L#voMz-ID5Dr2`H#$=f!y4YT6#9v9rBYKMA;BW5da zvL&pt>O~vQEv)rnsPTCn-X_1wlNJ`9a8eyM9m&ZS0eQHE_K{wKl(j+KFv{$NMxyi=4U~GGp+>$d6YyZ&W1Ar!29wzVavau zZ`!bfh{p?0nn{-2H+`KP27vliyhqtLHh&+-<&?}FJFxi639A8I;~ef}ZJf)?s1EkG zzdXg(eR}wLwK8LnFfT%l_s9fD(%?=7?ALuk{!ACnmhZX;a6hn6MH<)q<}jGRp4Zwu zxJR^E^iI!;_IbPmdvQMNGvsn>Cd0y0MAN}#SR~8S(4pWBVZWPMR)22;r#yCDB4XRb|txMS^jiQIs*MWBJ=W4*lO4 zbL+O+4Hx~l#c)@}u;_K^(c8zJ_9oXp@S@z8JY?nR&$RKcvvJ{Qpw*i#m9@2TSV7oELXVurs#ep} zBSp^Xd6^u1uYJkK1woG6?y&wns4Rlys=>#qnztB{qTfu}R_dX!N{@h^au6ihAz{ z55wmio>@BBZ2;dKKNX>chbK*Lo%r{|lsz_|U&){9k#dWl9Vl$HQ`wfru;;2UT!rsJ z-20b|z8l}@y2T-lEn3)JcYC^)7&N*`ulk#=)^7bd$Jgn4UO)kg?- z#n-=PNdA&a`*Hx&)Zm=+K+f+j%-w5y>QEORn2?Vcg%4~Rc&P+nNva$4UG>1 z0O9pQCWd27g(Z0ReS1Jq#a8SDKA#FJ<*TmBtR_qeb+bwf&JndK)LK6#Dl(<->od=3 z)0m266Md)Zdw{npTTtC@JjV?bK$q~*^3^|5*;6j^8aczs|0k5_2IU%HgovXq8Nv@8 z-(hZZW!68H7x}ayKfxMYyW{zJ$`N%$x85lU!f*Q+bYf4A?AOn>ac->nTFbe7o};v9 zJ>rI))s})7EzV#Hb&T!ML{cA?VeP8Rv_mEMJ8?)9yv%CE~Kk?cjt2xW4 zN*dGVg--y#0~UJgmr?p4#!P!B38Ff?47tvh4hy#O^4wYz)y38<-o>!f=ktO3Mu`B~ z1RL#Z|0hEtxf<@QtkzO1U(E#{imgIp>d*kQ{Rye`nX&R`dCkMz#3=^ijWX3A+9StY zr`JENt}%KU?_R1)#_A$vZVo?qUEdyc=)R;KyTwwuCMY7Jy5I`4nCDt$mkNI_1P^g{-zeAy0HcJ)e zEm`>z9d-qM)AILnope2GB2l#6LKFyqfJX=ND|k+OQNe-E^c1fSTH#Qj;P#<0KZ-H< z-a6)HAWYV^tjiUh54#QjQ(3_P&o}KkgZEpsJ{!lAbJ3T}1H-|po8%lt52?QH;Md=h z{Vr&tBcRJt_bx)_8BG`|noiX`U};Ntu5EmZAB&jg4Dw(jK!C)}+-*D90PrAnudT0R zfR*-}HsRH*=S!1?^$G{fmaBD~T}N~&u+3NGX?%SI+`E4OH?GBf(!k3PJQYpvH#IloacHyZ@Ow~$O^RX*2}n2eY5F@ML85y{g+d0tV-Q|+U4OPx1C zomsKY|~oYj6fa6+tr$Jj>d;}qQwngyzT80T90ETo#9CkyCjC|@8ujCe(rm0@F(wH zP<&B-OET@uOe{7N@8H2mQT?d3XOp3<>~2T94y0+e|#_Hx15Q+I8_F(8bdZVRWb z4hkA8Fi|sPDGy)UM@1bgbw52?uzbiOCJ+1a{N*V-ml>OQXcDaGTd+1S<_t!9igTFu zFV27?l3prR3<94E7D!S=deM+i3o*>H<-W>!d?hIRpuoONi`~OG-$eTBOc$G(1x9w{ zo!C!iCKrr0<^44#!W*MGQ&NZUM+q&fk|fK$qQzvNBR!Zu>wdTlk8FBe)lbiLP84WS zP$;N(RZtArnU^x$7^*D92s9+qAHp=I4B8fejSLUfdtg;AOXBSwocXWV+mDY@ex)3=BW)_I{&9Ax~ z{C+;(I>EJx^H;{BGt-#SD|8hBKDQ5>+me8$TjnXu;PVL*{>^vQjrE0H9zj{&a|6hs zIVyZxg-)9+Vd&$w2cK`I*|1NChj85@Q>C%|pdB;yoo0=zd*0dU?VlXtE}Ahp-3sl! zi#0wYP`iJqY{|7RbfwBwUkz$NwxgklFql}7n}Vx93?RZbanO2=JAvV;iz)TO#L)HcDyCe zkBk`jj}9Mdoq%%Foo4(1*j#wuHmjEkv8Ez!8Bv{nxy0~6xIz1LJ;|+hho#QeJfYoE zp_EIO&RIUZJsSCy7cru`vi&2+eQ4(|>&ee)ao3i)F?R(cr|;NJ5{$e}S~@<%De9l> zE)8yGAjpAfinxl|XnGG1DXPQ&Sn5axuWTjfpz~a1%9!kI#_&YOkS(}s@G)as2VobB zsESt3i`NSJxNo^%#H--s&`Fr} z6~Fd0hDhXHVPoJ2%|#nPLBmDQl=VPcL^!O|XPwbi9y`w}Z{0=8cze8zE9dzBY#)0~ zGfl%ALtJ-1r{Z#+)!)w~w2m8P!~wh6MDL5c$QcBe;Pof#X2W#j=%o>48i(eVf<9X= z(X0rt)C5`u?3_)-hip%Ta(L2oJtwqo)pyU&O_dxLom#cds>GIBPwyeXd`<+HA&fQ~6FAIt11r!Q89&xyUTn}|$caG=8tf$hS?-NbMu%|Jt1az1@ zNC7ww7sxx(thHww@VYwquhGSx^k}u8)nN(Ub zb*^8?Jmox+EBI%|xEEu6o{KJT`DbG8F6~5Ic3y(9$niE_k5bsm41b`A)_Uk%fOVMn z@ECMno?41Jkcbo=Q|o3ndO0{U8#%4ENvdytD84r0xbIFuoS=ywWu3v=lvv{W@C0rf z-OiQJ?jCzxL%}DuGLLZw)X7aT?K?UULjeFPC3>lA9BJiORU0 zvd;SsXQXnrtF>z(C}PW;r%x@Vc8dF0I_~&mnxELIhrN&Y@B4b?I)|_x8vBKmAnZSI z5LF6~*5QPKueE0$rAnnrxE*|E@_zmdFlepJzZYETV?;g`Hc-ObVFU>oFqHCNY-Y=c zdkV>p=10bh37{TMd7b}qu46z?OCgywHTBhZy(r5q&jsaTjnAg9>bMe0_ruewbe|zO zhpWGGIMmgMZ-M$Ljk1D30zYM!EGyg6m(6ki^Ph8!3%ecngKe(cK5) zUPu(f>*S%@=ZDUv<~If`t*!A)`!!7WJ7fVkpVdZ-KnF_hn1KFfvPDY*>3&D~lkgr- zosT@qg)-HQk9*M!ZDOj=dgx=n3h#DoMKIC%E}MoqLO6#!7*FjB+K|3Hw$?;4z~u3x z9-VgWR&*#d214Da;C&pKkFI~-Q`Y1csvOJvO|LKV>RuRkA%n_Ho|n+%$S9rbI%Bn8 zW<@2S#OsvPM`_oi&7d9N+~*t3a8}(}89$?u~I7pP8-M+V3!e6kLf0OS5FE__V_8 zq5=a7S)LeqUDq17=DFWT%?AA@KLb%~3 zQUUhnVEM)=44ce`D^hBETwXAB11TP2=WXy~QL!WQSQ3@F<#*-Mw5&+3 zh@pe8r&Y*hA;`hJvsM=l_bY1iM$mE;$)va|y##^1jmfY@N&lKA3+wNA7SG6-zgk2#_ zaB{?bc!jx5s>ckaI0W!8KievO_pM|4%*ha8ztxW4NV0Jr_ox$r<7o%LHwhsChX6Q0 z$G^>mB*tPd3e=j#+KPMiAM>2ty=;c)d!F}vEh?}MWq%qLV{#AR+hnJ5M^YADYvi`+ z(p5y`>+_D|>%luXYR}9q0j-V}sxtW8b+M%q-71H*I+-gqck=NY%~(n$_DCOl{p5`B z2!bW%h?lipbS^PDP3Er7)g@cAQr~WIFWfCLo>ieDB{3%KSb13uJzyvwcu-x54}nt+ zBVM%+Bm1`ZO$s%PWMzt@pzTU7k!=%PtpZMLV2%JMJ8sV(rqsFI4UHEUHfP`JwvqQs z;p50>ab0BhXhZ*MVCqyS3Wi0lK=*|0ZVk3k$WnCsDYa-@B^7vGTtPm1 za$a^4{b66qbTWwl(Zr_4w)5a@ZzJYMxz5B#2w05EdF_C@7ru<3Vbd(%aWBIaSS0G~U3aJOr0oW*Jz}ejjWL9CC8%FM!~^RMS~hanU*+9$ z$C{!s?=G1b?R{N+Ui?)DmrkXls~`+D2Sz1kU&$lPq(B;-aB%kfG_-r~e>E`Lo6}8s z*D^b*I)hM+#jGm>)Q9bydM6mIy$v7wA3q)QNLs{V-Te%*b_=N8ofA2Z>J>=dqdhvd z**E3tnqOWDY8@?>Q5|E~rk!(DbzLON-sz4G_V&`OZY^@!q9MtKg7{Tr(yV6oiQTVI zXh^$(&B6>+?1u=jI*%#Xf(7U`#~+BJMq0xK)88G;T)gQ*`y>~#9P{(VU1DNYCQq_D zOb_3=ah--a$lyvhDc8w#R@n+A{FhfE~2(5KIm zregky#5RE&mfElLsyYg#P$(yqFZ+3ZD4CijekqltwvUxXK`P7ML7}G!4N;r>Rn*7{31Bg>`c-vQ7w`9;d6SCGJ3pqxH4y;aLrh8)?Q9hr6mdvn zB!sA_CApYJtbx*~m&94i#qgXaz;6W0!6}Gns35IVS^fHu%~~b`L;9%x7P$A7h~s@i zZ<8ZPbS1<r zwV3KTu0@{S0n$8D8JRp3&i+U+Jur8hmCKGK=@D( zeQU4rpDgQ|mTeC`+a|rQHyk_EeW`h-)S#+MWkkSFvDIfsqH{Ny&66<4%vP2vOUbQ| z=Xz>t1!^SQfIZ8(TIJd8HcgFfH?ppGtLG*^w=~XQusuD(zqs16L~n9$af7}qNJ0}~LtOZQ442HXNFV+mU3{t2{)C#LH&U%SlS&!r7Pm!(4l zBS)NS^IzcY%d5ej47#ijwVtC#;8hC%XeL&QPryq_8kY(>MyA1|>N(S64MUU{ zhRl)|Fc;;t#QyNWO)F6Q{;bZXtf?3*>Wd8lu-m#7BS#L4+jObd@|a=gF$+8Bl2elN zQ3n7rwDfF}S?`HcDZhW^xY3FgV9BP}Utzv7r;#P(fQqsSMMOfY&d|x?RT-1Ss2bP2 zx6eTGtGpOzD2E|(ynGx8x$dln3G~+F2A#Qe!daSb!Tayv#0!oR_?rA0YTw~(6zn9Z z2da|*-go^$GF#56TV0BFXFr*v6Nf1W>eo#B#<=hH!CTv-t_A_3%h&Y@5jMXP(XZ=! zbjoD?`Z{apefukaMD2fBM|cUswn6yDx8bJx=VDu(D+D_npE{ZTN+=}f`N?d3K09o?oTV3*wgOIu-S z&c#sY1u8TtyYE_8%VOMX4`x@2G419rz6{5+XHlrNed2_Nu4y%IW8Y$kw_1xAQ=Ba%}}H;R3$D+@#+p z128_f9%29xa_{%+4;=4G+odEl+H@c_>E5-MEcmFLYgjDL8Y9!;4~N=4&)cjFXkwDG zt6#F7A=dJU)lBrEvb?sMVkCUDmRYZu7yEQ0<|j3;mcuE(E(8U`LM1C>rk|s>I~o|Rb@o49$!uNY2>D| zftXrNPxrOb|6<8u^}w!nc;stp#oPqb%|Qe8%-ptn0o6J9vfkt z^LI$aNs_DXL37?+R`NU#&AJb`deSO6Km(|n^**!KsT_^)curQ5Mwtu#wUYY=_?u_B z4Xe3M)JXslzn)p+EaNS@rwy7O47t+X3DXt^!6^0Ra$LiOPa_II`qqg3l^ zFl|)N9XYMt-kfQ9a~-q6adznd{Q_g|LWH8aHk`{^HLb$#F7d%CiGh)0_W1rrC1j}Bqd!v6iUdN-=CF!^gQ55yj7`6U z4|i3o?Ll4c@C#P#1lKvTyqqx-@eu~QQM3g9TOX{uUt>%4!BxCH4cAd&oo+9~OhO!H zu`z=nR+tHTmr3%%WZb=g8pe!E<6SE1ZRrw-XPx3lWoy=KLGiO`>FLl4NwC+-^T{lP z^TPwhe!_O)Iqwfq$BUUKn)JSuceVj2Ej`9LhQz&=Bes7Ij2eCE+ZDe88e~MUE2*gC zavJ!iyRT-A@SZl)177^zpRF+i^q4tWDbvI9vvX6&&gP#f?2KqKVwG_B`c7u2cf1ws z&aKn?sx4=`FV#QX_Q#|9l(cwZmBnb_iH6mKJTj7&redC#YNViYzC0rGk>V{JbrXRq zAfybR3pt7iq&UI079X+N=g|iR-@3es}V!W zY6<~BGQ%H;4x~?~{kRx1g?jf(>mXP1!x$g?Iflhp6e44gyLe#USyNE4AiIms{pCJO zfJwU<3M}{s4j`n@u#7);2?us|I20HN2L3$xDhMdi`vec*48>Z0 zHnc6YvlF36_6&1f&da-cm8h4QkS}iTG9CqZPJQ=-C4wUY2p=v_!5?D6FY|uC1Mpa+ z4tfR*wL8(j-Lu;~9GdxLycbBzNbYmVZac8X)cYxUY-4S2)0E%6&)=)A!y)q1z*?J| zWHJa1AO)uc3E(+19ZIAK4WtN#9`M3~85<*rzE^FcHtyo<3R)ZD-S9Rnripx_sCW5f zvr*7>;zq2ry}_C-t>5v;7}-o~lNqXUL}H}Qt;ukF7&>3XoH1$}0)&;fH-0IDoF{@- z(o!pve_w&e=(|kj^#PFP6+0_-QJb00eYfzl-j)w)_LY6GYclOc(BmsX2{;EI!tp*H zKN0(TbF*=$#>fJ#!>Jp?YA9k7mjVNfUuFHw1U!l1KC>>bkBHTg*=MLTUl*BQM5=q6 z2RkKW&@`*XmZ8^%G&I$bh7+VWk@A|}`(cX93OY;brI%QzOh|es9FTyaU}%7>LOql7 z)cAo>i2F;ctY6{&-ga{8-Do2V!+df1OS;L5VN7M@#rK?;`iOZFCp=dl6V-tXnpq0n zuQD>FtR!yG@O$-p5bbqGc%i#3S_&-FjKtz0uKEz(#_^^mG|4|1E_)E3HAEc?$}~~! zZ;8PAC#B2aBlmh;-QHZe)dKcn@6z&~_HT9mPVRhQ8AklU8-EWRy>>b07MtM-{0i?e0Ee8kMASq~ zxHXA*2Ornbaxbp8D=|(6+QQ17?t#+C7x(-w7W-%o9}{e}olSB&x~3Sl+M%W5aFRdj zScYEllAd}EYjy%E_M{Far4U9T2>FRehk+7ZH|aDj{qcoZ?>!nJzNlv9Wuxs`SKs`U zsHc;WLA8gF5)+#dv8MdFaxSTgoj^r#;3-hD`kX-sFqNNt@Z5%ErvvkaCmyCQx!Xw4 zAae!n7VA70&-!X+`u190JL=P51D*q$c0$q^s4#sh(fq3ohjJkSk}Ks1zKe}_t_$R@ z43RKtzXQ?bGAw+#I*#o|eyp zKxk8+01yxc)BbH~IXSK7npp98ccBl-B`Ki?+MTCkS-Y~>={<}MZms(x1TZEOPU%c$ zk#Ur;SV{Eh-Y%oI+-j{BXKwmIUlc{GwasSFTW^GiqX-zf6mmOeKeMzY_N6GjL|DSsQUhrczU_`3ZnORt3Z zeziqSVb+KaMnsC)OycBx+JC6yPW1GGhZ#cb75^+cjyTTCS0VH>!2r&HadF(qV3 zUbeW_CP7D7XbU!L91*{N1FgxaIxt^Un|RusLP79;ifQKe*Bcc7MA3%XKu}TJrssU;Fo=0zS7E+gb0fv z^^R&53f8?_brkT$)@MbmTqy3`8#sTJ>D)<)-FpVF8@X z7Anij6nyOWw_a2{>vI?K0$Jp?*%4T0p5}twnjpS0G|TCn+l2b~Efdlbce zK>Zl!KnM_09NJ^YO=ci57PfMoSU9x)(g%D880HK2WKAYg4dSh(+rG6Vaacqh0JO}2 zOe!qFV_}dKefW1?i#+0{!WFh&qV_hhq1}->u-Gt(66k(ZV zV+9i29mR+XsJOb^V1t|}_AV%>Pt^$9f-4$2^@AHr-FHP*Lq=eOoU0ncTJ9(3co55* z)Gxmx0mvFSp-`9^{0b}9l-9$ElBE&<6#tFk=W-Hg)qWYx3YNv%xBAYPA+Y46NH6Ml zxx1l#)?Wf(Le&6zE*Ig;Po7Jn38B}oR`wM<eZd0h(&KPNlgg z!P>`$1e>;4WONH@dP{?tY5=S?x=@%v4!^K;_puCdB1VTp`Zji^z18K#37859CT8ki zL~l56vvRNlul>zSX*coBLkxJedS;u>pI$wa+pKAWmSF540_KU#0^26L-~eH=Wddq- z3o5-5dIacwu<@V2oUAE^*QM#hPab{@65z~g}Zf^#qiqgPfw#&2w|iywbc z!C3#vb`@{t{d5icm||n&JK}aQlwTu#{e=fZFaR)SDDz8$Yucw45vSTjDz@o8<={Jf zMJ2c141zgFr%~Q4K!p;U4l5*6LbLsqM#sjfzzzjqd;&bqwD3Y&(Ib@|10#g@dOpRC zd~km^+$NAw;MetI`$!MN08a0uZiWq1y;MvBd2z z&rJHaC1?I37vvu7zmm{A2Xk_bE5%$jjfVx_;P1Z*DtBl$<_2pU&$9Dq?vbY2^@Khc z25Aztt~#$3&rUi#D4cJ(f7l{f!iVT32ihmsxVg%Kuj%es+!9u1FXt*Be|Dx>bCJB? z5e_F6J+iW{`|LIM$x~t;Ci7sWY{MKU(kR95Zsb#)*f{vK8#Fk-6L_#Gr!$RXed&wS zs8;=4av?XA^K2wPR;J=3KhNS~n!XZ)lGdPMRAzA+N9~R2*I3^;U!b*to{X_Z;ZIJ( z#9qUFS=8Fl%+op4W2%`650&J69c26TutO*Gyv}^`ULdcXeXN^ZZ#aRzH1CMk@-s_h zW5kc@oZVnGrdh&9?r|OLo)rr8Uu}H4L*aH(PtPf9=*gb0(sfbM;Uc;UitKJfU)Qks zklVjRbQGp`>NTF*%~Joiy4q3I!oSmrS;74k*RHUn#rVyQFY4h(94h)f1v~R4VV`F@ zB!Dz=5zp)JzCYv?ywhoT>)c^|y*d|?_Bg`lO>ZpYj0*@Ny-;mT%;a}=nn%({?VwEq zs8ML=o0D+FsF$^^TD6pRV*! zZF8<==bn`sw%1IIOLAd$bgJlZsTw&rwdB%O=6MLzu^q|C%9KCV+tpvKrW@d`g%ybf z&p0_$fmerz8uBc>&zXNy=X9Xe^yl2P_l zifI?8_$CqQrRz;?HaRXd*6KaYYXBGB0E*)V>v@Z;>-`L;*n2{Wn@FL9g)z3+$MVib(hRwABUt)IIl z*+S>a6Du@Rr(T`P+AY_SeNL#al*>J*jNLq1&Kso2{RWJzPCq87kAmNvR$)OU!TMD=TNlx0 zVX8e**)<4aZ%X>ugwX1uNaUz8ihSWBs4KP~p@BYMsmZG~UokzKhuHd{p6jfk9Q7R< z=P)vET#}SStgTXRb#`jQZ1IE29r{Yl%FQxI$l@EC+e%Cne$VZk4yw5gw}2XdNvv)x z&+RSb`aV9soyrQu^4zPK_PULZ%_Az~u@GD5ICiZ&glJHnMzp1G!5S`LH+emrd5XwPp6 z1g9C&&i0ghPIo;-b}}FOe+rL$Qzh3yyK>|Mx6Z(!UXj_%M?UPfW+$+s{D3Ca>mp}|x0{Rn#6o15azf?z6}8vB2sU^@t}kP?$RR=8D7^6sOO9R6 zGFRD4u`FTH?`V`WL_7(38!k;L+YDR;s07q8-kOY?i$6 z+BW;|ku&i%j0?Qyk`)(Pu>8oe1}M1W8aBajc z*G8!=TWqmnm`v+Brq32#tBQ$S{7TWw%zKB4D9kXQiO1-J<*N}>s-PG#7jRb%TAw5X zhlpZHnz^*%#|Aliie9Az5)B_0X1(2VE%ck)iqVIZYcE=s&<{bLk7{1I;$$Y(;}g(I zkZJLkT{BjIzb9T-*V68ro~V-V=~N?sTW1dva05737Axgx454&Bu_>-8>9CuDyYT4Jp1~V|OL;&wnR;d;0{QY=p&fCWei*c+>8~&}lsUJOEAUDT}|= z7(ahfEcM#0yT5)96k#S$oSFT0W23z7#EX10lkO=|yvXExuT29-lyGtr6PaHjTlD{K zQkthBj?x~16xN5Ax>uFT$yi+j^pV-p0sjaZlNyS*0n1S!6rBFJR1K{mazT4J(>yv! zAa)z6{W_=SdFLvN%1=+8%u#sj&`>x=VBm%Q0oSoD;CT98c`-5QS_he4M#iWxFe~ob|Q~DU^CkYM5Oa&UJ4PbynCH?;Q+?>rpY^W})u=t>tptchZVnQ@5 zsXaPmhxY(SUC)!+LA;ii3C>F;1!4f_c^VkX+O>-wT2(GMipsLZtGQ9^lOxf@q|=Tx zXYcnMB&}=dhBi%KPnVVT<8AIkk1A&OEk)`qLWj!Hx`GqsuY-Y}+u3)}ny&9KUJeC! z=HGK9e%eTC^h{$5caf_i$p)RYkw2LYV zuFvH+Q)?uhMyp2ep%rIq>F{A2dhBa6J6$!&^EK%{`tP45#ndT!<8l3L?v`<+bHte* zW2eH7LBfLpuJBSXd^O`tZ}Au`H+@24xV?(BEymDjeHc8pJOPyUH@g?KV8rr4EZ;#69Xl^?JHnE96iv`8*#OZtn1moSW=&Ko!8nCbTEi4 zpgkH5x??5S0ecDd_ zhYdg>W&|1Of79S%kFl18a`tCNIeBGl(Y)7^IKgXHwFr8Ln(f zo_8omVtRZozu$eaor<V&Uf+#(Hr7`Frpk zU~y@Xft770(#>2NQ}xD{mVhpY5u_3`<1Un(d$hklJ&UXLw9wKr`c*0|h;JM`-E*n6 z$7cf5+CExNC3Xzj5<~rJQI?gxGp&1Brlgh_-~2zPn;)Bcxj72|pXZxnOIrm4Kc{Sm zLXm7j)3qD09SiEENnuTayFGfC%O;n}EMIjO2<+dO4I_%soV zRI?$es&?tLG^w^EQ$v5<^g4n9M_XJN2lsjTHp8oi@d)KiZj>(K*1pd z2*KSUxVw9B3m)7(xVs1U;10pv-QC^Y-Q8j4LGHb^TeVgD-jBCiwYA^B`KJ5yap^ui zBk|I=)N>HQ;jORYG~1k6h@yQRdUAY3VO>&Ib>k21Z`IDj_B=MX5ZUf%X~-s`xUiH` zedUbfh{(QzZ7u}sT7l-$j!$h}-tu_iJ25Dp^U~g}`5QypA?COv?U6%n(66b*?T4Ag zSRb!!yj0r2iY3Fsec}EKjED^%m;&@MsWFe{%aQQiS zHlT^+HqcNKX<~;l18u9_#SIqX`O~$t^Bdiwr7$^pN(yDHNa?Fhlfq5iSym@CIwHgUXas?EeJa2RIK6~65|lCwAV z_Of~5+v8-HP!Ah9jmM^K2=KV>_KZ|fIcv3U%wKX+dG{O!h+m;gd=rq+w0!28=sxd!u7 zC$-T=jaFBdx6B8Lkk5iSK)3V5FyZszs|4AzBmB9lp;(wv+8LJHXe9C8{$%lfhGUkP z?^`aWu+Lm9#2d{EZ>OBfa9OLXygL}&%%2P{-smf!7jnSW|8=MACztlo0$n@iCUrRl z2h;Rsm3K#-@Y+e^2<@EjNQ_ixn!aw`$@veho|SKy&CFOyuP_MR)3peI}R z#XzjIGGQyY53l+KtL)9f_IYV2Y>ZAZi>%G2o?74wAu-2lkEj(^EiCm%&+8XL!^n@u zdBKmKRwgld4&i^TuwRmMKK4)ky&jeS2khhZKE*$LK3?0SejKoVy#B)(`d<0{dp(FN zGE#~Bad}efEuW4Y1pt8=XjT3``N_%d_~Ih-jO%^I)4i*^bN@=FG2n6G;yg0*fOlo? zeU(yKnOO>>*FD?NkKWyxaJT=gG$^dz65b*^`xWA}Pre*B$jxua`D|%KjJ4atCM)2f z?DEq$)XFmNR|D&&CBdSQA?MHk<%%KhJI?h^SUqpO8&Y!W4IbWk4b$-|OOy5#IkrwG zqJs`u|K)nPa>3c#=}%f8a<)P!b|&2UoQ4;0mxmK`t~S&9W6?pD|A{C3KFV{?SPEnb zeZJ+jy|t1!K&k(Ul&kG%t)gN~dF@NG=zrz(2dTQe)=0|~1)3wO{08UcP?jC4QcWg^ z37Z{l97yJk|nLadeyS&!8rlWU(D%9vcUwI_OvKAs;Zel6eOT z{Xd`pihtq^8MAvn%J-3gsZo>RU&96HK7=g44r zJ%0Q(bWQ92Ro(jHxHmc<{s-%SV(hvK8|zzW*6bVgq&_v4!#tT*iO6Tf2-@Y;h0_GnxP5^MAJ`{{Icw#kut&ez*48f`*G{Czjh}<80**m=0T` zP7v>3uQq2ad3`Hrw6aYDf!-EG2OgMilh0rF#3E>$q0WO}=7>j(%iTU^z-6z0Ammh~ zMgusoqmtF0ZBID;3kAidSrj*gI{S1plPP zvD-wDSG`078|DESuT*!+s|@%~v&;L`xxG~Mu{x9EKl$1QM@cr{jY9yIx$msKQy5>f z_<<+6j-S_J5f-N>Kj`21`k#Tb#Hrh83WPqg@O#Shb!zNh_T?lkm5|^6RCwGJ4=$Dd z11j>Lv2m({?$=#?fKlTxM^8e)yq+B(<7LY3hM8 z{PF)LC*PjgvAMsR8rvy7Zl7?#(2Ao4(dbHu`w37fLWEqyMxgr{xj*ElE#Y-%l z<|-C3`Rt@Kt}nDL?Fr)(fLuaBTkCERDr~=x2^F1zSlN)7W!n{E)LXxw!}A;WlL!NH z0@@~wKJs@OIDjJ93HwG+=y3`vxR~aScRDJ;N%x_H+uNURT+z|5ec@R}Y$wSz@#-f~ z;Mw!9w$0`mCjqiIvKX+g7GLN#q>c&tFKjix=BM}^l>jlf%8$!On&a9^1VX$Kd>Hk* zGd2Do_V2{7==aoagKkn@PFDle%Ze4PYpMFtT%gqgjYko^Kn{9ku?xm|R}=Z;S7y(^ z29Z1EhT@5sj#0SnyZXfW4B(}{mI_Gkp>j@x7~(15g|9u|){B-(AnEI(sX5AycgCceTtd^CBsr42?3GRw`U=I6KS=**+aXX&_`KRb z=o2>oufsZz)+~nynTjB`r%^9GBNwMGm5W&fxcpMAxVFf4)GgzI(AM7pvrB99#y0nH zfzxXjO=}=2{-@?9!W**(;I_q%urlK2KI!GdpXS46Dl~XLku`QY%`}qTnD(8`A}xa2 zO17vI3$IC4;EmI zXO7MMoZD-aH*561+IGM&kXm_?y}7ym$tHyN){v*dJY6v2GVO{Kaxt6vl%?%AqiWiy z`W@29l3f&^Eamk`1WQ7&n93XUq;N1Xoyim1@mep!tX5uO;=sYG3{Tr>fYmmC^!U|F z962P4KJ)hYzNDU?K=-w`)RkI6^!S*aiTTW9{CZkpp)~p$E+rptsii}HkNqJUQ?!Qr`m?*h0`ILv321IInq#bo-sLK6O+}}4 zvPM7Zb4LI)m?gRSaRp2IQ(=r-{8+@}uMAB@c(Be{Ib~HflsL@(tr5?hqS5UZB}HHZ zao~Y6jnvl(7af`0@;8!`&33vVxb%9(g60CF##?2UpB#6q7K1&eVdyqgpg-vvtXGz+ z5jPh))TBfPdwC$&EQ{{Uadh8~pxHioFh5t00HmPi5KB)a({e|L@>~|x%wJPzFw)Tx1${) z146dl5Qq`<&^WQ1cHmz$xbq>hy}rE=J>l7fYV(QmGxprC`9OH6XV8sWv`XdV{3nbs zkgK8td)k^y1!xJc;pioEnW5Ns#_Rk9*SimQoTzP*@0rol#BLq z8iD0K%1K-zKZg^A#!374b7fU611~wAoeSy$4Xt>j$k)*yx5iE3qzVsg_^m&u%{FQlMKt6@4f>UK;|IqGPDTk8J1{HILW z5b@0p!n=C33?imO2hVwt#!_meXa=q=U*`~deGXyy3ED&Vm&KuIVpMy8Zbj1t30FJT~#-ph1kpsnqWu-*26f{^yj;7)skEvt4W| zNzGxCI;>G}n;W$BIQXSX_cB{lOG9Pvz@)}5&9mi=eV}gwLqx3E*egdN`sYGX*h;mB z_U}Q=5=!s(p8~tTY_Su~pS>B(99l&vALy#R;sz=|(V2?#(7WPkJg)I$E6L15r?K$$ zaN~|gNCrjoyp)@~;oh^!ot&?6cl=eOr<0ASRvYoXLVw7sppU$*bB!qf?OsZj3XN=H z%!9mrGD0xgmA61$e0&3xmt$On=p0lgr)!_tnDN7+FrGDQ87|*#wXIqoLPBD*8(Pb1 z53g7tCtqm}=~WM~?&h5sG z5kevb?OJBFaj^C3*|=nyqLxq{z6@&F^+&S!R?qy!W`wYkW18m;Wg_pFMEUd;FL{FE z_UZ~Z*vySfKS7Sq0L1|Pmn&IFH+%5BE-9hk7=8EkN3g=exa~f{;u8<5j}P&}!aVJZ zu@j^O^c^`X{Kr-H64E>4iYv~`9)tWlnUr=23W;c*?Ur%oLNT!yY^=`9IQP7^%S)sk zvB8pglcvuzq_z+qd{M!Jg>y#^`+ogaa7fYqCO~8+%v!S?qwhuM$5EfsD20T(D4e}ivmf%Lc{~H{&t&gi+16(&JXD0hcXA*&>t?etPM_w^hshtS>tbTD zJZF|y&Of|$*~deNB%j%?V$HCDFRBEE6z#*BSlxOT94ua9#{TwA|K&n4N4=oN;{Jpc z-JDFCnySwuti<+_Ct**5NKo;jqT*4C83{?kxFaP4m2^{G^AGjrjoLghA(i8rh{?v8 zE?5pTGBvCR$y&+4_uYibKB-RPY5PYY5fK`ayv=Glg4;bl?^7M8fiI{!$fFN7I!kuJ z^w8eJ)BThFJl`%YOP`<;WHDE4Vypg=ITm9WB><^X9AT zhKtz~362K@7{6mWe2|Lt$)n7d0~>N9K4a0-2{UZG+frxzm$7z(w~pLbQ%ikJr0C|y z)q;DXp7R9asLW!g*IM}DN?$DcWCKDi#hGOG7j6eN`Ng#m`va^osdRAt`4odJKBc|* z9F2*EBy2+Di6m)elc0Mij&h#>DevJ{lB@I=LrsgA5})8+&Aq%56aE%Cx1lExAbme& z#z^mVt#J!)Ks9<+X=P9Mx0=ybWDv}YHx}mAixX5qVk&%>f943wRVmQzhc-#? zxY|$b-P5fug}#3n9Tdu=?)49?xhZv(EetVN3Z@@I{Ph_Ve~mBS*QaNe zOq`uWKJT60Nz6#DkB+x(z6!hIa3XvL;wupJ^DKppGzPdo!qUZ5B@^rQ_Cn`>TBsB3 zuP;=x7IAZO)OsqXaF=~C985g`x%>zw4+<_UAbm(yGy=cyQ&ze&vYJcG*GW=KEg13_ z7VdvO=A};~7_}(*Mehk(q+lZaL-{)e361_pr@Je-2i(|_WTzvHKC+R=B1KMI*l@Bw zQVy}-@G+M|c^8cacQGdLWPb~VuTi|eb$8TFB7Dq`EyD;GW58Ox&AY6mxH;=FXZyFj z@B&I;glZb$9tzT(BmU6(-PI;X;J$+6e1h2x{Zx$ta)2fgk>wk?7!v}*Dg>mF_ECGQ z{F-(+2PxIwIDlXR=%Yjgt&STn1DQ&&)>=DzOG23V9QOp#(jg~TeRN4N5C6np<#DF~ z9W_{pF4h)@BqA*8Cu2n7*RHZuLRi&F|Lf|+lb1Z*6O5!JIJ z%bfXB%h61qp@kX8J(_+N4(t{pV0HO35C<8f{L*0yyN;_|y#IR8dZ*T&z}wpGJ@m}9 z&Wbe~?t$L~2L}%jJg+Uyxm-U)FGxAoqZk6)0xe$k}hk zMmO3rp~+;sce2J)vkL^?K#RP2x4DQ}_w|#oU%JshydyuCurfy?lYiOH&`97JnQIjn ztuP(uxj8G?so~0`j+gP)-KwqQz1v8{ZEnA`TXpFZ4U@jHNA1HHIc5E}bXmzTgQNG0 zQ=6$@i!Y`jcLMqV@u+1u?)6tud2Im3-WfVx^CKEGsO$6wej>gxIYH?cS6Cp=CO4>v zVGP6M+S|tir-4P=Vl}-3HWrRXXX=DY2L0TvK>IzWi<#$v_wgjssdvOZV+=jgdyhGs zsFf#UaTJy>r?~14Zj4x}_oq$~`tH}U^p{7*bnJ!av-g6Pi{r;#n{}4DncTCdshHJIf@3B$HE*W=iWgL6?i`{{EaN-YDP5n4B6|?_8cGxK7+P!ToZt9ZgSo z;k}>A9d{8CYn*B_lL*a9ms-lSWrgVsElx~Ji^o=!t$2yh>YnlV%_hT)$5PYd&6BTl zuig|7{0@Tbo6GUbs5pnDU!+1;{RR#-uIqO*F7%D9+dQp4_ZU6F$vIBptI9?^Uf zEelkY&GHeeb@YAS!fo-@bx6t#53Y^aK#RJm{e;QuF9fhLuTfo(O?%#~@!~nAT2mJq z0uwf@TAgp5EjT%Rn2+7V#ZD8pqHwRE1E!nehcoPsi(?aN{HAz{pMA8!znkbb@%IqW zwb>4=iPtIo`88d%bFYO#6I+wkpiaCW9w!8)TM)xPTE1ka5X<+E6p!x&UXimY{KYa~ zf8W!>GIlpFI3^vE$|-g$-C0(A+d^a_?z0Chcj$eTU-II(s8K~YjkvKkL76G{n(+hW zblck42ua++eMH@ux=l5&Hl688blb|G$C+Q*>(n~00=5q~cJ+tVJF3CK`9Y0{NJm;k zWo{K??!pSE3JWR-_-%|>VAjyphbg@cG%n3T95cg(e~>_6DN~}aa`-2`fM|1 zSS2D%PPU6#Vun&XMzaMMb6Bc;nPQqnVy`zx%{nIOSUZ1p1XK>rtj=kIf~mjUCckwT zFDBgEy|{wXyO0_m{Sj`f7x5+7qT-X`;K{^#n^H7FBhLDqtZn4|H4UF7lx8^QJ!?a$ zPAZ;)?&gem6|tTZ`@9saZVc3v=;@L$vf5jFxX|^%nYBY1#LUg4$)UTw(&DNo(@kcj z1b0V(bPX=9`>&*F6vrny{umh0rPa$6*Y&uV!M-8E!8s*Gv?oMFJxyyWZ;6K!9UAKP z2gp!$=Zns62YfeZKQ_oL#bgtZqxmyQiS%39X|;IY^b=f%2~gU)!~_jXD<<#_Zolk+ zy?cyKmtSRt*048Uj!)XywmXGXe{n?Qsa)jk<;3XqBWF)Lvw_MpC$)Tihxln&_25mggp7;yDcB z_y(@Rnh4Hs0oiA=3DBs-+RGagL4-s*bJQSn))W)%&(j*Jzg2(zP=0oW2?=hF#06e^ zLLj|ovE^R9b&0|E2VT|QHjJr$b4)Ufg(v(&OQ}WQBrcCTMxpP&AvcThZaVJMzA!d1 z50Af@D26xyZ);lwfBz2P2_(L}PkBm>pTbK|1Suxj&tBmJ>O+jjH9^mt75T09Lbvb2 zhPAreA!97qQm%7c^fq%&1eWKlLmps2FU>gZ2E2U=P!_tzghqm1ML~6~z%Tvtr{By$ zGUnPWdo{1^s5nul@F+O{*jx7J(hpxtpqyiEz!ahP1WW=Os@!aHOl%Cmtd* z>mj#$$;*+Uhl=o`71w<^Umn6h(rGp?_W5WtOpN!U8_*v>b&%I%^l6TQZRzqdEuLt2 zNbv}5LB@iU1IYUBZeEV#W!|IH6F-hg2hP5XFq5f&IClC;=lMpbNvCdRResg^ZGH1h zFMR!qYSzT`5>AX?Bu@(WG3&s*+Rmu!fv8sg#O9B*9btV6a?BsJ%+d3I6^;i{At-B! zWwFEI<6IHtbzWRg*eM0{kF_q!aLhNjk{X3Y{aw*i>abWK4myB+k2)PEs^i*NN>N9NncwD5wb@311qc@ilhF{y9L3};Imv8RjCSZoIFVn@ALdAr2q zU+v1bLRh_W8d-=n(pxP!AG&dxNXIRZ$ga{sg00?;UFRojpJ`aWe-}Pp?pL=oKTEh6 z@n*5U0}u0V?fRxG?p&nL9~ejm_3k$r;vYDo%vBr*^cbQ5M8X&eN&s%zP*ZWPy_2p?sIr85(R z2g_a~UWI5vM6%;nTZSj^jW&KtMxl=|63!_~F`&&f^t>LT7=Ed^jX{jA-x-!UF_tTQ z$1_)%qoIa=@y=6GDsWaq{PpkT$~w$^-Q6q!ecSjcCHzq{)P<@@h(cYrlCUrx(bDF4 zD*PJv#d^zHQ-W9^LMRn#Vh7KRi_vmx-OS$Br$F(;eK$NMJOg7+6wytWvv4fg)l3+7 z+}YC&O@kY-iOkWAbw%LaPJEfVBqISzFUT$AEWQ2L=1tli=qQw1HBcz-b_3?KhW+?F zibUJKg-kfi!4Ye|%Y^<&W5>kq*GC?F`R~_U^_ScSin8!_2ym!~rW$rX1WL2+N>*c| zsT0X6MZp;bvPM+c39$7RtRD%#y_Wz*78d3~<*~=3BTFd-u?HlQpJ8nSh}0Bz&n_Sn zI-GY0gE=wFGpihr_zub%hvRMaAbG z=^0C-@DEpa+zBaWoU^}eM&lylLxSeXLvD%IHnFCUelO7mClU+Yvd!m!7dza6_%lh) z&vsFbH}O98-kCgl$-lc_UCS+BZ59oi%Ij;qc?=oH=79;eI3|b@)%>JxZa(x_C&!U@ z7d)Howt8;AI~Uh&9#PI;b)JR@)EzcTV=n5oyW*N~U_P8Vg3O9i>zQ1YFq5bB>ZwtC zh7~SyXaR`g{&r{^dL=@Z2sPFF*uGxAkn3jKD>cGiKwtP--POilmEjUEd%;n&kn0VY zM|E)UH8OF2e>{@G8G&fqJr8n5k6SUMn%m9mm{vDfeA~Mq7|5!Px0tgDYFrf)&$Xfk zu1uCc>+;XIVW7oWN2RwHGu<3X`u+@E!NSubP&2~VS_@5q* zgZML0wgrT9Rp6|BtMusu2U$?|XCuj}rKu~L^f8j{WiPhRjNpY-kG2h8bjE<~lwkV= zt|K0!u5-1+<|0lLHZr}%8@)17=m@(PR=l=)58h`h?RB@1y@JBR5hA3LGn0u7bZo?y zhx;j?=#ip=YZK{o*v2HbTxewQTuh!B^(*w6diqsv(@1Z6HT{~O+g7`?q*S~$sTm=}h4m8#TU*Zt4_;c{69eKuP2A4ylgwkUvEPVSCxElErh-2}Xvv44?Vnja zr3MOB?qO|BhKHekzj{JlJ3DIuUmwX42-Y9=;DX;RrlY1@OkV<+w2pl z57wwT97-{+#r`B2A+qDi>AgF}EmY2Msh^`6%-^g%i|Y5LGowkP$>u9w$^G65^Sxw4yqvvX z_BvFXyw3NwFVtH?;z=RIXm0QB&S{$ue&J(%-DqKYi;8B-I!afg<92%Ta7s++^`-vZ zeegIKK9+1SymNqvlXUg-4^EEtTDpO`M)5aU>ujVLXJ5tN1Uj`;(aT}xU!7TByl)ltRtslfM$1U9$r*Pw7BSg5KCHfB#6CKY)5yr0~&WF?w8JAn02(Pdtv5RO# z$74A>s8ep-#(?&<+bgQKLla&N8E^aqO(b5v-teu>iyH;FLadL(_-k$l$L{k~&UHM3 zs7_MFImYPi1Z-?_r6#m-j!wx!>$y5OsBGGU>EA2QYQ{1CcySNp*8+0am%%s;9hzYt zwrebKRfJ;C3vuOo!1QEC@Nd4uj%ojYesz~cK71GpT$e>=Zrvj0Zu z@hL=Jd$@AqV885Ex0pK=Ki8Wl9zS#MC`muXvpy-sLwto(8c{A-10qU6YQ1#bBDyLNg`gT zVjgn!=Vi=m*!sRxpssp*1ek2MER{$v8!K`Z><@;JTSk67rjo{+mp$A)&D7B}_vZUdc*Kwloq!ik(T)r>G?s6sfB69#*e&2YvmT^OsxS z(VuhIXh!i{!`y~|r1$1cDlE};S3;5B!nm8F4-|Lpy}Olh)k8vx)}GUzxPjeWaY-pZ zCyNi$5ufbF`2CDjg+{a7#}N9zgp1IO;KKlHZrtjGE6rFV}STZ7rOtHa&m<7Ip_y{ULqq=+2B=aUt*9zcZQHa3Krh9n7)5X%*|V#rH`^M z!kj@J=e2NpV0IW_QQ~D*6=pP*!!#xo9;_>kuF9He!kxr9g7WEW7JR_#uKS?a>3z4x zFA@t&@(*VLX*qOK>&au1;xmgItA#3*adaMS#lQ`RSHg`AVf8KbHCr))&Eorl!nqdQzNIY&d5P;EkCs~Gpp!$*!|S%`_#F7 z-2kukM5BA3vz66_9O5q}+$Z>E-P))Fw3K6 z{WvUzV4Ad`l>ZJn9w_+L%`6es#dY^tCSCx(*u9RE;#tMxWDZH;m(?rP9q(2LX+eA z><^kiILA-)l;fRq!h3imSQ>3TO|2i6pNNPYUy2H364rv3KsJ61)pJACY%YgiM{3qf zaPfn`PRGvkqm!^s3>+)&A9y#FdHp6E;jJ<_>(z8w4d0GrxK}6+<%UZkWM0igsL;aLd7AA-$ApRc&pTp}_Z>WX65$;h+sz;^5+1 z+Kr)AQ9|(G&be#D#?~1XTkZMy@)G|S8u7H`EAik8`b_hjn$c`XLB6OdXEZH7V1M7$ z@EgOE^^*j|y8-_Y-C1Ybt_s)YF7+N~q4#K>B_58uN;uHRW~}^6$@S1z$)n5OqW4k) zZ(`usRVGVxbydg8Jp6lKT`bWa>#s0%OoBgqrV|IzfK;mcgJ@NAeVzV9-n10TqmwMK zeu@?q9&Sx%E>PRZe&=UP%ZJ-pyhe{_MT;N?Lj6AQ_03zv!bd8ahNb!;u!H^j1&BWD`uDU*q4LJ{S@JYKn?Ze`&e6 z-#>_G%-JJhd0G)|7^l4$O)$cfMoDTghzVV)B(}@lP1b^VNMif#SC#VG@S6L(P6z-{ zl(B9Q&2ea*`YnIgL+6ginF@5zHtEk1QGf>2a*;J(@z8MJ^fqEP=yu#>e`csQ* z>`RVN$~r+I6F`}P>oXvBs%%CHmI3+)uv~xj8nE;0dgD6wYrP%>;QjHT{Q54GkLQQ{ z$4V}Q^Dfm7p46R|{=%j|u=mPtU8vE@0drsl3rMK*@nK|7HQ2z)z!1z-JfQ<9K z%m?g@f76b3IH*axZ@n&kpt8K^9%9)3o_V>K9ss3*r$zaVf^$igtCcj4;bmRN^@tk# ztFtCe$KPr4(e?)wCIc<=r;M2F==Sk70;vuY=oPoi)%K{0H6ESUa0}04EiAg?(3CXx z@db+DV3MLOLSDE%jMKA~!9bogHuk^wlk?Q`FOx0gAfg{nZx9Fdyhh!b8qF5y2gdF# zy4e!1`fz1Vpa%<^jYgL-kDhph8yVEa=K+JB9->|*w)=5RwQ+lLsg~!c8<&{xnMc%c zdqHCG_$~-^Z%23*cR0z(CTYdU^p@j+nT_+WjNA>w?rIQ3RmgTv$5v}&$!G!_T;$Q4BrS1il`F_qmsee zW6W8dR@ndBA~CFktK@F9jj7Jh>&2$8WajXAb}{_b%blgd*ARvnooq~VvP79GT)21Z z=FuWk+ms)o0YCcoKGV_r3SlHkaTg7Pi=3CFOsZ@i){3?3eIQLxIAr?puPQJI z;#(w}5R&#*`P#D0d5r4KJ#pE(o%|-!cJn0R-pTNnd>x8P+l3pp&u%rsff>`Z=v9*d zk%`SRs;hL61xXF@!(%`eD8?2^pQsJh_)6aqf^2t6Vf%09$n}PY2{K5UY z7k_46ZmayHV?3*3Hx>UOfxq@pEQ`F|qhZXWRUwa*Xu9rTUV{bOftOSZzNMrsq5Ye) z$wwY^@-!_&B!3&;7d7O`%Ms{H(e3}yaDdd;%As?&g3{NsV#4l|by=2D=$!BRC6Ae1 zY`0BSk88M1`R3^+Png7;j+j_tupn|fF*3cFbh&Xiq)s6_W7vBU*L&xXDwMzB*Uw~` zg2?(DetsohRT|@-NO3HAYw5O|9RP!fO#qS5kZ(nYO}@oPLlaR8@3-t(5_Y=ib_v?2 zz3e-5Y33|;BqUd;a__O*SkAyKkoHj%vHJr%I;|HQ6HPcFk+kd7!bSMxn4oa&uXS0k zeMv~^k*=F1S0|_pmc-&3?ecMG7@a#0&CS=P2Z^MK2IVLZ`o@tMf(ZEg>YDHANSGnw z1zAV-3mwL`n!7|Ws5T+L`dVK+B-?Sg%FP)(#j9qr7dp^QUxq&+NeSnkQ1;v^V?zAn zy&yjC^~ouz;2a$46gFrsX>zQ zR?7goilHGD2pd0<@`q?ddGnhl1L54`W^>7PYOy?aFtspBdl6)@P1;ZF1jiM~d{UdgL)V!$MuzP$Um#$kfXVb>DN z-fdyXy*Z#6l<;__H|<3U4*xK&+s0}yqF;59hAFF96jE5opdIRX_yz6VA3Mq^_EY|# zhf{fw4{HDcYBwRk=V}Mv_JA5}tp&zD68?ueN?yMErJH)F&KNBLjY-DuImcUflV*{T z4G#5*;<&F1g_(I1$$S0ScU*WX;=;Yp{LRg91mj}btyhca3gCjKL~U>x2lB4o#WiDUpkoo_0POJY}JGwv``P_y!D-Q z&>q`OI8&8B6yn>2V z2VJ4QIx)PTg@r>iBvY#pksMiAXB!#Ua$F)>QQ2qC0Wpt-;?=J#IM6srR|>VO%v?-) z`Mw4_wqB>*1m3;Y{67;|1wm1SfC$BHEg0=3c%WV zA<0>}*bvpjgg~1w0NqyyWn6xoR=u0;%9irJ~bogtNe^Tk{L84g>(UdbGO6Def1~^Ddo2;M8LiUArpUb3iPjJ*SC!+=M{y|(zKfOjHfmZ3D#_z2DRI@_oXs8u;F(y;A35tD8{fXxHY>$ zCT=n+gaol?;)gfhHuMaHo@P)lp<1Nul7)tfM-~q;u5IyT^oqn9%o&nrC&6)RisV|Z zYwTZ+-(B5qA|h2y?=GN|u2ATDgT;8-P9f9X9nFfim$>&5QStAON(lFkx-rV14-vK% z+k*Ns;wCVY9}>FE>_ql~iWpLL(omT>a|9Mg%xy&06k@%55OMW+BA>M?|O^kR*a2!VHX&_t<83Me1aGZ1^1&6?C z+qa}h&N|@<&z){gd7fjP+_>s#Cq~b?zBSo;x>p0U(bvT~%9&KC>t&5RL*3r+<{Htm zyHIVAdTpD@&xT(Tr+g<1Qq!+%ntiz0w=EC_PD_J|Pz+x_PC*_Oa5vVN&P@0OvsheQ z4ZpKUl{sPr(m`QIcX|tLccW#{Y33;RAU%J16s}HGy@y9%VGNi-zz3 z4?#9h)c!*UNO+Z;*=Uo&s14YitKg)m2Qct(?jUfOmq>zFV507j(Wj^ zlZuSmRftpRUG4frMi=qKkZQkGS!g+8%*1f7_Ve<})rgJa()&6ZI_jnXmM2#m#wR+` zQ3xoHrIKwLF*kkOmT#0;y|asD4zbU7lqnV@R#?B|pA{FxLo@(1AMN~@)&tk@fpn@d z>kGT+xIGHaOGX9#f$yPfMq=u<7+j;mAtvAUpy-TS8X*aif~5}RM2D`QcO^^S7h(>& z*t08Pfd*qVXMd^Y0%wGs*r4azdPO?8H^V(T>h^q-<}c!c!9}~huLkxNK0b$u9AT^`=o3poKUmh#F_gD+3gwOx*ICeXiplocC%3x`)f$NN-ns1cNvcbI zTTEy!{pelez>A9Sx4yN0+15V~gRrtDAL0$sgF*+xic@I`32yeA;fG1Qzje}@;d0S$ zZ2(6 zt}8)BW6o^f5HpsYNZK?l4QeH!ilu>c^oIR)-DLAj8KYC2!E^?a`0gBPcH18d$zB8K zJ)4e;o#BZ@Jnj|oKU)SSjK!Dijeb-iilLrw36Z3c$u^TO4%E(w8I4hj`RT?Sn(m{n zr8MW85q-r`y)8ZB;tp&UC+*ro>aw*od8joH4#u>V{K@j502DvC!}`OCVMPKOAbx$) z5&==LTcjB8=ouXxZNTYpqf%DN&&F6>@u<)tA#GetiJah}qP7gaLTC#4fSd=MJ=b>* zW2S11e;B-He?e5iNhu}FuSA#^0k-EGs7oVKLoi_)FA5YFr%Mxj@_qan?d{&+L?@PU zqf_bT%P~;OjZLAP{SfO1_4~$r_KO1}lU|OCVt?ls#c(sIXKsL1K(v^T2o~+Gntyyh z@n{kX6@47K6A%qhMuZ0g{0JA37huYM?$5cvfIGs8ShagmkR_UC^NhFOysWhLM z*4ZrX`py)N746y`IwxWx1=h%opF}?LH_$gfbv)?VD|~l%T$koc3*a@I_$lR`95=Wl z@8J{p6Qj3ea}PN{@ja@+NoqK6Ye~L5n}PNl4SiydU%>q^Hq@$LG*+CkcFK!9UUUU~ z6N1NINgHOvl$ME{*e+Et;@d>4>+^v z?#epRX&5BUQbvB;&gVgg#Jb=C^eB353J)j2pJTy2xvgtk zPBHo+mH5o=d0g?CX`~BNjlEjTOoIKOeVgH1$N7+5ZrKx4gK@6ldASEs_V_tny z1*b`NLa~$oi@s5b3Ah+th<7X=%p{w7+3ZlR48q6d*&7J;(4rwBQSmlK6)l%BC{Hb{ z5cC($jfDqXNywJWzOpphb+hs03Bpz~7e#|y%sjb_7u+BFzXKmVza{uTvNZChk(&^a zp!1-GgT%C;tAYuMl*AHMQJF$#kV%M$h_r6J+c(UwatCRk42;$W*&1^5VswcLsw+8L zv5`30)y9zownyipT-e@N$s2~h>0%Kv9mByBBMx;(0QCdI@9Nb2zy&M^5bA?0ueV#= z3V7%%TR=&-kh|%$>a0(_R+Ix}L8_T1NI)i%RWY2pJMDvrxIE z-lWozxlSS%-PpTncCX?CFRYhd67YaT*t{w`?k$R*N5TeANnZFr;*sw zrXqR%9x346N4$fBU%jK*i2n$^3zNMx0s5$8j9x~AjXaG!4XeS);H1)X=v2XCf;ywl zLPnvx*ht!aBzxZK9);O+_~zgNST%nX;hB~~Gf)+)dVMSjhDRr!t(T%*-D z>}rEHr#Z~Hy>bnf-!gcJ^c)r~>hD)6if2`SX2VKg*oXMrR$-aKB`Z^Z72hOfsx7i` z#0*o=j<{N&bayFNh}>S*%N7fMuUBq;JD_awe#8+HWe3Y4Az_)9r?*{Q;I9%DHyC+w zoNgj4#wagX^Lw8CNsWuMBtFPu3u%9mARrR2Q3fwgK*cF z%gZ45FL&c4ro5Yt$m-5a-`MN{ih^R0xb53wJX{4)8{5~%9{z`0X_JP zAZ+}KouRjSTI0ukGOhZt@LI4>d`L(=Zj2<*s&@x!e3tPq+LT3^xEr_6*2UNtm#|Kx z`n(2g?&nQWcHpC>yNe((05z*Wl;qVP4=uS7Z;6IeXbguJT4LK=m-6f3HO>$Z@StYM+M)^n;L+>$A)R`wRYZ#q5+q;sZPsmZP6cJgJiFg-)>@NBNx7MP0}7B(DgFzh}Okz8c zmq!xvbX@*>BXiJPmpD_Snq!FmD)~uUj7sLbtR^K$#lh-@tZZkt`re$pULwPei6pQ6>^43Nn_O8b`cJ%yo)-o?)ZmY1=Ym z_YAce0`J;4nGng2wFTx*kxpVFPiq5f6<5ox@nf=*Y|AB``5}C0)CH~ObkdE=z>3ic zeuu!|!aW;_u%>YDZ4{c8kkrjoXwxs)oP+bbXS0ye=^IClOx1Uw0U*EAOvSkwRdZWmyJ(n`v;2qGIKv zr}22A-}B_IhUegpM#!i87ip!%JcWgO_iloNk2&=Tz!HNs*NB-l>(bjSmCoQG;8e!z z)PLMQr~|E@9k7t1$cYpXUHSZJ4i^8{3&23`nvlfLVXLFje)ip7^w{#@d2oSrXo2)S z15fuAuTZMJy_gy|(K4b*3=ZzWu=}Zkea+9Kq0B01RKhn{{Okkg>ardae@+xAUeWwK z2eA?X8ouEs;I`gzG4ER+LrZ{C=No$7MKM{YMDb&)U}2t+>4$(xIei7~qQMLzK5SFj zO83#>6cu8_@SQ+Qgo%4_O)n(M3Okg&NP-MnjcN*@u+*Ioa4}6`mWyR&e@gJ6WTr85 zOZ1X6)w7{_oxG0tQuZF%LX$%}dHiN;-M1v!cD)Y4{gJTq0$LzyN|KT|;{QtV{7id* zzP^igMu!-{%iz3aDL`aDBfAl!xU8=gih=IDAf=Z*LaNgtZ_4cmWJpggXdk^w2X&wR z(&>9*zrHRVD2I^0&TZ+=?~_{0SkKRf*-+n4AemNCGUn5w42~(V4F40tH zCawiLylh28Wa$W8lEXkSa-Hv+M)}HZnOLtlu>7V_7hs*n%qq9c&wqb~ztJlac!RF9 z`;KV63DfrCW)exVY@F)%-iJTpuR-JphbO~)O>bH_QqZsqsC8m==pIVuZ7k{}$6vcy{O7(-84Oi_jSv~grpu`xMkWpc7A$EtVNW=0Dd%{iJkB-t9a&^gE0XA1KWof zuI#uXa-M*1ML}WCGw0+J!}$Nc0o639m#`yGxw{v`ik8;+Xng$-VwESFt_LA8Y%>#k zb)gp%EE|i@fN=W%(5Rc*wfOL0U9O7%^lL*YK+-$s7@Xn!zYs0m?Xb;LmB5&?jusjj z8tC%Qy*nz}s_H&riv5QRoq@iC2OaZ+(qb9Qh~qY#`Itwd^RT+F-~PikoF6ya#$wGA zQ8!F@(JxJy(E3k1SLf&l;)FZoFHWTpn{u6g+#t`|{h=ydRsv{zn{x zcpjriZAD5jz7`%8(p4Y^W|Ba|+b>V4#Cxc6{LaV!O3?3zfQ(_Kp;2{I8brUSTh4-mR1R zt}DzZE2`oMAa?Knf>!_EXdwT;4yv1i486T6?FW|6@lNz=4c%-s0to zi{$83vc6$EY`azbd_U1n{f)?(eQM%7^Fe49;hhfH4=g*sWVG^+Dbak(2A$Fu7h5~a zT}KfZCnsROo$}pKzJrX#`d}!g@2J-6Ov?dsbeHbyPLSGtC?2m?vWljVu)N-SJ{ajc zITG+6YlmCR;DzY|K7sP6tLrMJ0Oy&vK+NAvfp&02`Ff1+@2};d+hW zoM^yjiF(lj0)@>P-UIBEmXKd}-B=-0VEi_B@2i(1e5`IGDd{m7)3hc0b7l7FD8oJh zLCajxqw$6Xsp-p8$7=0n|389m|FONs>rJlNXM#98s)N(MOq$W=bxd|_M+Bil>i#Zf zwetBxkjVd_DpzK{_&JY}Woy@+zn$&pt~_BJGuhLr@qK;&vgYF^FCd430jRh#YswYl zoi%>j)47QBE{U;E|0w<4HYWg19rli;714);bR7Z@B5Ovup*|=S_&59hv?q+l8NJzB z>9?s0(MQ~X`Nz$=B%6(vgx(}CCubC1TiN4?vUmJD@BU3%*hxefbw-1s@qUNgc=X{W zd`|SRQLAyuKK*+^Oa%aF7Q85v=Jp1u(h+^~(U^-;f!sKx0{r+QqocDCQ4S99fxFnK zc@b3s+eE+WjjUsD{z}~W2G5{P272RL`YVO-{}Iz-5V<0uv3`_iV>ki=7`d0j0&;oK z@KC6+odn4CyLyuf<#nuZT{n^$yaOyY(XLeYA(h{)MYsBcY{j3Gu~Gz2xAmZnbx){z zrS%hV@6sGoODX*81d~>S0cxjvBERq5R3s3R8p={%8y;d3>?rv+^C8sTa0FrSI`bwg zKdF5dytl#SuG(=KaI&CY7g~?0%iAD`!9(bC>K4cK=J#GYXgxR-4>`L@d+_YI&`LF! z3mt(Lxcg->{CpeXtx>fvb7e@rDcQ595Pf4VFXwdo`@p&hRQDMTv6)Yg;uAywJ-piG zba5t-l$+9UyJpCk9~UR<`Q9&(-6YI zdm240WWxP$VsV})UK$dpkMujZZ(GSZ@l}ZQ?VeT!<+@+Uk0ed*{*Fl(d)pNRB-~Hj zgwjiUu*H(FQQ5ohW@oHlFGOY1iA^ewBnINJx))O)kM3Z@5EBH;!*E3coo#O#)3bvT zt&%3r>C9<7T8i68$dGISf1BR-L%SA8!0v^hC zYfm}cf9Yg8{>ovsn5XUdS(S zkAVnT8rl0)PfX$8@Q~NMUc#C1@k>~cs6k%{nNz(g^ZK69m|w2GVS#IyE1sM9X>Zx7 zfQK;c`BKE^9CcO<7$Rr^=SA<#%`%njFK#N#?JZG_-oz@ytL||}Urq_spYkbW0n3rU zd+LYEdvuw=FLfWBGU%Xu`r)bhr5MeHXbzH;`SUFcsR;W~z6`fNOp}AKQLqe;LiEuI zv;{Ku!EpY@i~u?(=a}Qn9E|AqzUZjMmF`nw6s!*6ueO(sjLmsyu2qu|-*yGy%+Q~D zwJ+aco4~+OS*axT+hHgaPyO{AaS~hpn z{nKA;;oxuwqwP1JJhf7JcZ&!G+F>nxVF*r^fo?N}2I|AbC%v+v>P0PvkpkF&TAnZ98I7=vwiU*?0%iNFNvQmRF_rB{<~r z0YdkLM`6|i@*9dIK({i_QkYl^Xs=Z4-T!pO`&klelMEiLjPnV+i@NW3Qqo*%b0AS{ znVr}`n*aA`;pj)X$tK!}(>p3sjQjKZRepAjwe-H9KdU-^-I7^#7F%usPS-4hGKWjj zw-3I5A@uiPr+`NiG=}d=D@YiRIXYSAv_0HCT(Pk_EQXUThikqbHn^yRJs`bb9fdQ; z?98I)0u7yvC9Z@C^R?pwq%+fIY$Mv%s&5Se-!;xcWO3I|_Cb#V4j$|M_uw>dv;|Lm zTOJ3t<6XL~!0}ZK+4wrmE5W5~^E6>p$DpV$o!?cSWN-i^A-q@sGOe-0b4vTMEWBZ* z1jn$0p{2E@kgt(s#CB4HkIM51>_#&F|Z}njeHrDhou6 zX)u!aI7+HSe5&Vg9~n+!aI*G80;qe(fgN$HVzOjL1a44yv1V$9ASHTF&;v8OxlFochyKLf_^#;O@DT4^p7GzXhP* zz5<^g3gD6HDxc+x-+#TFZROf46k?w^{P``t2^7mMFdA#AT1gQDcRAxKFAuHDSrvC$tBsi=MSo8$8a~P820^)ir!OPJ@#|}UJ6)@T zY5`LjW$uJq8a}Nv&%@1We;z|=x+_2bX6|}Lp4zO^o|1N%+0c7;H+RP6Y_YNEMfLw+ zQ_kY}-b21H)gl{58qViyIV0Kgiko3|K&?al%hlprB3F#pWwrWvP*J}ALCqY>EW5$P zm}ZNz8K-lVA|6sV>;3(;pUMP$n^D4kn{v^x)wD19?qHgLyrhh+m5x>`_x9AeYiZ)y3DsqL(RtnNUU&DsJ^?g z?hxx@zE5a%vEzV&^ZXL=l37jvWMCJU$+F!gA~2FFV?me8De_@Z1pf?bG$VWGQ~aHr z)*CHMHW;Rx9s7Z)=8HOl6&L2K-2ArK?5CijoiLgC;lnymiN$O6^QmoF>NXUx>IDA* z<+c_VsHn1A|HWsA!~H(nLOYJ0|1zk{;*e#obrQ8)82Z;%nJ&1`5);Q(MElroT4S&O zV@o=pq1lRO)&Wf<*ruJU=1OA|7u(yOD~BE*72wd?j^86<%&2sqG1f`+{u8w4+aisN zB#-4zv$+RJOti`gQ7Q%%X9ZSy7aU+SU=<%H_6!4exTcOZeOY~FDCW^0+-o@a3m@Q% z|9Te>ynyeERo>mRrxh1*uxe%tF}!q4_p}03Q#MA%D(tLK^DHt@sK9@$ndmf9EXQHz z=yy%4wC=qIZyuN#;Jm4Sh(qz8I3mjTcd#3{U8bVL2%^5;o6w9|a(WL^o6DDt!vBPP zEIg>o=yqH zqmn5#p?lM~fH%T#vA0j5bKoYxHS^c}95D(4fNw$2B+K!5HKlgqK^h2saGXm?q6ttI z3JRLAS-T{R*`tKPxW02GOP$|c`?z2&tXKK0Y>NgED6n9S0aH;b@raMc!KgIelwR!mjG4w7j8x*GK%vq zTKqGD15^|G@wiSy6R}a4&wwwSfKFs#2vLfyv>Wj6ai;)9K)S!gzm9CURm9>+?>_4q zv|ea7x;Yu#1w>m*qB7}>>U~SbOGaNyQe@p?RU4ouAc>a*>m0rgPdX@u*rNFc=ELvy z{Kx7gK*}Dat@&knf;E1>)`^q5Vw#D-MIE+tc6yePg&%r<-w$-qW?W`+&@mD98ke0R z6MAg`4lgA1lBa;e-$l=nH1Nry>};tU5%;1F>joZod`jDs zxrs^NA`~^Z?N2i1IHc~yi8;mWy%1*7@d@dbE~RI6M)FKuQ6*aau!>nW2Gb$95{eK-_|&xnvmx=K~TK64D@}Svq#2DUxBAG z!)gDqRun8kronzGOainog`=p`TYFCad(&$&!81<996aU;NA^IzRAn!auZ z&!yi0o3;_06Z>&>U(i>(0Sv6OyX^<3beUYFx$b0J7&3{31{Gd(0 z6M^(f5~KGC7_!~60AL>SJl!akPsHLhjbnLvyeTB=U+8se+MgO;@{aV;RKCsU<`wr* zF#^QAy=<*u0EhPu_p}%zSl>Fyd2z+ezzU6P1vi7u%v-K)3KaYW~ll2-6{F^bTX!>gO=*VSo#yKg6vP`-@k~q|EBz6vSE5(a2vxK zPn$;Y?-%@3*b2;odp@i5tT+IMzqHRQa#t{xuF_iKZY1De-mH~$%`v70J<@pPm&>n* zi@dZy^p!JI$p25WKlPZKp0)?afU=Hf?drq2IN(0g`DPrT&9CO+UR-xOxB7cT@mPtv z<`b&mB3G*22F_jQ`m)h(g}8)_?okP(#gs3fW+%s_`he0z*jLSMa?*#_M8LW40io{iFG% zgJBM;EWFl-V_TfyJE|gM>^uiO2&D=~pI5Gvl&Qr?ozQ<`mYQ4Ox@!j+^lF${u)@*O zI$Dk~EHaqUlJV!6`{cFj&7v~+4MExfTo`)nOVtt1E`U>>+Ctt&XIcXjS~7B#>D<%l zs7GVq!d1~(hfGFIe7V5kuvvED!C4zuqMD(#i|-l1=F{@7l1xhfdI#b&*KZ_&t6Q|+OLwMa0L6T9$&uw8e7@&DLat^E`X-1tWyby z0T$q_^qEDopT4W*(ebJy*J09pSCP-bazxfRE8!eAiA~mOYTBz0cT9A4F$v`ba~Cox z8Ko!TmLV%CTTo5CpJM})gA~mzHWs-CWcssKA4jb@67-E`p!Eax=jn&tz&ihcylJ;O z;6lBbsxPG{0@MT(#tL1TA71NLX@i+E;1%ugo_|jZy`;+bHNQ1%W#M4(xR}d6>BweM z+1ZQE_=t7#+L}dYm6;0bUvG0sA=!9<6Yn?GbJDTIYXJZ*&ybRi(w^mK;ECZ0PlEWJ z$Y0UQ_hL^2Q<{6c+pW5~{Kf#W4y6#HZjp~DBQgC&B882w1Sd8^1CSTr7{5J)Y7{bv zzyJWx_4Gx7pOVLgH8aLv&u%g8vFcqt)JCF-=G##yaWGHI3;C~>`_@PDm^{(nY_0x? zdCyd(%($mMlRZ0*UkWoEmFLB#t^W8IW50^-5A6UL*gKrxD;taYfx@-r(6GC$;a?dW zy!IH0xIF47KoWyN{K&6};JoPp1V@0r-+S7)ovQMw+&|UFnsb`$>t+*S79m+c=h)7l zw15e*J8V=j`u;w3J3n&_A_xGA(x&J4NH6RZC_4bmlvQKGFVpyP5}2xHCsFWG0VOm% zDJOMKUb~(hM*iVSEz~BUBlAXZ-EQ^?DFx>I<&?GxHVv@ZM9=$D*R?Q4F9p|bX6m0U zk!Op1=kr4EIsTpDR8oX#GLn6s)p`n!0F1TDB|uT+DZ?)~axRp-rt4~ATN&i7i)RcMS^p@Vw6`1M8s%c9rFZW&}DMD{tUZ#JlQ8z za<7e_zUWd;!bYJ1uxV2vSC0qy>_;*yzC<}29OE+((4A^>4Xj9=*8kv14&078_Y&m1 z6zR%>UJx^;Cdsir^5RjH?+U75i?YPU=VD*iyjBWJMT1#IF>0-)7#f(YG#HhF zs&Hc#m|C;he#nDs7KmNsbc2mbhcIapj8Cm74X({Iq7DpFv8$c$-fSg$m)b^ggm5v!GZA!&Y9WSfUPAL?zW(_9)A0G`L5%QaKj!dLIzeoLuz7%p? zear9iO6?gVwNc>3+iPbV{qGNiqW+O`$k z`(#Xy?bRr!G!+Yc&uBAi9Hl+%Z$fm?v{PceF39)=WTj*xP5QZ#?asQnmpEHMtW!eD zKJnFpT@6^QD-#XfyK@OY+CGwpy(V+gf-Pj!wYXWbqk);_wRM$Km03$T(kJh((2;@9Voh(Yl!%+4+T( z#RNYAbT6#vmpSiK3KlI&cSz$)Fi1<5HYJfkjbycICZA=o4~Gl@9Jdf?<6LW}d6bN1 zkUni~d$UeL)D7it>8d((s@lb)K_V&Mu%3r?XmHZLSH42YUHRtgJN1UowYC@Ao#j|$u!;_=&fh$N7BojJtZb2XSxma_)hzD)*kR2h`3ax zq@UC>LH5On+ytyQ&^7bty}hO$^wU^6B-1cxk56O7;bYq-@@KCD0N?HMg3hzU$$R2( z6<5fK`@2ItYBD84!giC)=+51$^5(e`6e>z*%;fhh?$nVN-k?69OPUZWKl zEG%O()Uc^H9kUDh}%e>SLGh)z=D5%88KJL9go`;@jXe1V0i! zyUn)QmNz3TgtPNI8cDu*sSy0MR%)UfRT-_vT8U(L#sv6IdPhbn4C_OSAUO}Db80bd zI}Odso5l1??jn^>f4Ofj|BXTKJg8|@bLH?fvBx-Wq`HJF5v;krYQgGw%HMLJGoD+f z?i9sN02nQ68E^Q+pmMMmRGLn2*d@fq?|Sb}9%O8ZbuDv0icQs^YkkJ!y;sOb`{;J1 z?aFd4EU~ci!a}RQV-1v#W|MkX2?p=H7fCcjH;(n`JK{`07L>|1G%Puo)PQ@QV(}B` z>|}UlgDP!K)Autq+*c$CAqh=K6Ii! z0;kV;4wtQX%4R0(15?cnqZwqwhlV zd6l@6oSr=e-Izv)$QZo2wWehqyBTe#f8$NS|C4S}tG*A?gJERXn;0KRr(%&6jH$h@ z;X5$}+RA^%x-ee#?)4S4eQT*9qP_=YAis`U% zAp+>SUyInR<@wrpq_A_jcfqPOJ8z{FW)7a@PtILv{hMv=D z$@8n_+QW0;Al&b5L_$Nznx*hIx3@y+z+uY)>Mn|fTw0JX0fLjzUVzZbKsY#({~L$x zJq=Px#l>`D0YXHY!w6a-d%lT@E!0;jevp!%)2xtis*}z+)PQGAW=7viCNoQ~`QKgH zC%lFNx)kHjF;3>ar?7_DDBCVt}yuY z7DArEpgC^=dws>o)GbS6p|_TS6A-Q3Msi$Qp4_ut67c@UT|KQ~C!cDpiqX6#<%O;_ z{-pGo?I%ZS$&b6}2=_zl;%3$D;-6M*)k4#3k2lRN?yEmN4l9-x5CE9zw}4sJ_@;Al z5`!FJ^G*PG1kjXMAh$qDtYk zxCUO_bg-MyEukb=@~35XQ-RE^?i)+1*AhTxF>7(-Q2KCBb;7Uex6Ep5I#O$J+YkU2 zc3fAh!+~-BqxFSZK}Z1P*PHvcnTs?D%)8TLQoHX3yujXM(MHI%E4|s*3*eT3+coQv z)B**MUd>XM)BR=f>;v!+}f6zY+dd_rhUaE_*C4wE18*~?WA7p6X35o|DDInq4a+JT2qin zvc!F0Y-U6e9D|MC%MnV!$^d%kTI>T5zUMF@KXe1H(8dd^EKfGw+^3GY zAo~WVz4LBY9sjFOUHcu?KIadVb%pZ^cHy;*GB*PgEytYmy|cL%**d-|J{l@(XG%wh-DY)JxwbsXl955SMfI2F35B&QV9gn_JN~ug3DB*0MO<>gCI8;X`b8drib};;|TW=Qv8;eOV8*NiangCtZ@>68W%g=yR*WR3{3{MlM zQ+v`V}6+Fn{!4Bt3$IHe6x8O^WmDMQ&BN}af)uk3W}H1 ziN6Pw!^Q4FaW&Hp?-Fd-0ref0I?Zr7fd!BWbRt_|e+FixnOj4GH(D0dZfe!4*XJJ$ zy8bz>@^l7zP!ih9^UVY`xhMr*$jNn1XPst^R! zpv=v#Gw-YQqo!7&A=6{+EYl%BJ=*m**jhpL6Yx2tD;qrIZHX}p;Xr-NQz5vR?2F=@ z95WIV8}E=(1qI#IC8nOx^VqU@8xmX1K0E6}_*6Y_S3%bx`mBS&bXIa<1K&!vbdrnX zy+^+6=~w0+kCKF0hcIbN!pEl^gMRK^&A^hLrn}RHoQKKz2O4+eAAG&DR0`Lr{SG~= z?;-$E;?=F6)t^Oo`fctIsol5*oF?*jSam{1Y{Z2J&s9M5QRv6!?;o7xa*GjPrt>f~4J$0Vx(Jt&ZZK>|)!s?XoDeuJx;Qvom3 z>Tj5IaVSY&*VEBcpHQ%ep+)QRj#utw~rPzExuxzavHkbAPA0aIF0?QE~b@kFy@SNtfo<%HGJ&-%O^ zwC%8ha?+!aZMg8#OosHFDTQuysRk%jj)lf0TtU+hM-Ln4s4hvsVSO3@i9cY>d{SmX zm1rC^0^=(fQ z&^M2aG{M`QT?r97uTkmw$j0JP7OKjFV_5%HUdl~1ga`r^d^DnyExmojR_zedT^_r~@_|2PFpcP9lq6V{j zIu$18{n9uLL2oj??R>zSs-s{Hp123Lc-LHxeVf7ioM8p@dw{05q^AqJO-ZCe3IsFR zqCEinZrx$L&1}EB)RBqTXG&So;6}>m)O38$p2j-`O8{sr&MaMg{Kms!0lxq)-XSDc z`*1gZw8}0m`Y(_3U)=?^tJrUrzI+Ny5|km0}qM`#7C;pCVDR~cXviBZdLzP@3s-sF1z z_HalAa^u>drljcvulH?kVBJt_faZT1Qa!&~eQ;_iUJ&L@MMc1;Dd22PSsC0Sa;&r#1uhhi-d!9OHJJhX3B5 zZz!nOL{855r?!OboJD_jP8|EH4>p)v#-^4Iu+jS~c|6)&1iKcFpfa!C?aCd%;9OXUp5s(H1oQDqY~Xo~+olnD_j1sCT=+PsgaU!(kC3fvY#< z?LF$N{n`9!m{(;~G)XW3HX+34RyT;G{U+p@d`c{PL?Ok0BCJ2dd-iOHlAF>6C)XWr$>}r&Nn6*{a0+q)S|F-V z*{#$lwqPFd?_n!$I(WVERtx(o$j>Y;qXFnS^{j-2#tS@IY!Askx)TJgWO$Gka$oZMQaj>f5kLKH zTe-bYOvw>Z2LL63#O6XZJ7^0p+4U!~^Rs*t(ox2O z^(s^-n;6hl5YTi#_CUj6^wrEt?p2DF*QjI{TX{Ccfd{cl*f#N#zuH*ptJ82ZzH)8? z{aAl$KOQHJ-%WhRs-Tg&|D9KS{dQnh3Y2(g&qwcEu3|p;K@1QwO6Ozyj@&Zd1zwuC zJR+LjuL`s>7#%@+t*)l8pB3qdad}!RyNm%$9$O?AJ*>s(AG4*D(bTW&e;PT+Lc{SM zMjGa%DSY#ku>^&!T=^R|XMZ@a8D;hTH+~dH0t((+y_ZG>nb4;SW2j`V@earGLbGe0 z9_^I2E5fVq;{mG(ESAI>A>&?FO26$YTZ+rJXF_4_Hukx)ERZm`ZW?a>#E(>tvAJox z_b_Rktst;^y45aO)Y&hU!i{{o(8ldFsv+aQ4*aX$x*P_hy6oo0!;?pppv7KDTQTNs zGRie#HP~A|6!4T>b{go zz^ugv5XJeZ;=fgD(Ln*+6%U$1LL-8!(Fd2n(+hx;UjUn;mfEcp@g_xO z>rX$7=&_}C&`C=;wMS|$V$)nfbs^Q+KXfmOEX?^?tJmL4#IEZwlT?<(e7US|w3O;& zovSMKb^Tw-_Q}DRApdQkmOpH`7K*X+%WcDSuDbnoJEadw2-V^*t4F)?-mmC; z0{4^joE>y>Y69(&`vkj+2NA7^T0{a)fNHbG*YyQ#u+8gkft@dYY{A#*ppquNF5huZ z`Fh`!NOLo`z_PrVB+PCop4|}n)2N{H>$e@hbmDP~W~YTh2IKpktgmzcv5PAz&*f48 z^V9^0Ze*U_Ln&rN+Pe<~d*#h|!uuRj#SV04m9Mg6bX= zC7{`+bPXJ7z~2$?a&e%WSz%%j1E)Tl`h?EY&wvSUEe@yDEUN)jm5uEIBj{33<(5h2 z*Tm#gGcuY4nA9r0m!}cv()t!10t)0$=mr%nHIXBNLMJ}SE!69{mrHDQFof(dp+f$M zOuTt{ePT>LLOODnSd9Cjo?UDO47;^ZDhT zpGZaPURnCd?3p8rW1=n6?1gQ=#7;{&)C8WAO3|_YRMN3+5r(y|Fy#$T@|3F%fBK9J zY*=y?X>U3fU3<^fMvh;={Gq;NsuG}ABxqiQHM^~$n;c(;M`*mgjHI3!=iJ*&wL1?u zj8?~+W32CJWjqA1o*q;I$FX6-wb0!A(;Py_`lnCNPG#X^7<9!%*WPGePQ}XJynJuG zP>BoxAE!YFrz;XtQsKtn-(}s`H85)5irp6^mM;I${uo(wW$`Wqi8a*Jn1rZ~`}Da0 ze9Clgx<2zV)5wODKR#vucB5D@q-&8HGBxG9N{x|E@892lqnEr`MyC7qYvISWayzua z(|pbzpz-&i^bJPoy&+(c!waVx{YuI%@?Nd!JzX1kzKK|qrm6TYv1(oOqRpekrWOG; zCmNq-dwYyvl_p?oyw)}Kkm!+4RlU%Y+(lAv>aQ0gNt26r@dL#Od5sTNiS#9^c-P? zuI1&-r@i`a#_J!w?rPB2oh=&}c!&rT)%YZM=HAW9faFCHh0#IBLD)ouGDDg zHcXWExuU=cI+&RRRi#DiRqjvcmV|IDM927VN(M4M-v zW|M@?0;OY%-lR<9+PQ!ND7AbUHv?F7Ox7|G|Ae>6V~h$yZ)f=lqoJX#h!KN-M0H|f z{fi#=!G26Rh~8b{Y;J9141J`v$@u%5oHA_1)na}tTLb?HEgCm|u}#B{#z2G{4>$GP zjL=H-O_13TvFX)Ts9KZ>jB8&0oCK0&*nWlB!-0E+2QTaF2)Fr2btj$)!dZ(Q^ydU3 zgUHVHbr%N>jK9y?<(dDfMFwws+G$y}$2yH?TfKarj!wVH8uU>Q$i#8q0GMC$l#(mW z9`ILeXX)rbSM*iw%Ow(Lh%+s1)F?bwi!-|`E}{P%At#3`#&ZY!PH;K%Yzd2dZ$+Hl%9e1bBqDOfPH$ZOJ9=CDAundE>) zuA5@fJcx3ZtD;)YA)<`Dio*r5o4R3$j*&qRqX>x^`6i7O=Dq`LgQj`rbllXQj%_~C zCJx)Kz;Ah-rMx!Fa{>>ezETK=qv^zoyh+{DjuEphPi=^qlW*j{@_x0w`X?Jw-a`aXGgnnqB((OOZBi^5?$E+Og)}SW^go zNlw;$<5WIdPkSqHEWSPbYhim@QT^=gcHO$nPDH}P*gf?mGJbx>^|!Q{j)PYr8t7sC zkV9-Nj}ZOQYa3uv{1IjYHcem>ZPo48%b$*mmbW0WDoUl4qbLE6M$5;{nTu$iW28`~ zP4~%#^=ch^e#QOp;6AxFM<~wz0ne`57h%u&#vA+8h5$@%cy@$5h}8Nn!&Zn^?s=gCevaMpD)JGffUZ?%(~ZH! zei&~GPS^TisGR*VlqXt1EjiHKyDw!|q@l=|zlmlKI(5ki3 zu&Yv0dxC}b#<$>&r_5<&5S}`kLf`WB6yj@EUB^?{?}`qyCLTYjT-b;NNz(jz-hdp* zk)+fpo;la6tfsKUk<+s?4B1=E^p&?y7?$JLcl(X&?Y4in(GFHxOD_sn6u$0~3I9t5 zFy#BCuD~)9#~*u5lY!=@+Tw9;4_>XqVD~E z4?*6J81tW2ylijx&CC0_EFPd$QS0o$(i2Om=IDMs)3E6Z6~L zG`$nu@8W|p=*}ArF{kuMzi1S)9H3u3Pcj&frXHl+Djk*f^A4ldtYo2 zpU5uXKIOIClqh(2=+`G|-xx`YNSKf8t#d*foSXCH&4m};Pp;-IsoA?(&#(fWNZ1+v z1^x(zt<(cj7r3}rSsAORNrH=+L^GA^+_JiY_D^g8fYhfo`2}XRHE!~U6BBZiVIq9x zga~z5e~j3nV)whwBBGl;uAlY3F!cK}2?4@a|3^1h`p;(8hC>;qwy{?gLp#&fQZz-Z zX`|{_Ta;<3h@hygv4l>kU0Q8XrfH~#gc+sOmJk|L%2XFyCAOA?))F+f*dn#PN&4me z1Kv;Xx9h|Gd!F+<=eqB6o$I;Jg98RRj&Z53rq9mkTY)iAS1iWTML8i)5`MKa?hI6iVwp%t)h7W}) zt1fNjya=gX3{!)xj=45Lry3W(v;hf=xCJyal!KGP^ZtJAJW!d4t7L@R_>huGs@ele zo!b0_zYtDNwx*W?aR4!N?XA-t6SzQ>%kq^sHE~C82FJ8qf77i8$#@v0eCfRdY#FpR z56^(y&A0BYo6Kr}ya53GEn8WBWyRP0h^=Em^W7faaVAGQ zNJ|H2PT>07`+wF(GxUX8AjTi$-pFY$Z z8=tFsCaMdseXaAoF;-*`=chFUDJEFUX;!CEhby&zE0ZVD&R0O&b|-AWl>JgQz|KFz zuZn{R23wIZ)EAbR$9CH==3^sX>=rHc+}uk~6CILtuR~=*OlbY1j@@ZD-{PjX=H~4T zkGf|)Ttigad0ERtyhjah==HxL^U7m#v@i{v?2=3|AQ`U@;d3Zj$fRa9clV_S-o#Wb z+-ka+)gcj_p9t71Qfhm8#NN5zRC71>1|om^Y)63xai#C^!qc}5s?v}X=}hkJN*GoF z6z`&ZxyAI}X&;A!k1W=C;*>)4%*mvyusrcy_F&ttqFe#0S}meVUlVb)59li1;KTF$ z?{~x9`_^iBY`RQfgi1C$JgW09G3%t|Z*s)+nofx6CwfFd znfL!1cs!~HRzCuw(fb{y76o^!+|52hLiptsD6>?-&JzpRMb5m!iMGA6_ijW030;hUNrF(UKOZE?9D8x|Y}0mu_SFX0xFdFO*w;^om+&#ixxR+<5qW1+pdD_$R^D z7EAl|8U8Ge)-P3swEhNP?A(-AI-rT#jf53K91Ynwho0Jh01Gh?v$1YgSekgrzq}lz+W8L4US}nL@j9Xv!CF3;9K+IuKsE`*{Qdw!Tq5N(i=P)h>@6aWGM2mo?kQB`&}_4I2)0RV-u0RR;M5de2@a%3-UWn^h#FKKOIXJs@l zaBgQ+R1E+Jy+KW5y+KW5y+KW5?EM8)m21~Njv^+CAfR+fN|%5%O1E@_v@A+u(V?P* zbT>$|7A4IhRk|e>9n!2tNjIElf&2IEyL@e z!gDmVlCXQHMmK@qG2TdPJEEbH`J?`KEo^bi3=QofTSol3nybOuna!JrBPm}(c0!bj zF6ez^k5rKiKGjU>V_vEEA#1iJ)7C7#!$m>SyxKF)ut+dZlE9cLfk+8?+fN!%%#v^M zn!au&!8l9Yl-KX#S6biT`A*mz^o4ngPITpwj5IOLV~oHVA4R1D`Gb}2*E#S(LX}eh9)EG`+Xd zk`|qo^I+GuTY}=LZFh`b3j3_jEM#LRE~LV4ZnxQVX`BxIvSdU#513_`*MzsVMjAZoQ&LZ=i0HPo52@x0`9^I^kLnnHK(U< zf`Hz>1;yVpncU~)4O-1B)TX+qTd1z?tqn1V>LGt!uZdsxN%N@%&v8;VL(^dTS)1&F&)F{}PJ7IDb-p9Zvekat zmbV0eQL1~0f)rHw&fZRC6FjMY4$G3tBlvh2Y-vdug3x47=Cy zuiKii2AABOZB^+0$f;O1&0AK5H^-}U<n`pRxp=X&` zT}0$AdXby-2222dDtJ+CkLQ>ktlEf6$tsz6I(PX5j$2|9Nb&^{kPXpr-d&+~_VgOk z1f6ENluk0Yv&yuIc4sDma6OvsfGuLvXVq%^vmW96aNiB-rNfbkL&2WI7XPSFy_yjxHJ%G3#o{VJmBZE4<5xI(tW+F$hCiDv)Fv-F)X|AFmfv)+^WA)u?+lQOJ%VZnKV z?OB?t+WuZPvx~^huBwLpa5trt$Jk!$%13P!g^_25=GyrM&Vho))4t0acbDBw(}Phl z86bMawr|eS?z^L#MutYF5^LuTJADB=3m(7L)4eU7(`Zv}{!Y+3Hi2WFq_k#w5{K#% znl?Z2D7E`U7~`DJeyqI-64)_1s`)e~)yRt7_q57vP2M_UeWt9lJ3K*zkJ(6%bJV8$ zBZtQ0$?8DZ%T`OE?O5N8YS|C1C}w**Pw58pNmYuNVj)wTuHD2;m9n2kW%84D1+fo! zZhrr_7ZO)ST@Onxh7^Ui(!zw8xyZfc&sEDdTL{vk?YiSzZ?vz_j-6^z9dYcGEIO3J zkA_ZPua%POpP9IwpJ6!$rSu;n;3YFr*>a5*$@3(SyWhIvI2r}(W{NSZ>YXo}Z2t=O zUj({e3p!cgHJ7(S&!Q(E30!ES-i|tpqg`@kK1wZ5ond41^2r`b)FmZM@!#rOy{J+< zZ}gvEjz7ZVBmIu~PiW0gMyBcS`j(L zGm-taX=5i-$v_^GMsNLra|xB;(NPKh3FG&p>rV?X!ta%y_KQnxE9nWM&-kopXJ(3l z-2ap=X6Eei;*YW|6AMozT!nY~oSG?JHEn(YFI!0g78Cz3x<5`rJ8F$eL~wCh z%I8O|i`M9}PL1(!Nm9c3}|O^#=8a=VE<=TEr;fgv6xQSRHpgm^}} z!K1JknjCA#y$>Y`zg%5s8616MZafv(eDUEQ&IMW|)|UR371 zzvR+A?rU>ncOEzz3hsMv88xI>4Zo-l`y}KN8IQ~4xjOO>!Uvv>JUTCEs>Zf>)@Uyh zHgmnP;_+szs6!{y$ zP?K8Ii@22W{sawlnt6||05=gupOy3g3O|%EbV13)w;5E)BBEtV3TE;`5%zaK(}(nq zB=b9l#k6+|3J8_X@n2J6%Wq8IoFoiMQx!T&F!Vpzos$5V$2LT<*iH}<*in6P6fc-; z_9=#5{cQPR`AGII$4RuRYKs?ovpb{PoHX`ovKt*iF3~@de5(tRcR{8{XfSbnbG8j& z8@3`2eKT8(2PU0Re}Ye%RZJro54hX}?X%impC$)F0Dc{Q#US`kihX&GmSSq^r%5f! z%Iq@)e;pF6buX>=@Z$n^QaCu76|!@Rx9vl;jMGGw`OYUhUn7a}Hx@x#SH+|CB6-w^=J8f*{p9I=p>cjZQ>v1dyn zYP@g<7jur|BRx(CD3-vAtIzaRmXGMqi<|ixtMtE@)~OJh08)vP@wa)SMMOg)h!O~J z59qE%5`t$D{5OZAMcr65K!us%EAqYO=Yy8=*q0OBkB@F%offvMy&i^3*_wAREcdyL zd?UWknJ52n0k;*Mz?3@O%)xF&=bKz;%aXSHRs3AZy#QtXMkAsu9WVQ@`SohFJXtXYItXsLBg z>)xKZA|>6l)s^wm0pke)#`CmymjT9^h*p}W5e@dx77qNRCr!r%5OfmTqElmK!!j3} zQ!2>N_4udcH4MXUpv(}zjZ2A!_EPP`=IuP>vz}>7{ykv8wL}3`a&6bniBMCCF4hFA zVDyB?VW)4(k`;Ab-JcFK(^p-{HZ+zFA68X_zF1NWd)Cn#EoF9e(^2;=pp3ucS3&Vu ztjOHM(TId9UXmy9X*#l_B)lyRA#e~k7FZ)m>|f(`z9$9#0Yv)#~7U|FQi zHBS;*NYN`BY3lu6KntLVFD+2|A=aqkwoON_#s+y@7fy*n=9A-YSIje!Qeh&3tx=ur zy+fgm$49ei4tFL)4;B&ra~wNA2F(i?_!rJ{DL%Cgh;8psL!?1RgV>AdL|luja(CZQ zU_S$_)_8vt7gJXRoq%{fM5ie8JT#!m+(o-i{;hl0IcUts%<8cE` zBKn!bAw4K0Y|SQZq3J;wYutmUH@_2H=J)qk$u0fl8kGMNh4z!&(%shz+}8#!It1Mg zBXIdNJ{ydsmgSp;BAdDRMal3Pjp9`Y(>Jr?oT2eef?i4++;Im z)w9p%pCga>IOgm83FE;YG1p?r049ArV`h)T$}%)_Ja{4jyK6+fTlg64HY&f;6TcN7 zZ4eg6O@K^s5|1n~2;^ray`aG+lc*L48S(l_RxmqGLbCyy&D1UAqinI_)omu7uJw`+u=mDjPDM( z=TndKJXyws;~4^T-X{7noo~wI^43vyQK+{qa`i0j;#6KTHSTYw9>IRe-O@z8y_UW< z_$!NERHv6Lf?7)6MbOTv*L=-tRfLY#&_|wU`Kd^Zhoni|qA%@CoSoO%tXl52m|>LE z#gb5ZYLi(z%;`9Eo=Li2ssMeEm@l%KN8G4>9bPzIq z;}!Eh%w=`deS;DdpVa%lNWMK4S+$X2x4O}85_$K&m6LJqLe zRxPYz({Fr~-Fw+Aa{fAIO=KpK(8hx9Aq68Jk0tX+v4+nGrkknE4_$N#cRPTF@BEee z;MhN6^|yUw={6Tqo}r5?^gF6)T>MCEr5{v{7TT8S7%V-tHmZ#XA_Jf#Xg@(!d#=>6 zkn%bahw@C}@w{&7qVcduXz;&+1k22l^T&J2` zxppj~!g-_sp1Tw7;gU7G0y>(d4ipz_wZxEO>sZS5VfC+u;77B!pv242Z}H;l{T8b; zuvDLqh1B~@8nSj#s=AY9T5s*X-Bzld^ph~UwLWQqos9fu8z7?OCb3eVMCrqB7DjJe zaN3X`-q=e@ji#^@&R04GlSU1cVxD|e1?Hp$%*hv+lR`39YIvzWjG5G1KQwwHj%|-u z-EF%qN#deF%%7BrrRxiJ9nI5A?tT8hn-%}tk+RVln#Aq|_nduJ>c_Ja-Yypa9_f_TvB3+lo*4@mci(R%%tB zy9kSmbQ4VRJvd{haB8DIehfTwh<&BFokS#Y&fYMt^!l&(A7u#K1{UMH;VLeI>hI$5 zW#E0>yY4j2TSax8L6Ab;%yL{fQBAASZ#UJ0zssDZI zZ%^TbDu#)voWa8}_ruy>dDN16PL3O}KB~Chx<6WoKd~>r$Z^NLAA$3!`pl+m7fQHB z5gB@&g1#y)S}!Wpw!%wP$2q&QcyyYDBlGmFo;HjZM&_G7QGH*cz&OhZFMl>*P-(Ht z85|buv&^d>!7{uLt8jpi3e!xbr9?;!@8_;A#@ZK?MNG3vIf(X{O;>E@S~wyf@ViW06b#M#dC zJS_PXF`!W3N3F<3BWkc3P=zLctg|R&Roiu=-2)yNk?lL>dpQ}fL@ z-c(4qnPaB|Q(6xu+3-rCfs^|ODqF5r)dc3#=MsXp2VI`JZY~%PBn6JL|6yEAjPUB6 zw3i1%*Gu2T7S?s$kXH9~lTRLMSJ~C!wMU()P5-r1=H$LG(IJOU)BbxkT&dD;Z|GLp zlYG)@kw(yIG~whX;8E(xyuIcU9?d8fQ>tdde)WT^k3`L&McI>1@ zN>;o?e&*&-PVPSm+}X#LnYYq_ec18QrYEpE=|+?e9l2+foN{T~`fLwvtT7(t)rj$T zx9HxkH5t%x)OHp$qo^=;942Q7X`IPd7=B8c(7726FV>4~l`C188zZae+3sg^$%(la z``awEqMY&-v8iYrb88veRa=DB+D9L$TQ$~Jx#vurx&@`l+gJ3#)76@+9e2x;XA68w zGwalKdiuUDl&H{k`PhXO;vj60;X%4k(oBuDMS}D3a~NUdhFqb;_Q8Ii_V*(ZXhamZ z(0~n#V)9Z!1fPj?(_Uq%iN_{KWBz7gXXn$?^qTprrt@p%4%Y@1 zl2Pe~_jeUbnnIp{O9`{4h^lqjNV>3Dez&WxnUqqtuNV`Um5Rm^Rj7V_iwjBAILPqG zv9J_FPS&=aOxNO*Z;8i1dF77}?Gqng zi?q!0_d59{1WVH6>TVtVtjEj|MY->>b7PHKal2k>X~tRW7-ZF2+2ne5WD1K+Op|bG}`}t&ziGVm@tN8k0(_coucY2x;RWOIyK# z${@X%$-WhiVExMO9f?WB$Ja6ltv1<>t>=;Eh*I$66y%iBKDgw(hrofst;WN_686cr zT1ksqKsfeZiuv;BsE{RVaYV@08Hu4~rurT3#hcB31ctsX~=)4hRdC%oVRS1<9_o%nq#{y%zTKZ3lo-r-aSX(`jDx}3mY za38w^p}W*jV!)T0Y%8bDvNxPwsZ7koXuQ;Vd!WIwxbReC%>C5B!EhVnD7RRq3Ila<$h3UgwZWJa zV!;VUUCGwNyulTxNh1;oxr*+zU1E3Ar`r8xBFIpE`$IC6p%{OJ}9$=@+ z30+ukl0Hp-#75AM(0PHAPslLU40<-_bQj~ni8S`&{QZH{I$Ay{1#`pergsn8>n5-) z196&CO5cPYxd2A#pivwsb%m`c`C|Zf*!V9J&xu4!7-g{D)N9W+;ZHA|H?x-CNN{x3 z%~`@!syBe*wN&!>X4}+9EJSTqj#Mexb3FIRRs5P;{R1J9EA?c~`7TB{M&{$S4vsc8 z<}s5g@7@Ky{aBYa6`4n?UZW;VFf7H+A$RIwk1sx~)~e+SKhA}Hg(P(8rdn;D7(b%U zPSUzBl?(up)9C33A-7d|CsT#D@(2|3Jm&uRQ+)m4;Iq=>y#J({X*$vE^?06g7k5)y zy4*C4w$T|e=Ncv~qT+~(>yx&X2Sn&sAa_qd>loVNl_{7I*e>O8-;kdpJn`sieUnS7 zwpixOKHjr?-t-R`sNJ^t|@lQ^Q|FLj|D%{}kn zySBYUGGMV0Iql4swKO)Ipyx3w2K!+d8)pP7)lnUO(eJQBWm07RZmK3MfIG1E=}WZ8Jm z{VBtGihE+kix;0S?d*=2w^+#672_Ngq0}6SO`7O3wUS6{K9-^xc4Db$=$X`kjSExx zPH`N8%&-pH-R=(;0G?SApl96($v-Sw{Ox%YB)Lb$* z|Hm8B1!DVr4NO)GDh@o|9x8^B<8j>AII}%W&u#oMR%yq|XJ+V&9^rca$pX^J-wgP+ z2E{G3Wn{{BX$7eLvbW4uWL&Jx?I<$h9Umu2R-TG3oO$kbpPB0j0dGOR zPgy{A<wFWou}VQKi>LIVE%R2QW=kyJ%Be7QT@1GCaQ3==V57mzps*94(N`vru`M=pdJKOh+i*{U@aj z$Byr^%FG@f-h-nV6h}9Uh;=F8i_URawI)3BmAU1S1uAkQALNd?zSR3nQoePbattGWxSya+ z2UDoxu*gx_!6K49wBkpx&8&CZ``SMJC|lj5EhCFy`mSDnYK8s2FgJr$FH`+P5wuGs z4~-k27a;QA4_zHP>xkIx;<^^eyt%TV*iw4N;EhWeg%|n^oQ6geT6Gh1$g6EX#YWKj zB`8EqcE#28u>ohlvvj?|^d+TJv?FvYPa3p^kMzUknPWS?IqvgF&ehY+Na>tVz5b69 zq$zdfi_7rR7kyej1Dn|1_%g2a;-YC!+#$q31sSf~o@XtOAO*)G( zcsg#nrmK{t(9wOmz*og!ivIe(qP4F*k?m$=6dRv_ftr77jg9_5oQAijs}?_0#D&Is zXa?S&hJ3@pKJ9;Qckk1cJ#EOoh4vO=PN=5TGIngi^y-9-SF=1QGplMB^7tYrY5T>~TIyHnwJl1%@@)5_Mdzr3TvqNch zvDL;S*Esob+4?g?dw)y>54i~qt_8dUsAh8Xf+Fa7r%ur1k|W;y6KHqezf!Y09m=L zDk^UT)H}|kqRG(RPM%PYG%-A_b!~UvA)+9UCYhj{zQ7%X-sjs?tsGTZ@(Sy&U4O|S zwR&r?lYV22z_6l<1lMQebLJFoqoD6~qVvk1EB{fx7OHSAi;llYhuIh!E0ksCd^mik zV?9*)(^1l;6W7sbU}y`G)0x%iOt&mz6kEmOnc8D|B-5K#cS~dxZ>1MYj*VaFJ5H5G za8{e1-#SVsl^<6kd0?My@f`zwO%sxZZ`&6hM9+J~^LjM8oy!;tx=oYLNTC5@cQ!!X zPN7*_2Qwa=N-ovv#Tw=jS6N5o(tA?j*4MXnPD%^t3$3}KV*{twh`qDa$G6r>UQc;A z1j6(-ERLp8alJ4=uAEc!+;-FC82nFpC6{|!QVN(`fbK3(rO6d!%+v&`&pkXF{znRZ zuZX>?`@c{9?^FM`KK1?h+NY!1!x)Lug^HGOuV*mSwq|#arh$IeR46Qgt;X?{EpEOl z7ll)si7l&Fit|^szinaqZ`@{3+{lo)XJ)Z}SG#I8taJtYm@{wWp3`zm$JGAV>UJCN z`R6JBF>ug^Ui{R^jJpKS#S!hLYbwIPkxleVHQa@dD4#;#JFM62 z4o$9|SA6iGl@LKsA=WB)Ef0rLLvM4a2Nq*w9jJ9dh5mbqNa=v{!# zh|Z`Ufj>XIh8xw3(dC&g+Cnh$Nk2HiR5b+M$lmD}33o_1EBTI%I+%-vj6KF22V&r?($;U)~=@EvE9km@Cq6QIDa*UtYj7v^i z@f}DjA5MIQ+fQg1TT5A3Q#J}4x|Sl)rZaQ2RRekS*UX|W+kd!!g*}3(9{pl9GMe?0 z)g>IX^9=lFBQ0h;N;Ahl1c^Vh54m_3h1AP?yPtXONTY2kWAMe8cF{BBs%7${4kEta zxH8MVz4E#u)#f7NqigK?3#F~^72(hCzq~VaEaL;!%?zoPheApTpWpWW0l0^>zEX85mO!N>8ghvVe_yy@P!D>Zm5Ku0I9|sqd&8QnyOI`T18K z&f}VA@|U2Mzw&Qg^{Dsvew>U{mGja}^Y24iAYx|xI6nks92hh-*b8;k7D~W=DXqq- zrNEVygEi1%%mcSa^G?q}A8IkG`MYmEy30-@Zyc>`dkhFTO^i;v9mHn(ifd172bN%e zWm6N(X-k(4$WtcYw-MCF9(*TzH$N*$_ER3W@EQjMKT89{?1aZ`rrvhv_1o|Eo9ACY zSdI^szeQg2-)$LitN#08nxOk5|%S^EOZ z#-~o+M$KuTRN;XZVLg3C6zpMW@#MmG=U;K6kg3p@Wc@;7WUWr(jLL074^Mx3PH;#G zLbJ9;eNS42_bwRmFD74t)<}Rzt-Ox%`L*9Zht5+EmOsxlX>$0LuMn#EkefRe9*F+( z^-xBC4OnnM>IsAfW7X@cQ)I)+ZqKx&Blg?Iyv>bWWpdE26hAT*g6qiKi~V0lbCs35 zP?w_rq$1>n&7P7MTDx2E+_jWE2d_dAck9k`(GcO%wu~B0Xcp>W(T7*jo$5H(`dG^1 zQ{vq&9i|(vYF-W+kIkznMBHT8&niCPciiuv`WElV~4P5w5L+%imp_N&tyfI32-sRi;y+M`&K_KGE+OK++v z>ja&m%ijildh8)sigibx02JZq!3;%wLCd*rW#rhU+9TC1gc_^=?d4bxF;A!(kr0(( z^mm94U{T5^S;a9~8!>3!nYv{`2u8rAl%OjRzUN>cU;_YeBJU%Sd-uk>U9c!pK!o=I z?XWFo!!h*PY2DFvz?43Do8}&*sE~3**-+H!${sf*6!yM96?^b-=&AKSmPl%yKjJ4q zCZW&j0B8fIzy@vY004N?Y_vS3yJUbm|693AM`)jJapQJO&*n-#frN^pi6~PGui3j+ zoV=K!1Bpv30OGa;#V(2#dlyKI6_114zzN=Aw z|A;PJE$^?Nh%5T~>qi{xvN8L*pes9Tii=&s#a|D{^ItOfD;iACm3@ zcy_7r(t7u<`Y8lbsFxJF=}b!nC;Nci#!bM&kT(ks30r46Uh7H&((%F90N4g_X}R?`1h4wHpz6yfNh8 zoQ`A@00l#g0Xx5U|NQlQ${k3bSAej;a%&D*#V?o++SIg68Q`wP>9cEPH$;tI-rKr> z*eY;t^j2sjd7#xvO$`o>OEJ#oNH#(|C`8j=u6mC)YQ})XFJq14>Vz2mxplSF{!pQV z(@=7?ef#9SmxM#o)E?as*!H!%A7#Bq=hw?tQ81X!Y!F-DYCXG;vJ1|Y!XO-aD8AoI zyokyp20#u_n$2ySTp9fWBlxOI%-{H?S;wY}9>9VfOkhA@HvN54eaIC&=Pq{(&~Dt~ zChMMUEeyp<@-?){5F@@TE7626)m^b`$bEq38YJsFYN9|Zj&}FCd%+njJ(^(zX!QBX zmG9oYV0n>pK7@oUQC|+eWfsOeeC^$f^qjiVw!}o-dta@Fbh!2_LZbh2E?UdYOWfWe zMJN?9!ZW_1eWdgv3kMLC2$)Nv@Y|~}?hUJ#cUUXa-ZYQBI}YL8|JiVY<8adv<7SfK68eIJjAGfDu28e=FwUn+xU+K}~k_w}B*t zDmu$Gf8GW)`_~V?47qdd7jDJ0zfh}i&1ot?03-t=T;r-$o$+%hY<-TuYK0~drnA#D zZJ%dK_TX3KZZ86rS^#H=EoQrraX3Sd0${gMkGuYU{DD7M^m8~6Xd3~=g>B$$RYF10xnI z#IHFHt_UXmH^IDe03yi59x10^(Vd2!S_%XW8ODQ1tIMZ8`v0aK(RW9?$0w~%!o3Ja zh=0Fq@kH=SEDq(}G=vWxHy!wQv!J1U^E-KTIl9Odz5mF_d2$Tsg4V&I+{CbW-M`+% zxJoV3sI_?@HTaf>>;Nww{AMZ9lFJXX&|Y+$Z7D-ukIqTI&GX4$|BL>v#w~Z6tVc+{ zebR>t>EGRcj^BEEt@O?83vuAbaLV-;H$Y7zN4yIa+&({ICB(%sYx65vV|WkFl?~j$ z5zZo1R8(_LBs9`*DXFN8^Uj(gCAOy_k3wnME0yB9G9-?-0|Ek!)V-==Qe1^1euF5dj5W`Tf&YzAE0 zTNpjl?WU`XkAs8LZzqEqj0(SfPj{G4;A3w=bXN&I6D6BGR-lxE+)R)^s&#@*|Uv-K=6461u%dwHO2#= zaWi_&u4XUfd3141T{cV5vjjE~n1lw4Zkp$uPD@-7DOCoA?R0(X)>)-xn~n`1ss$qQ z#vNcd<97<1l;ifGYz}^LO?-|d5E+pNbD{o0P9>=^kKw7m$~=RYS zc7%UJ3S^oHObO)-S@atyE8UK(-;K@8ls@uLvl)n$=w8_I*$XX+Zx9OA(xTV_PxtCe1L<)5fF*?9GK7Ux8;j%GLvgg`I)cJV!_+rXV~xK zFKxE2_vRKM>RLS&(qirU!w}W2r+Q_b3F00HP4L!(=5}2a2EnKJTxh9sfMaS9z26cbD5wTZngLgO7Y_;O5U#h?Q zO*ntpm>4OkiN!HBBAeV%Rb*|!y6eWby`*8jIdjCt7jI0|(~_FFlmV!p$4|XDjAI`3$LxHMaLC<<9SlUpd4acEt^2lH*?`M$vRG{$n& znBAsfCQH!kquSic_MnTG&?#PZISuE|FJn0xncS?g3tVO~!q)C=gIM*XOKgd%4M?K}ki-#zs?2ZN=JFu7cqkpFDG& zIwR4Jmf9Rjx+WjxW)C$e&7*eM$EfRF+PeFn%yUkXMdeR0X4BNKtugXxkVK7s=C+k6 zSued<=FRFGCAn}}zCUIxpr~C65#X3o zPp(ZPi+ImS>1`f;Ib3z3rZnK@Act(GlA>S{LloQ^Bb*ra zkjtf|BNdGy4ti@MS{v)~bq%xSRzt@hli5ZEXMWZdv?P&1v2C}q`|S0?)Ow&XBptJC zh|NZ3Z)--rp$5m|5-+*EaF{|?;J49key{Byw~@GRi2zlGynRNKYnL!VCKz6u<_!{%ioMb9 zsNm2xNzF-Vkyf@YH^PH!vg?ppkXl%|84b@*%I4yECHL0zfsdiN$_tjFhT|{YniCcj zu_hf^FBrAc<>^G}eo(8=Fh_l=8S2~&{op6W$C(pJ8@Qf;OKHVuywv`HJ29(=v_qNh zp3hm#B9P-6>A^&lxD^?CbEab zRO;y$I)a#WaV1zs=nwdCDSbI$hsWOzg)6?CcvHKnly9N%3X@+X z749JLDEAQ!sH4ptQoQmQk_MJXp^ZCYuyE2)N2yTrnp*+n$ESuR&xBEoB6h_n*LIE? zJ*8x^3!Q01htLshp8i-2yE3};ja=8}hNcl|eAhB8P8D<2y1}V-@5_3nqrBXq{Wyq* zQD%xW_b}=Xz92%y|#+Fnx%c-0s9mezV4$Chp)aqENWs-h^;jsfl_Tx9&3*0Ta zt2*A~l0NNH{9(Y#gc!7cj4v4zpgAKZ=Uvi&s5lUF8Nj~3QLyrU(=Gx?XsSk+S(iCu zS=dXVrf0w0D>2t;NAYcNNQY3xTel;N1S!WX?d?H#Sig+|mD!f4A1iMs{|;&BLBz+B zuDuS1tTl{q`PJ~ONHVIaM<64|iDOzzYVLB32NUhl)`2uqFzevyh)lQQw)gRApxw6p zc}UB4l~a#bp~U{Bq$(c5c0eQONjHIz7LETCEn|`n1{gl# zsh5-<(kGe0OZQUgI+iX<6gPN zc6ME9*VaMjiWiafW>hN~VuY|?7fg*s;F)GBfKn~GSFG{)O@El`V5IeAgNDKBZTu{W zT$I?Y)+>4KTM4LY#l0!xMt|$+dP!X@6l~>xXXilBq^K`w#wck3LUFH(-I2`CXF0VHD%T&D2)?LcYN)A0&r@)eWd5GQV=|)NK z3(S;>c!#qbaZfF1g{ada3bsvjzvWv%^;xxJAz|uI$*$d&LbyA2jf0lwxq0tI>FT7c zlqd7i%}kV7BD#fF%qbCXI=#q4)vVejGXT6 z1=7{GKbxyxs%9fPjkZvwl9Y9wi*bzLh2|s|O1<;{HKXu?>+caz!Y^&&h?8Kd3XIDoPD@eD3Jir#^W#jnYQt)xyIViJ#wxGArt8wyf_%pQRfMW}U^Jo_DL*HHS&)jpT@ z1xuQv*6n~;O7L{nBB}h+Q8<}bo@%~RZ633Ov8lhT(b=VB+aKGql62lIqDua#YSX)V z90$Ac7Szn9Qvo(IygBnYBG<1W(n$#1&jVrVX;mjzgKe^umQ@^R}uR`uaUL_D?ml)sQzbQ zRfQSHI224Vq^1RWdPnJ$pcup`cp~&X97h0N3oxzuwh zX30S*Kgh|u%d(Ej_~CD}atx06ykzx2umD&Ot}L!UjGZ_5EE$NnbSjmk@|9O{)D(P7 zH+Lt&=Cp&9kMSWO)A+=@av`^lrm%Ufx?Yt7p(DGPy~#m_YJ{J5HH&)%aPqA|+AjRA zqB6*hfbEp9I7^^TH!h$0vZ+4r@v7@~aYt!|&yUyyTkuR8Y8X{G$m#~h<&cC#g_Z42 z)%*1#{D5{**Np?Anm$GC2$YsNf1I!V8Nwo0ZkDS%b?^jLA*z*+6Fq-_X*9`JgmqBf z$3FP`wtYpm3elQGEGbQL!1&8Rxkl%SeR@2x`MOIn?$lNaaK#JD3aj)GCIx|Ee&HR^8NEL2bGr-epQiR^wyZbzTNQ<2Hj972tjjk%I|1QMS?;^?nmkXo z^#lLCe9NF$4^H>0W;pOgD_sJB%I+1bU+^?!_^qqQ1+mGxzj|@8#d;i-JwQRBeKnu1 z>%%BJ{yeZU_``&Ng!XNkap4Qi&1Xp6qwh1(pe|#l)1KridK!VabH>9o@SoTDso=Vb z9yIighu7w_3KdxACg070Ch zHe>ecD>x4aDQAb&scVNUCZGo+2A*=dtgp9g$xv~W4ez~!dl^$4oPH3N41Re)6f!;> z%zkxViY09i5pLVBnXdLKtR$6GifPvf3?DccAx!hoPx#!i>5QVPXbk~s>2MT}H@6e| zRR-t~x~(VjMv-N2rs#F(T*CqHOjm>|Zha9X3q7hur2zf>zUm@U;|G7jteCEN2>K|v zm5=k)8UC<;Kn5aZjzpH|(F65$8HH@9hdy63W&0n-jje3ozG=tDFBgNtl`ejh)p5-O zPO{mQ^UEvz4}YJO=iTU76!aRZw6dBn^*;8(3Dh0c=Ul$V(-f}_9&2hL!-DXMPe`$fyyNsVlQ z?OY7voaTahiSZzW=Sa&XE_up;4IV=_An@8carT#3dpt3UwBRswL8WFK-+irV{ z16V$;SrV@eGfiNgl+1`u^myX7sXTf6OI`mhetN6pU`J_BU6+>IkZpTBjBp&ps@kTF zp0R?yLz$(hF?Vh^r&(!*J9`8n5m{s`5)iONA{JmJq}S7-j)4U})x|bD{V49G{m4k& z)){Iqo6-sC_-GjkeJVVs+<~LiXe-9s!Cu$7(-cSJisddWGUs<{y}S5r_?kceDW--i z1Bh{cO=B#pY1wTWHu0m!*M{-R=7PfM@z5~j@T&s*;XXix_a%-OkCM@{-(`}|fjU86 znnDOzmiUHTSEX<0Li>P?OLMy>rc3AZiG6W&aU7AHazU67qN_0QfY(zhv{zw*w@Ohb z_(pI1q?T^%xNyD>vUX_y_5e&XWyb{e10orQ*_GW=>A)m_w+YGDuGE^q6p0OL-9mkQ za^mcgQ@m3O8gsYd!z>0Vp8(9p#5sufCwRhGwl7st1|w>(xsrMAM&SoZG5zrdeoN(v zL0r6!ZCNH zFZ^B(9KG6UQ@L3zg|dNX#Nk3=`Ibxsyk83D=^16F-g?j#Mdu_Y4%~sy9A~g_hcSZEebhSoWSD zo=UozAl$D+n9(!!4lFA&3OVlegd%ILKQXt5t~fXgN*`RP$WwtYJt{E%gWe(~f{t5% zX!P?C+o+}O48uei{csmyVLq5nl1}C=jg;*|GEf$)-*4Rz#HAcoQ=@jUEV1>`W4bor zCdQMsuKRGtf)#I03%fbJV$`ib!I@;DTluj`y~F8Nd1(N#W<$+%#ObKFr}|3n_qqR^ zQSb}hg^I|kV8zP9nEb^>dO%T7DwgYo>dOR=zYGe&J_u|7`MIRLy8Ts{T6S?UhYWhN zthv+1RML1V_q7Zqb5o_aSq5z!@YtS68_8qixf9RRx~EAPX#%as6vOV6m7IRVP6kW- zR6!Hs^_g2%_bsVqAJBse`b_0ync~>)Ts*Y+18*x^2IVPJFux5ws(x)z%rTI8(XHuF znxo{dj-Dkz$BX(j&ANv}13fEWy)t(*O`VB1SUY22xR)J|GBd6*auG48piRv(AgLiA zi&nC)M3`<|tr=>l+7VJNF7J5~aeT5>h@DkC=R1_KUh{EiUS~wIzE#+yC!$;ej>DBV zY*b1wqQ)ssE8%3;MDvGq#8D}smLbmaxoETzb?8aNIHB@$v2P z%-1+KVO9e+n0hd_^+k0~5tv=BHS^{pYV4@W2C0rtMUxX()CRD%T;Xj_cbNBF#)ifV zi?s&K{0oW(mPZLi_wZAKd`h+P&s^t()D#@Eb81WJMKxG-Mbh;M7yr}u%$1exax)&f zK!wuk%BWpM;ae>0iYmxVd!W1_mVIjUs{@8G?SsY7YTVHN`^2rSS;ZwX`(sj4S{UI; zLIb3#nasF@=2Ik!!PVjY*I+Lrd1SxKzn!d~WN{gqBiY)S4x-?)W^LvmUrl9)4`*S7 zSIf!Onzbj_TY0*Q-&)@^VW-Po-)z!Z757^lFrL~!8K~^#+vBHil;bKIazp{4~^}pqvF#sPdez;{W|3X18%+M!^ zq3rwTL}96r(Gq&W0rfzZsgf~0o$)BbM>wldt=sO9>C|7QV1Fkk`eAe;y9O$z0+ThX zx7|gNVNefXeS6r_Qazd~{8C&J(Kh$PBXfnLqAEB7wN-7@QzPJskV=iU)sQqtfW(rj z`-|CT4Pt)1R9(x1ILcxp z@W`E~LY9tRvN}PB58ozxDVF(Y)Rz+%?vX=EE64CC_e;mhX+_IVeAl`PxAO7my>yC6 z^#L)qU7K4;I2Z+iL^zqTC+CFiwlAFeg!T%>{()&bZE(21o4{9B$ufo4P$kIt{12ZH z9R46)pa(N(v3$ec2LC!=nH8<5-vV;=_MoKX= z7tE^<56l(7&u!C7V^q>qu*ngaG1XCh#ZUl#8a;eWiZ?v)B#!Z z?VB!Zx`MRjglDW6r67adRJ}H-Q(B2eV7Vyd05zLG2X623~ zsc|pMPkk~%7WPe<#knY7AO&=WjW34Xa6}_IRKseNdffRZyE6i?1BrsmQM-N<7`Z$3 zQA`!f-(MXL989M=$(D%-_r2JEt{L)U0IpvHihc`qoZ@5Gg5E@e!SS|;6RU-m#;{f= z^FP@UC=Pmu_jDc7uvSNAmMnKDPiiS_dH7qw;9R|5H^`QZ*y9*_G?>Rf3*q}(u*$HQ z)Q2^G>OK3D3W3^0%!rinN)m$;0VY>2w5QM<2M$uOT|WV(FMg0h`hC>?G1=TlcG zigQ>Nx8)Tcq(}XyVM>6?4T^Ub)@LWL7*yfhlQix?C~tU}G_Wwv3Nj5V!n~!rH|DX~ z%qZ37rj{$mcuW0E0{rI%8B|IXIDY&l!mLkYSAPMm^D<3v_8}aCKW{+xk~m#d8<*7S z*6Y=>VIq;~T6%lO$EMq2XH`X*eoaq`fw}du{X6^ZLRpMc=&c*JkyPvZU-I&UJcm-a zF!4R=KdM)Z!eqUz1!_9A2=z5@H5o;Zocz#UOVdXYa`N8@c|~3K15Ze!irsAVYCT-* zz@$Hn*Ye=;Ep_4Ae_NtIzw(X^u}}8&cSzjG1i$8}CwP&fe4;6%h;>`pMUlCn#=TvW zt?wi7?CX)gRn7IFpdUF~nn;#pcenaN$Mi-dl1dZ2-1I#knDE}V9%|3d`M(<{sb)u$ zt%w)ARBT{ihs64~i{0V)=?e43L%PrQw%t`-&XFy9IlZUwu2qGp$N$2oWbrsvx#ek$ z`@LLLSG|Vy)zd=>jli5B0{>1^|7DdSR98p&1S3iOz(k69!T$f=6!^#TAOb#nbMC4Z z=g7sqoQ((nl3kgaHaO!?&t>aBs-n7DE;i7!Lv|b1*G&(R{lT{{l3EQRRc|i4I)w+V zDx@6cqbwr!AHb@Rcs+Q?w1=;V>MEtt-M${e<#TC~|Ivy6?=|j6yTP@{Y)2PRWn4$i z3`JbF$$7iu{a<&_g@R`!Y@F#RBE1k8|^r4=w$$jt9u+!K-q2 zC*CR5FItr&6%bNWMza6&Lboy%RN<5ZhG!)v6B+ehR3^R-2)IMrzPOZonA%vS*}Y-S`Stgw6isGw3T^vqq!?*JJB%*F6>GC?Z;bo`uDlDVjVbodwnuq#E$Xb(Nt@mTPBQcjiZn4d4ds+p<>4XxZQh*EN6Gl{Y2FQ?2uV2 z*K1oG2TG#v!|FWzaN}p2LkSc4v9HU*%0*>b)4eXU8RR^tVJ(}zVfeR03)>>^Mgjo5 zXIFtB`A@h6P}n45kRkfGJ5ovv_|B`#k_QrH5p#8cCk~Fq$<^c{5*|?n{TrI8F|E2} z4%;zJ5Jh2JO1!LT6;zjb0`iEKz5U!?WR}E6NA}{Q?N+W>igp5ptp^mr9olWX4(8}t z>AjUKwQLs$L{i4IQQ$Z!Q$2F&8GA3>X6d&JTQ#=3+rY9eksSQ5U=kUBiXcN+G2R}K z#Lp5`xe(3DHB@9xt!AT7YoMFrq+`kUu$kyGohr_^PI2RQV8HiLYRgxpCX#+DAMP%P zSlrvs++fcp7@0`pSH%b~rGj?B!A#S^{srN@rDCoX~|Ct)_50g>>s5sxfcu1}(n&QKRD*)yIVcWk~qegyofto|@D zZYRb)7kYkdU0Iv9NVEjXz1V@S)%7csR*8UlIIfifRb#M~ltcnXcrQt*(f0<@lt(`G z91-slmG(|z8g0UZbVK=ZA77o3;QgmrLPK}mdIlnm9=@w+754#`4N(*iucb9>TVz@O zdgr9+`E#-XqT6aFO&qD(9*))_fn>=BNc}g2eUQvT*D`WG*0L!ufn{0_EzGq{SC-7i z_>By0i92FS;*-658@zJ6(`-%-Iu(gxPPY2=+#E=*PNhEllSiAwctYx_&lY(nvSD=& z->Jqi@W>_$CqUVdbY*ma3v@j9HTC}g_VC9-HH`M@~SvPV5a6Hw&j1n7*=2oXX zZl~Y%g)Wql3Xj>qJ8o9E&2&1-Wb*t%|zr>KyqW2y>?VB*YJq= z)lDWO(P;=ERnb7uiXgF60g63?a9N<6N=Te?rIVfE9BcqPK*YaEB7)-zMZCLU=F&yP zfgwh)nsL}hTZtb>#5V)JBRR*RM^^^=1BiP=ofg|1(jA*Q3O^Zju)vsrNM)|b+kZt) z=3!R4cNmVzJJg|K(*J5AnuV?Ela5TrmYIheE+tI5J{uJs$}aH(L96RZDL|oAn|-Y3 zPg<%ZWi}!$zuOU*GBpr+P$OWbqRdM-KSDepX+-%bWkV4zC2V|;>>e{x<+ z&7*%>I6`;CRN}M|AfBw+x$yaT`Pk^ET`BwKV<7o-HGH4?+f=AqLB{&y4((1jXha<% z{uNt}p+GcMDJD+vXB!vQ2Saoy=!fZQm$~I~O`_GXpjoY>0lRSSPX3c}M}TI?h@x_0 zDs8Ty%?0|8@LJ&?Snh$w4Z9{mxsP@oGOi11+uA2#R`8m|Ura9*fM7pHXIE$@RfM9o z1dMGnokA_~N9e9aMh)r8vK3cRfc+VO%zr+lt%FWu+X28ASswX;fmiMRCq2#8_2w{+ zsIdLB1eQ3wk+$q&q=~jFAEn7UZ{)JZMeOW^ijfb?)nO)4#Xqy3ce!Ob8A8$mh>3#3 z#CeOf0YJHIHA3`|gHG-w_l%U*9wZOJ zzyq9zqQ`2>^|p=u{fDA87uHF}fj8Q3{M%?==rlO>{XH6&LUx`1<-dZZMDQaA+8Y+PIMPgMI#5hN%sMCbw7;6_r)0&TOFLZX24o6F; zW-2L;NwU!Na?r5UTC2t+Y^EOsapC1^Gk&>RsxW#M>V+Cc%0LFsB*~G82GqO3GA{b{1zl#JXiVI* zZgY~?G8GcAcJZ`%gNqDcUgu0>&n6nY9F|4wbIMqs~XfvkDR2;#j=GPrBQ-Iu@_(D!up*R$zt>43jWk&vD zaC?g4h)i8*x3Z>Lsb?D*5vU>3s4%SFA?v)M9d*B#jBb?F@}!Ps4HuREBkf2EBAP#D zyN3-5J0;0B$f$ckh4h^wv23i)?Ingeg^TP7We4rwF;X@*<&HLPjTsflL^QBzcA2{L zeBNCghlof(c+IwklS+SqS$2suoY(tj^7QNJwKG6)o zU^JCU&Gf4K0a#rwg=kPKn_jfj%uqqz-Kwu^n-te8hzH#D=ClfV`0I<4&#w0P`5_Ft zLk7+^UXCY)u0@W%o^$!qe%*2=q3faL22dcKs9Z|a=>Lm)4=4`|%641av&MDac-j^| zHRyF2Qcoy2IkUivq755q@0izI_z|{E`pwM6w!R!IOs=4kXR~E^2PnJN!6 zuwIZrvFLy9UTgWe4;(HbjO-2ksHsVCgj|HZarhr*FRgonBYAsl?|(Af0RD5#++hoX zGj&Y@7*v1)-#}k~AwO;z^_@Yv)!!UfF7coVvNtAiF$5QDK=uZGRM*5t%>bnk*8ll7 z3^4ZEAK%mg&|)69Df@?c0#m8|&sSt5$EkppV~e%8f0(wocsJ`z%)dbsQ3oS6b^Y<(AAouF|M+6h|FcV3G1G14CpgY6BHvbbF+lC7i8lZ2v>^BoypG|Q z^nN^t6Zk{Z)IaHQN^%e;;?^K*L z6$7&JpoYnzzGiwT2_Q8TdYt}FxLuV2Y3qrP9+kMtf%IyyygyGF!XL~`x#%)3ZN%2c zusCeT$hvfdkNGdYGz;6Uc-o~gf9Rl{T5^5nsdqOLmbgxigjejB^+w_AutFrBxz}UA(Cn z@8(v2R#a;|lE11@f5f!shx%Y{(Jfvc_WXdUMVYe;zbl?PqaZ1F`YBv;M}osc+PK0L=qtoSF^ArQD3zw z7`~-drS^y&V-8qDac{ImmZg^IGXpkB7324TH>7>`+FBb?x_I4p%RO|j1L9V*?d;MS zc>#?uf$I-UkrY>yaKJ`HXr|)E7gl_l5BjWP&t1=4vf%2S(ipj;hG@-lSuwa7WZHnu-`i1pe6B@TcCf3ZFLNqYrGEeAI>F79){cCu zb={N}7Htn*Nq>(lr2X0X?u~%btSs&0*13@#wUEN(sZ596GM=N-QegwTWwX9x9$0?R z{TQ?kVy?iE2CtRR(XS6YG64+r)ik~FURv^Uyxh2Htr5t2krb{l+1IL5)Zy1y94VHc z%Wm`Y@;+fPV!5s!pE!kc?au7(hxaWmm&frhhC8(!iSF1?ZQ|7P5l(2=Do6Mw>;Kfl zHa&pgSfJBvWDJlK32HLY@_~Pu$vQ2>qLsMJ5xgiast^I^FkjX9j9~p~fgj8dEx&{OThn|^HdHaJ>5{jLbU)Ft3*(hO(W+F|+&|Gyur3Vf z_%#~83x{{r=xs!m9duQ~6$VD1QZ{8GN7kz`XKdrdd?;o#$63TibQc$#W0Hs5RL5^` z%4te~pG1Z>45NY+KjvR)AkMjGQW8PB9);JDn;;Tiw!S3^e=XneQk5)WQ7sqdG#!3_ z*xt{7F_UexbaiDma8cU&9u&jm^}@KiY>^T~WUl(9#_~ zB)!6qm+eB@UwWM_SUH8GeM3jU_x8)C@z>X4w!SIy#cw%Ad5bVb6~cWvS+VCPI19kL z3j_|wL5h~p_3%{!-NiKmmwAhom?))ZQ9pKMJ#Z(|AmO~_P-SP60k^zQ{iqkuwTAvK zSK@3UzE@f8cSaoJASSI8OK_`DpVf4ESuzMcx##l=TtF7p#~KpQ?7pC9mOm*tL1&oK zNIkWF-C;tncHVta=BRLf62YGqY*00u4CA?h5q^56#p*O2B^RVh2DM@|<`m|6LLj%_ zj+-yG+X%{f-XkzP%u1gxu;6Z!uLs$T+UV7CSPzw(V6<6=uSh#ZcQvr2(WiRSUwf}Q zl)t)eSPxnFbsbT3`1RB!!P;x;RFFoYpld$(1bbn(aOOyL|iINZLvlOQWIx> zBJXZ;h(vv65v1@>W>r~n?im2!Rx|y2^{Xlw7&{oDAA3=5z^dUx>v7K1pI~r)Bot9( zK4vT+oYXb^va%ni+C&D$SePay+~9Mg^|l|(VeMM8b+fQb+Br5PidH6yYGB&B zXmIOujjZ21v`?_35$#^z-r<)m!HaD1@K^pD{XVxdf>x6vKjxldC{P(>WYn#}O> z@ch9X{SPPT5+{1rS%aRJYE_>AP#1hG5^zESpw6B)SC{h|2_K5flC&p05H}f$u`z91 z!*hU0Eo>|swpYRfEBJbcon)*gzD%xCM0`7c4lDQ6gw`oaWtij^oJSn-U47jUAN9}R z%=)}e3{M|%Q%Xc-P7oub$-{46mO7BM95d8jDe7uj8xPd2tRX_-4XOy$Z_k8WZM$FR zSFB4XjhrV@$hF|_2tBKuV2S%gR-xS|q7G#Fn}uA9lkS%Fcu_(5*z}Qdm%B6Z$=;A_kkHL)mRO47sMy&pF)=C!MbTGWN zHpn=Zd?Eg^PI;Qd&T=Y-DWFfI0Rtku02w8a|HS9rmInQTN~Q@nnc|+KV=~IypNm z0SP6L=A7B14zFiwQ06gOwTW9RCWi|sfaJI0~LBB<*4@hd*Kbpix>{Ijsl zUtH3}0SOa#FdHL1;iF5#&3^z0?lUOYDr7g^kKfU>`(*pu*mIaizLc%rN@PAfZhp^M zvJ%n^*Qz45C#~f&u-o@p<(51n+{@ut?^;}0f&0CGZMic^rEhPTtoG^Iwfr}nW|rk8_pQIV(dP&Df`<4FsXDF-!LpTYg?^2nA% zNRdG;t7cc21rbJ-D!#BXEs0NJlaSk8zwBvLz3Tceed=9q70gf|d3*7@DcOjUVU#UV z1VG;tva+@^7q5zw+s9`$F1JTNrzVD0!GoJy3v^%{%md(`UJ9sFj@R-=F-GMmP}qg< z_Z#pPEp>+xRN<27I&;f>tc(i1Aq}X-RgN9pQ#ONr~Z6;P)sk?kM*WSCKxUqP8KuVu1 zrf=v8tZZsvI3p+4D$1&&XL~UlCn8k0bUxvFRDsP?<%%!IhoioSWG`ts<_^ApyX{c5 zAIzMn&aeognf4jWspHI{9a0KhBvoH7oXzJ&m9sqmtO%ryCb&^o0YfttI9PqF_!kzK zVzl|!_B#VtsWO*)k!SXMkMuJrtly2jXv9Y)7P7t3^n;5&L1Ig$W1&|m#N ztgUBK;+{Dme);;Qw(xP!Idf11ea;Y~=o!sUFc#d^W(Lt6?pdmq>FhTT{=$3E?3Xh+ zpt(v%WX1^wa>C7G0jCvU-TBkFnMM4IpV!H?IV~40Z(=83~N}U;PR%0dV;5glIbw&1@U9 zvAXnrA@K|W&5bg9MrYFlN{lIo6q~O{A0ayMxRIG7sT9CA74$;pk8Qa-Mu!O$ zYabW!(xp0#(1|*CO?OUI@&|dCy_7VQKQ7XmI9@Cwwj6Mit6bg{p8D%pLUW|{*Itff zR|S#kO#@~Iu3;7x>S9HWs*Xjr@x||}ma0cK$XI(AwN%eZI!Di|(=y7;CI|4It%Y_H zt(9HZYmcac5_%p$i!dpSn91pA|NiJ+=bwIWcdE2PZNl0#Dka@og=4{TiS-h}BKYez za;r3KQB&M5!B|brja(sUV+?YsC1J1H)r!6V{FV!pe>-WYyD}D%Z&_Ko8LPj;=m@K> zRjSAae~#@6Jl+^0Mo*A@+dWR*<^82iD~-|$hQ7MEm%35I!~;b8&EhHoyAJ)mYs6$h z7n|>br#B*kHsS3^`9PtQaz~)>;R8wzlghs6;d+PD@qnj=!82@*3f8YXdoKECnS-)C zOkQ6}JB@!8&APSb`{&KXlre=4Wr(85dN@-^j78QEPuS_Hp+RhAJfGR{2MK5R6W`PY zygt93qOK4qQtkH9!~w=A@2A#pt$_(%A2Xcya0VJ2$cN<4b%Irn|23gEAC~a$Nh>u=T3Noz4!HA zN6MvOJH$IEhO}BmHFWI-E_~#<<{<4{A62<>M8L@6s9B_S!MYjUPy)zCo5oFdJJ+k# zssBs3wmXL;xwm!-V~57DRP%H!&|G|p0r=MK5ux?>EPQHo=n6*r`1Wa^VW zxeFbq#V#dTS#>M_H4|!w-2KwEexVRytFY*emB`UAjPrW*rigqSNnF!{dU#&nqemPO zDremieN;iEj3%&r9heSO)>$w@`2HAsZ!e3S2hvZMC?sg%y# zC?N|$lu?XU(TS`uzcArN@yV7)>bh`#WXpXp#K&jHYfQ!Aha347U#b3U4^&q6!Aol_t zF22X8kCYUMy4*&xGZB7km6AAFY~I2>K%teJxxu5BAa>JMKkCu2Gm{$!ew3<`u9-+o zt8m5EyYkKQ5d8LqKDz*AJ!1!cx6rUfW6e2I{o7cyT@9LC*3qPm!#@cVUcN>NnWC!Z zJ)*d8SMOLQdc^8j(R1k7e(7jXl!mD#*ILj#uVD-$X8mz5gv0iZvpOYQnj#G=cG2UW=k6IG zQF@m9OjV|ccUxK*(VLE&Y?nn(9`fwTS`7~W745>(y3%hZB9?+J(UTT5CZ?JL9;~Ay z7E6oGMb(Pz3w%V48E0ZN(Z$OSVP?lvE1jLTFcP1V*+VPBdr*R}KQ6Z_@eBWlU1rp| z416!O$lb%M9~LjejiAsG`fT9n^f%t%sT9PrT6w7w-p_X+(XJb(YacZd*?1?4QA5+ z<-~HPPh;Fs2Uef0{<|Ic-$!BkcE}#XONU_A{BO7a-|DuRKhAJtyh3ic*pMxVfNgk# z?G|`1Jgmmicoq(qXmEF9P1gG#cFm1by4Z^KYt74ZH)a~y*4Nh^X20J&`qhMOcCx=- zYCXoe&Y`TTiG7qOK>ybv*!PbAZpXfry-K1p&c~=SZx?eHt1G*2BFo*Qe(i9|qI3=+ zw*9@TvwZmlX3}Zsum5%!d0{%Tp! zIrQ><@XPa|?f(27RF#_ZcLN&P1vzoIb!(`f=b6OyvW%n>aA4}B8SX0S3oYbt)M;s< z3}ldU8}*um{y)C}TsZ8#Ri++8kuq|!P&G4EC`3<1m7)KKZvwtlN}SJJoak#`lu@f3 zbSMCg1V(zDJKr}>K!n(Uke?=KEYsHzKCu`(KrTBN+hsl-aUmHbMt0tM{)g_^DIFHc7`$KPK1Q=P91RwLT|*|3fwY879Hw6vk0?3-()nIq6J?JE9j3- zaO4T`{ON1vTlFj`o2wiRyTO!QCai^EQsBD&BVtAMdPr_dq1Llst(G=?m<>p-!ko|f zjD=C$7vAxGrXSS6u+tf=&i$Kh*?{Zxj_VZsjH#E%o(a$&7!Id${c)%gmhJtWG{O|4 zl8wh@El0jMlkeL3+kxX^EmDP9!=>6m|Y8cBZe5~jp^XcOfGIb z5KY*ID`psok%sI*sx`RpB2`n7I0ac_!VwR>5jz3FP_Mr&bky?a?h~h<;0+J)t)6EN zaAZ)c`tzyM-qeM6)LZoj)(wM|tuR)4Kh7${Jy^@1?h_8CLM+RimcPA%;KtiVQUV?a z^%2ng>HdjPd~N=!Noxk$R7~4v{l>xDTBk}r1F@P=MHK-MBR)8|h*_~1%B4$NGG4Ts zSP>%tN;l2n4D!=dtV*g#B!O7H@z1|8mJY9IJ$rFL?A`UB1_KC3oR+EJW;cAW4j-iGqwiL% zUJT(MhU3lEoDq^vDaPz{Hm(h(VmIa180O&^9DPp|p8W+x(mE(QE|fADYxX}sbxa27 zii4%|AvtQ1)T$OahW93+p~~=*q6z{eZ8ZE5KfT*w%-VVC-e2CR>*bDa=-=9 zjT4Ypm^HvONf$9B$W#up%om6M>4_bipu9bTA@qf`x)U=4)ns~P3CZjC zLaqAV&8jOn#xa4?J%@cT(m?h2>MjW{IllbdbS6&Q9DFoFrx1{LRx`p-{)aDLG<0c_ zitDyN)m@yQIBd;H5D^h^=yF6kUYvWu92P&33VUi9_?&^)VI|f2HBOM--Q9Scs05FL z4I=wIf!lr~EkOibKVN}r>f|TuJ>rhBOQ5M%R#rXZ@*Kj#wv*Qfy6nbEC7}8Fi^GMw z<{b|SSoPvxPAh?DGB34W|9>r$p>SWC#}SdGwtH|uLZ&a^y!OM{`mqi)OG{HTj)-rJ z&+E8+pOnyBDOJ#N*ufdOx*8JdG{whGn)+;3@9_M1Z*|6Wl)rU|3PK;NelnxzaxLN^2p5*JiTpRd94bXz$ zN7?r)oz(c9E(Xs)PET_(CA~(YKu{CikmHwm+rgZl8tyHxaUgZmCB5<%{412ss#q}w z21e(f_{SF|vaT+icMVKLOb~0}2Vi=i=T_c(BQ7BahKIm;K~pKKS72{Fn_4U zPx;ZBk(er}IgQ-a=)jrs4hBfEilhU33h$7SydW!{%qmOT-L2Wl@MPp5WK-giMM47s zc+F$aas3GOmP7s3^|*61&|E$Ei{dsH9zvy}rOr8@gAhZyaE7 zbziCS{I-w4>qfGA-6&%|M(zA3{-07%D~O@AXPO= zCx9NRSo!2}i-ua)d}fL2>8$GQs%0bRB3JpbE`|EyA@1rN;1-vHOE!N3TyPl~sFC`q z6`?^pHKck1+U>8o$Qz1%-YxY=Rl_)>pMvlq!ReGDHQghmht|}=keUxus&E!d7%<7a z-)}BH=Y}>JKjERuWhx?4)!kZPxTUbC#+~wZC7Tf=BXxlO=-qSWkkj@LvO_8SZ$9=v zM%}Ob{3@a?)#+2+85^MGtec8B6{5TJo8FeBeM1^3aOKLrS$I!O=8(Bj$)P{oX>m~? zM1YFQu&b2p0JY?FKHcCl;c(z~XnG+;1Z6@^>YIj8@Mm(_mAYvQ@BHOf(akR$@1yo2 zfEGbl@j!?H-xUF|zS$eHpi{dYu%U(0n_)p02&K~Hn5gZ=65ZBgDcEQ7Pd`%bq3REo zON?V?gL|`$gC# z2xh}CS9n~6WS=;lQE!ckt~nd?JZLd-IP57y3A^#L03$UoIyDO&eo%9i&YGbMrtt%{ z1LG6^d-#m0GVfn$sb|XUyu0k|Tg+8w89LEw;3rR$U)wXk>fIIAT0^FO*8Fnoj-SM% z+=NKV;NB*7kWijIpjCIvr@5*5c?A&m!Ah?$ zFr)LUOEQI2SyUS4UD7(nI_cI2zw)bDyx-6ZP}T(JAtHT|mL`&tMuh72a=14#ZCNwL zgxwD0fHV^ju+m5)%K4fM^)ld?exrB2=XM9Z!|E{0&IB*-#&kVXMMXuaNgLL>8%}1y z@nl|~D8IhG{`T=|u~pb}OyAYv!l>!#z|6z|n_wv8lE~>VF_`mu;$&l*>!Ha+rOkM0 zg6Cq4W;se>^+Sp%d^ihDe4ESZMGH&-8`wLbGN|{eVyJASnx_58f)}v zWY(>ezr1^K3ft)p?mL;cEBioQm7!YED@9lEQ50UT1uDEgwH45^AizcnSHwO5!cZRP zLj>pGF^~L~-!o-y@N0fvq^;bd?sCW;*r^QwAAXYU$y(w3l}u@V0KpfaSRvzSbd#t_ zG-;h2S@m&l9?ccFRYIu0v*~Zj* zd$rGG@Lqm>dxc82XSM}ZIRe-KzK6gQ7ItI=S1L}?m+fpFYu4?{NeBy;?2fCY|`q%dRIG4E9s!eIu& zGB!}(`P!<>Jb;(vPxuG8)02=nAa;1x?NRp>4*sp>GYL&WFKMhsx8Zndeu|;I2NiVh zbPBXx3{ZCyCJPTr`IEZNmsjfXjGRf)4yFJmUUB-niIu0`m+=pkW1!NwNNPgl7FrV5V(`~zXr4d!tSc;MZ(?m1+ z2uS1N&Yk`DT`zA&Oa*=T5?aYrucEHgwgT7-v*7Q>V>kxbkgE{`FOM%1KG}boC&3(i zB>WB-;ThQyr))fmWeCOpK2{FsgC8+u3n&X;A6V=Ry<|=( z_-yqAps^K2+@OHze93G1{a=s1UJm~LZ-X;~)ajv#-(`i;bB9-6=3NZONHin%rU=4l zMRFN2zU%M@Odrm=6bQ0l4HJi0T`@qSx9STF2+(@{ zw>fI5LFx72cnkFVJhFCepO5Y@iG#nC8r(MiqDEaXpgh>Kr7e-12zA`=GO6lTiXl|p z`ZdI7JgfK1MIZ#H4dm1g0&=Z(BS&7BONBG3K4)`PK-nu#TP_IElYANn4n z{<(&~Ss^$X*_M&Ws|`+s(l_s<=kuA%U;BQH9xzyZ%$(n^gUD0X0f`4}5Q=vz?R|hD zUn@w3+*MXJL4-bU{{EVRETiGV$*dH%3GZ7hH1upv6b3wJ_BUG)@~P)q7Tr^Xh7QT4 zRdu}MRV;hUXZ%(z&1CPPJ3o@^r1zdwMcb=qED4UH)2`-?-6LyaK5DCoJTQ1bdG&qx zjpvyDj0mF;Cyk3@N#XntcUH|FQ)Q6+eFPbJlw-on6hTlYP>ag8VHy7_$2V1!63T8k zw~#7td*xaPdRZYrL$HiE$P|eLI;;ZiI?}o8Y!Xw;4)MEsrUGCm_-BX28xmsroJ>u%E_0K?Il7F$^he*2exoMyU}`7=lyq#31WfTN-m<>HX=vqv)h<`2 z*aIAnsK1#QvmB+q@!1Wxb|0^w%R_S~hIaV?8U16xRDr)1-RGK;? ztB;guI>)MLQ|d+L8=BDLu&xBs1#7cV726 zUnKVEUSd|JkDzk%D?Q_iWiwczuaAU8_b8Y9hCFf)vnvbw*#1I&d0>+yDko-tUBGNU zlodguSZfy+DlN4~5IVvw-!KBwt~v z^w3w^z}TjAV%*$SGO^&fOI1M)cc-b<-e*EYZ2x0RNCT;l;hsZj4gFrt zeQ+<0_;x+kC;OTWVVGNql6$SLS);c33v^Rkea@qPb>(%^kcdfM){<6pK1+jq0dw@G zEf=Pq8`3_fdu@yFFe~=jd*nC*^3oh}t=y528i~NO} zibK~VLDZmuQ`N1VTn&9h6keFpB=7XgIN2w4lZmb(O)d*7db-+XoE#i< zyu;)C-y=8GqewZxG@?txvV&wX-PLUC9!!Hd8RH~u`K6Cc25MN=Wfrx$9Xhm1zn{Cb zapO_8RzMZya+;@J#B#n$q+l{BAz{xc6NCFU?`B(rz!@Gs9vvFp@DgP z%qsXbQN6eJu$ik*{7c&Bie%LEn`3lXs zRXT3$ctZNgmjWV64ERz>AF0quvE}3C?L959vDC?ADdO#t@ z4X)kQc1!3eZf}B22z#tnUu}=>Xs|@)Ba4xDFI2^v98v(NK^OTKBHik?;!Cr-6%~qjN8Grek3+A$*>8l_R zW5u%qFJh(&Nq-dBmP}xzwULAs>HIVP>QW7GB9T#Qb;PQTe59H*%|p5(D<4 zeZrvkRnc^~_XCxwO$N#x@(c2$Czl7qs(M%BjXTXdDg^@3_YY#E(8UX{l|DUh2=1sU zJ)6?+DQ#&GN`lddM#gr0H}s+HX(gtiy3U;j>IC$94O6NxjsJ`w6HpJErx16ccK1EV zQU4Ch--3Op=I5q!XXuQVIkP(yUl5+Yj|i0zZ=S3ePG1q(iAgR%L>a`OAwoNPko;rM zbRFe6aegpP3?B4BV@M=#8EFw4Do#|Ds!Gm#45?{8lKkFO`3nZKTTv^7`ALr(&)G*= zd1i%4b4)U|71Q$9lLkf!;!!dZslme!dxg7uT{2Qr_cI_-0D`XfAjL5#5YW#Q;$NaRj3zDr=s?DQt?7-p~hI+ zB)$uPHua|KFx`t7mVPz5uC9|{s}-$oG8`Oz2nkuK*Ef6Az5Rc8QZto?f=vaW$`_ia zB@yc{@qR4(9dBjub7R-pk3aJV5}DQ{G|QjcEY%%7nns!jTUOn~*d2-y93o?A617$q z=K3Y_F0V({nAS5v4x8ADJJrEh?Kh{0iBbPr3qQ55(NFoiS(0y_Y^Zs^nuv3-w5-BR z$R(suEU1m}ocb1@tmvc9i}7G_lHZb}A$CJf4#MJWuHN<0+0mWdjWW{(Z_`NYzF{C2 zxm6$2wbJZPc|z^gPc*sYt1(JxNm}HNnnIN6l99;$$Hw-c5G-Zt9`Fg*(J-4Zr+5CB zSb(~G{wAV=wDxw@i}GOZ@Hb#^FtA7g3aSj15IVWE{S2UdtlEkcC5Oj#N!8UWfm;{lk+Y!OXOxRfOCCJ{w*>AGduP;yf|^(9J!Y z&Ze_af@uP8bI&t0pug--)7)Z^EXqs zOhFy3%7Z@!@If{RYQVn4isiqWbB0kLao4=K?w}Fp6tB)!*!pNKg3(GBE0gg-uIgTN zC0Wdkbh38=w(FMM8s?pMP=s4Q@?W*C)&lg%m1QF=xFfr7!gMA-tqZkpTq#IpOsC%F zTN9S$SXmm_+ZU{Z5&jrS|u zJk*}|uH=8ER%3Csoz?v2kG6*Y5BB~$t_kJc7e*;6VnbyiDpG7<1(7BlDV}rF>BDs!Hw;80sNSEXy*AOk z_VG�`)ga?-sU+Ok}j}cet0u@Y-WdRtYm2-wA%A^nOQRu zSz)g)<&B+IxcxmrxerHIDz>Y_nElsfkezy6bXV$aqQyDaMR-x4^^P5zU+?|?JbW*A z%8UU$urXG$rQ3!HIgJM*Df~LJ3U4r1^6_UbT!7{MGI5e0vg{9ZJi{D}7r(4&9pPOH z51-U$q-onUJ1GSb`PQRfcZb-wVau-;ykwq^$Rk1WH3%e z;Z2q_ZQ?)-<4VW#LY>vuUx&I#v%}Jo-<+9KqTwPGipUt4iY=iZG6=A1z^9XH{o)WM zo~9MH>c@3LJnQgJCpu%E-x$2Ed2;K)v}>u)*9~rz*|M=>`(GQ^9lIct@oM|w?HSuI zvcKi%ClB<3rg4(E%?PdhP?+Dvm+Ft~ZhLjK!-cwXuK*E;4lD@@&3xY>W6i~hBv8Md7bm~H~OJS6-lAVAWG)H4QS&j@j#>r;WOKnC` zc!WPA3VZknvb|HMe3fnUTjsjh*|e|TgCV1{^{hD7u{ks#-;TsPH7~yJ_wFO}4Sc zrH#i{A2&*`Tep#|113PjUlz-ne1F%beBts51r%GuN2GSID!UcesZtt>dI-lEkUA8o z&9jTD$eY3D@O@|`SLb%KPR=&=cS3&&76C^mU&OMp2gDU1I(4Dn2B_fv9i_m7y@z|V zwy^0pZL_Lq?CsGonL%#&=Gb#62*a6qn(bTLw|sc-4`4+quRCEd>duAj)ZJwC-6pJ$f1lUIao`!m6f_Y!Rg95@;UOjeDp zWBj#D*C-LsxnY8-&SxdIt6UO*GdH)@cz*PAr_RJ>pZ8SpHly!;!O>r|9qzR=q!BxD z=N0P!swziYIM~>7j68RaEF|xHnar*x*eigXeuL?aK*MX_(saih@)M_vUzsbXG_$KY zJq_=zbfatB05&xpPnp2PFJ~4$8sKUZX+SZKZMw4gS(}-E+%!FgDlD9zx2*sxcisC5 zF&*A`!y^O1b~E8u{{SxXoGW?fT#FchQ1!|$_cpHYv{E1QZ*@LHBPFejqIwJt<13yM zve`2p{@Q_W-}}nzb>5gN_8RQ>tPeCl{Haov`R6?;{uEWgNwc$fQSys$Fof7DHGXB%F{ zuSz}aAMcSYg{d?cKbYE3MNZcF%DsNOvOwdsd$w~05cj+n4<0;-WBlprExsr1lcj$^ zX#kpfHV-<=Sdin@v5Sq<=H&{9Mb+4Hj?b(|L&-q((Xm=Tk0nL-dyQ|quG=igv(CvV6-zB3qjxRrVXJG#mru8R!CWyTpRqyRo605^s<3T*{geFz z8j2qJ;@6`+Iclpv3?L_R<~Tn1SPA#r8TrkN`Od;q-?4QBCobL%*4WObZA-pMwotOm zOCtJ@Pi`k~JZT`rcJ9c}eR}oWe?e79IuMm$KggFFX|AvYq}6g2o?y%2!WVGUKtx)9 z@YBJ%gY+Tc1z>6x@9PSC^ygBvDm57yO=N#{bbxn@4(M*DlJO!oabu58K5gXP2~M{C z%QBV%VI$T{__v)OEg<0*^lVN<%V|d!=p&^K8m@b{>+jJV)&4*B<@=mBb7`5_!hi0w z7Z1r-Ldk?4v(But&kB7@Z+`k^b9`E}@i9Q$fBQ>3j5bO+H~POqw_}f;_o5%-)c@ji z<$j*e5V=Fe8l&2pVD-5FZOT`^B#z8R=Q$dKC`8gfH-6bVWf<6#E|5`WKjHQgG!|qo zlQNgK5aa%T=QNqe)qCSKNH;&Km3$xoDRAsCIf9R6<}(^qf(f!2fO zF>h-SlZbBJ|In3$1B1Trl9Yb^e_$i}-kmlS;zLv&BVC}=D!zDayBs#n>+4%&Le16O-2-Gd5XtKXj|RqUa9Wj zu-)5_HJH|UKYBOzHp+IQ_2K>9o*;Y)ag3%^g_3XfKe|2ps%z42OR(&Qyc4Bj&!gjw zu(1dp3$)LkJI@LwYd)WWj3p6$l0VJexxaxkRj!zj5*pL4p5MHrma!YKV{At=mxPv$&V!}z{EfHw z^ve||w~MXwdHfVtw@4!6;*)vm;3s%qzBH9<>=Cdl96A<2Ixa9A!jcn)(R|>>A6qhf z@B5+*MC?T>HVHeC(HrtTL~IQHJ+a*pxjyJrbJA5oE2XOg&?Sm1ksz(u^gKMKH8Y|n zlE{8sKeRLmx3Nj*c28$DMG{WU1-}y?lq&|xrK@swRkHQ~>k=>Bh^)LRo?Kl(I&;?2 z#Um*9eCO6zNzDz52ZonkE}N;F)9c4_9f5|5S3))uY-;>H<@3x>T4BfalI;ovPj&C< zCrq`U=DC#3+KBp|MSJX5@?xpo$QXXd22ZOqpdF6AjWg1qtESlff>dr3mqxCMQ*9~2l zZQ$QCR%%wR@b-?V+KFN*_Kt_uU-bE3<4xcuM2z4O_c1^o^8P1l;~_o#qqww5u2Tsh z>HA^Hvf+JpvIMY;gg)kitAcoc6Hn#!JXMJ=61PKv9+_D7r-e}>a(VBKfNy#YK9=w} zVDHV)wCb>RGx7^T#8oG9eL6M0P*nAV;<&A) zp$iwfV~kR082YM4ze@aE=T?z;&<20-mf~6CYTi03TqWg)E>uD0$DUK6PrEN>lJ0Mx zJ`_}~SgtC13}0{`KYKq*=%(`Z*$T!w#|#6@)Hjm~hu3+Y_!e@|J(vF-FYx~C)!9Cy zRV%)Q7ayvUxY}YRc6s^&H?PR-HD>PsCw!|CpDw1}mZlkSKZQ=rl}?^VR@fVc5mnc{ zwupRrJLIt=%O%IsZkyRmaHZ$K2Nh~x%|o5R9L}54`c-&?+X*N)mP3CvsQT`EiF2Aj zhq*%F!G3kC-r&D{+p=o77Sfqxu*HQz7|iHYJbiGp*R{jvuFh5*F;Lz9wMo@HQnDZ! zBw2BcCrAC51^?^G2GUz3;)U#F=YBfBzW{S}3Gn5E_*iVjaPCGt=Lc~Rgn>{4a^aT5 znUE8&FM=|?7zYr5&!>6mH1tZ7wfuzS0t%N`bebXQkDp>1PoLTFp4DP}jFSETasVHHk^eh5vZQ-P1*zMgsp!KPl)tdS{y159 zx)&*!Gs)S-+s$PpsmMc`+ueW+wHEeuZsc{bs6J@z234g@zQ}259GTgy?9q!gAOAdmD!BXEg8DXz@n3DMPRt>cL(A1>?mKOYmP}!wc-&_2n zjDLiWX#zqc6E_~6%ix>Y)ZoK^td)28+Ka>&i*&sNE3Y*&B$x5)wzgE&mH`8MNF8sU z)~DVoK)wi@UA4-`y<KTbgrRsNu1;ULgzWUjzn$_t z{3>k1sAkcy!Pk!Z_1tl27T2A)-^`F=+pXkAC*g7{MUj~yT!*@4(^8O8FK^cQP_Ct( zCNy<(`3YHk-zb$viWn>Va(+K+@5_4pGcgY>lB-V&N82Q8<~OrXoy|C-8`^lLw;+(( zqY?_@dI3sL%G!J-F()}_Yup$ zcHB3wcCrkQ_n)asG&c0UzaXNYAl6`=FgGAF($nZHsd7JUtvL($#5$;VvWj=o#gWt2 z7Tc;kN)~EF4YnOQ#N))Iu+wja@~|eR3_t9>HJ_lHXxvMkNRD6#gRgq7=JT zW+G&?ntS`$LI>^?IaglXbfHR zW>iF1jqU%?sHzOAQ!>8sGNNK`_U`DdDVxbGmsdJj(=GhJbP}6#mJ*$e3O*|(w!h@^ zb^|g=d;|e@w))J)tPF<6F>NA~*@VfKiYLWn3kOWiWV@*(^C@#5b(AsyU*nf06Pz-+ zVe(D$Zp&Xvm2Ey_jv7 zs?3q@7~G;;Hb?4$Fakm-0Uw)Uv$|>%y0UFr0c>nO`rhZX^*oN(d9fXFF_T1IUpQXp z&G@gYMQ85zVaZK$c>@gR6b8=*!X6KI!-AE;GGu>H-x3b2aty~=kac>sO`oee^PKk> z+h0bbObJtyY1lC=XaGHzz!fkwS9kTN$|_ZsNTloXI8neB1IhkX#)<7qYBN(d0vtjQ zHYjHKKR(05RzDj2I*%vM%2Q~5l>OCSZ|jVwy){o)@urZsRYnN>n9JDN<&Ja?XUk|f zGo&Ob#FlmK?@RVz>|vN|omU8b_|Dzxbl#^En-#iRf2c(q)6Lk%7(g}Hhyi@YEKR+vFTgyqw_y~;EbP}^OGwS7y~q%VF)>sRJvlL4{Wg7V`F=z z9xbLHxSL5CL$a8pdeeDHKlK+!&|~_7j#m9MuQ}9Q4U(?5>r*z-X?-eS#B_-!)R|k} zaFuSNuCk6-TzAXKUo!LS@E3j_e&^eobYWNeAT0vt4PbO%gw6r%uga7p-#b~ZS@3hY zCs|B3W~|zE`04D+EX)0^%>UxDTprUYuQ%AUMtcY`NgP}uv6N1&EAzhzMl9;`*6_O3 zLZtwDCRH8%y|abn{^}L|BC@ArMxp9swJ4w_6xfJG*8# zw`U8=!LPfW1I;h+QRJ^)jTY;WHYhz8+F0@7kldx)f9LrE@qIPcLWe=bw-fHnxvf_e z#Zz03NBm+Opjft#K`bUx6Sh*ibbFs9@)~Ol`W}0L?$S;8D+!+YTO8{SM$&gG7L)yJ z^Xi^{lnlMhI^X&I4b~U_EFo&bqH3oO{LblWIlK4O28{&27MIN~OXQLi8b2S}7_^q( z$7|PZytGDhoL#b5%!X8ZB2LhLWOzK7Ak9NvuTGC>thkN78O6X0UH#8*43F!xo^z$S?k$*-d zcj?(q!UT)F@^Oj5(PSQ2Vt!uS!~W|;1w*jo^%Isz0=IMdl0C3yya)-45e z6DNK$R#y*P>RAoy^mBJFH#fSD|32r|KuDH}0f>1|LvQtaOZkF&b9%6(TfJue?aBPw zdMr6(?*H0Fn|Ri=DQ;-Pw%R4mhRyG;dwJCTQ+VP4xTlp+`_!b$t<$ec#(*#-2TP$$ z&z!{Z6Xfhr&bae)y|wW;v@RtXV{)nmUqmHLJ1g3?f{Smz9002L-0?31A_f%P+orX_ zfRIM7-~=}MR>=eNqY2-`9BmPksQzROW!S^r@zz^&BdbyW1_BVtcgONw&D7wO?X65o zywOXSt>L<_UDqg7*7!Pb3 zhy~pg>f`OhROX%z$%9c8(YVg0@L}|)Fweo#ZNlccwLaLzK~JiB6Zec|1y~o1|2CvW zz?!DR2QYY`l35LkWR7YblmW(6qI~o0=H8M`0if#0rF>D0k4c_{)YlF*t`-botdfzN#{G@*WfUG9A< zkw;sfc_0ThrTMk3lSf)z+uk3R2a0<1fNNWg#Nz=jrC?m`Xr(RMh~nKQJsdQ<%ay53 z>3&S$`{5_${gbt-(we!FK^?n4SNo#T0|fL}vdch<;s#fWt?!l*s^ zJdP)~OVv8>WG__pl)K^psxRE!%mv(-T8Tb~g6GT>^*2TUY1B`A?%6VVx5ak6gq>8h zaCdGRu%sa4(NRg%_l;gnAJ%=ohHILqcqaR1f|t_Cki-k+?zuqI+!JqTgTbvHpQ?$9 z7)-p`)PUucJoX!Mit@8A04n~?Ijhl{ za(ttnvdzG{`f7-T5w5Z+bpF^*UpEDU$JiTZXeHnhlw#szHIgAOrjhfu`Vf$W{QG zdZo+aeg2n+D5I#ixYxmJELOx>7pJ;#J1r0TJ{q_?_Tp8^$?u=&qgM3 zKTAaq4~JmlGj;*u5v07$p41i~I*Brk*LIf%4R>_up_lx~H}+Go7S%deZN7M|QQs+D zLTY>WRk`sVROZwV_N3PE-fe89U=;m*h0I5VJc|AL6K=qLo6JhZrUBRzF}@mTub^>X zTtX}c^_4h?5;_Ti)bN_O;2qJPQzM;jJ22hKr!8T{{ZCnfFvOjAA!aOv+Qvey5mSB0N}yG%p_9Q(F!kcBuqAHEIsn<$)7h zvDA|HH+8n;#OWNOOmpQTpi+&7v>E@YXS0zV>w+qSHMISWF^<7}?$*%pC}0hA42AJ8 zDr?#VH(Kr2h&a@Xs%^lP-b+gD@qM6TLq86%W@3V(*ek{4#3`i%j!kB65nCn_0(=ca z%cAsrQr@VOE}$snFDQrHE?>lnzRLKR7+AgByvR#|JC)#eB;Np_X`pmreyOrZ@%Wt@ zmM`@1K>3}lkB5LWA)<2Zg>EQVFzJia+KqUX0wRV=20aA!WheSJ7%0f4r;&Ow>0UXp zQ)GqgYCXC13W4*!F8-5R`frTP32t)RPR31ia_@|ojnt{;aX~q%*5F$oKq8~~^78oH zffk|NFciQtpDv)8Q;$B9zTEr89)H2t1-^)BVm_-fbQTOp{&-ld<7J|mvL=HxgugU)xTJ|2 zQN3=k`iq~u{2sqAG2rolC{y;YxU%fJsqTJMn?jqX;iIzAh(umpa+|1SoFlM*R8>6EEM zN{yU>E-n?WxeMdHi5jYdFYT+L*5q#6k9l>*WiI&i7GV=7LX4CcZ%0_6(C}dwj@u+N zpiHS52s63Y&HPIQ_cM=^zxl2rR*5kNhsB;_(Jx`jgu-qz0hTMp@0(nUY!kYBLl!l? zrz!+r-E`6W946`6OW0dMj5_3=uxlp~w(aF%vEr`Vm#6CDk0sA8Mj5y~cncUh)V=QV z9143_@IhCLYrRJ2VCNU|C;TlXo$)(4Rg(JkQwJEnt3M^^dy4&1)IbIGdn}s?qJeMt zVXpz_xH=pfHTcAb~@qNlg0~58hcV)M0AWC8```kb`D8?p)`G};(Fw+Ub zyF8V=s-heHpqKOBsuS~5Tn!gS6jdq=QGEUGTfa$KM8>fd&_Lq@6nydL559^6zC2`< z@|ktKB2zb3#~%-Z%w^>;O-}Y76Z&R=DR+^z~Yss#v# zeK@Ee9#;*nauLU9(khi1`?2DSLv`xh+NALsGaUTdS^+tZe-8toI%Q%`e!hc#@3s9@ zJ}iv#68PbdJId-?jTDZ5sJCvd1bw%0Cto7Cj$#lM$IJNh`d#@u2{TGf2PZU9%HSHp zUh95u_u`_RWc=*B_GO}&nx_-wioc!j^cdX%Q`SB1Ez#8Pe;e~aUh=M>l>Igxq_kxk zSnh8-lmWW?t)#qLVMp51JF6LqlkxSAa`4_#G2gjTu7sEH!G4T-(g4(6INqas0Fxu+ z?L|%_UdY+kJ3Et$7pyr6dT2ItxT5RBK@$Z-EK)QlTz!1A+=d!C+Pa`l z!DuNUB2l}ucHL(m!%=P-ZANs_9ehVTu0gdak(?4t zXKd%c#~*NhdF9KUy(A2M-?qk{BQp77Hv|x7(_~uNXMqo6bdv_iiwB+_o zsmr6U5%Q&m$>>`Pxg&S6KOD<_Tb2$lK#E8~S%(nKUn9#q_Z+teW6$HhInW5ZAZ!{= ziLGAmoq_ursg>B`hRjIR-D+Rn9{59Xzymr(xobj)x(c!2XvIW!N^9Mxq3UQn_g%V= zldyMwV%r&Q2(R7DJu#KYs2`tTIYeV^|M!0OdE%aPcqR40iaRwES}r*-OJ`--x1~;v zCGO}YBTd^0|4Jd>okhUY;P~0HJVbtVAHMiK-nXzDOddrJ8T4;;fw zcV>!>dMus~3Wq>@_f<#>RtZ{3DSyb8y-6LUTq1CSQ zac15#k``aRmt3%6X~Er5sCH6ri!GJXfijglc`{ZJXs8gu=3+@WF=%#5s#14h;BvJ5 zu16lP*JJ~}*9Y(ZV&dHf^?QfOkax|blts;R+rinz*rJ)4yA2mS+oY))GYspsBeE0_ z%gNZiQ{lU@86>_TrAzh7T_tuLULG<)(%#p+Vo^|@Efz;zzE-4%xB9+~gr;NJTpDR3 z*t(mcmy>o+lD-|Y9Xo3&L>bV&K*@g9p9X`K%BrLRzRnsOu!{hHOY6)|o;d3FqqF|w z9%61fjOgtv=Y&;MrU&|6hRhHmRhVD=(A$2fnblOXR8>I}oY zI^jN4Oerj%5K{J_S&ThDh^c%y=zEeRtoUi&#&;!3k{$K7e5E*%UoR{Ut+lY^j9ZKg8JyeQ|un{=N*Jr9!I*v zURFdmAbYEBn&6%vWIM*p>Tda#!o53qP5$b9?*g7r3W!N6hmwMN)?xRrzmoaK^wSYD zY4-17|6iCRTfP+J)5)MaQ_M6C^js*@who({Px_J=!-}6lW zja1l3*lXr>)9UOh!>b!88>(8)bNxL@$I2wJNc_zcpwFNE_wD~JCp^UbFH5yB*8I0E zV<|TJvR&)FG&}RRk1_x2y*%r$vp5>Zz1<>VBYijL9!)Yj(2rp@eAya%TV+f=%#Kau z0?`lr((l5sHrohXPR!AF)?C=Eep+d~g??tt&0Brx#->b{IsSNqf!2rrAx*iGxc*7i zuTX(2z(N1-SwcZ8CUZz4541A5Wh|J%hQE?t zGXSAt3BOFzDIW*RSKf2e*sGGry*3G4Z1=(rwnm(8s9ef;`LokHt{}mt$fYA< zb$HukgX1GA=ZiaPj5U)AS(n$k(9<*(He>8h;qV4q{%jor+Le5|Uy;6|RiVe_0|5UQ zyjH$Nh^%^*5M2l+k+EA2aaop4WI)T$)fOOz^lW{{jta1@U*?bFu$%!4;*4y6==UwDvN2eFNv$#RI|VNd828|RB#!aZ5d-LTG>VIDYLKZC{(+EHx!zT$ zzq}tOvsdnETK@FYwJiU)FendOS0z)%|ACNIcln2&|Kty=f^M3`{pO083#QtHZ>8hYv_>R?#P?|%J2Qx|0%PjTFCjY(J zs+4wc74e!*5C*Q2y^DN8#ij&^ETlUY7efKzznvZ93OxS>k-+}JCr0c^g-Y4eUhgk4 ze{c4$NBqL0z@#3d^gHS4P8quaVW(R;*(z9i1NZyMHoshTxBTqFAB2RVLs9$Ic6#!3 zw(H0+Q!TmrzmQbwWz6V8O?3;8L*$)^e|y{r-e}r6W(3Ps zkAO9Q+Uo8#m2Qj0MIDI9PeoS)^J1kG1GUTaCF<~bp2_LMU7P%J)ZWVR>^yyUz(IvTM3DJC|8gZ7tJaWU)WmrAt8ejGKy%^c^4K?s^Ti~XLh35h1BVickVYK{0yh$Baj zuk2{UA>iyESyEzjVaj&4?O@T;f&r-ZdbR}Z0}OMSO6#(B_r6tsLSjI&2)xgYQ$Ioj z_Yo@r>4j9HXXei1ju7*F`R#7ls6xHEVW4}4q3!ql?zRtK(}76947r}DDJx5@>&WA z3)ASwUr6utnaV2n_H8rsvVPCmMpqt5g>+9qN6%_090-8;YV504OuX0CF*ac>5sXcS ztDNEi8_RAsiShu^S7xn3Y0<_x?;Hagd*2qy&57mehDws75Zkm-Qkq72Aw5V*kNyG5 z_xt5F$r>*6PXWoUK-)hn3kho)#CK5Oa{X8}h;p^ltrt*$qj8i+C&!K+fA_kH26|U-#-;%DU@{dQH9} zqj1XsS9dDuygLBh(h1$Fa%{A)ygV|AkphtHj*J??3^(c#pIqkJoD9t`jFQNVA_mcI zK_^DaxBydh?VcI1O4d3JF(8eL;fD`>iYy2D)+^npuokaLPEew~_D!FCJ;9X=MP%t@ zFAxQB-`buMsjwLI;62Ly=w(4jqZ@=OT1geLWw8ZT=v;e@S|CE?X0SiP)+b{IYNky7-7$W z0lR@j6NmrcUs#&?9wvNxBLI|l!Pk71`$no1K)ZmUl*f)}d~;zrULq5^wJmOZk@S>+ zGU}a8zyjjVPZkBxrzzrzfy*ZV}0Of5{uT2s(P#?WoVIb8ry|c)gZ1fz_)E^io#s1*KP@i4r zJu}mX@D$Ft1%g5D{qkFwQ=!Xtgc0{d5>PMYz_)T^U5uv6&wv^d7Ohc*NK11$ASt3c zHwLyqrWTYoH74oxs+`w!B8OH=wKy|WD-$e}JCH+>Jr82<#b&q5Rl5Y-VWiXT(|Mj9lXh7!EWS7v`b?&_p_m8PY}Fc!c3-gMm%n! za~SRQwfsuB7(ZB%=;;D|S=XzMuFS+s%7N}7VW5R-x{UV@SYA0HDoI*!@qatEyWgkT zucO?WzQcd=Y8 zPh5O5v*{TUYDd0F)5c-62=%2n)ZwiaSevmis#jN4e;k|1)ZuZhfSXtMk)0k1cGI1b z>WNl6tI2#GLsaQqB_cAqU(QtQdzZ+39QM{tjtke8xsKRN@KQQe8a|IIF0^tHN|0@L z2f{x&gqFB==>+r)e}Cf*2n+8Iw@i@H3v72KWkHIuY!g*>X)^ZR6Q}5UPzI%1yKdu# zi$#bsMRx<158eIC)n;ZKSm&&whpwBCG_f!{l}@v7@N*%HHKJIZR zl9X|j&c|I|@TG17oF{@V;0R0sxM|-+=-X+GFBdw?L$)oJLDX8u9@j_fjr6`F{Ll@P zCQqa8!6E71W$q{!+5u5t;ofCdlPjj?Ia6itf-0+N(6aO8xTrEY`OVp#(ARx_@0`8+ z2t^|DRf@`Hx~na;pmIK+ge|%TG>eGS4VQ=oq>U*Gei1--UH{rj+7OSZQS1ylJI;vl zeyWZ!_b!;3r7RCWHda$l4ld_j3SWBMkH&wkO?q2xUK?ILBjVV{RVf~iz_j2^6AMGo zeTgGIQ^~h|{R?+Q0b1`6_K@le=zA`e`!C^>YH}*NWBRH0`$DH(&%L}($~~zrv#-m6uC_noygk-mMxmr~^Mf1K zgtaLUwmqXEyf`!h`(D1V1@6|T_&CN_;v2bV1M$b?Xse>yfc5nnnau>@xY4&Z?h@R4 z122}p?Aq)ZwSjV{cK`yBi%L{aogVOa`*FbhGO9`CDo|v931OVD=j$XCacri{rP|8n z@Mvf7>=(Ls+4@+sSFjz^Zac@54B@%d(~!eb4Mn)8@(scYF?H~_mFT|LIP^p3CW2s< z^-C$sFMdsCmWGW;1`Gp)tNo_Nn)~7iJNyt#QhQ(_(1G^}k`N%8eVRyVJyDt8=H;ms)w8ltNEp0?#)_ zo})(`>NSWjsZ{cGX!$+dYw!75PIpIA7ID6mt^w3{!Fe>2O~RG42*lzZM|33`Z|C^_ z{u5nk^vUeinKnk0b$Yr|?WK{}Zk_ny+|B4Ibl(60O{(ulR|)`Oxg!s#ZHZWTeP`t^ zWud6A1wQ9M_ZqdZRgi>7iimpu@5iO&N^hdmNaA0mgn~ULg(I3s=NZw^fL+k-WP={p z!2)av@ncC5nE;1N+vV`s0|863W+l9*P>r=viFn)$K}B;xW@u{ewEO3+1&|oOzs8V&$&l#&WFEmRBs(Pjp`HN zl#qz)H^Ro&kE+|+yCAiM6C}Bug~`Gy3)7}@;1tQfB}<_}iTG+^f{~#_7v^B*wi%R~@LL+8-+_QS^?$X`(fkgZ0 zKW2KU2Ry4C0frdla~C7LFmXH!BJbX=1#OQng+>fkv~{Wo$xozP`c%sS`YdflIsUiPXY!DPVg71=LXQHRcU80*cbWQ|}?w z_QK@5C^L}U@Mz*mb-108Aq+FDN97ebhU!W^SZ&?5iKX}sz62RwZ0z*Bj^QR>sHjTx ztC9y$J7T)6IO=peB>h|7$e$^Wt-~Kms`*l*IUocq(%{0xhiv9-MBaBNz*80F;9`k1 z7wtafD+)F(n&=^bFD?zE>W)~tJDUBbJys#jB3Z6f-123jyr|l@<7o_K;>?WYUt3kl zG@s#N8{ey*AZ!zgh*!;5Jp>Agej`!iHkM>!RyZs}fPaGdO)0N;a~gRCI)q7qlz^V| z*PND{5e3~JQMg%wqZ%|JF94ww>FubRhs~w#Q+p|~Z1foK8dhrlsdciTjBmst%3_y{ zI~j^12jUeYBoZrK(kv$7DDYCHBU)Xv6rQbquIWVGR%CU773eY zz)Z;>YcNd>#jyqCxz-V{H7wHErQfH?3<}6U2$hq(uQ(D}wxl8Kv`m z>STFrZlgp{Qv|PA9)vTKhP);G(cL4H%&}jd-L1pVZ{#J>6YWEo-C`nfR@JX<-?z6n zE(cpB8+>scEXS6ZRP@#KTWmWApma=Yd)&yqPdMfGMKM6`*w0+ifFu&RpZev5dAY(} z{)+dMxN^$)>v9ma!sK#z?`V8?x8G4BS0gsAa;zVr5#5NCXe~y$K0Ez`x`+I=Y$Vn$ zQh;LB!`R$xx{s(Qs~=i=Y0nrtoB41ME;V$PZc}DI0+jNEjf#x|`)1=lI)2u(Mb|k^ zLV5f1W8>ujd3b`2ur&jbfU7R|OzV$9_`uNRs!1}~w3ZEwR9FGx3tzp8FQuZqXzq(r znQKb|sBsu1lpDVR3u(dj3KWA}cAKg4hW$PDx&J-(MuMEXB?wSc>C+EeYMGrGlUV9B zs~k*XD|esN*DV(`wS^Vu=M$71?8cx2r{z=?+u;Yr)YhT=?$iCPPHfRIx})9~P5r7Y z1qw|)r-@v%+OJ&-?K@qO-jF>Ku1w_LU#Yd-f-K#f%iU?w{R?Z^Jer5pG?Ze`a;B|KG$L*z!Nu7`6C?`EVUUOKSAu==784x!jmW` zjDN9}xsi-~al_&on)kA^EV12X);d$gH`8!m#H zVKE*JH+D%_L`KMAWGY-=Jsaw=lTW_%ZsBRUjS-+<;ME3ERq;3oubmz((O7-$VKJ_5 zH8EO;vG-rl<2QVp-WWVH71I>{_>hP=jqYnm3`n|zC%|pGJGWE4vMFa?jBwE6r!YY9 z{J>Ecl+2g*Al*3LKw6y7{i_eSpY0gm_A=eFuEPi7I#-(X@pG4FvA1w+c}J6+=J8Yg zOPQ3u8#CQm2aCa;1JatgQ03F5+kh=b`&&V~3WpuAAE4GXz1{G1uGd^d^yb{0X&6=$4ameQpF@wh3vNPp}!POc+zmcpwI?Of^y6uy@39X9HQ=Y~jSLVNk^ z2PI?L1&JGkeRYb-u)UoZ^-8yimbVPg!19=9@{IN1#F7*q|5cUzJ&?~`SLJI71qtQKt?c24Y5TT2ptO1L1rT7ngp2<~ihOB$DHO5p^AR)2 z(hUt)TH{(u`@x!k#x9xb$MX@!J>w1c&pmZ#9A3Ih900uw4)1kD8&B>Xf2fQq7Pchc zX)^OWY%V@4fr6MOzXj~Fv}B$XX4T6sx|2B8?k``y^$|}DHr}+|XyhOZ%`<2$dpwu$ zD8bS48z50OhClKHsaDxN*Zr&0`l;f*c1_&R68l9db~c+C!9*qE#Y_`U=h&BusIl7l z&F?UWqLpWJPsHJb9vaV#5YIb&0NE7+rg1xj2Q5#DnISQj@sGQ>Z}yt`mYUXVDn{9* z(gQJhfQqVLTDrNk_jZM~X+v>36Xojk4|bWWsUC8^cX-M>t-lq5qeqj0$6L^zbHq?k zqaNxIAz8(Aa>A^?2iMe!^ojGEmOnUX_ccR2P9br!Mj>`&+x<$Z5SRauRm2rwy_^V8 zCt+%QCN*BapYfbypbYn}dZ!0)OdQXj7aOnX89k9w{^JS8@x8DOvOh*xKQF?yW4cfF zOwwQ1gD}c{pfodCIYqfxbJQ5M3-o@;ZPMHYe*-GhG9a-7axB%JIt5q|qmlZbvG_>ECO4-mg#CXrk8r$nuL zza$_}+e1`_H0?L~08;LT7$DDtL)>|V?M>6+Z{s~V4%;s^)l*I?lB*1dry)JtB~*bV z%LgtLe--XiJn+E@d=c7)a+t0p52Ea@OttY-BEszfC?1mGTor*H3svQ!n%`Qm9H2`fF|9`q5ENjZ#dJF?G)^{ z>G%U)zKl|uAUrBtteN{@rg}4?k?{lsSsC)ejS)uADw6#Ey29GV(8-iwjTwkMsTsoXqAARAbl(!lU2eiX$3iu&`bTtm&7J)9FX2N*rEtt>F?miI#5L=s zolcXC?|S|wqG*8j;@Jn5`(!hQk3#Fxz5q{(Hs0vi-MT$>FW06F`Z3kmN!SZ`n&ATb zJ*SJHG?!knp#kaA7zHf1ccrpLq5D`EUe9fp3xqe9>gQ|FdP6QWda9+{ml=`euZ_q8 z=VtE<*y1Im(8DsEBQNA7L2~7>rR)a_?kX>Q-tti=VChG-{2&QHE{l$@mQW?QH7!jA zSv(T5@{Mpz&NZTYS6PaA$`4y|!wmp|o!79p&MZDRZ}s z(&JQ9A`j3GfBav-0zAX9^0EuL<@0UCVzM882gFDymQT^p8sJkt*ZIZ21f!T^Hlg&? zed?&YZ3SUA&O${&u29|iNe^$MsKAra$wP=y!b$!w%;4f zfcKyuz{r#KpUie-TUo9h%Z1HcI z`eCc&8CQRwkAA-1$bCDK6^TfD!|Lt*iZ4N3f6dMmNugoA0_Y{OUER}XDiTY@3w;4y z$4GTUkPgMYk42femtQc3HL#W9Bs>JrxKM4RlMjj%N?l22uYg~yix%{7v*ehl)~-M?mB*yl12!!6wXN1IrorRS#n053WW6{5`4hHxLZ0HRN}oLQ7WcF96M| zH;jL8_OI}kqf=HzPy4;M53i-^5AN6Bus^>=uxmGj>8Wp%tdU>aX)E7w?zIMQHnr|E zLrX`j{r&*T_%jx3gd5QKIwm~w z_p6TY^}%WbW|bG1m`0}7l$qR(ZGNTTpvpj2zVGn=e7-Z7KAY9ae^7C|JuHPj+$r}A zc32*NHGGWy*nA&qMiNSn0KZIT_gF?SySig`c3%JIAzw*Ehr%3pwq%5?0bQqZQ!x=>TWUWq?T9Mp zWXc+B?J+AO@KQV&cTj3Jl@@Ful2Ob8WNZJx%2BzBFeu6u{|z1W%z6Xryr-JNb~8&3 z>`+vkEx1+tr0Y-+X4R2{+N#!X)*er{_>@Sogb4>pTqC0LuC9W~&ZxN7LymV$oMnl&xwOYR9*6 z(us-KJ?M$={UO@`AeJJU5ciiyvvpYrtUb29!(izQ%8ot-8~>msDH=WIJq^j_)`ZQm&eOoDOQpZa*H*Z%g@owZ?hUH{2cA$jpa7KFzuObydodY zIQJG_Oj3(>?k{Ol2yneVYjABvMY5;9>tbzX{0cgLHR1Gd=P4QV;S6OyT{YU(+%$^XCbCJf@kn?gj@8;*T5hPkLd#KK3qXLnH7QfRkaG7vmJY%UTMy|#G7%^ECq zys=Vk`*CKCse_^_zdkcYcM##p_!t?Iu@@dtc( zn!`NJp0edyQgxpQgTfRq{*6|DF^dh=-OgR6$beD9Nd3f0hcyM8L|%dYCZ7=z5!F3$ zpN~9He6%B;395}S{>y~&ef#i^_^V7!@so^HW|g7cJ;4q#+lHsG!nDL3{*3H3<&fBp z2xydu=qExed6)1ko7WRftR(8 z4>c`VfG9QQ6BTDo6Pa2+c}$=ADu%MQ@|4;w8`i6sNilua!wA*a%x5-}=}v2&*=%A} zL1g^SDhNa3=3~BhQ2iaw#~bt*M9ei6qRk;_A~?2!qrMCkz{%Diwp;>_Ei{6eKf79x>OA`yOmyv#2R~H88BrLxky*&62FEixUB2u-u5VM;~wTq8#cD#ROU-& zkzL@*39MnGqXn&BwOL8csd;rKMeSlN+gUwU1+}1y3JvrTM6a<5xrOj2c{M5#iclpP zi2KINP1f^@+&Q+!X9#$Div2+vt9ae^&7x{w^jQ^`tY+!fE3orSz6zHWtLmJ{F0Fu9 znQN=e9s9IyW84)c-d*j)GAS>zgjeRFdmWqwH#yd6zg-;(ZoIl~LEMxZ+& zKS%fjrEmMR0&?oB%b4}5Qr^>bQ77-DV}7+Lj!lwP6V56od{)tO`k8mY?#x&w5%t3n zsx^DZI>*#Pe+rPNX^GQoiHJ*#J~BzFp=$_Ygna7LOd?``F5|!ohCWD;Nm3E+`Y^G! zjLtsR$!xQuIvEb~Jli>i?mrfFTL!iV2}XQ4$Ggnl!#j-cq%ftVXLjQW>1!Fgllgf? z4&Oa@kueePV};i{>8=2M`U|YOj;wDP72fK?xwrpsv|mr>WRG))=?+0Zbub@>(pr)@ z2?fpRp61!UEXAJm^9*Jbi&SFk(EVFKx=1}@Ey0?8fB;EAw!bUVd9Hr3Dwgf&ecoe? zKD@_%Nm$U}X5A|5Byumnw1d9mzm1!j$j!Dp`I(r$fhyZgzuzi~39y|~*-xJHKE-}L zvJb)*Fw5rpPG%FfxiZW=y?}u(97ek()0&OAzk4kYbyq;x_N*^$NBUxwMXvOhIGZZJ zuEF;?($^ud{OByA=dJZpxS--~AraYSUK9c^&9YPmlV5gJo-{4_5~Ds$XQYdrN7pB^ z6=+Z%o?l*!=q46>t|Eu|Ekpe>Wi92ZWKD*`+i$!gsaIUmm3`(nX5{)3W*`$2_DwoI zWxSI$Ao6V?&Cbmo(IIdfUb;uyU+qh92!*;1KY?-9iPG6Jm_F!Rv5L+WhO~P3?wv^E z%^XaBX@0|EQg+S;83t@mQ1u-F}|XzwW{5p?8mOW47w{)Mp@K4=>&6+xVBs z`cIQQbw@_H4LW%`wA&0sa;Wr8WC`voov#v~;KS;wr00<2_7fM+vF0Tr90=>|k_)SNkIXon8n zG9QezW0F*KRikrj$2BCA0N6QE1J$eQ-bVM|kvJupz08TMIn*7*=*PEXmNkYrb5*0P z8O@n99>E^lZU`2!eI1!4kZ~Nv9B=wEhT$=vQ^{5{rrhs&d?m}}Rh}Pn^n%S0x_GUO z&d*$dsUw4=FYDfTvg(i>xa642_&HAG0^OPW`QbKQd92J0nR*zbJwLi5wb+m`scvNIZ|;qWP?lu>s&?!$+mF<~zX~5Kz0M*@ zUKT86Tgs4q?6h30czZ~CvVR<%*aSLbhn>v=b9{(!(EGfrP(s+(isQ|F{by{9;kGb1 z?q}!k48GrxY0bZIcXsF^5!eyvptoC`IlY1l`{Fg{O|{Sag1Mh!%lv(%Mkh|^_`z89X%z34R)u5wC|!0N6L#E|mKoS7o*%&kUS zx%XZOC8V>Ka;}7_!|61z)>+6jgy6}tbb+xx}l%Kj;0ti^+}j zvCNmpqI-Hj=XF|^fvs;ItYfTTzbQlKBa@epte0-};)8J1j)Il3=&Vdx-u!1LS!Uzs z9^c-~5TKRKpby2c67;b=SH|-GwU6{Q%xYg=b*@fKL0G*gy7bY<5?>yR9ultJ4~7u^ z_^IV~wrd54rt}d~{SFWcSZyGY!+jpKVzA;8!urwAV7!?w0E- z3u76NRns#}P{i4vw6m<)7fr#+zq9PKleaBZ@T|kWUpH;yKK*%zyMwI-IJ_WE*%!7? z-mMu1n?hu#{EeUYM=>ZYSmvf>$-0(2%XXv)Jza1R{W){9t%bjZAf2Q4F;p>wAudh! zh^#oP~E!B^oYuEg!$>QG&7JGtUM&8rl}kL zWUBzI-8W4SoGc@z;@4h9Z1s1y6_1wNi?c=RlTo1Q>6}HSw^HmKm6#~!g-){ujU4w# zMb9o+GlG0?(sBw21G|2y!lC1B2_sqvl$a&z*>rL`JZS>CWT3ZdJM-epqkQ4~U{1 zbi=t|$x>V>4brnpnw9N!@6-YXDt)nue97rBM8XwkTt`X8QZWpAqjc=eqik@lzymv7 zzb_SOePHyJNi0}0A8;9uXczt(6S4j0KHl<2>lKmTCdY@#Zr>JrDn7}tX_}Y=I8`OZ zz2AAj3aJq1e#smEqBm+mK$bdC^`7t^;_ltK?lUYIR+PAuuj@%QgtU%4#;$vK8u+$mIfINe?|!6s^Dd;LC{bq9x!jHN+DN6|jyP{_v?h zOFbkc@yk9f@eQ^l(LVFgso+ufMp$@y(kWdfa*{mn@Zjy46bT{_>}9n$;zqWrXY5d% zLcHs9Mdxk(70P0V`*^hgan)k&{O2E{!!f6Hm1iG$r_3={NmT|iY%V2006+0)3yVWt}honaF^@OHdALW8>$;0xF|BWI0Q?k6IXTm?nd ztS&J;m%W$Q2Y;~@L!FAyeb1Sy>{|Wa7d3gJSn!DNL~nA5u0G}Acb8{N(VXa^`VeQ! zBv~#`6-S{WFzQFF_i)dTkI@E28r%J~C{IAPg#6NYxIh%*EBlQ+Hi%@D=S{$g<7#d? zr#4EFOAe2U!5YGNb7>&ZXcVt*vc#i$I*kH{Tb0R133 z_{+1qxdrxiG{@JKO6Y;}AH-MnD0U_WA?&GjrirNJo~r%?KJSEE{Mw$Dn0>KoP5i?Y z@wmMBC`H*~C=OE1c+x4wzO#t#xX~39OCkQWg}31G5_pwLpQ!N$ct70KciX*&E7RH+ z^W!kOC1Qt3WDjEFmO?mq_O*AKlx+u2V4MFPq_=%`?`>7hFu~8W0p;zsv@*khk%XJO zrLFPKMg2~xy?1E2yc()rpSPOiNzj@ByoE zg1(NhYkuEL4i%h7-4r5^`r{sxw&G%7W69~ZQ={uXpNURna~138hPS2Wmnt0Ml@M;- zcc(?=J3KBG>cV5}+$R}LBGcz9JjK2F~&w>0qbaZPUuZxT$zH9Ycm0b@t(UiQAp!`FGC0E=_)M=sl?4) zV=yY@9;8hx0A@+5S{Q$niJRb4)e5LP@edBe{#^WPF@IYNC2BDzKyB;-Jqesu1w6sEH-7_0+HgP|5J?7gc4eY6MD*fnAhL4ex9Vz`!%xa zDeh;*LgyEX%l&39*qyNXd=O}Ay?u~y*R0a7OUveExm8+(STbe80QZO@r!<>I)H@Cs zTI5F_uSCos2l{yMM+IFB2=4?8i^y}C7)VXS-nMm@$>#eh*b@`+Y!gbNy)IGK>2}Ae z+qCE+tiGb^ZYn&Ssol^QxL5Y_498-f0NR*lr;Lt@I`4aGEZ97~er%5dYEa-u5tq#k zME1Z}Z_A6#4JQ@h>GT*`rjv-##md{L^y8K$hd=g-!iE7$hh;vxA*Vs26z@2i^^HEU z4sA4s7hejC=LM8vKaZCm7pc#dYR7$!+@T%tneuG%ho5Kjw0{YpvcJ;kG}qZ$MoePn zBp%Q7d<8-U?$H%%uWO-1EAdD0tdQhrM=O5Qi(q~pZ`IQ+^<~JAC#}BXr-jbj7+u!F z6tz@EDFLV-r{k}PJ9Iq#G*OFA?Bve@JGbg$q$-VC=20ec*3`Mcks_m{39SxQYYY2P z?WK=kBK2+S8};L9l?3Ij-ragLA!*mN1KyVy&??XQAc~dyK?HVpQvP}rk6ysPIK;1E zg8t>8+P1wBI`ByPp}JCPwxa9LCq>BVj&nb&xlee}i%^k9s3L{{HPf6 zOc#Y5B&udsgG99r@+5;w`jz?#K|{ffmNJ1P)V0$GSpG93$YeN*JDv(W>-{lxuzo{o z;Fj=Wl-+Yb{LpI|+fLnhbKM>_#aqZTX(|X2E~J#G+5q{YsK0FzO4+{EL#Wd2L*fZJ z>?G*5%h-rifvfe`?_RK_LOpZ~uW+2D=S%-IVX_;h5cC4Zj(eKxSbH3ObE@sMVMEAc zu6reCeNMrYr~La>g#AgHd*-5&iN7V=;-1-<)JC zTSKXDvKX#CBLt^M39>IbcPH;q?~*>T&2P5GyV<|QK2W}wW)k5NDvY;C^>_5>@|Dc%+KOj+kkiMaE*@mmLm-xZcN zy$eZ`K!URtOdyT>NEXstRl92(RH*j?z1?nBijBc36Ppoj{}R8*{zVWkNk^)Rsak5% zJ;;xPWl=amKW|YrL*bSh*AVZi4|GRTP*Yyc-cyxU)V1!*2W|aC>O@1BhN}ON2JTWi ztXvm4KCjs>2ZqO&=SPxsFbtSR`h4l)H$&gX&_0i05HJD**~CjC|x~+s&K%P4@0N zj1osy_58bR!k%y3GG{!U8xoKN2Ro7Gu{>+JJMCaMv)V6bAxQRD_`ybp-VDWA!q#)S z$lfL6IRf%@Ht^OKt?3Z~zbo#VM|`=8241~Jicdc3_EA}CZQcC!ii)tsjOoRhz!`4v z5QK+}oH(7l59nE}IcIX6kiqqtDI;R~%-HRT+w|6jj5qsE537ZH`q@LhTe~DjwjH&( zV^@v+baSRhAUC)(nC^QeYXQY?N4mF7K60czenbZLo{oSzY`fQNrU?E}H2@hA@=61= zhC~X@Kt5*L%*~iZ7T;6BrP!;;%e_bL|ElU8DbYY?9_tMO_{-95@e^IcEj6-ZJdD1r z-Z~PO|2ahLKb04IUZR9-3RUToOZ)1*#RKaFm&AFaqE605?Ae%YeUR87za*w69;ZtC zYEhISaA@%MSxe^j)wi)wLEu|+*>yaY*gv(~C0+<7-Y zoI2JgdF$r(YMgN@J~br)2%}1Y9#X}(Rk^(?$~x)l@^#vKp~V_nsc9!jxaNO*}Wc)33FpTl#3ON49v zoFMP+7)(1VzeUwnwuIh!RKJ;}#UA`_&!0zA03UR~r5ul#`~6(ZPEC8`Z?<%!3k9YNx7B=Y zj*(|C^!5dA$0YK=KV}x83ke~4gRkJ<)_u5op3CN|n4J-A?^l{EaPIj-+R&Rss&8xf z$4My?mre#ZA$->?q#qccR5h3R3XUZftr&t?2(e0#TB8lV8y{*NgvLSf1x8`rz>BaJ$N7MoqYY$fP*X0 z{c*(|H-2^ACMXmjlMsL8s^(acL>xVO00>G-ak{Elh7zjp%&B&#l?~g%)o;E`XC+%? zcZ^Y%W3y)`8TSAT3XbHdF2azw>SQ+cBqYP9^#47eH&$cFU+D@7^Sbue=s-SAB2r>rE1F!i_ZMybt z-lVoRIdu-AtFtfn>?xVWB=iO;66eh>l=}p-_u0ZHfJV~%6YT&eSuj?I^eIs6dPGID zf_=&D#1nKekk5|j*xOvauiCWL_lJW)D{8C~FzRniw?ot*qDK z8hvvsfv1OqLpY&}V>5Fk>vVWbjC<7xsihhXG4vH~JNVAQzwNybf1jpsJf!1smW=zj z0ZtAtH54QjOSJ86znF2$ya zNcJP-w#3-cmo%P@0UKqys;I6w0F3hG+75PB&o=G+ST^b>&_R~GJ|JQYW`mJ@bzIO& z-61~JTs8yTio-jMuXJe?9iF=V9PlF(KKQ!2NeTBaF(E2S$%B)z zHSlr2Es1R3cNiD*%{|IuyOVC!G zJa*8fcwP0K$-KGUE_WyV=uTF`%J!HHLq6}%{FOlV`8^4+q1`(o!C&=~ks(x^7JL6| z;<|C+sND^|9Cd>yqV1esWzl!VK1p64m*riuK>hGhz|cC0LEZx2ublHndmpS+Ho^_H zVA62ta+iqlvyTOJT5eYM+SfD2f`R7oQ&j_9b3!j%C3yN@tfSP7_1iVEn5Y#(NG?Q0 zS*O%{+t*>VQWxERC*cQAz2X1}_+FwX!=K zhJ^}Z>Y$dw@T8H}P_eUCe!!hKhw9IB&WeNp?FP+bbBZG+PttejQPmwcEHSpn#j`0G zauEHHzrR0?X09u#8}QDlre^taYW_OQX5A`dCfMoRGxk&-e~J9$^VW!Jr)@S${<2Iy zGOb-|5=2Xq1!R?8&TALt9i>NFX29q&!n)6sil$O7N%~LcM+fzexM{sF19EQj%}?xa zphvtjCU1G`*9Gn4yhmC3sF8S$src}t*1D{8D?Qx(Snhs(@Lih|vZj4HUZLOnLZgY4 z$B*+kLp#1tA2beq{uV0(sOf2k1ofV}B?R^dPAMNyhJNQ))l|{lS~9Zxg^BVlfM3^i z!gNjYZU31E@}S$L-qcw;I8vgLD5V>Ba`KIHdFMV}bUi126sy5?lT_7h-d$_?m!dV^ z*|9s`|Go>gRjcM>K_@8QpXk~=X>EL3L3rj7sxLWT=v2EqeuP*|oEq7NyX~lE2t9E^ zdKD`@iF%sLs~abn+}9%=D41f`H{C<<7|yaE@Z^) z4tD3X?*uvMAFm2F$beg?z0+{J(}J~arvNI_>N?2)y7Khy+t*Lv!YxH%=(?YoKA8{S z7|)fB9<1jZ7nA$hq}d+W%S7Yb|p?ewfi(jCAwmO z*v$L8(OotfksSE8BSe|KCaT4q)X zH+f&8j~F#o&?Kl^k}oKSm9;a%MTD=uLirAlL*T1!%L1m?owXT8z%{`$iXR{C-RB6A zlM1vDm=h3%rO`;~Gfg+gUun_UzElydXgKt2*9Y>eFjIekPMYPo!5s$u+Wvav){SEj zWN@@lBLA?D*18;(1~el-GX|h*8RCXULxS^@PAp5b^5Y^@J$QxeBOsPD2#X2c$W0(4AgR~>ulal^kBnjP|UMW#kWGG5h+3*LoPig%}vC+D2kFq4ZpU|$i_P- z$%t_bguScAzRz{wI21xgzV6nCQhWR+MU}n^k>BY4aJ&*RbG7*dHcaMZx z>C9+1SGgM}Nu$SV?&OLVj2hCM+d;q$rtW&S05sIGZ(j-28T+El^d{1bv=r3}05?v{ zyLo;dwos7+mq4uvmRjWNO-nz_3ep@h1%nnt~)09CZ^-x90rqVgUExwYUs>VH}1 zeIUw&l1J1`jz8!dNz<9Dw&oI}#SO1-KAidM!bG+zA5PTujKjps;XPdvgSF937)5v+ z)n?(Ns9Me;6@L;JE~IfGWF6*WKVX}u*d?4+Ku?8TIJMR38t=I0oWCwAb#arqbg;%u zje&r&Ve%fO#p`wcGs?yj(FY8)18$p8khge6n*0~1iw4oXH5eBxvc>1Z`8y2Nyqx>F zs1dU*Zp?YQcd<&|tBFEMkzcG*MmS673r*lP?WjwdMQz(&VG`!bh-s#cIIc=glbCHP zsJ*fMi<8e?Xkat~9n%De_42bj%v&=Ry^8PEZExm`2o{ZflXUmF6l#Bn&LugyGHGtN zlY0kA)H+4sxQC58@sKWF;R@o7VRpa_rn>FkxN)5~c}STiE93c0azoqcdnd%o zMGNIF7f;e2_5!miNq!&3giHM!XPWj!d$`T)IFD$NS%*A*qr%?dbd&dttt-|9Dj!-dY7APx`ri@2GC4&BqKL{>o{Kh_lwH zv9>Eh2}h#nt~BWVYg6ZEW~V^J&Tkj{mtdL5=#3|f&^Z*03IB1NJ38B4tczOeK{ZeB z5TPuscX#*&h=vRZj{Ciq;3O7 zsU?kd9hCd;UiiLvU%@eA;C_2y#;Vk3SQ6Jz(6Q-RSJ5agpG_nGfa`HJA>UN8SB!uZ z8Sc)T!?s6;?r6goKDLOG=BWR4mHpqmSS~E@F_Yb~<|4K<_zYHe`M%MKfsj~zhr1H< za4#pkmV^197qNee4SwF?uH>LtH`6PQ_W#Q-rrYR>(G;`1tg}5Qr8;fHCtvAnV}9e}q^> zh{h%)Nb?9OJxgXUIKa5vPwPvA@Dx;(MaJXdJz;sW+ zdH-#7M_8~P(K6TJCrgT~zfR8>l1I_PTI{Ux`UecK5kpj%FLio&v+9p+m%hkE-xVnO zE#5s|LtAWAwdLEm_u%qKJ%u(Qki^93WOhjw8WCbj`QG5TW~gth*9OaoD8?I=dN0HK zua2@rCup#vL;rXK^v9>o%mpz)Rqm{Z5l2^`hMV57o~H2r8siq<#<&B^Fs0s3Ve!_Y zP3x8+PT8ziG7P{Lb9X)jEx&{jWg)8!DXihSmnmS-{O-@a8Glz>HZzgCBa!uXrGP0y zoF3g!76l^9u-i%T>J^e0Xu6lI$2C^`ED2n<`*jX;(Cw8>T<=vo*2@nO&y_#RZbw;J zF`esI{Y;)KV1nTGmMjm*1lP5&h|%7DI+Jw2LT_a?jIKt@FIsvSLb(0rg{~F4nE=4t z6}lK5nZs1gf7LA9w>^pp9qhcZJTF6}*6rSr%p$sI?T-w}&nUW;t$M=c_Bq~13?N{* zAM1QzERY~a4ZW#&(sIY=Smwi*Wi+EhE`3nB)B8P{;KG9_))Z3L6)#G$e+uE<5v9cH zo6W%c#V+PCR}=eKE6e{?9%C_g5As@}N#AUELEd!-mPh7eBK|m9DoM59hqwziJr9}< zx`UxXZ^;qLLB;!7*jCOQOvgnDXfAlTtV#g4_OR8t9!s~!NSurmy*el2-Zst z2G274{c5_*G!;Osg`?YfjpVBYOurb;ILqQy>p%7DXd1OHs=odrE-HEHw#>^h8-Uk!I{PruBLN@M z($YqnzBW!z=j8Bauq3Iex%nxPhyaTZmqrLGdeS*VfeF23z6N0;a$UY=m*C#z?K?vA%omvhXE?dJSE_NB_$98ap)%66kYtP~e>Y63z%OGq%rXdhOEd!}nW}PedvSKu5 zN~n|HGP0T_n!n~@$jL8s@p4xIPv)%R%vpC+rl8d9P|UV$)$Ntbu=wF+#5eQFS!mad zWoR}F55K$M7IVL*S+d#okc$VV3nuC9L7k-Uspo%$G&8C;#dox>vw9_-L?=>oBg=@D z0#G&g7hMWSoODaV`pfek#a)bZS~ey?6Xv2sH?9bwnz<6QHNy+#niO9KLjN>kCd&|I zhOODMf;wI{ff<)cL%~eoF+%`fv7pa~n6{)cXBi|-=U|ZyES$6Gex{3b@hfxTQEPtU zW-#l@_&b@ZqKr90`?EeKq#4hgDULbQr)2;#18FWfZn+Gbelxkj>N^W1eV!?9n|edU z=9mg;oKL=nKcF6)c=>le-WvmcXKrWB-$YqA#Nf(8-bzIx_-CW?>E5?|u z;4X_?*A=|R)=mGV;7d&_$)99TC+6A;)@DJM?eC8DGk86^F!)bs(~HVxRbJPqf(x(z z2c!G{8jLRc9|A3g#@+JA=QO8%wdv`;54j^k2?qg!SJT7PoJN z_4ewNR}D)P*})~F5%L}%Vd*%{J=U6yI`I{`Je zl6A%_ReyBq`8GD8+>UW;7miD>A2ZjDS8mV5Lj24}G<*lO@~CMi9GAMnROKWv^7i6y z#Vo4eu^@!!q&G!k$oac1*E)FT01IA4l3=a z1R!s^P;~cp<+)a z@($HSDZ;pcW9PR?MS)M{u%h0!L}(2%DfUnb3Si&WxZWL>>mjHVs4#;Lu;k@H?K0ZPI!5A@E;JN!V~ZwzXFd$SX2xXf$3^ zB?X=c@}@|Vi5rT%yC)(e>OLJ=YilkH*D0`D!G%ssl+2vyaq>*o26xrC5B2o+c7ZL) zQxjcM;t`2SCgz!^Ro%13@`CYTV9S-7BNnO9a3#bCYm)z-r~ zVTYOYe5dQfX$eV9UVDQZ z0S|zx8-l$#4#`U4;t$>T7OG;=GYC zySrOp?`_=eB>@IG;~It2D;@_{rp?C7`R9bSz{VFt#~VKl&sN*we%i)SN&|MFCls9OI6ee*bb4N z&F`Z9Z&}O!GY7|8jAYoq`Vb~%% zoAuGmjw3G20rn+4E3?`Lbpj;x-A1akVbT$ZeUbp@-k!`#$KjWW=ypvI#XADkA-&cb zr?{phv1#Zys9QRNyWPp~x1CU+PD6yUtx!MnuDMj+Yb2l-rvp6Ybd%%u0%UfQtiu2~ zBECMnThydMEEoY`NMeXy_2vY*be^R=oPQ+T)(Fu8?51jKuX)oJCiNgB?UW>PEM?-U z{Co<$=%Z38&5D4X;TWYHw8a)pgv3pUq?Ol7luF#TP&#B7RTfet7Fjk(AusWhjfCqv zt%vN;o#**ai^rtFiF|m`>>h>7ae2=w8 zvUh6lT$hUb$Y+%za$;@vur>um6o|pck4+P_523oj?rj76aVZq1c2o2tvXd+kgx_JN z0i_TJqtFSUbw6U#;p{-pDYQ9St3v2cn>wczaG4h!W(^_^avS?JOj8Oapd)hZg(P!j zC@L{jF19gJC%{Mb^S5=EfzgfV!DPZnwX3ZW`Qq%v{USX@)9f=HWOcM|Rp$-uufD)f zeb7w%H5}qC9yb!gYsV$r9wP@G0k(};Ez}7#R)DbyQKF)vks)znaDn6m?HWQ3M4`)^ z{q$WX$a=u%_D~4=D(y{?sePe$sr(dG76_|qtGH9R0B-Ys|GgWXFQy_5by7x@(FQt* zghNn!t6FPxjIU0t1m?|R!OT}m+CMs6&Iw8&Z~MDT^$YoLgXLfa`bZ}tX-*jm_VBa+ zq*OGP;8)k7X6f${-T26xco+K=Q+{5eq~;(+|Cyd*zg%{WR|ahddgkZ>Ui3m!$JT72 zz>vp=7w-9!^~cj**7m zL5!V#8rR32V!-#h&n9>=5Odx4%`{Sm&tFf;RC6@!1FDdv1y>x+64xu1(!skEvyAmEko?`m^JpGR1Xq;Q{q^p87%nC0(A z49>%jKO|Pu=^JmMm2yJlo@~R9R)T&6$MB>Z-m{b@Cl`6QV;_6y{_yJDXJ9Rni0N#P zAuKW_=cj*mVR!_>w&$f7eC$xQD3p75f}BvIXZ;bgH>^0V&9 znJqb#__#}}E&#%!=mN)28}RA1lqh(xAK-uV!^QUeh}$~S86l#j3V_-YkgcsuzGC+q zVb^i-H%X@}br$mPY9#d8Bo!`Xs7t6U)DW!}0PwVba$)JrNSaF;mdFE}*B^X05SHpz zcZ}G17THDS%*9~}YWOsWYINq1zjjz}{ z-%D==PW8{@XOr&B(j|t7CC|iOCjao7oVj28`S9eyrJDP&Cm9*fCsC@((UO%N%P5z`(Qqm57?}@GYS4c=&60Ud5mSB60HaX}p(YQbF@$QJ?)%s(9JS(-v8s|$){%wxi z__E&F+vK#iMo+B;m68%IOXLCy^QJKqWE-EGKIS^!#pgbLG2Sl98&pVmJONSiXR*aE zo>GYtQ1SlyU`u#8_p=(icgc#kw#^X3dMh$Prw4x+yM0Q;NSNAkydk^gYDXw{kx=kT zRpHO>*8a`YUNCA+7`itx3Oz8IuLx#5?NgPkOr}A+J+VanJsTQNCHxGO1nk!FYu~b3 z`Vo@mXs0TTaCx7s8*7KhnnA)yWrweH~LcWNz`m+E#` z-y#ELN(a^mNYlWH$b=3 zfS|-v62d|WBeAOGsi1?M4R-L>rXuuQaVu&}JholkGk#1M+%-)(ZSaJ9d(Qq}fg4ky zLP$bqM|D0xNH5i{xNsb5xl}}a%LBLLj1o4aZ{18waZV`Tkzk?(UQDdD^@0{O%oLUv zHNh+S(0aG{ir>%FFwvZYO=zJa^bN>TWaS-_1e%c9ctvmk7w&C8mDV*d5qT$ z$#M~;LXTzc48KIhN68z-%7v{(`AfGByy$hb23p=)QSTea8*!Q~1Q}8+_Tj!&UZmtfL>~ZtgCoOF<>#`(LImIvv;_a}PF<+{ z_#!M#UFw$Dd!TJj#*}OGbfFx-_7ZGbp_4++G*@-(oE1i4^O}=X%Zp^*70 zKeyK1pTC7`r8~vIZ9FEq&)t`7s38w?6+Do2!qlN1Mt1OEo{PO*UYCLOk304}+=~aq zsW>%0z~gnU=fue*V;m#+s@;DKd~t7C8sN8`{1%u^Lo)GD6XhRIvrPTJq^QEAe7p7u zc-;af6E~yv9rzkvA$%kr(1T1g9Cq}YZ28TKaiOEJZ*i1bs&dwjGG$ltRj(~uI{u?dr;F`fgh+-IP@Zgl{m4J$#?};ZSdJfm$ATOgW?+?WOgvv8%uI&)9ap2KdefW; z*u3z0#n%J4L3-4x@IPt0|4G~ZKa;lm|F!J%e?`Ln1#K0u>7=-LTx}pv3jK`uh zkE>RSyXooKrKPLe!a|_@L?CUC8mt7yGoUBvj}N)#+(l&f>tOCyxG>x?YjSl zx+5$s#90Zt_xY38I3>NmKjw#(IQNg(sf8}1zuEW-vQ_=(qLO17m=zEi-=w7Gv|K>O zbGql2KNXi8A05p{l;0k|a?kr1gD{?__~_L{=j>3f^U_n)%t$KOSOT z+1@TgK^Irau1yJ58V!?87@Owm{(g9EYQhc%nRqU z;9uQVkSE$|%Xdx(tlqBlyj;TFt; zE`+M*bTB_Gmr^n}T+{JVEo+LEqEE{oVaxZmZSPiqA*{tq zcael+AXu0;wQ?6(o9eV84)@I~?qzz|sa+dTeiHkLiM6OWTF6=f@5*KG^?NdM42TSq z&%*XTYnCbDC#+>h@qp$;c$f(ufqRr&JD+pAGd7`7j)Z)#!_dnhSpUS+A#zGOg6=R`^ae`cU652 zwhrFW(J>h;m4DK-Ln^Q3TrGz@S=*AmnW(;iAU(38J$*7geROA%} za>vSzlVUI}*^JK1P=(L{!KLeBu;QL3UIXE)MoeS%%H=EP%@u4;-b#T!@#(~BPq*_# z3Kk6Ai&zT+x+;gaeUrR2BBl(wC(Ni}>~(`Hg?9zicmKdL@P&!Inf~fc-hH00vHLWg zp{CYNo?zCt)0@8}>eyf6{1XkNevt_~U_n4X1dUWPF(u5EC>$$XE(*v1%B8`EolMvt z>}HN0zKl#^VS`riFRX%u`nQ?Y|5%cFZ3XDV1Os|A=VH~;_^^>^!9Z^;*8&`6RV`#u zxiSP(5k#|~I-b8u_o*zSPZ&ZIwOnhEIh#QeYqn*G>uzGs>H>qNQw$si%iM(e8Llc7 zxIB3?3zkkd0W7412y0KaRx4pp8Qhi`Eq!?D|3`!lj2*{5AX5 za}E$TSt1D^>hhW`=J9${;vSgat?X^((XF z-%lF;Q1WlTG^(gfbxk_Hb73r}G>H zVHHq3%W`2!V!NR&F%t1mVm#D7m-=qjeDvdD=JMU#vhW6{2@}?SKw{Y?4eZ(XZ{FYSe z+^f_7Mb5pINcquQGaFl6bt@b;QGrHO*(G5{eDT%owiY92JyuJRnz7{!sKKe{-Tpvs zT!W-}ckf`l9Dx_xZ~k zbf=ZVg1w`84AzLlee-x3ehG_d4~H17m0?V!AJq;|JrNAvCKJ03g{| z4ofu~Id8BkeG>BSleU|Co4(xd$&R19y3x^p<~qttYv|i?40Tbj5|&9th_}W$rX&ft z2f|x;H6UUo@t9oKcy8R>_u~(VSNE(gvv~DBqbyzS*}QJ}8MP3UI{me=8wL*Dt*MUS*8hoQ4jNv>L-OGD!)`rEs6R?D;x1xlbq}rT_BgKgY~Xh zpkaF837M9F{v(gc!+bZ<9&Yk>rleuoAYZ}Vg1~; za5$~L$_2Y6>GB+KW}ixVtxk~Bsd%JHtNT#ng;mOr@3S)dr;B=mzgG)f^-wNk(?}wl zD~Q&)#3*0lWaJV`oF2QtM|WiZ(yfan5{;1Au(1b{(PPp{R&_cx8~ z*;n}AR(a2cb8>y>ynmew$C5F`v=D&gU(vrZaOY-U&H|kJnUAE*CKA$1YAC zeR$q~d&X z8Wc#jz847>+{{nqPkzk!%_!)9aJ=i(JUu?Jr)u~OX+T3+G-RyK=*ntW@fv&nZp1~s z!G9~A|-e(HJlNs7uW&ZSL&-Z zTHqb}n=zrjj5nWVgK134=_>7V*zxGiD)XcN!J32aWRmp$(fq9MN?@B%c|1I!+&+Y} zz-fRmjmSLLVcrMVS4`NH7R(BoqrR5tR-MRDW&Z8XWZhUV>#IFRUj2-YSKGX*< zG?FaW$*JSM`;d2CVeLbs4|(NF8$UTckdgfy`)#X}5bdT_eO=utTS?j7!>*z5o|now z`%iyuex7SUedwbDha_dXlk}85TK$yMvzMrsB~0Qn^Q5F^NS?`gc`EC#U*yod`7y+r zJkaAtql~)LUTEe*3Ay%Tr-TBGT#ynq5iMuKj!G9jofPnJfY$Fce%F9YJIdvt^%`QM zPs`9Fi$9UU=&d9>dP$uXuj6z=j zhXi`dOBJ^`-l%0=zIimkRg6+JsCq`wTS^L}1OApwQ|Tn5Gd|8w@Jb;3ZaoFF&0FJoRdS!O0lybQZWH z6U2W$F22eFZRiX#^{=+;M4HA|CU*{MWEK`g^|%HWU$)9h%y=|@YP1#f9jq>M zP3=GJ|3P~_COrZZ&D@56pFJqs0cUkSOg9~G%4XjYdoIBsjPSaZ-d3E^c7JPDtKM)s zeGk?4(nqp07}ng#E5hJI)@Kj3w+$=f(%UwWua33Tw`jTXSmx|RhyP~gG(}mnhaat) zwn*XC^)&;7GH??eH7kvA9gFuIpzEJq3Oib7(z&?v)4I#|^`En`J_}x5JFrRz@ty-} zrLp&~-5kns@Z)ANA{*=Twv06cdkIg{8)KInPb$f%B=!N=-(0ia`roXOs6d9Dz`HhYZ*$@scQ{Cxtzh4|44<2M2G{T@Eg>G`*F{4*WXDHT~)g#=eDY z9h+O>kDr=|jU`@>ew~x;%WI4isbqdAo80GD@ZC)1ZyWNywxfe9c$)^%<9*;y-rs(c+ZkEa8x|4Kf@PO4WbpsB2kv97 zP5GSVg)AnX+^YIZ>aIQD688HdDDQT`pXc*)gD{ExS^;dDBTGcwj3SB{UP;0C57PYz z8vzkH25%}|`LQ@0@&9S>%j2P5`~JsLQlXPmDxp%;sc5w`bSiC@79m@u5E*NR#u%k? zd*%H%W(=F_G)c#R@LD?I-+9m72Bj>1*jf zgLM3L_wL<$lG6UlULCK{Uk4iX@#{*?!Pk_Ntbfinu!=FK^WK|ZDZgd2Zu8AKzS7U| zkE>YQFSvffPGp{SsV@BEZNVVXy05x zo)gcFZ0Ij#A^T)SRvO&@3ZQsy#iAqUK;KYDZn1(IpX|flk=>LJxQF2WZI0scvw%}N zq@%dbWEiUGffKZ;t>`j(Ed4;{R2wut!k1}&6JYb&#hARA6M0gFPDL|Mv&I1)?%Ew- z$`v{ZhvOD!n_5fO2XIJL(u;hPGQs)l;o$tHAU?p-D@iliS({6zWdY-`3;PZO#x!&n;ifs4U2+=VOqSb?|4(8m8g(8!v)v)`>iasl)a{fU{qg^)~`Go8E9^>%-@03;mhyTSi%De!QzW&Lr@s!b#YGJ{H=?1?uN80Pdt`&o}dnfvw_zX#Q zqA+6Qzw;Zwlg(OuBtQN zHF8wRW2<;8TA}5q71u5iN#=qmenOf|ew?WQp}C3;;@xYpZo)vmA)U2ZHHphKOd*h8 z!PqL1js%00sy@2~E$DAdHPkJfq!K{>MPh<@sLhL0knrYwqx39+1mvl!eP4D(>j(sL zuom#!khkCL((0+IV#5FQk?8Y4AcLGO1Okl=;X;e@8wX@Xq@xpc&%E! zj%lpOI|I(JTFE7_{=xQSzy7+PIu-(663}O@%EPd(J&!kvtPY?7Ft|?13d)}%F&~M% zEjYR3Soqkxs5%wJb(`-WcsX9@WY-tc0{Dc3Oojg5Hd~j}OlI1QN&HiBP*BCXN=iQm zcd_j!4O8o1qOAdED*6u)8m~DTvAZJzt~evr>W+{HZu~=2<4lzzx z=Sp{e6mK^|QPc8MO2Sr(P{5*kmd;dQyooxX35x8}aVZE4hyyC12JDx@W9c!s?8T%f z!n0;%I^Dj42vY2v)3^8n#KMu_+nJeLIy9TyKqtND8wh;aKA=uuBW0I$?^+eO;y1kO zF{V^uswiDkC~Qs#F&0PrFYGLBrh#elsOXLUiJL|OcHbLlIt_Hp9!=m0SY3Q zzN-$T>pp)GcQAnL`6ONu9Jvqv9kn_Yk@|G+Y3b>HcN;XI^!XN&#WcEc;hhpL1YBQ zN9M86uoA?v?u7>?G)ON}OZm-lFZd4kk+VMmR#4ak!f4{C_&~hYT*z>&1`)UC>%fTN zmJc$#W!t_O^W5{GG*5_3w6J3z_<=N=>($wS=%DptFe)y$1_zg)DhkPeT%&F)CL$|# zhFH%tVm?80n*HlwTf}98w4Ee>b`enB?S&wtvkA;BYnxt!F-D9dicA5t#RrEvys5E8X11GY7criw#Hyy=b1_HEYYhA;iGP0q@xQw!5*x}x%elpX z2-EUs^Zpa91aZ-r6);wPD}WRDrvmY_@piua@_&6z{SdMxezrlQCkm4D2?HjIo~z~b zM8R%;M?(}pzE{&Ci}|PZ+gwKjG?`~}x-JSm|Nd6VTvc*qPE^|zUW$%#?h$bom7e%# z%I7BzEb|&BqTK5bHA@i}G!f2!rtRH+{%ETG{m7gy`3>j~OvmQ^tx#8+nijbZ;#jL(hOrnDf)cEPC| z-|?7I9?P~|uSlu0Jq1OrgSiLoxB&h(Tad+C+hrta4qtA#?!B*B} zWHu$UfcC%}#vs;`?Arv3GXR?qC1oNdvQ0aTai#6TT<(B8h{GZah*p=EQ5XgOlY+E% zqc?n$j@;T(C;I-^4f`4`=|MvOc7L+%#p*RIp0XyX@N3x2e(L)t=ePrLyr6V6^+>wN z+72*d09AGlk;i%~e8Srw-lZ#HOiI?!z}Bb#jWPc5tY0kM*Q=TtrBPoy-2g+q_r_ac zWOImD%BXuIu{AB1J5%+>o*>TNq-Ve3<<^qeIQRF{!k)$oT#g^tFb%p6gS#t|qo}9@ z&ieiRZ=)aj=aj13TqJ`nlR?$^DJ!B6NsMcqiAhR^bc~hq1nDm*#KA9G zXk&JcU0+x}5<^4W-=H@W$#o zP16@FTtk6O)qoeKG~(ow7~MAg!w*yY?TY;)lJ!(V8RagxHo-_eJ%AV|?SkG-vqXP^ zZ*ctZ-9t}*Y{_&{Yo)9ze^cS0YwKfd&FvabuqjujTPP-wE?WOheDQ13XP>XaihN$> zQDbwTchYtFPB8Ll2v5a|?pM1ZJ2xYa=4aLD+-@I4(SdK|b$JOt^JgaHVEbUGn$)!9 zDYFCfoOjdxdVs*V3=VlfQ(Mx!7|V6*)Cy3DRZAAmyua09Vj$D{+IUUo_kMQiXHWPN z4bzAHs;mD&U@3FdFnvKzCgiqKsg*-fajmYALQe z<{uaP*CD5}{-WdsJh99_zM?D0!S)I<61~&^DuLiuF-TG1l?uo0emn6)U;&vKfmMCF z=9|RrNb6GQi3wq}7off0_!l6&=p&Pw3+o?HMry*KLyZfGrYGk`p(k78WS41R%@6-| z80)#XOJWy1;PWpSrph?~(Ir+V0hdP(&_c~z!JG@)aIr%ru7oBtFHc2h7OEmS1`~vV-}Fhz^OeTUMA&JQt8Blj||gu1CuGsDN2KBY8`ORu_*+Oq~5k$ z)6mT%#f!BbzG33`Bfh38_vV7vw~wxpHxAQ}pZM$O7aU;~PU54guO!B*__Pu70hglQ zkW=YQ4N6@GtkXEaRfX?m4!Xg8m`UL(Tfgusz0ut%6;XfB`IGn40m#~CCPY7&4SD}4uAsP~OoUz~*z?t0m zs!lBHr`|_RQ~Bj|4r=C(gDP)ZJ>%-{E7t$?V=OLRm6iu>I!V#Bk_4J%~CDNmxyQ_vMrGbTI;s_ zS=`?X@{#rv<`EjgOfv|3r9h^4^MljEzlKb1>awK|4KtVf0N(SnLo)eeQUGl#IcYj(J354xMu0@=8FI3e zaqwdP8yq>BF&t$3%im`!>06^^;{&+l!48G0GyIXNUM~NIA(SyHG2xE*tom*jznFLx z&f5EcAF2&sAw3_V_**9bBE=Ee(ejjfA+PA3jrt^%k(J{U%~*00K_a;McpkxN1P)mL zkOE!HHPSG(#M+`$Qk#N(Nh%56lJDO6k#qY>W32hH^fSGy!s$;V5daoM%L!c zzsPpR{F5NET}s<triJ-W^H3ZE%!u8XaozXiMQqgA zpmJh~-_yc@wk|2EBLxoKMkIXAhtkG3b+zJg4FPIl1KZ(S8D|Dg=M0x1r%es|LX+Vo72t--uP%L#ide8&f4gTKmv%id|4(gpb5NA<5% ze3)VKU4Vr@I)=y88=tVa{>iQfhQRT5jkbH;EQ1j=cHC>bBlN3{m$JS;iq zWw9bvm|mk0F$-`3DaL|VNY|eCzrGizlBCF1ox^MhQME;r^q5S*MKa_yjoh}o4AF(v zI=VYM;I(gGWy0Y&s+uzm=F*HwMIXYlWHJ1=vKmn7`8$cQ3|~6&BI+=G*Sy4e)t5p; zKMyn!$Fk7v*xhWzWg;U^X%RN=C`=}HPW zsPy|Q=+iPfSc-Y>q~j1+2a6Gd^9D8>cZ`hQ1AKJ}w|hzw{=Tu;>%@rbOd;2_aHJVu z=C`beFl9zj!7tH6_zT?iI^c;rul|s-XqetYw7lO4Up=qzUOMzm9urh-k}F`I<1o{x z+4zFCoD(iSJ5Zr^v@m|!%*+`~-#5`kfzl&kDmuVSM{$b@jGe>I7`LF~#L|EmcZe~x#k3vyf;^;8cpfpQYb&184JX3TG8|ELw=R4l? ziVoQr8wbh*7e>+^l-J~_`<~}k;h%DrITnBPMw%n}CK!Glz*}dT|MbYQa7TH-Z{-@u zxLnptwEELN!e4`qOT9j-tflnozHC7GJK`!=-;^e|6oh(hx%#uB7nGQ{4YY_|78ud?~X&f*tUJ&&+&(O^GsSS z*|}IEcI*efceFf2FyruCu9V&QPD#0Opyf{m^4MbpD^f^dN8t_M;&?_JCLri0y$)M3;Uy8u9db%Zpb4ECd|+M=OSi zM!u7nRbW}jDwTSvtYJ0C4ujb?F63;W7^jOJz=qPrEdA3*UT^+8_ztpayU3qG!VlyF zN(I?*<~ukCJOLtQkZrfcXyKdRMdZ(jX+#4@vj}qbxOj;NK;RZVA*S&x`Lc#7yL&&x zLlY>*CDK#HprfT&D-IVVuaZJzbP&;-_}H-OHpRod{Vyd(>yQsGMQIW?EfJ2!W2mxV)Vb*GIv{ zH&=30U~O&WHNqqZbU?-_<#p;mFthm`Cly}e<(Ah@nkH=lScsatxiNT`$c;mfIIrTi zQb`ecPRqT+%Rm5R^SexHg}#Fb8Qt{*YwD;B(gO!~p9?dsy5t8Zv*hBH=0VA(I+cbI zK8_6eOdV4nXFE_=wu@k{wPS_y z_e36I(ZO$bxfh1Rx#S0$WT*hoYH-jU6nOW(=CZGQ2zyq;2anmZ`AaesN)l@Y`roLB zS-dnU`l*~aXC)}dHy6KK%_ZJ@@MfOyF}MG&=hGYYTTU{TR&<+~81)EpsPN%n|7b4x zT7qmIxsZPeZU$>PD)cr$MLbocb2M>$<06^|uj3)06A6kAq?5=zsNa;LM)+b^fc1%> zp1vwrFQta0eop0K4&fwvN_#t@s3y|qQLcY>P+Fq*)fLu#hR~`^DQ%p^$n|!{TD*&8 zD6+rm4-1V+kqfTq3=s;?U4exR#=YaD>$x8@aF4<3##goredE34-$kM`Omd!1o;fKq z{V8>~t?FvT2aC1xDAsQ;Xo`7>j_hE8&twmYn>FUcC%{@pZFJggSg(cbTMaLB$GO5hNw#x(nuYyHW|vb*k8f(E#LLY^&MjKlOz-UB>gizuR#`Z4l!q=6DTDc+h$;c(Kt%juMXt8k?Ez6}D^+L2U<{5Oahxzr0V=BdCbYE5upKMpm%FdgG!;w( zX|oTEO~1-ILfG~0D1G$tc6!8minIsFXsf#qJ_)1O@tP?OZE>oV#|b>fQk~q3f8abx zb*qO*B#-WpxC>};9Epyoii)s;hY3^Zz7+K!ejf^M!c(9}CeLV^&R~>KiH#It!c#+p z?I%ZMG;vR+ZQazda8gL^r(aeIyGAm}k+`@T1Kw?7VW0Ku22R)EyV~2}$z9)^cGA(U z{=)V_iYs}nsUnS`ZY9d{UI#WZ{8*@S6^AIkjNGmzntUy%;jP8xGH(}f*&Y}N#j>5ry`1DKK5GXac=~|e3 zi);4Puv^-=+G+C#mz@p1rM=X+X~NWJb$iJnpD?pJ%f4Fo9rgWW%#GnF4tiCL2Tpz- zlJpE^_fXqOSam_j>P@Zeqg+xc7SFPwHzuBs`#MwS?VyiW8#B8bQZPUH(tdlMV2jW& zEhFIe;-jE`Cyf7 z{AyHr#dx_bf#Azzk&ot23gU{fhSceZ7s_SvQsSiV-Q6T;Ng#>+(D3UX&U&WPTHLfM z261gu2(=iA63E~3Qu9|tQt)L;wVxSF(_Df&^xx)?1{*&F`N^mWKc6MKTx~E8_GaR~ zMIaf~`PrmY;u`tSDv@7MA-Q~uIJL`0>-8ucRA#5Mu*sxjVaRLI<(^3;OZH5{u($sf zL;}e()QJo}$c~ z1a1{em4ZBXrr1n%HiJI8(I|NPl>MrmfMVobkzZTt)Xmd@Q!gW~n2o$~UVF5BH~TXT zqhY7t%qATkN=Ni+XVY42Pfa;mE2@eo zD5(}6Ksu?7?R&SUhDne2>|1fXuSyqYd!;K}Yif637&VL0>0Z80^M_0<$zh7)X-<%? zOC%}E97s0liMhiZkt}D(z0x%OjQ;Y|6oRP&qo$*yn03S z=59AuhVR3$KC#NX5t|E>#7W%QOH)7d8947>kq=KWB*xMx&m5&aO+1_%qg^k-7s7AA zKMDq1>FJ&={iE7scs5OjL%b!k*YE8phqx_J#s|=%Y;Fg;MA_#Jr*;xQ+2%!JoI=-K z2a9jq*al>$a$0GbXK2ZWC*wP<00oCK0!9W;-wXXfF0gN9s>YT2*dkHGD_NtmZJPdP z=V!@iY;{`RRb$0<&>-B2GOtUAW4GlD;gf3-82b{_8!J5qE-*9eyOC5Wf3hpx-uT z<5}&pLwi3x-B*dHt<&6^V1;wYqQS0qstj=jrhvsOCYt%deH+0#jdT;vL)Dl2o-VRK zba1bU<6?YM>RDi4X+nzGrdKb_yzJ+vyY8@jYPK_B@3r?Vb_{VTyKCL3*JIiE){HBG zH>jU}HLft^5#@JW^B>oRrcvmcIM29-Va~Fte1U=!Ls76a;*9SuS#LLStzfqX!GO1K zFAX0I@Y}{|?2b)H7Q({OW{cb>fkV;qy}ql7;xCd{Y#0Y)v#9xiASbq|Z=mZE9yUEu43~=T6kv**&9oKR(uqwJ4R- zwIMnV&?zlkem%f8FaFhy+WSjG%-^Pr`54v>Kk`k=)_W<3^c&5ND~$rmoTLk=KqZj^ zfvAAvjjhs`RRg|u0kP=Nh04B)BQM8|h4`)HJj<*zs*{ho8wY+`$GRIQ%hjuUK-b4{4PPb1PT|JtTtxzu6FC!eb{1`C( zn*!9H{VTEg%hF8OnMWrGu9E+_?r77U^Ka&s}2N z+qCs@4T~ofKw(wSJR_Fd|4`Q?*^P3tbl*!KB5*uu1sbt9cl>c?;#k+ZvO3BRiRFO$ zk5>`gnPuozZvGy11c*MHojB-hYf-jzkHm6;@V0s16UVu2+!>Sd&l4r{O5Q6!BmA~q zY`{MLcj_;2_2WgW|^Or{9b#I^hB#{k?0r;0$mk)5S9GYY-<67S6pa31)=D-J_mOqY#M zQ_fnB^7&cR6<_q=6E9$;AuRNh%G%)jra)97g!Zi0ZT@QRg9tIx;+zfopb~1t=D5mC znE@fG8PSb*8_!4Y)=INy?fFPY)Oh~}kE zjtln+2%=*1*pT+AeKCww_G{QniGD?QVBO36w4c#bWw4wr5*^P)A>@0%i=`mD2B%itO zy9h7=UT?qtyd}WwMSy8pKyvbJXH#r{qw1qkgvohIb$*SBi9c5jzo}#uYdh=uqk)P- zVvcOs3q11b3Drf7G}I^Zn!;$OwaVy5-XN4+T+MLA)*ogJN*lj=}e(G-b}y!~>#M;gyybve;5Pp#_m>p@}yT7oH0 zm&U7qFJ>n4zfHDP$i@>whbLie#R)T^oTq$xRCg#7$U%oJqk@!B2m+52M&*T8J-hmO zKZPr4Wf{J7yfD^2!{D$gkWh-585 zI$e4#8()#!W`M7HL<#-Mb{-U!hXsAL1FU!@QQOGw1l2(1H7CN8YRalc`NqMLd?TqQ z7luj@BLh1zGlN#q5vKuV8p)%nmgRCfonS5WssOdmfxNdz>CHZ2VY%c_5^g6)!+k$k z7_}0o^TJB2E!L*-Lt=p}JI|#DHl>7w@hWfu^s1n?>il!`rMZs&<~3IpI@`%SMad(;BP6cxvPHY&qk!p(*4 z%+#yx!pq&o?d&mnj+vUAHK4_)NhN_iDkW*GVk}=M4C(Mb!&M;TFI7z@-cguWcfP5c zYy;8+!j;AWK0Y;oVdF}_KTIOJFhVY+a!>oVw7Tb3R2y%#b%sxo&oYyMl8dg8tHzmZ z%&4GJYype7G{B-lt({UMI%Hw~8CZopEowvA^F(xvX}mLYs4q zi%z9w>*xjwYVxD*nrWKyeu-CtC8N+|Nmj^CB%i*MHF2$v{;5{UfP(KfNh?=nz5RqJ zY7J`+n(f=YKM}ZCxTGGT)w_TD4v9B|&&l*KRJR-^)BaoI&Dco3DATGlNzmiO;2L)G98OGWA0e&lE^{mf?v$ql{9;uUj5M zwp_n>N*FGO>KXiTcD7PGoE`;ghw7$C zN3|%*sA2gdCkapU{B^?^iOtGMA{5dcAXf;@zZshrwn)~3^pW)?k zKkj0E^O;FpG3~UL>rM4am8=+uEJcr0Oh{pdVg@fF157#@I@L2+pp5nUh!2rcpm6y%cqKBOZ1^f5CJ2nQ?;a{b#W6N;GUJsW!}xp^fS8}QNah9Xp-YVeTteF%My#q4ti-i;nIicW zyAB!I8eve|ItlIV^kI`VI-&ed=|f|yS5<|^b5iIfuXIn2MUm>H`cUps;LT!~8A%6C~rqIU=vwq#4JKm!% zudcRV?d!*s%^PebuzCxEx}I5 zzA6PM{t_SeMo#of3gg$*+KY-^zqLNrf-%F`*#<5OwgK>MgYrG1bCd#KKM9q*(E2Lv zi$wqIt4i^Aik;UM;CHX86W^Pk{=y!sBH)LLQ%-n??-J+WS{VUcbbtb>_!A$k2|uWs zfAyWp)p0ag$a!~!RTs?|Hjj1;rqDwDpF8*w`7v=Djx`sfWqt$kkHR3y{#`~nQgyR$ zDXvqemFd-_zAL#4R&gFQ>AFlR$-4mBvKLPGrP?T`TmMk0d5lOevKo1N|I-}1(4{JjfiU}G zWWs~q%g_NSG*)C$|h6p&hFu%(Lh(%LO`mq>#lM+d1Ui~E{mR2Q*)_}?<8W7>R z;7G{qXAsSR+ycv{|2`5YfOMW&zN#oDqw`j)PMW9k31V=T_aX1T%;NR`!Y|t?u>8!K z!y!3gp2}85a+%&nZ9312$4?RCJ8MpQ|N1ZdG7q16AgiKvL;`ZKDyvbqjXjLm`9IH- z%7@F68y^USU&HcW7C*K-MYP_Q<-K`jo6gVCp31im6vAZFRxc9IB#o=egM;q4V zwQ2vKr#x@?L2FRNv*DxVhovCD#~yeTyTXPa7xmw=(%kT-BJ%xvK$f;>{f%Y&7Of9? zA&jv*wgBF=yjmBO9Qp4#+wa4_0jpu}0^UO`j=3MV zmng3L;fqCEwEp01_Q$i59TGo$aU;I>{}cMZg3#jV03lTN(AFVs3B3yt;NRf`miu$} zoxT2VP)h>@6aWGM2mo?kQB{TmG@X=B007Bp000&M5de2@a%3-UWn^h#FKKOIXJs`m zYH(#|Ra6ZC2faZ}W4%F5W4%F5W97UDSd+`PKOCee(hN-!nv~E%AoQw~Ktc_@TIiuk zuYv{XO#%c$l^PP7^sY$n(mP5Kq^lHB5&d+Zz4tlyoO`~rPxITOm77LVAJt+|Q>s zF986g=ZJ_Ys40F-oS6LQs?HIUkdgt<({fy(W4J6PY3z#`o1kZ8;*`FQH1$bNt*)sR zmoYTD?ckS$o?PLQQZex~uJYq(zd@bBKA8UcdbyiB249lsC><^v{){zSlYK!7q}_bC9tP*zquyK4mLjPaeXG*BpJ4aKUZ3degYlXLI5 zWf<87(GV+MQIguPl@U06Q@bBU?7pM=uu@4&ck}-Lb&X{2cw{x|4&uq~F5FPVQ@%)^ ztjzpi(w~eiEZ~GBvBmj(QrcCq1N?zP{C+5^3fdk;D(PuO7_fIRE^wP3)2&^Vah(y2 zS4t5vPwR*VntcbLmxM{*8y1qLs>(Y=YQ}38D(i%i3EE8t>^7(5)nZnFw%-9?h?VW} zR=gB1aaqLwEB-jYGPR{LL90>v#K~^g4+1+W!b= zZdvgoHW}!JqTxoSntiA1>9_df9@%B`_}-1TV35m>zJ`@D=9I5|c0|wbE;I^rMq*J= zBB^;p?i>-}T#beyqS|7(f|aFG;+=G2lr}n`u|9lejmx2TH5;j622 zN5Oa7nGtr$-Q6{tA3xuhO6li~jddK`I|R7#qxCK`zARYS0Q?{ITB2yPz7YhtV92vI z$5PXRtFf>Izqbm5E6{kHe^y*?VSB|-)wOm3B_~fIe*G4#h*wtQOnYePTe9dSh1|Qh z-|Z_pE-?{}{t+etL`xTXmHV@fwMn3cksey?(OkjeM7Mr@Sm~>_R432Ob(wVx#wqYf z>Qef)1UkB|aT^R-4x*7(mM0!7(4?YzU~4TEa;6hFRADS4aCeisB2Tv*&bt`6I{ad` zsKC-SUOk#o2AG5z;nFmfC3_}9ZZs68M$pSN3VJ?6V={qbig&nvzt{Q?Q(Q{PJybPToIRI%tnkd_L-S0yZ+7+u(kCNz@c3bDk zkD$hhTaKBz3yv_ySSB>CZSQ$|aG9^*s7T;MCH2)~-sXXvZ56Tc@Kg(LKCdkxHdA;D zh}t%ED_ejt3QmK$o9$80Y}Gv@>~?X%=9NFQVM+h@bbV>(U6F8a&3{ZXI1mn(0$X-N}oDkF9yAA7A1c2 zhXm!eX+y%jWZCWX3l2EyWsEW{?4#YeUljpSX;aDMV9W!#NVBNul&v9rG-V|VV>n|r zq%g7FzA%ya$|a#3JKgCTk%$VZ?FLr&0Yt;EpLykU{HlCp#&?%lXcw9&EiFy`?TWJS-MCTV*pgBS%a{+5 zq~ez$%@oFIKrPi6WXVvvE)&KRyO9yEMB90dX1-Xx+#)_U!2F$FSuyE?rB|I|m)w}# z!j3OaM;O%bfJ-)I6Up};I?-qcN)|`D!v`QHM@IAGEM;BWa&2O??;q%27k4du?`&x_T0E=@t;t8?41X;AuLoPk-Xk*+Fz&$Kx~+s6TO8ysvsF-rWx zoVcdGsiCZxAWdRtiMCEg5PCB(1mN^qjAwvM3au8MdD@Fb?vuew>^@}=&FOc}71>L3 z*6)I*yvsSYk|_xJh!-TO)mz+g@v`9$N@b36cmnQY-s}&%4;8mjU51Q#2(P1Oc-oAt zdbOy!a4fXwiLcydCm-7HBijF#b8O4?(!X%-dH+cd+qbppkg@x$e~ACY7u#CBzhYk+ zwW~_X_>)w9LQB_NVf=f&{|AKbZwgWPjaRbYwBHhLab#o#Kb&2JGtWJ~_#MFenko1+ z(fkAk@cE_R1*+qaq2igfd8rWA%M9ZO@Dm#Xth$To(|17K<9+9v3n#Q$R0ze6b~5T= z`_9kQL+i}1F@U+U#(NxdSp~rd?aY#CG;idgDR)B6h#jg|zD7ED#lIT_xK3LsKi(Zd zwtc=ul`$B3z=|D^elA2*WA5=ywMG_pvVLF6MTEW2&ynxd*QaFvn_exER;=%ZcU%}3 zOx;l$iU%fhV=fbKTb3f1F$-{5w+nKU89an)%Ex%yL}0RqZ%R!kiQ!Ao4M}_f zsuOlT8n{-V3zoQ-MEdBDh#IB9e7ppz^m>L-`aTH6My8Q*i(e@I&9gACH^tMHQ>CV1 z6WjDX+;C56p-EayArPBH*Z4z!0x)}AP9EiN2e3zmXK$;SyCVuz(2`dhKx4Z17r^;C7HEjyzJsrNK^ULkx3Ln9osmiUVp zBdy+vAYv(vzcPm(kysjnat3C!=sFz<&B|YJ*KRKV1AFS1(ouPbsuU#t}TzYb8!;4>lDRzwXk&;;%?Zk;ePX zog7QP6>l7jwhU9p$;5M5y#aq}gcyob(c+cd zklWt@R*IG)_ArAblczYU)>U3O^=5nQ4J~Y;IyNKdTA*1F;bx;(8lteZn@GZW*wi+^ z%U--5Ar%x)rLdh6e;aO4}2PZSGC3FPF1korw)pNeZ{aLDV-K2=%!bgt?S9y3=r5Vb3GtS{-6PtWl>zf6v?;eFkw|=LI~w5Ae1>-!gU9TXtFikOTjPGB_cvYW%4T7{2K}6FoU$tJ#kO zZ2lxFLw5HEOs&%Jlw$2Q#^1_7YXpZ=&(zurj*mp|uvxeF`O#$h*T$ z!*gfq3jK{@;ggCF$EL5ce=+L+Wf3Db^+w{;7|!`pR{`nxC$NUJpc^v67lq}t;OzGY z;cR5ru9z$IWtTfxQ(3u9xyvoVBy6K~tsS0tA#z@9O3ez55C727YY#wacR$dysB+fV zRrrbYP73NCCs#8wSGJDrv{`0X?957;&pNWXySuY~y%uWm8T7>RGSbAUfnkmMqMeAA z4`ZnaCnl1<0ErdN5))d34oiaXLL%<7*J;OE)G;%@uX&Ygu1!&2zwR6y<(u!@FukLj zVFA5!4(822nvYy|#Ch~dB~`n?V^gC8HNuQ5R7-SGRCZ#r)xY7(8+sx zGEWs{PzowO0OCwO#aETTIz>}^Yq@Vmf{M?9@V$+~@m)!6SU}}L$cM=1jmNn@x6WVt zNx!oFt8sOCAKmeL`GA_=i0ZvxN^p}hR_VzVSgz+kygiiS05w3$zsX?@%<@WBn4I@U ze~IRK1OoaM*9dtk(9jZDRD3Q$)`@6l+9A#Avx5$e#Y^_U`Gx8)EUZGg-hn4ri?C7; zk$zE7=oL2gAbX;C?K!QG9gKyaxVofK;O8rS=?g~4!mFI z6-nEMM);No!`s}0_T+Lcl$xl0>V&Cbn3VdW9XRK84jj3F3b|rMU=rYw^@#(LAB;6? ztJf`CLVRcfLOSIVY6SW zv!;_AFXIHOAE3*OMVX)&J<)o!U1SO4O)0Omg^Vpl4V`!9EMs-?4eBKd9*)4bF2(&B zFTVpQpUr%<3rsJ3f928{QkrF8iB~|~)1J0~41aD}T_hXj@+SS@R^IgV!hAnQ0J*V~ zvEuG)tp_VC0^1O9$~hCC->b1CbvT@ za*pLn$s|7M;UqT?%(cp8a?hdj#l^opQMy?)VP{~hnWP)FCo#{X%Q=g{O7%VEb^tkS zBmtc|0pRJ~h3hT83vMkY5iwi?kQQAX#r(L{XtjJv$;=GL7=s`!pQzJzDTZwb_&H$f zcw75onIwpBZ8#w^6Dr&}Y!0#^W-pKRw%t0~Z@{yv>pYGY|p~m}5e`EXQ}GiY^v$Y>W?94B{jX7TtId2zqBYwlFTLFY!7Ec>ko*VtP1K zJ5X}LE6F%iY>jp9X=b1ss<%!uDZ}Rzz+E#cDk}Ee74~196~Qy)*^8?Q+{wE`B;(<& zj}@@bjqW3Z(i>j2^iJIj^7(}~|Ap7AFN8vW@|xts%%uru&u&`%hm!oTpbN1+?bkl; z^s~nWJC0Kw-glcpD>Hq3S;+hruu#bzDz=xaDLq2ea6|K}?Sj(dJ6Xi;tx2DH>qD-* zmLXdToKsS}!g9qr*9r$}3Ga?bn2Bd~Mp6@2uChE8FCL@siAqIPZ<))X5V2zo0e%$o$M?L1mZ6mc%vQcU}|;&pk=!t zO~KNKUnQhT}f+jbvc|9xF=0xlvK?BAv5=Po3y76Own-1bvLG5f*EV`9UyzfGMjSYo^Ow+iJ% z$v?A0KE%vND(;TdPDwy527z_))&vP<#jfqXq|^_E3Z4axIBKv+%%l@mXRG! zGG+vWvXH&GCHwqJwQUDssz@uOWLMI|XmYJW=!cHh_NRj?lBkYZobYdUWC&E0)%HLI zSErhtW(>XT^ly6EY3^qVq+o`y7Ja97c^VO+?DM+(6HkULDL%GEeC!v~+3avkVEq)Z zH6HLu+2WMy}_lh{1dOcd;+Z34Kfgn5YVea*MZVNI_*8{H=bYL^nDaLF+s75xnd z-UnE=#={5)^+r1jk8yTHp8UBYZ)5TjO0_gC2l)$eVTkAUQx^>|X15dfqGE}a!xG{= zh${aaC;WfqUI@?u*yVh1s%r$w;zft+XvR=B7aY%uSE zL0h^=2=mx~g4{+)>(Wr~Ya25t%RE1i7g0E*UPU5jp&_!F}PO%ZA^^ zk!PQitY3OnL?^h=2Tqj>#S&%{Z@53;Tq~$C^``8j$eOnkWF2CbbYxQ=bwuOiW*;G%)r3lVVEwgVg+F4r=*`Nf@eIK*(Q=>pcak&Kemn79HzL zt&OSzr%|gK*tR~jbg!+pU`$>V7az3?rDYhp-JuZD}%LB6>uU{=qox7#Opo$I#&&fr4$Ir9zo*Y$4%mP=O#^;bW~vPIU;ki@`o@b5 z;BfA5;Fqj2l$@oWV%lCk)WQV`c4ty&#SzI=vjS->q=zse=;0-flFWbm^dhtDi%$K#^amNl;u4EZWi}1!t(nZsd29Ydu!kO5t(Gi_& z^M!e(!WV9A=QCqJ2!6DR{Gw;E0Gl*&zjD&pynhp#q-8qsPB1efiihI^ImRR!SwSsp)yO~!f^+@ z`SqqO&V-c=W47D}A8}9K$433uqipgh;Emj%IOla&3HK?PW$Qeri9!#l#As8KIzt9y zC@?Z2r}1T3Tji!#PK)qoBa20_Z(!6R9WdsRzIBo=`P+-=Les?%g;jFrrSh!c6)v8G}wFr!nDDC@6Pra(h(2+JUFS z3G`ibhKGcIJK-zs`q*TQpPZ8PVienQTC0&=I+wSw#VQ;h`KHeFcO@UZLCPU&l% z+>Yx@-vKuloy(K8x3_q*N&@owAU>m8|ENMoOR?mON*7TC5|BAxD~fWcfi| z%WY-#s~suUFF zJU%@y=`MsW8%9w>+Po!U^N&9yv7r_67m;E*H=w6X&joarj9P+CJ)UPluv{-hhdXk=_ihb1zk-d9+RxdQkC>JOuY{+@EK=w;kuhsq zrnLDQmsC3^G{q6HxbxJ8E<$3a9g>?8Nw+g`AOg05&dC3z2snUsmnB&%iMA4Dn2m`@ z_saFcABonend>ze#aVm-CXl2$%GEMvP0HA5+|R6vGgegQ=eXSDG9fTc6^JVB&m=Rh z36)9S4i|3FpHi>YFxe;5bc3bbvlkE-y3n060W|V>hdW?yZD^=Aff+j(m!=BXl)PVz z)pa90oWI>;N?P}EHwn!;W9>U#WnmOjK`t)db=$^kN=?oCtl!~=*B$-_^$DJwJrN2c z-VA4w{uAvCZz0J^z?hdE2VCrh5F?rzkO1jd~y3#rpsEcWhw?>2sI)RWvJjEPghSztEJlD=*#F~a1#MtvLeuo)rz_pa75W$enMdXK<}r$ z$6z=@TX4)7y1CG5^14J(AWii*tirLz3CS}Vv|f!U9fI-T+JVEF0g?K)&Fi3d?8YHm zqpW}L4wFvqH&c>ia%YjP@23e8nLDo}Y;DrZJ>_XD5)5Sk6(Q{FY8N)`N2lXezr@<~T~)gV0p%$A^iU#T|h&Mgxl$vxt;B@z#&pLxb?VkZQe8dhlB| z-a3kF3N{k8rxtU#>6_)(8}L8@wAjo>6?v`FzI@XN@W;UpkK1T27R4^#TB7_r2FLxs zjxcn(KY5Yo*7H=r-tcnd1hRQchBgAME(RYJ-GZYL6-pJ2=`2iF=mew+ej zKU5_OZ2*!}dF3S+Sd1xn_z`)_r0zXMtsXli}0-t`F* zys@sxpeK!>xU?}q<6rt~U_kP}S-s%bzXHAp%Ezt=JB4Htf}QRQ{j@L`67W|SFW#F+ zC_fh$Y}z;e;VjuC%GDL6xmb$t44W1$)JAUau9WNf(K$bklNR+DlzIAv(ve{b_+w)1 zzVcqL2}Y~N&OTtPt@pLvshnKyay?nW>Lqa#INdM~pjSy8C(PBUs^B?fnoE2FZN+OR zT;DGcX!qzzO3l?rWnCOHIa##mMNV>T(nhyj){yj*8ZrUS)&|C%3-;U#F`h6S6`Zqu z7-0}^wx1FA(uc>91;#2hTfb#A9AC7MlCBRw(%g0$&2%gGr9g~s*l5No3LuOSowO23 z7&Hge3!mkn&2++$>bU5gneAcW18%LA(&6|#xpC8zj|<9;#w3e#O7gv5?0VTDUcBei zLq9@B8Pi?qW`g=~%fxM49mb*xfhCI2x!3n6-GV(TiA#RqH1>+A+t*O0E3u}*?J%YU zcfBaf7s?SXIT^pf>_x8?LS}Y5V>K$JdJ&lfTD9?>DLJgL_&61$jN&>OmeM4~#G;}~6U&8@yw$%S5Nk3S>g8vMJ*zmtSmpB=HTHyY{GW5w2 z!J6{l_bE}5$l^Q_XM=)9H8nGA4(fiMxL)d@#aO>v`5n_`>q`Vt{y5Q7frj->3j?(P zwuT27?jTLCJFaQYP0&l#0&%pVeJnWvA~*DgHoGn3_vkXHf3J6Xw&neGm7Q;jG`R@l z#o$q{xXu$Mtafj-|LNi#r;$BLiwdU-(ex0%Yi|x;cpZc~!kFXtm>eGQ8hTA}J~f)L5CjM^jVF6C@uDC?a-7z})E(G4EvG4DpK^!gNgm}pdTn4GE9h{t9 zLxoHKrYRb?E_)qdPcS;aN3njCD`V%(n|o@8_@ z`Qz`i68JIOtkDBSeRDb9=!;&{vEHh0tIzZ1 zP^2Xv%8CAr@IgO-#%P_^K~Q+wiXNnd^3BrQxQym7b}WI=05Bvb{3C*A9$W2V{-i z&pfH&hy?jIyPzyst{1_@VJk`dOnZVpm;M7+E~8e{T>?8Leu&9b4p5<;*=EQKnkDaYTG@qQng4<0Umj=EOxOi#2G!L>V6A!A(up4EGrZCJ7AH-romo+O9F2UqVD%>+{-www|ME< z`Hq9Ux85M}9OpZ168Q`JOye6(j9YKz4tA7)ubym4We<%QJ+W$Ffz(iK7tqfk=S>3J zWre?WQ?x%7BJZhE99n0T)4p}mfU_yBE}g9pT*Ej=e=Do$v8|w62dn1${Yr(nT&2Gy zNL|AoAH9G724hi4B8!d;01f!}_YMFk&=#+Q*YmSYD5vmrC<5|6b4+|h#x^}!nI-#4 zS)b}xf<9sXjZpyuPx+E;S_IU(B?kGVSuD_Ma5y86BhDj=PFu%VUE&af?(CnGmEfM{ z!Ee|bn|RaDCoM>Y->bg9HHvb547gwI{$Z&eTF|iR- zCd9pr!6;a~CpSz>H}`&RhDmOonq}dw7Pl%L!fI*gx)o{*XO=@Z);2$%dKjsEew(A@ zH`)SzYa*(v6MRb@N;66JajAY~j3Jv9R?tbQ{gkNnR~*~T?ZkcZyPn*+4!3wxgx@@P zGyJ9STfE!emX`WI)#H3;kDIoU6R{ae{g=k26)L#q#h9ASWVe4XPe|LDkCmOOLgAy&K%rir_@2r#=+!xHWYu zJ=7{(@{;ab$Mn4p6>HYyGadY#W3F7#N$-iqG?!7IYSv#|H~-775aVy?I#(H^*|Le{ z>PZJ?c(OL`I(Jpq`>SM0Li<(~dxqBDaofX}e%aYXPnyc3jA!(BQ}F^SP|d!ovFO~h zc9h@W=#{eO-3)8+48a(^6Kf>n{w!tVD+EGjXW4ehdBxQg6VmoYct?!gw2c`u*(ed9 zpT^&52ppYHl=k@{L5i=R=w6t=6YMgz_zjOe#yI?{IFJ|rR&)HVM$6Tx=C7S2Idn0Y z)QGlu%sl@`fT--K#f#|yX!)ie&|EnfrO!wk)FrntoD;&7L`Hzavn1f$iJ@- zf%>tl1d2Vu?ohVw6ziiN?(#5)EB%jOu0w-;CX|Zb<})G z0)zMa(&qz#y;kz*73zTB8UC-Ew`PBO0hei=xLwJZvk#`<*V%9h$v|d@zWa38GYmSa zRtv)LK1t1}T%lc@twg#zH~24Bh~`r94uq!n2Eme{a8Od=PyX2)H0M+M6_v}CjW;(I1g~y7K%UP%k7(Zi4$zU*%jz-vG6Z=D{$~)w|1D#0h-0Z?>>F7JBBM1=N&pThcpo z3#i%i>!{faLlB=3?N24y9}OL0KWV=(84D^sac(k|&9daU_+t>D%RWiAjbtanUU!QB zqI9Mk`$etu5v{!wS?F%%*9e+cNZZpT9H`36qxcysZ}VMT?xVqAtxQIoPCW9_!OeI` zVe?@0qJfcF(pe9cRz0E4YRu}kScmyTrr$aEuLr+>gOLzxC{;~fmH=C&cSY5a@QW2W zZpxB(!vk~bBxX*ZF+ra1~%Iw;Kha)kc1dmMjAWwa{ymM_`^`ifp!HjvO-~Z zzeYw+>4-3eYnrA8H^inV$=zY0;;(1oi?}Ssxv?B>SeHjdw29}2p+XZ}oC;!8z70P4 zHT-U@;&-_@9`QSeq+;qnlDStGaBpyrnrC>|X2iuVr&AeE1PvBiCQfoTz%U0UE7F-r z_>)oH4G2u*0T%0?#1__7r2uflH^|*AgqIB3Kp||%r}eWX)%*1pP#xzHgn{!27x${; z!=%>=7bL~r36$0il-Z3Q_Z`jGc(B9!>~Z>OoKM#r%tsu`VQYn1i<)sMW^7(M0_3w7 zLfocb4@h$0vJhMbTjK;8a3V>bvxLNa+-Y~Z7fCbY^T;Zz(l5pQ2XPLeO=i=3@9|E& z+ek}o)J0xSd0>af=meT};z9`1TaGF8Xqjl|O472^1a+{Ov|8=>9JXq&&v&~u#tY=u ziI^(y_sloYk~n z_@QGN8qu3v`V{nk&)WP0CfQGyre1$%Ak47LR4%<(wc4p#U@)=5f$m^9jq1Wk`=O37 zWLSm`{6&wrU8_Jlm@3BkU6af`HwDLOkMDrEdJlJ(Vn{!tU~zg%fK#B9 zr5k^z^rgn#41K#Wp@R{jH8>lni(|x{Ak8YA0VaqE)H>=6xYY5*Bq<7Oggk->NXL&u zZuL7hWNksz&=z{cT~VFXl509{3wg$o`34-8Q#{Kp;zoseMQ^*~J_{pENaDreOrYEs zy{s~q?B*^L`zulnlxjmT6Ub~Tk~H5Aa~NjV%OmxH(~Y{^$Y6O&JxXoqWdKL5%8vW4 z*ZqoVtg#__EAkcU-J`Ew?}4lCh0oF`Jh>s`&%aeV#=ahg0Zrq)iYvdo#FW3;uJPE` z?w)2mU`&=~97Ct{e+LjT+b@9lq60v{uf*?AeBNd$6sd&Fh{2~0J&z4?5+k0jE}UU= zUEOKD^+b+jX8nH?D)L*VPDSa&ZR7l6i4EUr z^o~2`qC|#CIPG}8_|L-C^{A#Us72BtKj1?m|H@TFTu~M4VZzuzO2lCjt6=-2V>B<_ zH(Dsy#1Y&6Ii?jEn{vp)6jL~r+gPCyKE9uS${%dcmnNXwh)XHHR0E-N*jgWZJo5nIoKdrn1z+kd7FV0PH0fp@5Vx zA-!Nh4=Z%)v0AET=zKD$$G)+~psvAaj6)b~vZ|R<_9h7;I{>+L{a}e~E$D7Qq6VL5 zCVq-tCAv_P*V1#nF4Xp^ta7@Ue1=WIm-M(gVKF)A8l~S?VSmzT+_5CS;yO|SbwoI|E`3z`gloAV?ZC5?*Z-iR;yS!nHU4yneM zU!|p?WDGB@A5R4|j0Yrvl9E2rw4UR=j*_I9-YStv5w4#CXQ0Kq;xg{sQ2q`;30&RI zeWG;_g)OkJxnt#goTV%fT2fwgy}Wu+rY-|wU7t}rk?z@Hr9GWWWU);f*K1U?lK^fo z$eEF-WlN$uzx&1K^RyL}&FfT7?U>eno`nz5S2ZGzdRYznFsLDq1&PAsXu$^YPJe*K z1XX5n9%MKR4kt*}Q*DzPigjiASs-&fHwxgwvV&ZlovcFui}t_rqW_88pPwfYK{sBz zc%Wq1T$&9k7&!GEU{B5kRc`ztKhC9f-OYhRD{RhRaCfGi%_*C2rAW$pET-V!iO6B# zN+pj6`s;NN;+#Y9`e`0JHBBLHX6pjKn0Iy!`x7ABLjTVr(2W=MuAf+g^|vP}Q>1UD zO1{m)^3CC@o8pBdnfcxzS-oXyrWYb}A28OM**NBdH9K~9_T9q4^L~?F(Au~xW4Gd0 zMxVB|`xB(8>f@^+tC*R|ZE=G`?OJrS9Q5IBgZc_G5rHD#46Wo0hYt=FLsGAt(xhY! zKoJgE$Fy)we_1;%iB;FN*YI>rab=AX{ay3}gJMbTyW6ROmgyR#PVlRsk z#EJv7UFcq(B(gvlamMymrV`{uY9T^Zx_65p#fR)RHdZ|GVF8oqJ-8l-5faUpV!cM} zGWXW8MZz}DJ9?To0LyHo_uQoRTPdGHMZmK~>_jH-H7rsTs+*|dVBwG(q8{L z(T}<@I49Qzo^<1O%J?vtbK^o8*vRhQn#Vkh^#~tIB$Cj{Hn22Yd=Dd@jZP(4{retYe`BZi9atK7^uWW4TMsYB+?VGX7axNPM5 zJB@dlD3o92-ad*t0lc|t#8p`o#!(<5jCO;$Os;ogN0_a!NQ!I z#q;=P+(q0{&aO|k*nZB|+YZn8MRUr5xXJX9qUjsgh3g7GK)45K#g&O3OF9>$2q=PR zy4{6qKk+Cj@R5mK=b@;94rG_5=kvEhHOyCg3Zvcqd>fnUEQ>45))cwo&X}FG8Bvpc zDIY1wY@S9iU)?X_Mt=vqzc$_C<-SN*x7u(B`Q1eR*ZCDWM_OG+n3`_&=5Cu5)jS<5 zz{5wberR?tW&7f-aL$^wIV8R%Si&EM`VR2DS$mt+Q=3Hg*VB?J#66p~5}vA+^{NSM zh(L8EEjuI&Nw5ceJ^xBfQ0P^~a9@+!hXi5uL}bblO2WCOdEElNqJgdvqB;WEOne7? z8GDceCReNecFA>b+Nrpt#aWs3u5Cx~+7IVRFG!c8@IU0S|1w#fZbJb@nQe+l0WGSM zx^FmG(88T(8}8fD^2PA3_r2%D1nYy@UbQBP(J55D%U1XrAo9^w98wgp<`Dy!QUvT`p#iWBa`+ZCLDAPUSp`D zIkfbspc~Qo%uVn-#cAQnpkLa9|8RGa^}>i_^ehn@T1rEz;lP^6s%&%=38dp#W`-x3n8~pRAvA z4LW121TXjRlq2n1#KIc31Mvn+hR){v4OWu39OghpY1hBl&u%#hCmLu@f2ygM&46bnWZ}L#RF{{v&#&`sfX$XQ(exQavF|xDzzg`NFzx zx55}ECZo&L%fC7JXBaidgFoY_Njw)T?ViDqT-w%W?kO_#4VM-oWm~73Pw`z*AC?ei zS2uM-IAZ+-i{oQZ(QC#x5w^#}N1A^I(1&UMxA1JTgVAR~r)~Yh^Cu9I>c+xUrF1Xa zt$IYS#8kwF4Ey3a&A;AOe=xu7!qUoJ^N(Rknav^=)*!EF#BC@yq`)IN!V|~3D0a1# zEb*Vfn|pV6o7V1!=o@bjnj04CyB)LG8qFT7am+EPt569o2dou2NxB2UvASr5;8(AD zU3Xj9ZRZ;#y8V?eldl0k6?^6uuDtFf9Mn~(JwA1gW=m9iCT!+mi>q~GAaOq#8hXjV zce)XzZTI0+cf#MfMf#3$yutk5@5pvia!8S%rN0kv@q%O@L)1`Hxy-Ice^*`ra0823 zS+={kK^*Wiy5Mh(St=mMHYj?LazaOTbmWCs-2`ut1r|Cs2LN+F1LF7o0a%^{ar#Ug z>DkMBWgSCxF8_6VGTGCVydY6d-?H6a!!s>bFl7{EbXMxqoa4p432Qm+P{R@Bk&B&I zq*EL0?ZxZZ)}EI)UAl?GROveu&SSmB+=?y;%M|v@BysmW<<0?%GIfsmeFr$X28X_I zZ_DvWFO7$eh(%*_*%ZIYRSy47`!(M9e;eY@6zE@ay>#2VRluj;btqim0mn4Eyk+f1*3{d?r;6>>ra=+583*I*FN1orPkwf_PGPG7rSI{gtZ zw`SBO$%>~3`!zn2_~FOSDQk?&Gn1^j3|m{x3~5l!mNf>KsuQ&Z>U2Y8s=9PEC&e;YZ1?XfT?w>#o(Wv3V4m+|Zxn>S*1=aTHS;ySq1(-#m1 zP}&8!n;RR`a*NgQ=?uj~<)) zl%|(}ODiJmQsI5#JgsZ-D#dML-7--}2P!onm1#A#1_~C@y;xQmK#rBadZ&4{SDKH$ zd&|R!%-eHX#ZL)ZLi~11B0>*UhqdC|(Y{l1_U|eCJI7H&?b6bFoV!m(*K}f2<*RzF ze|Y44+0h7z4R}_UFZMQNi;XHl{GE+@G{{MG+O*VOZGiY=cQ0mc`Y51Q)2l#HY(U%J zQSJy^xSd+jGi>5)Vb85o#H}77lTjtQG_lz1V&Wx2p4Qb8%572vzLBV#;K*N}>yweP z-yDvyjVr=InYA1j1W8exn$9Z-{L4XIT}P9Z6oITvDeoFvMj7#gRLVtI?zy+BZep||*u8~QEeO)7NqA2G{_&!0d24YZi@XgSi~HK+ zi!@ePc5F`t=aEJ~ErjxLM~v^#RIdm(=;wC}AYxU}c6N65Px^W!)h1*#2Yz1Ei`_!R z>p$$8H2@{ks-k=&=R7bAB}ki8hq*dyustJk2QhD#G?We;X&l`dyA ze{N>W{1Ud@f&~kj5qa@XeiQAq7Fx_ zNan;PF62Q}PMGy4^$YVZEOM<|wNC;+VYhUnaU}RDN+S#uHzZl^G1_37oshNXhVDGqX}P4}L&DipOxH|s z|I)7iY`S|T7_?{U2@*!>0p;u|8x!iJlEKm8?pPV41Judct*N(5zG^5{DOZ)kzG%N?agxISy*I^T(Va(-u;h7RR&L z0R$C7qVOdhcSeexg_zc(n)(=5*cknq+DR{q+(~cFh4QfvDSxtnkOd8Q*`P;w;<<{! zBNy#@!C=~tE(9((9ysBShG=4(mFfszUT3F+^h+FDp3VtO#0k1(`y8X9`f zDN=aLzy8P0Zi>!$8oqYt6+J~lsYvei3}a~c19+&M4srpB;m-D6#>1@NWIXNECAP1t z^$R)6Sdx4d*VLqTxDzRJ*!co-X#!vZvOhcRcbwM<>Cv2-e?|(&W%RHx{LxejVn)}J z(K)U0H#ML-nFY9I1ud0jw;_ZKzF9N5I4kYT?|BF zVq>)P=%K+=XnWO?!iASKPrACa55Vb{-Oic67}&u%x%L{w#+vP}(`z4q zfIFf$@C~{UO*Ndk<)+(gMMKP`LI@02nB*i4Eby-fVm!KnP5sfo=!%%Y_BW?mtL3Jr zSKd7p+cIk2{+I5ReqJw@_w&B{X7p`ba$hWxt5)&TW_5zjv>7zv1qLC`mu*O6M|mO_ zNyyl4eYd{@-dBcknan)@=Dlx!)qJNmVW)mUqSyM?e4tT5d;*`X~@>{C# zY>0Hrum|P}Z3-%+8Z14T4+NK}mYcGARk23Zn1|-?Bw+^d;_L|87o`?3n>iO!4(>AA z0PJeO?oz45VzF)7evf=EX3F9EYZF!#tXy5y2@4)lVYJWC=T*Rxr|B!=3$&Tw)^aQ8 z21R7SdC()`+Qxb-1m2d;UZb`HU$(noGEJAkCK1r#KE1@0_QuqW5Zq|9QM8N;0$HC5 z>9Kr)g7dvsSW{THX%d54-DXkt(eO+zIb0qUSG{4~@9{F%Bd?g?C`CBjQwkq1gm+pP z#Mk0Q#9vV$;2IC!g5C-;^hal`U069yTI}z4%^YwYv}rT(OTAF)il5tS@##<5O`c{f za7)(}$6zg3hDUg&=8Gt}UM?{$#d^{KmsY+M(^*BF&{u^HPn^wF>HLsGQ*&)EBXd~X zZX2?WXSM`>zjo{jsEH+0Qt+~!lcJ}9Fq3~&gC2_ybw%g<))~ur;e|MXI-MKP%p(HV zX7jBDwb7?E`A5~vvtrX?e<@1vZ)gfFOg5vnidd=>7=eRLs6teDBEe6DonqPqD-_nx71jWyiv+4M#(%v=ke9dDPMi?y0v4q`4*#a zE@Vk89VaKWEB2gNe*=^OM(vuH@>VcOBohYd%k-=7OlVyaz{7bto5xa2X=Gg;g~`S< z5oiakVMt~GccR3=)}X|c#M%XCaZ8?qO!3)DsvqTIcYUKQrZMo57OaY%j0Fqf0~x= z<_=LC7)H2pqYcojaYrC9XN>3j4q4kt2Lo*B^ge}Bl11Z^p@@N?9$bJGwJ!0oMv9gR zqIq4afpPwFM$vMzB;BJR`h1xz{+ME}XR^JIV(&W_^c-33 z%`e>Q2nypurrnLb?)2{RxZ~2?Gpef^vms5@AMdXC4cVR{U+#R-_OX^FEuPvknw?&{ zVce;bsr4Oz()E&1D!^D4*JrDOMu4lZG8Rc-PO{>}d<1J-(D3%gSxIrT%Qsh-VKzEC z6W~fG`F?n%StO5-q!_qVDt!gZ_MAbOzk~DLt!>6Eny)fpBXdnU%{9i_#$a8U5FXy` zuDo#q{fU*A{jh0i5sDMRBhA2_{2o(1=$Lp6y<#4EcG-qA(`RBr`izi5Bcvl=FQxTr z8>drK*&J_6vH?7%4|~~5xw|XjzVcw-w$Nqo9$Ar(skUL7kZmQ4?M~#FBQ-HZ_@>&n zI?lI0;*4>lwz=8+80=H1Nc&`b_!$3jA&@6<2lCd%I-lk&$9bs6NDALUC}5-O#C;~P zn`UJWxQ+Sr<65*HPLXe9JP;3=;K>>!DJg5zl?TovKE-QUwoxsXt;A6A>cF6qM2Wv5j)&%-!*Yt0d9#xLfp!`{rZuhTh8rKlLa!v z^xZPOzQhpu(qbhLP_!ZDWk>i|7dJHwmT$q;rLdfCn>@Oe(UnqGCbIT@GUWSXZW6IGB(V&m;HPvXPk_f)ZvTZ|V@; zI_kM#R`+WfCm${g(*H57+oJO0_1Cv-$ML>X|7y&`60P_8EB>s|Wzm*e!zuW~m^}+d zE-ED%5fvBrR9xxPsNLkKTde#2qsS7IW6qQ}Vco|aj}|Wad=-!YI^IhkA#9gst={Uh zN!7X?bJq|5bipAzQeP^979Jbs>{^%4`GQHRh^wx%4vAU8UU;bxaL6QaikQMpF&I8@ zMcU{Y_Hr1c-ydg{))9c0O~ZR-#_KRLYY!)_59y?x(>v^5WOWN*I_W>{8Q!iRmZyH= zM#-IgnQU^-MNR#os2f7VCDOS-xKkXM6Yyb!(g5!&rk5}!#q2uqben9n11{#_rh}A@Nql= zl(Rrv!{w@r^nSK#3G)`WBP_Y4#%awU{BS44&u^2|0x!iBJ7?MH`#1F5DDRT^4sf~R zCq)y!QSr<@5_hi=_8pLt`{mM-P2V5>I^uuDGLl;R+_e{`sqxiwqer>DK0lnwGJS1L z2<3#St5M75^aU>#OhEd-0|G+1dFDKqWIhhSfu(wn9F2XAnY7cDmKQKzFHRB`!3-k8 zx;LVs=27$P!C&2hj)EQy+G>jgTk;&@D_asZ`L3Xe+peaD$5-`t$fqT<7MENsJEfu0 zFn6ZgPoN{RRjW#ZwFu#$+^XXNbtU|TNyK(w(&Ixj%*sYdT-B9ge6eRVyXRKQ=Dxa@ zq7v7|sEz`dp=%M(AVLD12_u~^9IpQWcT(v3bOEaU9<&A=@q6pmk4djR(UKo49~huEsv=2Uv_z)s?PoG7wHi<~Q*)gbIlDYl98B)F zRxqBokC;XT30#x`OiJ5+>(7nwU4+R^iKdAaRIGp+Y|%Gf=3^`pgwxF?Q{h}kGO5MQ zj@fF2YL&t4aoml%eU@%$ql13(>--Kk$<3owJQZaikVZ8+C|4g|B0qdGT>BBS8Aqr? z-7%x)Ob6$;@gD0zkGc!E2sC=OW>O+vWO|)`9mY;Ac2=sIQB42$6Fh4RMSQMThZ!+qkQy{b2 z6w=nUd+4j#-Z!3R^bpCm#fP@fx_N!=_4}ykcH7~+aUNJWSY1wF?%|Xm`-#bi%FRVVr8#T%9=djzk?TWf|@5i~|d4$pROJdB~1Kx$B{)L{6Ln39rJ+gD|C**5sf5dymB7ga448 zIj{W;FGZ$*5EYBb^{8I_vS7gZtQ)Mg+ni8vTLwKErn^mVX8Q`v?C{chJ|7j~Goit{q{(Tsrrw8^YvU!<1_K; z$hl@*ebl)jBAxXcwZr9@Qj_%(!|iwDbNNQL%|~GG@#wnpzHK;PCVXR66S*2nR9Ktxw>XtP(^v#mg3^uHvKQ2r;Ym0ouYotFnv7j8c6nqGccCbeq} zkEv&@O>xk7%&6w-q{q7ZM_P2#sW%n}mSTIXVZzq{=ZXh+>kI{Dl`1N74YAajH!R1S zBk0g3^VD3M5HK^mlyaTBL4Gy!NXKs@eIq>!lK6w)9ST&^9PD#j*-Y#1(zWLQAYJSK zuPRfW_A|S0>LQj@JZsV{_D*nDlIpHu9`)}4N^Mu^syA_?1h>X_J(Fz~4yx4RJASeK ze@eHxbp&EtNf>Xi82#4(1OS)Pqhi5JatYV5TneetjB+00-vNymp8fq~j=zCq|7{`! zv5T|m2+LRY5=w$^m{#PK9IaAw%nJCPKJE0lri#90G$$v~(O+KGnSQ1zHFOHf5(c;3 zuoZpM{Y1m}GmW4mRbi%(_RH^p-D}ql1ir?6G}sqx6J?JiYcS^5&kT6#GpnUjpIWZm z;XE`ltjG;ByTAGPZ|?SJ__d2ZRrKC`;Y$|wEy4^C(UKfvuxN06LP6I{`FisF$iK2u zVx>eoLsT{S#&l6hB5n5-$j`6~2f8{C5ppbdN0_JL1Me}>+TW0a>_0=*-(PHYId@q6788z5Azu)b18OYBTs}MG;^h!6Xm^A0oH`j|;vEc)lGOvFn zKk1m+7f~8wcS>S$V`hf>2Co8=7SMX^xj&b$u)KGZ?hhav{*r&Kn&p#2oWybXH;X$F zT3heC8Z(oexbF77)zJWzj=&3tEU@QGHQ7%euzEP5m%G$Hg=zi#(v1O~|QUg68W^p4zekWfS?_+GMLgs6hpPHv`v|@qADKl}_c>CT)EAtjS z)lNT#d7S+$j~kYYjSs|yX5xpeDGJNNvtNW8ke$SK3kJFi%Pz&u15DACx2NI!gR;Xn zR;3;zlphn;Ul`My@8RoWYlZS<)9uu8y4UMpSJt;I`eFL}pvW3CImH=zYr)17z4^Mdcp`7aFOB&!U#k}q5vpLTNQ<gVU`FI-0WpFLXd8=x5cXUu9ihyfsMOek2;8&}}&Pq83D0kF5Kd7%qJ18l_a z-qi#+AVOAF0|*E)F$nDcBo3HBH~NGMm^^rCh}lQ?R83D8!l+(yA>9y6Bu(&SG-U?Y z7?`Nq3^6QiFzq_ZpKmir&9I}p94!VS!z#q>p#3fz?8}Ge+mKvi2M}?EjGA9uf!k$qw_M#*_*lT2{wfPm^=$JX+O zy_<;V(uB`0&Cz)EYDp`QO6Zz0p&6rh63whjC$?&7k=KGCG?qM-TuGesr%!uKt&ai^ z&F>eXMCS18;popXJFJnVJ9MGr=-N7FT(;(e;-CThxN9BS01YnbFQ<|x6^2KtiyqZ_ z)j!ti^^@mMmhkHlua=y0J}C9gAl;5U47&{?p3vO+T>sU(JuBj8&cTp^l;nU;c{N(Y zG3Z!hEaoR~Mdnw3(m{xZ{z6rAWONy^!V%Uca~gZEp3+rWt7qn3cD>u3#OUsQn-Cd4 zx`y8_xwIe0*kb_+=)p3t5Mwg7@xm%S)zz;Y|ELH;y_gH)ogVurFPWJII4Lv%c5d2dU0!*h{4eOwc zn^|!NuKQ~+=iWBU?+*m^%>B#FI@2G7qvcE3qOzR4Iq9bz}&oon$ zljrgs4b;PLpJZOi=U&fJn0mTi&fg0a=bH&HiQ`YqSmxNKLN8h4V9{RTl0wJ2_C%ly zxxfuLcf^KqzLsYe!YnO2nADZr^W~F4fL#o>5?e&vwxX-^*(B` zHOaNU5c1{@eGF7>iuW+mrBGQWU19(BtP;LM?er6}*e35RV;*o((mnyT*)7MkRu` z4Z7*WPViQSSz>%p$&?#3PTbwjFr_*&C^PpqG>aA$3Y}kPjAv-yOgJ?Y)ys5p66d5@ zfUp;=cXT#*kPZ!Vk!LM%JD8WBhZU%+gUWvuLtp$vbVd0Y&49@U*3rx~b+z6{8Kz0b z$29^6-@v-5&J;9x21QN)2X@#pDmfljHc(h(>UfNGL#>737UXYt&)ne1*i|EvE5|gQ zlsmPI47*st>#&O`Zw+Fk`=W{I-%T{_ZlA3VpP9~6G^CpuWk_?QhY*(nM1$HHkVP%o z@RsTiIs_M_Yn?N%+}EWY-^iQ5xeP0cMh|~z^d@7Vz=Kq3z$t3jlCs04G1oBhPnpvMal5nIhDKUIG!mmet@WM$eI?6-o!A3DvG% z>&bpBDO<4Ki^E|03LvLov1vJWG3AEQ|MU44G3I(tq%o2CL<)I!J;32RCjU#*uyWZ4 zY4K@~^>-eDyGtZ#O|&~_#q`JF2*>KyEthQbQ@3S2c}ruLO! zkl9lv=2M4OHO`-S46*14vbkV#@x(tLnd7SG=p^Vn(7QYZTc{@x`~Taph@cir#>tKE zBrhPUnAIR1dGTytpP;jPI;OFz&OC9o4@Zpug}7A8%Z0>s=ABiHrkf>_Lrchh{hh^N z7n>8{|M=YNldJY>I!JlxCCz+^UZMwxOUdHzWA z9fQ8+=j-8`bxAAg+kTRfxazobEjH31D+o%zAz#G1V&M#3j=R*zftBp@8{QUKjL#Nr zvhrB;wCLgSVI`P*t9(pQpVcxw9}UUiTPaP5nn$dgJB5q%ztAA1b#qw(=umV*dbF|O z*GGGARQ7H*cOb5yvZ3kqJX#35+5nR>9keI}&x!Gp!ad3A&Swgr%&TCj#AY|4uS>Wj z)U32p3X$FytstJu=}mi#C+?MvzR2|iRid|m)Fm8QN3ZpyFFuZk_wX^c`GmoR2nkiQ zh~IQVzrJ@PRSQsUgeF8cbwSRq$soB$zyb?aqhqU(I#Fv^FXOme1G0W9n*cb zO6+tQ-VgZ!y}Q~mzMOd-9Tk)9c#xAgJZ|YI(=*?$fmH&B235DuM=E^XT%}l`efWJ6 z5pGbXZ-Ty~(b0Pfz}54yVf*^AR9ATLFYpOikWDBrZC^NriOnzw)<5^GCQxOPvh{do zmn67~4(Xc;K;s;H(7MFqHB9KMkfC6KLS#h!u@I%O>8>-u0ZZ6 zzpZhIXfwdyEj3E*bi%?Tz)}Ovx<+qe_huVZf(L_LZ_X~q546zpQK)71$Y&#LR`;Y; zvuSAiP1$`~W$mp1R=$PG1C}1cFN5YJmo#Zd6xf6FU0(W8{mx{((|l@pr=ZSipWgp- z-cTWLpM^n%SYo2-x$A^!COy61DXI2{uLdpCb;gdXjwWDp{(HPU`Dn>yMLFp$z%yf* zy%bXAy1HqpaZ6~hZu>il1Xtp;q~vHE3Ip@jm90I^dJ=pN7z`1C75vl+F(qD@b@H0grgtty@4g zFyhfre7ASM!Yw?w$^C$N?0{kT!MVqusX93z1&q2ox!v$vFy6=Hklim|zL4=bL(L{k zUbF$ZyX;iDmKa)to71it>+qrTlF*$)?ez%6^f}PA2Fq z-Ax`Fd*yA7GC?Umcr_HeJy5;*0^6YwjJL71IuV^?O)O-EbzEBhPLP;y)ZdmeCZYQl z@Mcflvkt2rWS1^ow`zqM0H3D%583&x@cNlaylrf&H*H|_M8^UB5G~Ha?Mi0aX}J~E zZp!{IrqZUFoKe7CC=cI=@U9_kI!FTW1jR(7Om7Yp>mQ=+7HATNV36MdpR(_3iD=i8 z_CM32)KhiA&>*%V%EuB}Bw{ zCk$ZhrR(jQNFwwqt>IrVt+ofx@_7wa=dI#mzrGo6I{s`b-JvaH#m?qP$Gf@z^kSGW z+EX7c#OiAW+hks_re$8iP0omYM3`cj_X&dglAS5{=EryLkM$k#rTRdas{p&~HxSJ~ zEHuIs6bLO-mDsA(IlmMHr|2;I6I7TmP^{E9lBWX_!b&9?B8hy*c{5LUuKW#d(O8*R z`p-6Hj7~8K#++5WtqN}CLaZu=hmDNE?PMZ0Na^9IbDdKaLT994>KT(7sEoi~MQlkb zG>jmk_N$p`sYWRNp1)^C1lBXVCmvGeLzV++WMpk{6y6F@2`!DI$-qAl>~K)uvw65 zZH*UR#q3mt7F1uKg<&eDWqHUnd-dl}1!Mqm!w*rC!&_6@0do^u$Oc#O5_m6 zx`Vuq6^-ShNk(?=I#Hvi`qK29>W*go6 z`BxVqo)bme{!?-9ZxL_Mw{!hjeC!GIMa?07Zgm05qhMWh`4nv^!O&05@}b(#XH}U_ zWL*jIKGvD38UoD{XLLkXrvY?D3ZgRijTT;$8(0>YEG6wHRcd^2KH>Ww)#VtT;zPmxD9`+?&VF+<3442rM2Kd zUJNc*(*yKfkeKwFm{+2jWJTjdUCATYbK`{Uwv)SbOUfx!kZFkv{?ceHMc8gB>gZ;l zS(LCp>YKIk_>SO*oI&LJ3T)%$E?$TCVsBT6n}h`*@AV?|#PN_avh=gNvi^5KU13Ik zgg}P4x43$Hem|jyl^JQ|Xd8{&1}`m{?VdjKB5b(Jin(zq|G)NkD_Bd8@7CU*yIm0E zg~54EqjhY?Mn`Ik)gRE}gNJ{sr6@3|&QPcrc-Fo8@!1L|{nlZRVqW1#!Ik#WgWYil z+avh7te#Wv=NHj=!eQ_b|2qQ20V zH|Yv$eN9-Z&7YXi(s`E8&uun|bF(5otjEx)B;igFB)Sj+it=A9nTuEcOFG1@52+TJ zAm))K#&h@au-6cp@rqv)Or-FW)*RGK)Ts@lzzo>Nt#02wuC>^uv*-YE8?P_f4 z{kLJ`EA^RxT_STc((L3--}awWw0FZR#6_6?uGqkjlpLRHRqBiPvs#sp{z)UjTbG8W z;&DOl-HcE1xyHUxt1T9350SY^@*bUC13F_OyDT5@$aDowsK}@asY8R4u<3Wk9<qw zuLweizU*HSnGV)zmh}sVul7`~+YVJNl}WbB2^R~cX?5Hq`k^n^F%6ZPaE6)%(X!J1 z;mpsUHYa2nrxN3Ru@s}b&;TYFG$R&P3khEJ3pu~!uSbbFCGJ8G#snt&TsCngy)F9R ztm`Nm<#dmi=9_1f`+hLgdtnPqo$9rFXhip(v8KLM+rO45bzcV|TSF;w41p(*E5Yf@ zuBsA3=h?o6J#RhTvk5fZ?hO4RF}e8GP8w_0>U6L(j!)Wt_-2&K(lY1x*t!KuOg}4( zYV%j1%G7jY8&W&+6RxH!me^0owKgso(}h zG(p!bOCGt-0(={+8d}^v^}~dI@kC92JQaeutPV;KnGZ~+y6bLA-xqZq*}10d-^FCd zp~so}pIrJm_Ua3g;h{)-&Iq`=3!QrUlF%yQmp3B#uKDeFSbTKLB3aT|32_y}Lag@% z8O9@nEQgFl7e?le6xf(jx&yPUaI!A{JbuwGiPe5}>NE-^NbwEe8W@Zmfq1I4+?u(i zJawFH7~VC`YsECDEXYm<^%sk9ka*A19l*=2aMWijop?^ zB;PEJW*Q_D_4Fr51sEGtU^yeMn#T+rkV<<;N-w5^WT8wu90!P?k5?-1!^{kl`?}30 zw5U2K5rtpKhiSQd(^=K5M5&@s$kd^wPko0-HRu=-mtYhLxD#%>@cYuNsOcj)kjTJ5 zI!N2Zuw#PR43(k^M=m+Xp`VANWZn~MJEVTHre#rVw;P?0K$Feq)UIcX~rq39^) zV$sbhtZ8}AM>lKfI1BEX`)SF0e?(7_v&Hdg%6KPxIae=))6I`#MBq}293!(Bsu?pe zTi~5_1((Lc{KeC+l$tl%*Dv^-3um-BT9Pm_B!(zOLQ|cjn)ck4ZXR!FN^sX95KzjGM@{ov)KW1* zldAV`!gC%|5T*)c7d9y_j72-qQ<08xNF;$fbA+#F!|yP}$ZVz%dcaP5jKnfh?x z_LCQ1l19PNmV4$CJ#f=j@rvVrwAGNxrkP}yk9lkbk3PZLgXVWW8KMtcv@SEkc zJG-wx0bBU=5=mr-=6$sK-KqL%iE6qcVu+^C6eD?lot&t)qC*rzjWI~#Pc=dODV6-t z+@2OD>l{`77;pcWSEUb+=&n|Nqrk^MjIq}jXR89|ITEXSjrH@dg63YKktGhos4j?e zxFY2$s;g_uZaZ#-+^-TogPEGO0(0%Cro1E=;xC)hTX-s!i)}d@Vtv#aXC&4u0>477 zItH*%nsFY<3+vTCi|aGWUp(sr3xOM#Rf~w)@s+yX(5uJyyFl^_j0}E*R?l=IbyakQ zCiVgWn{>Xjm`dRFmZYU5wI!-n(^ZhRgA*LwWLvQKN?%_MQsT4MsWjuxP;zKmp}Rh# zjzbbkQt0v8}1H%~x5YM9^gx91Cl5o5lBh zU4*_V65B&^n-`6mB?gLI!;Dsa6!=${Pu>A9d{^I8PDMKcdt9?0A0hWhjF4&ExNIHX{Y8 z@s((B90%CO7`;n7xu!D|Z)hMZevjbOvLa%4?4B=rW-;)r8b7-v33Sa8#(JF1n>3yg zU>j9@!0Q`Za^+VxT>h+7jiF+2q=)VJqNFO9D2w;01vq&|x0(WR&&*XaFcoXVRD~;` zFwM{k)7^gLJbgp7q?O778R!BNszste6uuMSz1zEs$8&l8WkxLi|G8puwr)Y}GzANs|!X#17+vS7u-NmXaD`72tv?iF8@-s#nHaAaezFLVU$4?0dt+5p+< zuPf`wq#sdtxe2}ovX$1|_4E#?{*|chK8BD?uXM*T*JBL$y=h}`uUzrM@(}d?H&psP zZep!3E~a;4BUNxKpr=E1mmM!!W{W52#*&Gbg@?8pB=MmlS7suKh2^vx_A44~V&AAm zVavQl(Hf>69m5a@(T)Q;31VQK6C;>nHO zf3U}4L#GQ8PF4QtOc+Om17KUfCe&v)aipB3tjwo68ECc9Iu* zH5RT1MAj@EOKPT>y+nz+FlxJpcGZ=Q3%YG11oun7^3%`^wd7=MZM2!M+uarW^m#IF zk{42act+o)Ug7#(WmKM(?NjB*uZ1rfUoMj57=QN;4pPK3a4uvirS@G^V<}(@!@^lB z(|Z}V&s>%vL_XxXH{2$;{t_%@k^CkfT}8O>9RrZe>V6}oN2ij}878~%zwUQj5_Kz@<8ZY55t?+N|mDK9VpWp z8M00|=&$T*uN3v~HStJvh^I7N%%yVVk5|a2QK>jwl6o1CB^|2_P&@z$XCd_iCiM^| zS6ovx;f*8-A(1aagm9S4R;)FZGZ!4PKjDxXp4`Av^oPaM7~n_B6|K~eJbtQ}iR|UT zhlr3^E5<*D6+8Vrl}C*)VBjk5*wi0-fH{}YK z61CtsYZ7@is{v^Ct+4Fxd7X=fh<7%6Xi29-Rd~ER2mIAUVq_rW@LTg7IgY7k;Bw0j znu**&0beY!wJE^%u-FMY#VLjoA6W--nT4gyMhsr6%t~y%rtz`|6A==S(;z$OS5Q$- zg6h)Z%mvM2vuyIXP!wIr3X>44;WUD*#aI0VvZFZNA>q<=RZc1ejqHDbHm)*$?kW9JK7=@Jo2s!MbMt!tByWAmt75g?>lsr8Lrd1e1@X*T6n~lqQrd7NvMh&d5S-Faa0BRL)dV-BAdA>RKHC=J(Kn#+h z^5OnAjO=Q^#IfO{+B=-|Mij~ndm-$H6?SuQ4^TAQ?p%0I^rG7SJfIaB<$$}SRHORU zvCaucNa76q3$_S~qTg3Fc?j((#O(rT`6s76V0Xloc96L?#dTUE&P_t}&esa+*TLBn zLs<;M1B6NL)P{hE8m=1W0GN5veNQoZs2&9G19Tj6>{N)IzKkq0z9e~s6d5FbVSaz; zN_l;WXR$Qibde}2UlTC0rMRFA@7OA$2LjD=bn#B-&0HM+TjYhKNF#-yRTXl{$%OO- zKQ*pp+GzsS;D^U8A130iT}LqDuQS&+do2bHcyXM_W?qDYWUg>0?m|J;iH_t(C!gh} zio}I_+(PDiIiumKtn-_-Cvt0jwwEnZ`oa;G`7BQ ziC_T66e~XU$+zeqyCN~Lp?)2a%cfx}LRltdn1DEECvytk)iaW8DveWYMNpv!Y_VdgNB zwL&zPk1?Tc4VkxkqLpdtS^itBMp((BZ{&l^c8+LUwLYYa)EB$ZxRPb9Rz1`C zuT~{8%0NzOip3Goat&g{JV>v0ae{pkU+AdAUO|9@s`N&ig%&OwNmeND#_*#0SYtVs z`e&h-^kEFlA8Fb}GuKPe(OBPk%hc1>$A-YMdL+a}zNz&ujq#5OTHMY_-u zm4K8Mf1>RbOS6|XDtr4fJ?Dt)(b?6M@oAnwFRHwj#+-R!H3=FAzk>F`b}2`@0>pKi ze7N|-m}}aQf_~zL)MMJ}wVXmBaddybW}BS5K}4~1adlfYI@rL#7E5KmpzP2i$n6nB zFCjnl`PO@emC?Dhobxvp`hCrQZoC%LcItZ+e|@i0fCq>R*N>Bg=O>5Y3-F(QmP+oeSN`4^P1IhlzxzdTu2KlEFTd{17+ky=@tdyXJ2SE7<&v-V~-L!8FWD zCs+yf=jY$f*&~viz#u7APTb)YJFR=oK~%Ax={kH@DY_s>hzlFAv53X8NE8wqqqw%& z@!hgxydR}GjgG^0r2uiu$eQ%cR5ae^Kt~q|vh#Wi@^&RTH-WSjkwHc=f*##R)dMXw z_JXp!Mj-ua^&Rp%=L>CtX6LL8>eSilzF-0q2k`%5#r~A`vC2Q^&H}DTE;b^D5Hn%x z(MG{ll`7^Y-L$={QwR-O3|alVA=p=j+%-Z8q$!eZm?2lB;_}=)aW~*lti4k=c)ufM zWf0%WF<*->`|P(G2d}61+Mv;nFlAH2AK}UlGwl90Vr&sKT8*5Ensk}=ZrhXkmXR)) zzc2UCqJr?u+3j{J-eRv}V1#ptGxx&46k?_(Y36H2NUzfL)%660R2w4hd$bJ|C2S)i zb2~T(Wfh5Q=&F3LxQKJ>Zs?$*ZA1~ zEk!)s#a4Z7w}P}k$`sZniSmlq)SDAA8TU151fT?^rmMQJv!YDK%N|i}`rA7Z1)0c86ja`E?0pxNf)eqa#)Jpp>%|`^V3H1w*TK3nX&!>H1 zoIL+pIC?SZnq1Td&o@L6+j$~L>airZF-jwwM((~zTyfu1a^esPM?cNCB!*OhNS4$yZp zq1evO3Q&Hw!YV6_E8@XdUs@uA11{&0;ca@ZhYdYp#m3(AXJxT4@y_BVOnGsSesqPd z8OvqqfcH5bmiUB}Nr)T0*LpoAb|3HY85LPpq-Vqr&XfRrf4yp+n)Ra{cAv2d&T9V7 zDwv#0saVD)N-LpRjc4v;?URP~WNVCurWQg_M9dXOjdUYZ8Aa}S%V9J*x$kKF-0y60 zdqxUW{CkL}FZnHnk*b4BsivOi7rL1Iee;NAqcvc+U^4yGS^Ir^EUX_Z1sqx~ABtV7 z;1XKpNE9#ioog1WNJ!W`t*AJJnUd5E9tt_YU?DJO z+9oSvq7@xjZ9$2{ASDcAh0)uI^~R?Lf8j6gyQK^@52EY7w08sbbq8C0Cm@cE1KjAU zr4MwI)th6B`B}E57pe~xNC&UK;9)`z9*;x2YrPhRv^+{ECpM5m47EBcCv72W?{Dwd za`vCW8t^xM>g(1}jq3=|GmA)5559ns%J05}b}S^LzmB)kMW7P(S6KutWba3B@>;Zy z=Vb|mY@A3=25I50NnrZt->M>4F0ie@7RdQ8vm{CBQLN|^Rn4gP8wyGTJ$9Q6vRbx) zt44)m@Z(Ofv&iZ7Q>6h{`~)mG4y2H9+OD<}T=F|v0z+q9(k#q|JC1)0#6!0(oUGXenR0OYR~kf2&#DCGBMFz zCC{f6f5-e%J0q8c(-Ya?jG=lw`ET#O8ARkfU;jXv+uNQ&&-=ro4IN054CFQ0+@{fcu{(Mmz z^~80bFj5{$L~M>bT)XXT1iha?CSK&GUS#99we^PffM|(PH%TJ2oxwW5ZzpDx#4wvj zyBJJ&)Ax&E*NX5L*v}rQ!h)SSc$&kp53&(s%c^XTg;`K=TZPzDXo;;@AoxY$Wbm!B z$t@coRyGF>PU0btIr&hwUzJE=j#2ZgW7}j>fGCI+C65-rN3!)oc?h$ zrw?WRUWuOH(jPNAwnxX5d6^=_(i(Dr8 z?>Od=_=vN-7d!;`-}({C%Nyu>%hfc*bq!07E}GRKn)MYK2m`uMzxO?89Z?R zEoZCfeN+z;5M%m+>kc|%yRoDdPckD(H>Vpu@^W8I8SrCR$XDGJTyb2fsAcp_$ip5j zulD(R={qI8%s^pbowx=+hu~9F(A7N;Rec+mBJhYcqw?+mc&st0uK=L1y6H080uS^# zJA4Y}8iwXD11Nl=85%bmhMMcAN;3AB6-LZ#?|PnuLz`K)#NWe+{I-Nv&T3HEt+`>~r`~*4#heCzg)x?H+a#W;@&5c!<4Pr>@PYyJDV6*LjK;X<&d$*1Hur~F{`L)5vxezHc{wS9?DE@Lg<*do-;C{P{1n?xhVnl6=N;yV<#8>t}- z2|2Gw5{_D!!(&X?0XzobhzgE3oF38=&~LT~<$QH3X*ta5c0X&9NgJLU)AV>T$WeyE z|I;pQ<4YUIOO;SubMl7J1zFi5nvFX9g6q;`Gis^$bKWf*4uru8jBQ z&a=iSMhf<&wkJyCyo5*IK0IbdQS&s6VWQEeaAZ4WSFZE3yIVud4Sp9iC!t$adZCH4 zR0x}1G;ZSEy3{V`BnY#yzI!yI10`n$l+v#l%1F?ziMK=)qp4{6HT0rhRLs3lhTvpt zFiV|FDh!=<2vwtCk}fr9&*0GkLQPmZ=}TNyH$~urQ#3_)Z|@?g;en7ilhixGzRkiS zzPx(RTbku`v9Ra~HrY5RJ{$pV&ukXVLeaY5LsZfL<-$?33H_iH8Q_%1u{BsIK(iG2 zDKLM3kQ?p>{G-6 zLz+GF8Wh!~HEZ2}s2jrH^+F(R^Ph*nK`4|C2SWg%Zr`S*ZTvPazFJp@W#RM^e*ce{ zY2?erYV&P(N8eU`7q|Uoo)5oCbnF#{}BUG(6i_B83Zx@ZX(C4ShaWbmNd0Pu8#&w=jnsj0;sPHAQ7Uiz2xMsKC;~FfUVZ! z7s-L40V#KNc$vF75p8y)w^RtJ++CUe#5$1R?o8&Hibq#`Li#qck)~fU_r7q9U@6;m#*U zlS|lM3d}Z(*Xw=LQr7*d-^A?CW}4#^&J~bVk7g{s^9MpruSf{)(8p)81%3n_E?t9O zb!M5?y;iW;^HjOypA`q;jKiTIi%ORiQldvEOmG53M17Zo9?jOyUZ3+JiYX&eqtDe~ z8Y95WV{`Bs98CCtR|na&;WG)dDhxyZ!yJo2EoVLXHz8su9Yf-D=4u1y)SC-yUXR);2Ox1zbYyC|$s zRoLw6m_gzS8=ucr&$-(1C6!RpD)k z2q7-AJ|3ROoNa0qbKc{AQ#V4VvLKHx&O*f1?H+5XEd^)PWRN{%W1zDkQlAN~g22tj zk1lABPy$$@JWFWLL9bCgJ@M7{UkYK8?_I+Hz567j~+} z6xZ(%b*bzGC;0b{^&lLm=0BDRZ|MSHj^M@Y^=J9|eFIh<|Gf)xz9-1k`KmRW(Mrv- zNz0iL25WC_Sn zj+9+9k?+DLzv?$JA|>pfs}5G_v|&g|b^m}9>J)D`>0`I5u;PcKwfEB8@&u|6AUv0n z<_TmSy?pUPaU`d?)loe5h!epkXOdW|e$0K^Q@lkZS@pTyq$B8GD*-t_2z&)XTEtA> zpXemSm_*2`+V4rt9B6wwwZF2L1yN(?RTE(bp2Sil!}A_;?qmNUfv(cf!VaAcqE zqRTUWFgNAJ7v{+i+Z}=k@HS!%BG;q-K*Vs*Q1t2>F2P+rTt~1~8&Y1=WA)_Sj&8u5 z%{Zl_eaK~zzNQ{7Uh}Qb@KX939T0N+wPKcZ*RFmMzKt6#J~Wx@72$n3)tWtOg)054 z63IQbihLdgc^ue@W^0O6OL4CVVsWT@IV+pO$}REyc4TdPWZ=u}8h&jQH?ZU-GFJt! z`Ycrl=_2ccd(UB`OIL~PK%SYS!l*>WTVGVHS_83~So1h!stkR#tl;K1Y$%@Gd|sAC zBba7$7wl10U~^dq&pB7M*LCQ1ZqX(lzZd3SR^wMHg8YltszhF;`7OvwH^n7*=x zKe+qnI7fbJDg&PTFPY1fbwYP6l7hEjsj8FqTk-v( zds{9(_r@$fxI_l|K0zFYu0;$Crmyn+wOv{00edOcAK5wTvMtxK5}u=~hH*5jh2accOYbP_4{bybGEiSibl5wx|aRmP1pe?@A@iA z%_>*r;y@*7(CjUq7@0%*Q;RCiW?C1u%>_fJv5?m4NjQ4~9;T~#v4nq**l52E5Mz4A zf_df7&JBB8X&Nm2P~~4fH5Zn(OdTDXoDY+_6ugv^LM29HjxN)LENZdd^ps?IIShm83CW#VYrC-zQ10Gksf z;e~OX)QgxrC8sdQhEdlJd~2vf7D0q8*!<@#%j6vp2v(gOzAiI=Y)36T@=X2_hwvdyWSXW<$nmmZCI&$T)b+A3Gp9Oc;j<*FKE@$j;)3qxpA!nh7JdRH z1?!t|9X|#W0!ovnkh!m}xgJIA=S1nrGmz?0I(pSu;eQV$glr*)Nq`)sF#D3~k<>tJ zT!>rXQ8un2OSZUOP@Va-O)lA7p&;W+72WO6%F=(_iwPwl>`4m@6c{=r7sY& zq5UjJ_Eo})mPvi?7;mI!-X8Vll$Kn{&MGK^Ta)aVFFgJugKxO-FEAs@zW>FW(b26W?AkQmr8|S<0h5?sYs`J!{-IULwsLQ||d2^FJ7l z<4Rj_zD1Vk_n!kgefG0MONCe4x{IRh9u8rYjmz`i8amT5 ze+{>jc?`90hE(i`{JV7OR2GBZmP~V48nb2cZ!SbuCgs^&^|1ELIiyLO?=;SI&ZLkD zj#0sHhR4Rz%QU8O2x&20MTJiN%GMjI1uFRWeyL?kt83|&gyE$x_$~WE9^oR^rqt}_ z6Kl!m_WJ`F6%`XMF1I>x`SS^9tlej4fcmu6)+X+_k8LT=go3OrAP+hZ6idiqw$P?r zcU8Yq){Ky|?C+Swc2$?AeyPH_TiwVXMiY(CUM9YK?C%I^_RZirVVCw+W7tN#xFv_0 zZR2=tT)_L}8N`0ip22p02xiU*tZBW7zsvvd8!CJZANP_2Xbd*5lck9u*l{p=8eQCc9g z!_&KbHXQBA>h!6nxzLj0c?p}M4YHKAyl?>e7&^M~GhML<&N)eLfiaMjK_hgf6fim7 z^lj5TKCskghO+D4CEMP_tAJ6E=B*8(W4Nf^1n-Y2Vq?4Y`1o-5zTD56<2_V~c$u-| zi|Hko^zr!-odqLrcgH(`b#7XbQ0(C-bsX!J-n1ZOel`U)2C7slzli`TWrPalh8Z>m z2?YsHPkdhEFL3Eu7lrGEm%8W%+OzNYnUErS5;FGA3IsAgwqiQ1BLq8;t4g)GOKx2H z>4J!%O|xAY$dDFolM>RiaXfDcxRQoTiMP5_OZ|vqKFR@}3Y=brxXZ+rf%hW|>AHbZ*6e)dn|%70qwZ|V16a!pov zKI}TEw^!QnoxM8+LslG%U( zmj!OAu~y(VxA8DbG_9eJ;9G_7H1Ov&6)ifw`aJ{j25Pno!Bbw$5CH`8>d9kPAdoEp0 zPinW6XdlE5)SsXv8lKz48G*6y51(9=mXRVw(~Y}k=!8y$FKY_&i$S#_*tzjW3V-xk2vq4r_$vIMl{PCJ=)Q}Fw zqmJj^+sx|0ouXR$$wv060Im)jwSHZcr+NI#DinaMvPiEjEU}4P^&o5IA9*x^Kq4Uv zc=!Vzh)Ym*E73$cV%Kcb?9UoMc0c>Kz3=ed7CtoSj-3A7a7p_9S+k>uj!&7~x%~$j z=2mV?M5xI>o21`IDr1y`?Sd(q(;gUYHifG>p|OXx;aeaN5^VS=#*LJ{JXN zFYTWMldJFmM)peHiqo>J@|tAZYv>g=c{-103$?=zoSc4oLdN@9sRJ=(pe!q2e%>IK z7(+TAq~{ATbDU26Hir;j4Gxmb_>+AG>M4h=dST{?NOSG^UN(20Xv`-E`^Mcu@ZvA2 zXvVTOS21?+C%Pxjv`{Hykw2|H?%SV=XtkFUKHGv4)<+y^bE9$kKN)3Tzwb6{5WbWg zfGX)9s@LG@g8ux~JvKDih%>GMHR_Y~oG#YjvC-dSlI)%RQuB`&U;sR?W+ zb$`+q1zv$Rdcvg zg%Nb-9@o0^042}S9SCP7n@}6zSW_0$p&ewdIa-W5kpjzTS4^z)6~v|7%zY2hu~0p= z;@@r2)mUKtD;yWq`d>X&{yiiPo%DMrAO9LB{*~vU&FZzsMIZit%P$xZU3mAf;!?eQfVn);op^%kSFZd>WMOxEcq9@VfBw6} zXy8|qyr^3G5MgyEwORobwE!J$fiwug>p(xG3ORLf(MhQ@D*RCvZ?rskcQCxvF5qgQ z+l1aJbKZ32)rQA^9eLnyH0VDSU6eQL;m!lDSZA{kc1-kDSFX=B|4-3F-ZK+ocu54Nw7#Oau`BNU4ZhvV?ZHE3F-h~N(K$k{_iN7X=Q@Bi&o$Y5vJw_1 z4+1z^^!X#~Q~QD!S-sa)Wy}-5A>k3v%?Rqi#n?Bab@y+5}pngQsZ*Pcq!|+wXwiLP(;Wp7w0oF zT_-`K&81Cf-MSZnD7VenzZ-6H(fsch>!SF;X3VYxEtm+uI7G7k>g$qh6@Q#RKnp!s z)lNF!8yvLk?r=tC)|aI4v&;HUp0uz0f6H<}GG226-T@}KBjjVTUv~<#$@6-Rmtc*w z{1-?89f>X^gw&SouZE&%QP(*RRqN)BRpJ}qGj#-0An7Z&=Z2_0p1g(ogrxzb5R(xz+~02620M;n!TCM))d)LJKU;O7$?R zy(N9gt1fcSY@=JdyL`pkq;grjI3Jo0C>VOgk@y^RcL-s1DaEGnty#%hxBpbU{@;Ro zon=PXaj>FP9E z+a$eynbTE$!Q@c@!p@`Vc*Qs|sF>=m+PITuw}lL6qRLXNyUg?AzYE&+*Zx{R5!zvu zsIgo!K)OQGTM#S80PFI2b?D}Sf>kwTXJlO}pIgOTBBg0<#U}8=NZlfu4+=#8yfRsv zDe9C5m8s7JS1Ku-;PzTP{EHBd77BSWvFBUHsy}qwPUdvh0hATd5=9l?^i)X9d8?oa zdCgT1qU!VX* z$Ssd#_Ce~HiJ2^Itaj;QIg&f^&slU{4>niz9kq+eM$t8wh&I0l6}?OF9Lb$XZq%R6 z8r%fq9{AcXS%pu+7$1VQZ*;TL8*GT7d$xAY<<||-M4YUEnk0EHYH?qW)l!D~q|v<)NvgMY?xVbM zBvXHlX3M)OnY|ZhZn98Boeis6O$7GA;xBeS6T!d+UO0cu>=;g?i|5xjpt$@TUQR7~ z4t1`rRzS!09%Hu14WVj8b11|%d^k%Zbnayz&0X^36^-K>z!w!iN@{zT+jVzLR#9^) z(zI9-Z+Nw+(zPeoIAvYBZGg8Qs~A$3ioPqo*kK&`;OWpoxDTpcf=g5#tWvyVb)V&u zH`bf08fG*9F7`a=)8ndD9s7?g*;F^!tMFZ+NcZrhEU_@o;;st{<5rxqqJVy_JV&h^rcBoQkt3bwD#*-QxZgHnU+jD42ff5IvelY|W5%GpkKV_`IW@UK*Vd4_(Sk>Q zhn7bc-UoekGLPu3yU`ovTDgYb3iTwWd_i<Fch#~;Gc`i9%gWjSHaa8!^V4wD9|7Iu4H`l>0^*nbsff~i&)VF1u8 ziHg%p(sMtse|q$)DVBXH7VI&C!L@mRbQDDxrqSBMFm}S6oj7{n>+Y(jssSyHz-!@0 zeAWYs^fNC94y>T%dHhiwl7)ja)Y`NH2vg#{Fz#wVWbVZ`Rnt;#Igqr0@JKhVdsR2f zKyA#et~#OQ*3SfJ1h3s(oW36|{mG@GJ6akVBQVIqOTwu%BV0FL-KD$rJY)G&hMsp8 zxi{-MD-_a&yn;6|iJnh~mCJf3?#92znV9Q_jnh@1)>cBg6{BL^S9_^-W8Fmo_uSLt3%klKMborVb0f`p4|5Yy~}K%DQsJsRY% zRW$%Bi@Ct!Eu#5!q zz8S{{Y`?r^#&}F`vzWbhhyF3y&7$e;z7vMNse81&i#Kj2D}0P^#FBmdy=T3`w|l;7 zHSEdc=zb18z$q}R*_&*fntpf60hiFCvj_DaudAQg{WpR&MU?Q=l|R@2r$@0qx&)|U9Bm8 znK6mG-n_(2ZvfSzYns3+dNuQ2y0KotRT-gp%(w{}I$X+wm38F0c)hjS2|-92Vek+s z5g#Am==2q;`6f=yPgJC+&P-lyg-t;*3)icjLoh>#{2zShW*U}p=Jj;8<4LwRXT|OM z%w!2AWh?QlB;ex6kOzSG_)@YrP?7}EDG(`)e$Y=+AsKL(R!RkN%*;>vrTp!ACCvpNDINW~qcXP5&ycYVEz%}>=cJ;|_=Vux=fV~(=D!Yq>#Guu6m zY^SQL#)_)wi7i;_BB5xN5CPun-|8Qz-`BLuJ&lFI`Ef6_?ETap6leP|&5N?jhz%6$ zTe;lKGfGQN1RCwe%5(cDHv2ium>=;u660DZRFi>V= zSH|xSoaf;Ejc-n%C!VtPeC~{J=y*1L@i-sGSo}?OZv1@?-L~Lr^i{vhYOh7_--CUh zzfmVH{MK#hgI?#PQSUHtQq0)$XxNc`)*}01RM!R&g%!G3muopTU}Xy}ZGPQ-q0z%g zoFDaZHQ7Gp>Y`eCQG8x!rXg0GQr-B=rYo@B#cCjGp!}0{I(yb+`h`g495@Y_u*rLs zH?l@(kqLciC@`8uz^-r*!>TS^Hy0s`)oc^R-Ih>MDW$C{_QI19G!i< z)_Z>4vf(%8L_)jM1|Ot|ud+VPwCVg5b+J12Jr;Y_03Ew7f%#cibx$gpK*^O3Fzz)$ z=EwHVx=V)kZrpXP=Z2X~YK|%dOoW>R)tgC-0qctLos`(cwwsKC6WFnY&p6}l^uq2Z zK3wgvs9Yt3#0(=pT*|4jh(fCvU{-M7p8&I5mj#a%O-cRo=ty?|mB_^bc+bFu#7e zC1*GNbI8qnU>NV60=Q+iX;xBs|^SbnvTAW4n;OCh{bNh(h9#yw$s_Y-A z_%xw#Ku8mL4mYL+_{`!L5ce9=&D~z^;CsWO0PQ+m{}|3Oo_Q*@ux#j?we9QX{Hn&b z$RQ?M05&;~kS71gQ*=W24Ao zMb8~RDoJB0oG?TaNRy9;s+>%L*1Jve7)mE%Za@7f25bIQcei3ruR~cbO;F-1re+`Z zguEe0Uh-+hzonUr@Rf&zdl}g}iIaw;naojm5*NY>{Al6l&!0k|=vUg+SGLg4fq2Cj z>xaWweP{_=U$`Qj1C1$g3T@~F)ft?ui9Q5$aBtjoRIPuu8La6d?%C|r_BQyaeBrz2 z3pLjYc)`n@!xy$(V!L>IiO6Gegw+cLzWngMu5bZH&2f~6jy~UfUtf0P7@bw;UVriz zoK{udpm4=VN3rcjtA)yT+zuw;!JDe>$K$|w>V6)o;9_d;_*A=pFCgSUPdJs{rd2;2 zF9cv|6QOv4>zv{*v$YiF8Noc8g@PmV`f0Jr z{x#h#0h23R&c1t^J*k4xyBHuYG9T-@Pr8fjl&w6ZGz_R2DbFrlR}L>7Dz}zVw{N z1By5}LBe=yJQgV0PZL9($#bu}16ba@e3!$;{vvf*a??8_T;#30!$poDg~naE_&LEH zG`(3*K@kBo_%N@<^@aBR+?)aR0mdn-uRxNFN!teyRGV2ezOaES;(KGMYcG0j+syxr z3@@AO-50en&q9hxzeFc`;U2P|0nLy&k4k>1rg-fuhfuKK;#9raIKFNXBv+Qf|ChIY z`Rdmy+Z5KBrkh^9vq@DMEXE>=JBuhIjq)5LUF_8sp2SklcbDD&4Psn0_D?UdR(4)? zwjAV;m;t&iFi01uch!o%m^~w-9x@E%iPPj{nG)@=Ytf%}v4>#o453S4f9vp~ z){}ox5WzoU-4c+p`;F%!a&CpF7b>UO>`0`*Qi4u#l7jntHaK6D*D_J=$JFkJasI8p zv#{?EODJoNB{wtIpJbHfSa{R_K!WGIv*V&6917hC!M&yXgvvndtKrPSd6|NFKF@W1 zamTQ$uV^G@gc9p8`Yk-v;|X^;!nZl^vd6y=;%G6J8z;eAd9D{0-TSNM)WW&ebG%&V z{uBl0TNmI8OU%Kdjsm``sBJKM7QWzFMeI;j4ZBf$f(wp8;M77#)hST zsA)0RRYN4e5E(dutv-HnK~gaGV2U z%zr(n7B68^QatH%;HtMWX-;mq{t5Fg@;w9y{CY<$ayPIL8y@8x9;JG6yePUBQT89| z?N*t;3!?OL*N>Xd$olTiUPy61wiY}iD}rmIZjxXBgOZg*2VMj1_ITJLI`aHG$y=N%{adEnI&jK~)_IPQ|(nN&e7xf1PKO!aiUui}TnZ+)rW(VgP z(cR)731Q4Xu=ds9Hud0XO-j2a!nO#scvMI~NK($^p0AmqQJ~!L3Nd&7+ik=hc1Bj7 z5}d~LhD!SNTmrJ-WaKMb2z%^^cU^W0=xv1H()1bGuixLC+wk95)m?^Vikn#t-Ggej_S*hXt)(uISlH-N#M% z4|cRyid!N&U8@GwxNsMD05_%fg$+CjCAHmscDBUge`_rMH|a8ctuu@l`9M2Ov*CLy zXH|mBe(YBzB&TuTad=Dmr+(pOhLt&Ymn;CQn@kQzJkSlf4soST<(^^KpoU>wfasZ2 z3_=-=YGU?Wf46bdZK7=F^uDl`4WBTDUu^E2h``wWmWE?OsT-F&>2-4^+VfA>ELgZxipeq^*oFn_2JYtePfWkuw0N*-6# zckG*G=`O2Be2Jk0m@_hV8*TMU^LW>Y!dTOk;L=^4J3 z*N6HkxgAbZZ9bPHn6(!4&a@CcwVU zbP3{DI^@FLC?SwGWL4P~CJ?5O7!^LK(VyF+Bc^3r6abo;n`7qLF}i5}m#A$Qp(NM3 zZx2?4${FaS(^Zp|B6RSAoM&Vs&TkukqDzKepeb(Vn%qdmZG3orz7`48)M$|Cx}7=g z&srg42H>HyAPIT+j>RV*c}P9%U}L=PgcQr(X;D3y=cRj#?{WX8pQj(AGcl+4y{}V- zgZ`O8)Zd>p{+`er{!QKQl@ifK}BFfBkPoO1za57dtY~>_h5Hw({ullSL=_-_*yzxIzBX`~)KG0u^eWy|T@R81fg%v!FC1%DiDZlHa zE4;ls_DO0vibid$q{X*X&$D?eb^d5Z=5w#-P~=GU)H#jHSKMikK|DT3+#yfEH7n)= z8hhIX#i2@nu{u2Jwcux;{QexnrHH*u`T*PEsO@l~*WkAxy=w|`e>XjNNu9$`7h)!d z{jy>BSdJ#2k&bwjiv)e3QX7q8>}1g{AK24R%w$g)WU)_>YaCl-i}GxXQWTS!jpwgc z#8=FIBzD1i@{7wz)pO}SpNzc+%7Cw^-aXoPWNa5nY7cl+Ir@r_-D&~UzCF&Mn&`%T`R%&)h+PEM)ulB#fNqvPOkVb(okSEzf9R= zMA*3QI*{L`%!n}#+Qx@>nTi zAeYItcBwl3B-g19Ja)2Ctog$f!9+Ldm4Y#kXI@|R^g>lJV^XD*@$R==FFU4y4MZ{L zT}4l$K0acKJ9Dm+8&B^SY#p^o8{b{`Zb%zTuy>#%y9{arm3z`&F2NDNkecD$y4kke z!2_!*5HJs{&{_wh_G?RrU;Lg|a%$}U`)r7+hA}AD#8LU^JvKZ&=FTUEov2V2(?2X6I z$X?erp1WIq{bza5g#o{zfWsh=@yO^&NY4^QK&nTg+lwEp3DbF-g9o+n6OMs`ce=F8 zqaiG(VsBX|Jet~eaU--UkCuWmv`tifnQTvP_)hthr18h-nyL;I2FXub2UG|AQunf_ z$W;3SCd|m0G&)n<{knN%+!%U;8Va*PW8(p=AK1;SV)o=G6r(S>Lo4i-BVF_?0wjxO zq_FFKSEf(nB5{#E?LCt7q6^5D{AkTBS{&mIDgub>u{Uea^C=Yb%$A4y^>{iBWj*aP zGU=fEe>GngYvwPfm-F`vkM>RxzZc(Iyq-P&}m_IwIw@I#M?^j{vGoq4D&o8>AeqGR|?TMw_&+!MB z9E0)E{OM_C?k!@Qt(73`T8ykrAQTZI9MN+wRb$fAp=FcSQ6#^f+R>ZD#vnFsXndv5 zktagaaNPiK*+f;+qt59;d47+s#h$Op0*CEqd5}2xz$JVwbd+RofBIozkNi!y>QC_e ztN(Mbv42#T?v#3ed;_wnv%h@&(Rw+pEBwgCYHJn7{D34R91Ro@yT$lg41m3r*lsMW zD>G}5cOru~&=}S#QK-xA3CP!bJiHvgqBo`qMFY!RQqpB%71@cQCE^qCu@cl|l!i<2 zHvF$oEN>C#!34c(#HLiaW&?#_lhu?@3nQ8fqJ4n1Kv;ndu~+~@oEyqMQ@kSq**Czi z2hE_ZnA@^RP?bn6|mKXjl;S-Mpc8uhvl%W@UHDKV~ff< zNyP4wH8-TW^t~2WAJwmCP2Pa8vXU#RF1oxV#wkzSd1XbJo_SsFL4lYMZ^JosMsoLS zPEHQ}fw6GUcW!ocYVHS#?U>J#(}WJmQr);dcXzDIoYsf2FQPNE-nU+aF~nWh4s`E5 zthwyheLC9UwE*4>_*Ub16e?AYnEXDMA}oJhs*3Da<5pK;5QE9vUzre;c{=_Z(mXUy z%KlFhvxx8tJl)Yyn3}es`g{ZJc9zH^q3o4EUtb=YSmj{|-+e^l6(AU)l=udp0JSWt zIRw*PAc7)V4wM6`I|UaGD8nomjOvFCNJTV@Z{*ps76U^RaS!K+a{L!WVCB8D7(>!< zpy-GpHU%v|x*Fy+?`FVb;H1EI+@WM`k$Z1xe7LpfV-gVW#Q}+DbVHnyOLvd$|5NVv{AZy$fBD0~ ze?s+p#X+t&$8Ua4^3M`<|17UO7&Pf6_S%Ji7zz^@zCDx&)4sqxrDl6VNu%PqlI?@XiTRP|IqtFpZe(M-GU2*< z-NQ2TTzY>a7uk%Q<0ko=-=}GY>gpz_M%Yw*>~`lG0SB?y&32!WN!@CfyC1;FSMYh; z<4{pLld&ayJ=$lN=;fbFS1(=4F+3pDW{YdVXR^M8S&GL#op8OWl?F2fgDV9++>ICN zbwmrGXJjpvmXIuQUGy&AWv|HriiQAh0g}1ot_z6&VYxcL>@hs(^bs+_{6e=7FAAbH zc89meEo0-UAC9Z_sG?IAIGX#;bKav%r+;g{` zDrTTART9)W-g8%yjHs=^G!+DDy$J-y>Z}0D-&Xqm=cgS}L{s&3Q$%KZ#yG?zwGM=&uXZ@gNc3_;!?sSC$$_Z;gbIRVJ zyeu8zLHw|jHz`g$dH)hQOs97>1y(E({+gxWW!xMz;Oo5sJuSv9ZC+pE6E{P*G$Mcn2OXh<3^{L`f5Uzx; z;MS5Ka~#+1(@hvgvx1d%$7(t!aJYP{C)bHqdAhsCPqb3%xj8WdFF+5lTtg~qAifns zK`doo*VE1Sb#}BT^y;-t#R?`a1UsdRy3a#_tg0O;93;wlX!aEKDpCx`WhX`te~ch% z0`7~uypTywKVQ!OrQ!~JzN+(4fB=v$5i7O4a%`P0x{X1 zj%15zlWU$knts*ae|-6)sNGLtSn6ID56@8i+xxBaK;FrH!TPW-Ci)sdjWG^C&d6eK z+?iR<8ZjPxFXr>-IOc?9%P-8E>k1=nr+HIB=AYSq1Th^;#%hJF6HdN!l-!8^%>XJ> zoYebIF=72X-tOGXisiaE1$9Nl2%nh2!09P*fG{ueqqo3q5@xHbg)z}#s!c{=0Xe`3 zHw#dyhL)dIinz352)Hc4AjSQmy~|g<;Y%s71i2cAIzQ|y3P);D(TX%y&dwKY{P(o1 ztp${^#A2}J{wM3B%TPX|E}wlhVXvxloxJQPgUJXgW1I^n#lDx6h7eXAkXc7 zMLv{KKx0EAJyC5F7DHKw`W$oL3C@}cMMbPj`|@?-s_(k1m$8UBxvJxzgOq|-?fMel z3m)BIkMJ;=qp9giCf$8_b(>%KjI5d}i}p)`eQ5s&zg5r4d(%cD9d!;p+01X~P3ytm z=kIIIB~D@xZ|VeYB3*2>o=+@FPI@d_LS3So$0WdNIudrxqi9yXPAhPE z#8QNx*Tx|?u;&lb{_i8luh%Zu`7ow6g11*sNd^>>K~jK6VrOJEyUT&C1va@}#shXS ziz7ty%35*Xmf4e1^iOH15$Tg1mx5jZ=`BAYGKdYv1uL4-}qZfrWmPu2ei`ihrF8VbJ|R!N;ushK<)`gK7Jr?cX&B9 z<<_-i3v4R7_e#q7blk`nqhuerT~+_c;zXQX`KU2TT%8B9@STu5Iizkxy6(*dfqGh4 zqbbrEeqz=fh$)Zz5gm%%R6W6CluuB_bu`*q`IV9f%|0J0A*$C!n7vZP_`WhBKYyT- zkB@txf!y&fLq=T#Z>l0$CbQlt6%ErWUVFO{> z?_qJO&z%i|t9e!9@Z#!vi9U z0%FsyQEGyf?F2Qw+XRodtPdQP`7gSNSvB$d&-au_sV1(==VNt@JZ_p{vDIiUZ5{zz zZEDJBo0uUiV?7PHTl?2WM=n1bQPCy#YFtr&Vd5CeFdhvNv6Nl;QV9aZ5V$qDFtdZr z<)8;o(1qcNhH2X|Mh9QIO7rU9TwH|2OVI2cTnpo!g~Fv>5z14LD{fm(0Im!z13)z& z11p!6iVC0SR!81kT4L?MdD=GiS9xqGOA_BmPn?*q zshfnkj_l_toUoa89W#0+MtDwT1dWGPc7H1Vxli+E9xXjA6t5$S9l3XDrkJ`c^3o3R zbC`$JRe;wr=<}q=qlnGzWrcn3W!0)IBm@*Tcz+liGP3y(zi}*yl`IJAqIU2Mn$+2P zwa2one^6H^JDYh%CP)?2cN8H{clzRu-RJuTsu{X(=bx31osqeyet7%QtH)$vWob9U z>-e>V%%3~Feo*8;Wyb2Fbw-wasm%$Ha7Z)wp~*W)2mK z7jSl|LqVP3v9iOFfg3cP88E|w^T1oRCC*1w7jpNs68aHND+`(9d#k$HvV#Cnuh&t% zBO_M{+)+r(w9>BSJp8T5gl`%&gxx3^tPOo{3bs<+VE~+wm1e)lmxLX#$S9ZRPN#c1 zwzMy@HTZLzkpC#PY4YXzwALB3Lsf0$LtY`7AV|dzSrb)=YZK+R^p}l6S&Zcl7Z&Aq zK398QFv#f^F+0b17dYUZ0UZ}32uxj*x5BbIXtUsj=!R)h?;R#M!nj&UZN40dQ!dtA{TL_R3@)*J~`%{#^O6gP=d88lv=Jnl;*w`S|!`-hW ze@4gOPC!@7jeZkVtTTJF&+#i539tovySSf`p@fiM(s5UNv=UE*DAEn{`yZ(v9Tq_g z65HmaGy7a1IhxWC6xeaWsLDzuIGL{}ythR}Y8_)bw0xD0x>M8Ktp5S2EnZiT(G05b zeWq-A1JMAiQETrUu=S4RzrkGiUMeY(M2{er0%AWuNm*mz#S=7eCDR21tDuFEQDx^G zIA%@aGq09XmBlJ4x?CM7In}7=>%mtgP_evJ zz@I$X*e~4f-rv|EoOY$>It{5vUYoppO*WKo*eObDPT07j@fU&S!ur!m32)u!nk7uC z6q}?8=O!PkHtywe34hlgMy~5LL-3-^;~$Pcu)Yd`23arlR^n}M&Z;^VuT#^8;nRt( zMtapR>~+DlE<7aLhjkClnM78gC7 zfaDtE!;j>4R?a*Fd_f4oYr->+<|0JDnxuhi?P$t3lQ}2(?lvwi}jWj8NjVH0JBzfnw zVg`(!sC%^Oy?1mZXy5wsFeKixR0WJMDCySh%*~jURoJj`tMk>vB{g1pqXRh%cyI%B zaR~$4vDQKki#IZf3KGQ${F5W9&pY@PE+eFdEi62Oycew3^Xz&S_39jdq)^FYSt+lk z-L~`_NooRMYj zi6b%`M^g6)-OVbN{H8>U`+P~)@O9}ZS0TR`s?N|=+QNy3QC&t|lM4LD)w}F92QVm5 z0waso0k++^AjXxl=UK-C&J^YyEQVVkrdCQdH1)Jdb@((wS_#4>0&i(-fk?A-hl8|0 zuB1mQZg1q@X!UFd!cn)c5Ajz(K_V8d>H}WJD<&RuT+|sFdQ66miQ5pH$!HZ5nu;)m zT!q0y1?Xg?gz%_1Tr$cS8~!;0@paW#YEHUtTSMz$N?@{HVh+TnP_V%&;<%d3;<_{g zMadmnsYlRBaHMCEhRZMyO(0g2SE3~$x_CsnY%4063tW2Nmrb!T&$dz1L%FkfvR2ZKYv+-!!v*Gi_&4m1SFF;anYjaHI z_pw`jd>g3hnnl>LAhn&WEXy0==p~^#L2aX$s`|vO?lZC`d_=WVv>kC|7@s*-1jsxh znXQ{{%*3Xb+6*t~FU?Eqskv-B4~)-fY1C}yoqyjt$pJ}o0o|qGlZE-+d)N1VAdRK* z`WYGAk&rp@jgZEVo`-`#==CYk?bOd1%}8)}tMvtSHnPPa|+lrXQbY zntj|AP}-ZN;?DlIe|FCSOj(uubB=tvWHRN?>jjqS%O7veE}xG7)aC4IkserWW$XhI zccz4>sgq#%N&?-G;DAk?XbMwz?oY*)I(#r960IV;Hw>tIBFyiAhC~rU3@qP(ikxe; zrg<78^uJFR1P2VVbbo5OlsPEDZPydiA6N#8a-8{*s;*gXki`8=qSiUry;Bq38Id@2 z-WrFQRg2Q7ifXlmI38@nGIX#Emd}z6N5i|pF0su`vjvtPGV{|smIzMlI-F_Dp^#&y zO|A^}yS&?Ts2lCtfVn!ZZNZQTVGSLz+tY^y6CRx?y$Rf;1Ndc$U-@LH-mGbozmxx_1|6HepuTucw;f`{)JEbD~?U!iKtH+td zsszr1QP`?S7tt~%BgKjv$4fbzU(f35S<HS4B{h=m@^suwA=6lwBVji4Ar&=X} zT~jE5<8iW~c&(5c7tqSe#Er2Olv>L$Q~xY1Q@8~)45PEiF#;1`c+8J1@YVPwXiK`! zzvG@z@nAx7G18$42*itH2Pk4=IXwDPTOV)Jbhed~)`c^&=JGAGHl30nnL4$#e9SaWA;lM}hrC4tTCkhdHc1OP6@>`L&3k`Ej}QGg{kB_ES8|Hzf(Z zun~LNi8M10a*QHn)lZq;LhP+;rd_3F>_T`LEY?C_Xhobuywas9TAJ=E3$+ziuRK81 zI3kJ0k)3?yzIc4iax%ZMzbs`eC0KLZ4m%Pvd90z}xO%?86po~vBvlN%PJCg+3 z=NgW%sbCK#;SDr*_c)3|w%sj~`knGEj*Or9@#P6ex#d>$`4b$Sw(Dk-M@!FU%wFHQ zRDYwl6rpq3(ekS|xOo6>G#YbZi-|Kw?#AD++IsmDx30OX5~Fb-%};i5DisCnveT+2 zFqU?RmV=&(n)ZuwyR=ym62tp2U^JV)r7j099d~`?r9noqDpBL9Hgl4&^d}uPv|lJ2dGti-()z;n#7DFoJR;wcV2uD$=`5 zV7gy=?~_P;ajR--ds)aWB;LkzSqpIIzdsUwO^cJMG&V~oq-+vx5J{m{0`J#Ln#$n=`@lQ%RdHUi zG^>bcsELcky^LPznKhxBTL)NdJb-=>#3A(Z&cuCXjyY5Oax9c5m(i=)$2lu}*Q(f+ zcf#k2Iow+RYSV>IZ-y_AOx$MUcY;Ne_W7qTXsU^-PZNED;Tbpm}7*M z8nOT=jZ%eF=k%ZceMoec*gw?M8jpa;U~p zc31-Qn7`n?@e5TK=D~;r4iE(Ek`i~(?ge5Z5t>++!AoJLWf}SvJ3#CBW;W`z0+nH! zZuw*Zc}iTk(aJ!bs@ecAe#*mFY%6>Uun}9lxed4d!(96&{u}a%k{Wa6WMl|&ck5%? zMa6XOWGw(;Z0ij^Xx+@Gy=QCD>o*dw5N^R7U=^NJ0u zKq;N^B6Z@bV};Y5L{yg7t?#znR?9OyX8GkcK~;CkuW$0To8QcvonL&}=$+or)!WP&)HZdY!IRy? zl5+?1l5T|(biQbCj`A}%-5TiUP@=Vj?obG!{Aqq!X2(Luj(Ba9=Wrd+R#2^hQiQY8 z07MaUqBSJPQRWj%Ao6}X^1y=T?0xO(pZPRm_dkRXW@}) zHEjtMaVt!>N%#k~ zg~d7V_1XVakI~M93q4N~3iL7xx}v_X4PrG>g*yc96cZqi`vXku`{pW)MpQJH*hlwt zeSxBq>Q|aN=op$-92_uP(n#58H)O6T6zv{zE^yUMXt$^d&L5`&^x*z|jckzI|b}CGKdG+CI`i zuTrd9op(kyG%g!u+%uZ~*S^`6RKkGAV7 z)J!s$tZe0MC2B_MqOLx5lx+SqG2v#8`iMpa4dl`9#Aoq5Z}+Y+&nUNxWc-dGk_OFc z_e$wZUKNi-*>$%(+UB7{Scov-b>TE1nID_`tqMH(0FpFd=73zo=~E26rGlkyxC*IC%b#F(n^eO+EbM#W_AP)_WwBZ0aJPnv zBm&#Ks$o)OjIi;aEA1~OwXJ`uq=lw6*NRiDrfqzSY)nN#6#+?AJ@#S+ z9e-MvG+=o|OB%}WI<4JgPn|=S%DGn*yiob=F08C?d57h1*I@1X?)+BHSl<5IC*(tm zcYeDT`=m(r#UGW~6*oc(2Qxo)x*ca^nx9h6 z$T~TH*8Hw4N98uQ*h#FkIW>w+4>d^YHEQoc-CHv z8*KgTi?<7vgt~8C+1@a{rD~*Z9vlvkLPz8l+r%7N2A3F%SF?EPQt+^1pdQ)^z#d{i zOOfb^%?=hDs{saEu!$5P;mZd2x;&P6=G^;Wzw})s7dx*oS3H2ihoSP1+g3Dtt1M&E z_v1n{)hU#rX}f(w3?I9M`eLe0ja>vECJ$8dmI?(w=CnPWM;;8j?|<#-aw=^Yyk0XG zj~0dov@z+yOemDp#jvVf&nzRqCN#g(8kDj1?Fk<&R1Y_6QG$LfYvJc4Hgj@v&fTHC z+B8aa{+sLP{MW}3Bw>_1ZxI(=FmV2^M)sB{%oG?txT!Slkv7zq+M)X1`l z#yq17rK1>EZW1n=qtTcIL9Jv5eG+jr6uisg^xQ}tt_-f!K*7#j5+i&gEowo4a{6wy zo_(W@ps=-=Bl=0zcAL9W7A(N(^^!%vveVkNQ1R$ch3WkXzmqnbo-?vv znC@JcYtzBQmKRQp3x~yDY{7P86KvAk!8WZy>5dBQk>dSpQ}yOTx+K}sWUBn4IW>u) zPi3fx6a6B3+#PHPH9^U`vf&k&)ivU|Dak2@7gB4KVZh zS7kDCJxc8d5m?G6=IcaQ{U#oMZFom{DvmQp=P=4)sdHE&Dz0kWc5ImFWiQYSuF$H| z;zBpGH|N;)f}xPRBJ{wg(?y9rV?=K!mHYhH$8JoNI;Mw~_0&5lVIn~NTFrFI3+K8y)i|S*`xa}pT11mH&{-w^*AYTWl7?`e!W>}GJ zQICKkJ0eZ24sys>B0Zr|9bC#839Sht>ZP>(v%M3m-b|{ZO?pVmIIA<8GCcb^8fPZ*dl`d7cx%@4nO^r8vI_Z zPRyN=-Ixms11x_$sZ@B=41d4<7iOpGfvNqcM9#aw{Z@?g$><}gc!xu3?z+{Oc0b=c zi7P`^2plVuHnaA(r-UF?0k<9fu#a~x97>sFV=CmIk+Jo6P97)a>|Ht6UM_ayL9x-E zasBrxmPH%gxek*^>r1$_320Q`Zq}V8_v+pKGqN|YitB!|;lDJxEPEQGzxb7O+fp0iAwf+35F?%HAj2^o;E2J|nBS>{nr~WpnaQW-52bO=08Q^!lv?>=~K! z^?lohjJ~6%|5)=2J*#%lj}Q|>g}phZNMjey6P0VaW_nu44E2_s+=NtLgKgnId9Wku|kCdi_G>o?0-$2w5U$5BiIhck+iO zl>Vw1V@*F?9u7XnbFO?$dids(_6&*0m6)=hr%w-6I3t68;<$T879Yt;{Af4hTDXgs zFE#k$)$z#TweP!uFxf+XRM{+-xhHBU9)G3K*Of(D%N{qieoN;-jiTj&5rmaR<-2D6ZZAD{=InYvda2|uS32gqNlI!VgtJ6*;es1*CVrmI!*iV;k91j%c~ zx*R%$`N0WiWc#M#cW?B>kad2~4E!ct318ZY?%#^~MSoq$z`(z+ZE6K=tLIObe(diBy^@EHzQ_N*Bd^zs|MvCBOPYbUDorJC+&ISexHLURS>nF$J>VNI zZ0~`}N@Pi9ubzYbI~zqIFRAuGKxygbxf5nmUxzW>urH z)Ir8}{l|(TnhSx^qL9BsANP}F)epRAdYCG4Gq^iuhLEzwVPb_8)d8AX$8vM@nuUEM z=Y7co=Q%2<&jm)QVv)xEi#ep#bic1g^mFM`)=iUh^G#9Wd|xST7hbpSPtu20m!LM| ztxRH^JW_7B#im@pH&hTO@;@E&Mxt$RzFN#QWrEADBOj2S3bAjb-tn_nk)Mjn!W~;r z589=~c~$+}h3$P8sCni7Sq`#fWc+o&ZMbc~)@9eVtlu=R0jOj6?hx#^-MAb$-BD_uXhB0y?RY2qfLYX zJ9iiw?nU-rr+=R7^8fCe`A5<}EBf89_buW5cO#0FmL$#JpZm1G_ZyQY{j&9+0VF!b zvGkoFJXdJ$Ikjl|a+vFZ1ygYoDx_+K(YQx)Bf4<=n4>1@sm)5>vO`pt(WqA6$q0|d zh27_3)x92r3#BqQuU{GXEH$c~*1YzMB&WLnqM5usO)1%zXrbLq_k&`s<_rH<_5Z5= zQT3*PJ|a%|O82`Or}PNIIclT0!aflOUgLD<C}?&B#L+|rOF(6ZJlLDdia~N zebKMCy5^OFrZ}6wKRper7Z}TW6-5h^qKu^8?rH^xC`c+B! zMu}3iQ|zW9>{41WHQnNjd^z}@inNCbx+(~;A;1FRckbiw@5583Z}6^E^{-ptLEj(G zzx?0h|2_WSq^vn`?Oan$H<%O5*&po?pi#O*y??*(8>YRzA(o* z7IR5(dK&FHpY}?JA;Kk_aw{8Xsa$zzjItLV(|GP#IA2X~@kwQ>Be-nbt>`N!41*B{ zwSDEh{1)e~-WV94ui-0at&`=3onl>x;Q#vcUot6>{L(eEiC9$_%hMOqBo=F(r$`Wx zaiVz$Bf3>8w$OBevl}AoNs(f6qEMg`iB}dsOgaQ@9yn$vn+nfgGaHwW9dy>a5AP)< z*aM{zb{dGm_{8;{C+L(PnhJMF_x6K|#FpOTJ!pL^Z02MZ_xptM)ffIH6JratQbwZ#Cb8#IxrOdjjSzo}vAdd3df8GXgB@mYjjPm16gOKn z$rX=%j8L%-JzphOhcCpx88RAh*b8y7f#jy9RV(YYa&vnlINjUiKhtfD)GSxCh{`FZ zEg-DKQgmWj;Q)r9(wMvu-(h`6xZ@iU5Y2{{vfjU9nY=q}vt#D?K^!jJ38Hg?>STOH z`W8m5A;c>dV~)LP`68y(>OSgGHqWCeWSM+`^NRgR;1WTNb{F>|UFD9f4lilDq2WMx z;{AR%f9>qsyJ+`4ocsGq6d&f1%e8cNTYC9l8=+~|op&mW#S@O>$OGk+;wY`n;Q z8{OP|RB*4$(omFd7_L4|4b&3tdV`am+nCv*PDWTCKIe<@QqttXxs$kKO6p3rdBekh zfK>w4L8|%{siM#vaqgt;cm@i$w447LQg%aPC}|yvHqj{M+(~XaxAZR<@`6y__{g`< zm#U2#_(~Cay84Bx8rX}G72gfx<}^00$rT4uP}N3IaU;qN7-lcLFi#70^l?S*LJPa% z1QYKI>!RMcGPza)WeBqwwLSdZP!3LLRAL4mY{eoC?+JjHg!C5ZII8lkk4)o9<tlaXNyyH9Ry#Jy# zw1Dfg$2~WKFbNpUcQyWYczAmxXA!K5e$rVV_>64Jx3k*3M%UDnD+H=O&z1K1)h6mw zP1f|mK87PT7gO%GAu)N9fU>t0$Md=YO4gD7YBdFHh-W?@3T}B!$p&eyGv%@e45bo;LqX|!8p6WLN&67f5 z+1w6lvCO|1{Y$9VKQRTJjs1TBP)h>@6aWGM2mo?kQB|^6SU$9=0RTI*0RR;M5de2@ za%3-UWn^h#FKKOIXJt1oaBgQ+R1E+Jy+KW5y+KW5y+KW5%)E1SWMA|>SRHh1JE_>V zIvv}#I<}pTZL?!19ou%twry+DpZ@;l-&wPUwJNJ#<-OE9_a5xM?>&`JIT=wnXl!Tz z001X0CZqrWfZYNBARdq)pT9XdQ$zTCfwC1-cK`s0=KlVC0n4b%1ONyD;z9ySt{JCm zE}pA*Ui_C2E~{BwnfWv8H4QWu;I4jHM5o_~a-aeN^07$$^TpE}#M26os`68%#TU!I zfM6Q>N0P7CSc)f=w>QcZt-Nr1`((6{EG;4uXTG`f#SQM9dt_f6th+F6Ci8{I8m9vO zJ+`s9SHS=0*i#F#@!t{R1ETep|BeXHiB>`WJNmXN*!1s8-=<(&n12`AMQ2~XK3?tU zRJo`~{QC<)lW$yHTz-B&mM$0hDjO@S)q0zHT)u2R)xXoel6v(T^i-=NdGg|M-z&(v zE8m5nLI0h5v~8m;rn}TC?!J}Gl_iR>pwkrpALEjP=0y4PyU7(H{=M(o^Z(zCK-fb6 zpV8p=(EdB>;|}RKD;|IhC|+ZE}cf2x!5cNEO>kDIoFF?^oxPD)Ce0ot+aBf zTPOFbI`=W=rObyAr}FSK80%ndjg+^lY10hrA`_7$##_nf9V=D-+JNZe_+u_8n2LJA z1c%04rW-kyWJJJ*1Q}T-SW`Ym=jq^0dvGvBtU`75slC8$j&kkJumG$A~=rQ+vs!5<}Br{))ODs|l{{oTq{Gwf?NoI`0 z&ZDGWN26?_V8=81JA!63moV^c>fHTh!UVhZWI%?!W9N#rVBrUo5HFlz)$8a_Q!$tMaQY%m#Yu=@b#QUKH0E>W&D~A$ISh4BsL$0 zy|Im4d;^H&tK$oXqJ1btCntAYn$TD=L|s{TXPK^QXbRsSsEDi>@Ub6PbDS z=}#k4G7L5DQn#OQ>^Z=xp%q9dE}^3oe~Xm;IP>2#&or1pssFy4k&zl_!BljJYF_Co zynMEyZXh)cDK8!}(iS&^trQ=LIYL#t{;{Jhu0Ehvhz86h8KD`xmQXQKN!Ct}RknWX z^x^!|X7ep6G^FL^EZll{;V`k#$Z92Li#VNYSJ5p)KeeC{Eva0}MEyro@6rZ~j8I!# zZT?ZH=@ji#dKL$lm+eYSvAV5cC8;z$w8D^!eDA_%=s3Xr4e7pAaQ1zbib*oyq^s>s zm3jI-e8Ah(*mR#$b`?b{o4dP#ZtEld8eJc8wgGE)x4jS>@~O!Zy06esb9t8xXneP+SZV6g~ljbEY7LL zhgt1-T5o3pdExF2HCu}?#_UfsH#E&9=A#^&8+expg@h~$i4If8Vg`i9+xazOGYo;b zVsad>Djo}0)uv){#ZRx`l#+bfzm#r1uh8DmeQu?19(-vRQu^?=S*pi^u^HQObsqQM z!>cEb`l4Ij*ys56=~DHiP_V$vNtS1AeV{o%Q--!RX|A6zTfFi~gY27QgQtVJ!1q&X zypt=>a)Qr--$f(vSrdF+b6HE0)^vn~rhY%((?{cb6;V647j?g{K0NT;Z__sL)UM}x zKOo%o;!PY0CUDh;g=7%Fn{>9eKJ>Ys8tk0E$I>m}Mbj&nKHa({g|Vu?=$NJ26A#vg zV!0Dhb=;inyy#kS@}e~9t8V0VZs?7&Q_rp*PbQ6HTGxvd%om^9IP<)$traPn!j3Ys zd)F@~*^uRaI^||#V`WB<|IK`@AuGvW@Zr_Ad8(9g#qp#=?&??;ULuzUYPz+vYLrG= zYJ!dQ0CT}7=X%bEn*ypvVszuR9y~~h6$x)+-pf-{wmduU!m+Z=Buk{KZZFjmeE(?6 zc}v<2cM@5Cw7WZ2W63WM^YCnskL}cr;$>aRry8h+ABtVHWQRV_iavK1hK>A2feMuuDwy?al7g@|mC>#HfsJh0a>Neb$o_2Cqc!uz%a^vs z-_xw$dK0NCzQ^tI(r55^fF9U><7kg*(u0p)~LI*Ou}{&&~5^`D|*Iopx^%3TIQqs!gWR@}ery-fiwqPV`Hm z5Q?&~=l%~JlTqf;npGWU&&@lwr_~HkPY+p3W)sD@2HWbh3~Ut>D%LidQE887Q2bM} zPc*%P{?AHr78-Xv0ieVP+mECSW(c*MeX0fHethnrLK(oj9KHu3GIB`B&eBo!Q;z|T z93yO=tQ_MQES!*jkdfr)gwY}m*PI?cNaLaKksd}adXTfbNsMujJ3VAO;=0x=qmmd5 zCE5H?A2@-udK$kvI@k_+oBAAF4b6>&b9ZEOQMi)%-4HA9=e;?9c2oE9G z5&doLfq-NdIfB!vk*SipZUhlfndmL@e` zr5x?MPQKhwsj$2L4V2H|TtbdTOq4+=HkVcu4YFW!;Szm??PY)!6k2o2^NQS2Y$c2% zed?=xH&rvjB=gCUuE_S>h)X=GRv)?NL)a$)1$@)$wI2S&a9I+0zNhZ4KA({|Ls6C6P*%n)ah-#8?G%5Z${PTxNjx z{zyMhvZ0YHbyJVi&U;@>jEq)cW_~;1-3`y;VEv_C1JushSK<<0a>9b`ebmaiPur3# z#`%Qt^X{R)=Ebj;?!F$Q0+-)B71!?9h1m~2@fvqB$TK#_`QYloooA;zdj6)(xP)d9 zS^f`(oz8aL+M;!D90i2dmSoEm>oz$sNS`T;);trqo2}oaZm2}IhZ!n{T#!{O!?5k@ z+}oSDkD5s{O78ryV13qdk*!+nG%`}Ju6$B+((oX2QEF!Mam^j>NT&SWgDP3dSO2G6 zRt{xKudKFn*iJn0lMIis{zu1TuQ3XL;|dB{1qTPOWZHbx+$(q#tEJDaaL@@&V5J*# zlKD*S;`dDGe?+{VoCen2^}bhxGw<034INwzq31|32pOw{n~cC z8~vyEnmgg?=8EQFd)N5YCa9Zh>8X@fKQA(nG+8tJnH40t z5^t72gSPUzq&G#=*>39&8Y$p5-rk?#N1B`U^+m0b+IcOeSmz@Ux*#o?R z5tWrk4PR3G%z?Vfsya)1qp6tX57ns(1wjznl9I=vJ z9)0#bBg4>rv#3mpQUhoo`E0R%{s~Dz`XiO&kDmm#?M|1qTD*-abNe}%8pCqT7*hl_ z-`~fKd&7?JfO&S`a&gMzY$E}AYNYi*9Qn+>Vd@}b)q|6C^0mZfurMMlD5cWM0{e+;DL5(F8 zEB?e)^B!TD-mVMlGuq+5|HnEEF6=s=!qYrH+zP(4a{7%h|5O_4#wvkno#!?ZBdR8gpYRq_ z%u1yQgA5yL9;6>oTzBW<Oy@q;97 z2?m|&wQ)Z6slW3Sw`uB~bGJ1eKN$HmIFI%0)=50!IcHvf$<|NoAT*rSfsETalNesfn4>_N-6Z=rPCJKWa@c zHO64ebK(&6oQ?;fV`a6v=JT@=J#YJ-pY4`ydBL-R#>Bfuqbwu#9nISn43#DpWm!nh z-8;-SKI$20dKu!0%W`eyM~zqD;aujU?0H5RNJdFQYY@?ncy?+;*(cjPU0QyT+i%u4 z^x8Pt;^J@@s3eIe84*#*@N>9)WNXr|u1t+%q!CuIQb`YM0Kev6U z9Y>^$%$d%j3-4Zf%rlEtQ0latkdaEq)Pp=VcdNuO3qw3YBDuwGw*0}f;fZ~>xQ+*@ zc@X4`l{oq3?6cVLVR1l1elnL}o+qDr0khxcMV%A&QlAX78gPnz#T{(IQF%{QG)?)L zB1o|`qi3Q)fzfG~pHaP!{U3y`VxHJVJ2%6jM~YOvu1;3IZ6@yj{2}V{mO>LdQ9e>B zR;m_XuV+X%TAfRH=2Jh;ik)&6cYymTdOEpC8wwlsO*Sl(Kk?*J^}p2;JL28wbJu+# zgCL^r!rC9$)^9Ju-_>9t@<>odYbD^SSFnJR_PRTd z@wzLYa!qQO*#cHVXBg>|Y!lfSd3Ld{Ze?_kEB--od+<3%VTPNEVOT!v$ak?^W=6af z!3@GOZT@4&XGesL?94Z#l)j1wC6tb^>H2AOQ|^BvUJLu=D&o$SuBMto>{C-5{t@*c zeo&h%*xTZi3=xy|pmR*3|7%OnUo!RopJgK-b$4UqGhi!_)K;DA?;4mdwdAFcLH;1a ziZbAvXDiKC(iW+)#y9BNI8{5&=YLm#=EZRcCSbZXz+A?3F~`}-lDQh#rt%Ew7VQcmN&X;PM?ZL)_26!_s* zFujFCfD{@sqrUK_z0@Llkc@HkqgCOr_0f=@Hg8JwB(AE-)lYLdL9$_TT@R+U=;KeW?SOmfTPHE7WQh zH&5-K{ru>dj|wl0KkG{sKRfH*IMB;Y!MS9@R2fCP(024UknWfg^Tu32}ax`s*w zG!qiiDD3Rwj5X!(g4uQ0Tuc6LA_5h2DNPic=$-aWh*)|OgOBv_C3oq<`|LS_ZWhR2 zN6{gCIj4#p{>Up zZ4>t8v!;@&WWmd#tzQFP zm5;tcyWr#8xfjXAu#HPnj%~?W5+u~6tp-xM7yR*XT--tp4PiD9M=vO*oK|K&<#Wh0 zSZ{H((<{$o{Uy$ZMki(@m{YloG+CEL9y+z2CuowzWI5kbnkbpboyAeyX|2E2_op~r z*HyPb{+5*h^NfRugTr@AhV>@$p8|cy0$J$6na3`BqAaq~ctV}e0Ln!!|{%?Jkp^Z|x{r?%Hn^r&G>#gFnFgrefzkWXu+} zYIom?0zR^};q67IO5~u_$#oGNd!jvpBlORq>D?&LMqnbQW< z1^43pHj3bLSequn$j0Mi>93*4bF-xyFBW~bt)lbE_A3k0wT&_-4`X1GY7Hf|gtaCG zu1EF0ks+a(+k520!P@m>&wJGwft}RkEn@^F|5Msa_zX&}&6}Q$rpvc^Y*%8OQ#7O8 zV*b^}*0biI9B>4hMc0KkkKvC|A5-+cn_IBY`C?H0ET3IyJ$7vm_1Tv$o<8#3a0PA_ z(C+tlr=HJ34)L;N2CjS8^ka%GgX|v%)eTvYNOujcv^V8A?5GI^nHILdnhA8pzNt|RYHzuu(7tXr2cT@|FMfXp-bKd$(n=WGrbLmTi-O#ZD^|E<1vp$Q(p z{CZ0cenwx@Y3jat$w~kz*oGYXC_rT76RlGbsaeGka|2=iNzr!sm z3N#r($s^Y-J8})im|zFM{tbZOzX6a)ip}@@dNn|Mme`oMabJ+DtXpEv)ojxBONjwC zIkV|lf9EK51XgfDU@~AwswsXlGRKd8y3L_(+eWdJ3O2KS%56>^8#>d~M2ZYZT%`0{ z!hb6*nEI$3p0`(LuupwTE{WcHaErMjKfG;+rsLN)A=t_BKQ<(`_Ab6ge3YZM_jf%~ zw8SEBNP%~&C(z;gy$cu-HhgVov>vF;@t;m1to+X>6uXymZCcs&L?*@!lyk*cAwxA% zmCx@BS*F)nc=*Elkb8;eflpq=|lO8X-teHOt7&eqDHCi1KMAh)KCSIO%}bkqys0BIOZ2v z>wYzn)a&J`C3L&A{o&^VA|c&@@z8Y}$Wd!oW?hZmAx#7?P|gkGMurLrWdL~>Mq&DbH{zNIpS|`WteMM%1$fQYRS3XI;LslmY}it zeT=!VnB8Ig;6|@+`$!z}2qIv7?cdq4z88V52xmUkxikE%@3AXrW8^Bl*FG0s15Edx zJw^@@vvzClzCPTZeBWN??c`r~pFVrgT_5?6x)A*5<|ekcM}L%lGR;s{R&A8jOXvCM zhk01IXep77&CA0N-i|U`GjnSv1^XH*hW&FJyA{pB9-`2YzV4~Ki@Rn7IB9~n+q#HT z*XsHjrIkD9vIQ5imq5{hjrXE8+Op|u>bQ8O*`9#L!X?i6b4;udWTZQ8ob`*X7Kox- zwvNVD6}E_bsmjqaP8OwX#B)o&_)2p4+XbkRt8PVVx4fw=FKsw{??nf)R*|5L^bV)h z8ls}&)y4YH(*LJxc&AcP+g0ZDa0V7mIx}yKA^%-T`I8f{iXj^Ov;yHuYq*C!1(%uW8z}?^V@{ zyxb9#DHfQvl<+hCg2R=5U;L!gU1lX4OYQRvJg>W6+%NRc_+AZ8-O_GoFyq97&kvpR zd`xV;^85|LZa4%LG-XWo-}B!q_TT919dCn**g-$TS~36GN%HKcyJY?f$4Wh*E2D7i z%Je{X)$3ucprC-6t!wC$+M|tXq-nJMF`s2_4_?mp8pgO3DYzNq#^+qV+g|uOgJEJs z=@;ybAZ$DPU&`Wq`qGyJ_?V$TfX4OlBz$lQCxdH_g-&NpWW|DbzBIFRGiC9Yn5Rhp zl>&Bs@5ei>XaXNY{q^w8jP;m*x31Cup1Cq=J44}D#rP{h@HaF5cZH%lF+`h(9+G+n z1WX9R>u`RQ|EE*N1XPD~o7^nq8Z9HX_7H5KFGJ%=uL)$(Me1v{A^&SIKs$kkYRn)V zyR>&yA`Wa?ss!J}Emu&=|LSG|`A-#XUN?X5v65<9qlmEh(F*PB@OvNx$jb34$o@XG zwtnZJ{=eLfpiigYbPQ2?@v-H}jD)neq42zvO*1~dB}@6Q!voU00mfI{Y_yiTbSz%h zDC}#Gm*_LM=G%3-${o}U+H$4GFCmZZfbftIvVp~IoPBX^!H)-}PKMEf|4i-52(slC zEv8~iTDL8mUjFhmjge=-?)>Ay|xlbs`fOaw$MqczZKo1wRvtbGA;Sv+M5*X`>}05@u`M}m0Ox~ zikItpBcb*XCZqrx2ZVMi1b~gL#s@B`LOBd<$@)}-zydOfW3>u!zQHry_ zzWEuK#Vb>ZzzRb+vwysc-o=JU2^F^O&gquwv{8u{?FHx+JBYp{eQ++ZV*-IrB0U@L zTOx{Y!=Sv!tO%$n^<5Cy~b6=oZrX7&1(hm8oQ4Jbzn6$?CC z&D%jr?Md-HQ$Ksx(!I4e=CDYBLB{yrH}8EDmF*Yqsy>aYxrVauPn!fEd9}a#autX1 zL`Cy!I|4ShpiIPMXeAmcTSbA%ACmud>i9ke*m7eqLa(#&+nixbI<6`%7({CusT+jo zPvC1q;9ynrq%$r|K7A8h>pBIi#;JK{A zYm>aF9&CInpEg7v;1`8~2I>PW{8omH%qklT`!T$4L5O6O$e`GDGSWaFm_s@!Zc`GJnQM2@UUjT_{ow5JnVyf-vt8{@HC)-1U|4&TOuej=A6e}7TwvA==sB>)5}P~P@y zkm2G%%P#Rr;=72B+RsYFCk;K=b!h$T^YYUlKU?jw&5$Un8<&(~s9Dq0L^#8Y(lJ1Q z)0B0t8@$eCaUR1@YRbnYMT(`ywiQAfraa-#%#qKk*O)IK*G;35Zc6jW`JH|g}P>q)Rt$G@-iIr zKifIz!Gbu2c^<7G&dZy6fl^E74d7Uza2TXzv2Yn?rr%g9i{ym>x)n@w#Cw5+fF;w=I zR}IWO)~(z5$dzS95$^g58H+TP+k~Aye0;(t&SQ<@jPJ|g`-f5mG=f47FvSs#ksPA` zE3=z%M5_~w$iqy+yb}*uW^|8ccYdv5@Mk=SZL?D=H_3!W$NhQ| z8;ahoqqWJz0wNG750bAVj$(+#D!Ku_TIwBv(+-D%~i7liuP5dPYyDzu^9xHU_kw zGhEi1sv?VD<#m5lqMQ6yItB5e%GJ@&S8tj#Uj8XDRvD{E|RU-^NPJ%lFFi6(@I6>e4A+GR1F zMn*a6oNm?CP_&-PkEoDbYdtj6laf>PnaaWHez*G18r%Brw3TM6ZSFQFDYiq^wHWkP zhGp~!WHg#_=0i-N1l45o5l&#*O=Ou&UM&{-T0)63B9gEdQWdd8A0qYWgx(+$cOHAC z55wp$-n9%yll0qC7$*vFAT9Tcah~0{wlP+yRBzO~oUOfMy~T^3Ql74hs(|0Vl!sx` z(l0I_%xH;s=j?oiLe0Y09^v@7;t+R`?yJo)_J3Hex9d!I!oA36ud6X|C*1I1O#l_s zS=e4pS!M3Dw2<8p$(=f;5MO4~V^gDJWFt|gKW@0-{e1GXTZP<)v2YJ(jr=9b8U`_x zJgbbmfg$JmzFEl8shZ^L_C(BZo~j;IYp#erd$|<5;uxc!C)~9p2mC>z5K&qa;comC>B_Lz0R4 zTxIfcQ`lSXUv6W6Mj%pdo=tA2yyMd(4egy1N0bdtOj%un6t-DG$jZyWPAji&#n^;W z8CtA=C$HK9y2eX?sou$MOrc5FjElXe!LF1$Yzq&l^v*;U15z{hY1PNelyc)fiH4Is z%k-e;AYPysZ-6~fG-B@*DvD#~G+)7BuKn&9w-vlTlkkT?2 z&%@+tI%w+@yF9bF?l#|{8aLU#NABTnL#gFy6~-oCmSkk}Av9CAHn;*5A{k{_#y~-oEB(rnd+IfjZ64 zFDLx<@^3u{8{F&r*=N^$zd*0vlAFsp+vW0ON6)M`f)fqm=FKRVG zxA^jpdHyu}zq0cY1rin;I;dW1Yexcv>ilmRACRJnXdN1YdgQ&feYI2xvhBaA^o&q2 zq;K5-^Y5O_pXZr_>tS$nRf*iuYPDg;oH7`D$c5DE34#A^JVpxHC{#Z7nTv8b=He-5 z3VM}_$}x3ICkimVk+emv*Am5OMXa&ghBvSHq$HpB z6|9waGm~+~j|eC2k4Ip2iO1yr7M3-iru+bL^ufjR)6ZVktmw_511f>*Nb3jYjY7k%|% zjjAk^6o~xlCdv!F44QJwrZmSs78Yz0XqLm*CaXRJ>TMAVaVj zNuh{BRR&ibQt^j6QbqdIr(t9^f(5)v8QVa0j4BY<4jepB*^p9dBD?5df?EUjzj;%| zh*+Hvh8@kwdZ3o9q0#LrE5b$^Wg>~E$#m0>5`lj&FnPO~+mm%VxA!2`wJoL#Nj|z&mI?{SS^K@`8>%}1iJ`7h!?aSGR1sP+lOj~wT zzeOH+fcba0TNw;`@UGW>uk2uGCW+p-()Ey)NwN7DJON6-tz?;Fe6?ulSGs=8TA#IF2z@EIwVWMr+~H{pN7VcsM5qUiJ?f z&+ROu&hT$PRJ6T_^pQ%F{?6CZehgBPvROvIN&4ZQ)Wli|&E;HZ{n1Xx;E)gsmR-*W zlR@cdx$`7sEsyL?a+jGk3XM*IhPnax#Bn zp>T=GW^~fjtJ(Rbp?dVT_Fvs`{b|dcj;c|h;qhaw7&Y{n2LvgWhTXH0t)IBlHo zeYOW@d~)+(gN<$9k3ACAYgP4D8XYpLPWkX|aOdYCfzZx5YZbk3O|#-^a@=(v#Q(7% z-bySXR0`&GR1v6$0-B~XWl}Rq?JG|z&t{ev%AdgJX0Q0Ke zo_CL8)kJc%UIUp1A;|Hp)h(2eW68vept*IPgOTWCqbRoTqsN+hQK#C{CF=zRgW;FG zBy{}+DL+eFF0`{c+KSz8o3V+IXU7VY$4K(l0=Y-~SJQt*y5mzcVXuVsoLtZkQLx-jB z3e4=-nZzg0?E`OS_atN9hAh<8MC4R>nC)~yly`SJzk62tq=r)(b0rJ>xuihjIQf3r z%CtmJq6b&GeNy4-;rvA2b4Vol5XtoHZF3y6)ma{Oh|z*dNx7(K$Ua2r31k_qIK{X^ z3C()nX;DG_)DX+?TH1~r@{e=h2fq#2yxQ`P(V7p@K^`QLL6|R0`Nou3KnVpq=s?bK z3JXmC)V$w^r_Q2ui)jB+gA~!)B)Eg>BPW{d`4i-9BC0-+@sO|z2A3sZ8BWN>@1k8nOd8uC3hjsfzc?cNkwz>hPPWKfRbZbUty9`ake~{~o8L*<>jhbMB zZM2atJI|VViLzirRj-taMhurVTsKgo?4ndaN59WPWzj&iINi91P;p+%hN(i1RZAU* zsl#}Y5IPT=}@fg&i(y;(w|+2DBZLqea;t@ku5=bwy4yaP$TgK5_vLURATQ0!qTc5 zG#EmsYu(aTDx~-gUuWGfYfr~M=JRVLq^qxtN+nPd=YsC~9DEflfsC1HsAKlx=rYGV zGhGYpTg1SbCH874cQ(t9-|-$K;`d+!L9bur_2;j>?yRi@mgAHM#N={!!3w(NIy$-t z_EDx;m44u3VWxA<{*!X5q@S)Ja$!XPOOUjFlSp)0Xd>HC(aynft)Fsxb`s}$U5%yn z!Jq%JeE#xavB1;P)c!;DVCZPCVEVFhU_AZQfPrQ8_*xbpQBt9ipCnGDO71smOH;4z ziv@QhAFo6ojWKBnqt@7mn~-%2D5&Z`6CCgImrtuB(L{8AD)_r53Zs{nA>P; zx19FJqP?wuk0 zX7U~lr^O?OCBcra2Bh=hT6NwSVG1KzW!okW3thFghaptI5caki9H@*svR9PNY$`t)LWHnu*{c9un>$>~SOQ$L$7mv5q zkyeNNhR~^`26hc0yMcTCjVu4y6?{q;f|4?BCUf)sKD9yR=5UE(JCDI)-ud5=BufPS zl?wmB&X${6$n5tIvA4UP7azm$fPxru-0Ps{sQU}onkCjZqx6`nAGL2;5DFvIG;iDk z^s^NtxIRy6-8})qjjH@waq~;3Xjp6oG^Es;Pxl+_%o(}6^V{_|SIu?zhq55KEm5)(jI2WU4A2aJk2*JtT9iCS9 zla*12!wcBv4fieDCeD)9R*nvaQ8)8sqv!bKNJx3pBFgyth%}n!ef}*i$;%&Y;UM_!I}7HOhj5~N zfkKU?yUabb%=Jr@6@E%a6>cn6!HD_XlV3arM?6veblPKTLPN4>#a_wL5ml$6n2d@@ zR2G)6aa|D3xy;JdTSZ4ixu&=4+c=R)?>bTu@2)Hh*sGR?TML^uNfvWTqC|zCNiO;O z^jY^M?Y}&Q+j2&?r5bPXxEX|>zi@44CP7BJ;@mkJWwsQ?P9j#7eQ?kvKm;)vu=TT?4Vjc|+Sf`T;s zeWg_zRJ4T|!z6)Lye1WmDl_f?^K+yswS5c`h@980d1tgbp}X^qI4euT6X3d+T~+t& zMd^}kMh8mjv+jWk{UvY`1!0EjLHZON4EOVst&`;sc-UN1YQNtvR70kXo{cbrdd_>j zh~$9}zVs$`14SKKHgRn}B@TnwhfFA=$psm&H`N_m#jDHDvr`?XiJUj8Bqnr9$28al zeoK$z#x#O`3<^S!oV+VO+RQfr*8i4V(mu%#bd>RMg7E|m(=s`j!D2b%Aer)6Z6XI-D}3AQ~tWZgvo!MB5zk2 zy2Ma&W?uTOw*IUNF#=kMXycZ&69WjNFoXl|){9|E{Mftm4#N`D%74grQo^x*oKc;L z7{&#`_l*AMU&dSt$&&smiu;kd#tPt<}`qyB7is2NUf6D$c_AjNRq={gU zj$)s5#``DjucF^B$^Pey#SS?CKlsk@j!CQU5;;scs(#`UA0H{lN`05spn2aC-M>qJ z_}WUwiDKc+Q_Z|)=%k%#5W)}1izKBkRc;e+BMX*VURbJrNe-v^-7Nwme)W9tx4Uq2 z=UWpg5E{SnYqX|GE41&ZOrvXr@=h{`DidX2;L2F7c7LM(oG{wa`%)!{9$R2*1c@FR z4xkSrK-0G@{BY0f#i~{t{PpfC>9=*LS3_CTG{y8=n!>{8ofy({LAjtl$GZ*IL))b+ z@?#hAy}J`+IQGyo*%n;k$4fpTMsfcveiL>HG!HaR1MwGMSHI4k&%tIS(=hfl{b(oy zq=1LPjtxWja`?NE{og#*ua+1LTwCyFFsUB-sV`as_H?(_PdtbvB-pe^*mr@Z zTN=sW0x^@5SqVJ`Fq_Ax=^u#NA^|E5`hCwdWx( z&R`#HZKnY;NSaL{AE#)3fG?7|%kDV!p8)LoICIohAf(?byMTi=5?J%szR{a3UbmMK z;BXOlITr{rdr?c8nhhYh6~F}5c)#BwXc@!(+T-rFMT0knA6owlNT8_k%C zw)xL#aM(gE`6Ese7cFlkw#s93v*17s6b1kko_bzj*jCe-?ox|(fdw*5PqNb5Psq9% z{Bl>*sUpPndsnz6$EVUz0KoAR6uY%z`@>_-gYMB?0N;r{5u_hs_SfTPVZ>dHn0RC? z%J+n7T0~?@(j*=0`V>N815WXfBJ+c`EvZ2Ohi)m#7kq=jbOrwO1xz0n1 zjs^up0DEimlC8z%N+6f_E;tr9mW&V>0f4Cj%2Cx4nf8sMi7CKV<}cawBW&4Z<%uC@@J8pStG7X zkxqIN0Ae5lotWy&M1qIPdJ;OCh{E*ai%$t)+2=BFK%U&;Cr(!wzD`{+iH1-p`bH;% z0}8jsg3BeI;c8qR+KH3N`!tUpbl6O8!)pBEy-Xv!R-=(14bpAn>Dig7ec8+%sixws zhG%hG=l*4Jc53-f9JJZ-b$$;i66!#7BbEg}({e_9iK#D1o_%f@dtY#1sG7~M9X%US ze_}Bh0AgZ#!}k5}w1txw4=g~Jac+Sw{Zy(b{2AtGJ8`F@HVY*>t!FvOcz=rQE&h|~ zF35vFVKx+qY$xYOl+A9b`24B`0seighOv}+Um?K>;hMerwp3{Le2O{k1|d};?x$E%BS@O?_kXb7pDgxgA0(vTD}LC2!`gZ4aJAQ}n1 zW)X&I5(ZhgsNv!`zx1C&Aq}iuOX{gg#NZTw@HGBPjyBn?z7Qf< z^Lx%Fxw@JZqZowX_Qf26UiR&5a z4};fuRX8BH=&`uGK7x*F0tN0y0-Z{&iI5-|32e^1+8 z+5dC8e^VF8C*e)7VCYGFPKf}InCjJpckX_Dan2EVf z2(O4?EnVPsS`gL2GQU;)^m}v<1iKif#}d>#xR4CXJjg4MdVg~cF86CSSP zD}mg+_S4k7*<5cBa2_xT4}@+CY})AUUe#_SKUSn1KqwV0-};Y*5zt*`mrqta z0pBQ$^l!T)T~x6mq;|JYtKM@>_gWSk?#~-Ct-K;kj})XAq6XefKnMYVq>uWzHWJsH ztu^U0?=P2qk;2h@@eaK|JEGxRW!vPEJ00KP5YXTe8fo9Xi8ibj?*?KP2F|^^F;tU& zF{HS3$iXmh>RMa3{kc}jvk^*bmRo()cj$*gfMgJz{t`AlX#er_yq@H2GaHu??5*DR zC`mb(#p`YQkwQ45ztR!T5u$}{; z2KeU9Jig!L!G3#&6Nm2h*<6bv90vuQT_s%LsmaACfAu0$9xHvbzBL5*S zL%=}A zbe}nX;h(@G8k$2viA^ohTU+1HD};#%>q_=)v^)!%4dyB+du=aSgP&qYz)U4Qr2$^>!H1O*|TKJNGKeO!soKEy6`T6)efc8B`X zq>$9Yk+tQ^8u{rV<_n6Jw{8~7;Z`dmEvk8ukP0U+8-8VG7QWW9RKjfxlFB#tqzl`f zj)j*12D~W$uB#m<|5goYKMwUM z#)uX6Ox_?UdjKL1`Idj3iz8QN@e=;7Ym5l>7a9P-5Aj;cIpxxuZ*z+QIh_^CMj}9| zkOVa?<;4esvpy0s=&;t!pyj^ac@0%Fqs&gFK{cV3-r*=)*7r(UC++||3Dmmp4q!a)Ky1c}tjdSn%#u84sGxb1wy&;rJC|@%4 zC&gpPHU~^LMS+Z^Q+-2$m5&QIW-y?_z1(OkXtf8SC2GN|ho)DmiH%|Xo zfyA(@@WXpAnPIjhqU3=U^=b>R^V9xgN9V0mn~KRI+EpaN{4i|Z#cPwnEL24H*Df?F zds`pPvn%d>)l%BR`Ekjs+5G&P)2|}Zdq^8wU;` zfJ-9xx*wO3){@K(J-h4>>CkG+ zG}mgzBdyO5C`eC`;{60lObq_BecUK_9Rn9Ae1r!<_`wG zO&6Z)bKfjz_NbB~bAzq8ifa@spPB9G&F1yhw@n3DP~Qn&r%aE+ELbPp6E$yDPot!S zU%mzEo#{vbuqYUJ(+?xcr{%_CFTy%tp| zZSSG71tff;H8N#Hge-4GmR53fNyBYqt=<}+oN7Q zjs$SWp;z;{0ssJu)x{Ks%ITg-j$IZ8e1QzjO7S$ci%b`MhOGC4PtiI!qlvBXX!FIz z@w(ZI#mS~xyS;lN{?NR*yaD(D2;;<+0Lhpa+-~w;dZ9vvKsMV?TeCH7TFFUe$>Of8 zcbYG1JFF2p8G&Yz4SRxvLj9bS^zu5YZmb>t+3W2WXoY;J57*tHKaUZLjE)c89ep&EKS5pYg2F!;G@&Xyv~?9ogi6M!ETSND8b6<{;XWuygFu~jJtIdup$y4_)HDiaZ9m#VK&Tp}T^RmuC z)IY<<6$8g~RvyPFv}0Q(7?(|JSLl}yf_6q2Vh6wH)1t0?_2=Pd9vi%MLt1B>DR!I3 z>Ip|iN0+2pKd$v4ADlQ+HC}Cz=s0-#%I*JB?u|{F`R4c)`zx#=RNx9sh4&%rwHv!J z#$H$UIR}@0?#gdv-TO;mn(6T|)IefEc{8hXTW(p&je?CMAZO#muzI&373*uflmvTL z!@?=pP<}6T|kAHpAE-1y@#W7&1DYacHILP zNzgu4wH|KY>BiM!H_K1T`OmPq=VyE*J&y!Ozbi?4w6dG)Uk7;@;@!PP);j|*32^GU zrX@Nu_)QI(nhp~mi~>RfN?y5>t_a8D&DcpvrjZjVW_2t&U%~m2c1LQskG_Sdn(Z*TrBWwIrQXwQ6#2tX~ zc!jX8t!;jySjpP+x2raWR6T;5sk(2aLNl=pq0QsovENG*C!ss5F)KuZqY2n&%&ij4 z2QI)x@+-!5T4`SonMFrswfmP4|H43`pWg~K0(rk=hx#VZvX09Dj$w{Y-oriyjy&odL7BRHy7Q*PZ69h|f*HMh;Ojk3q2CIkjL2a(gwd5MG)jWwUT6C9%2W${ zw$>0s!%5@a3VwR$m5)sqz?1kMgfE_#WOoI? zoV=px9XHKHD|=c^6*h&Hr5O3 zTjX%sMcv-$!~7;mZ@mf9J%FcOIGX^w362lwQs>puj_ojVS~s)^tW+&+k+%)k;_lYT z?wtq_E@JCtsRG2qfndC;7@^PWA~D&F49r z_ai%48>x+737*f6ZxL`do;>J5Nra)2B+@Sw;=vdrf1I_4X1&|F$&4grBsgRbT>Vzc z)F8Wr-0|?S2$d>O3BT(wPRXQa#=QO`$a-*h zRPBgJoJYC|8{TA9cE8xU9Q`_ny=$kJx}1rJ7kNG=U4S#MC+eem@KxDUJ)zpcnfMEt zZj-pf{zLFea8YAx8!iFl^J&(OPx0F2SSikh6v4Y$Erc*scF#~~7Jv3(Y;ghVz*ENU z5NlYp{cwhs9g|}V8W%EP_ROUqH#+sl#%{Tx6N#nIS>?P_$ zl%(J{C;$o|fUIv*p1D?uR3b+~YTH0EA`AMyUFfs+L9}x_g8~(YSDAdVN|dPY%?$y_ z6J7RpY7@+f55SG*)&je@KYO`)CzhzjJZPu;3P@WoIsFK^4)Y# zcL6(8&-Q9~Yfme3nJpt0^0tWC0*lQ}2b<@g@{oLS@v)iwQXur**7|@oOEtoC%8h0& zcu05Q>i z2c>5Txrl<6jB)=ecW_pO<~Yv#?t2xOad3A6344;&?)~))K9jj2_9|$?$N%f;yZVQ6 z+h*;A275f*pDZj7NZgBR&xk-)vq?urFn19m@O8sXCm(@@^56q4m+wP(u-bYZ^xO-h zOrZx_`@;@X>khi;%l<0!LX|L9+-c_Fvju@A2yf~d?>bdWV|pa1)qGywp$&We%&pvh zI`kMx$eIdF298&;PvST>vX5%*=>b|vA zQ-)|ahR}3bw&&@_H8jLjKH64DeLY+ZXY*h#UONmPMl;c2%(cINQqv3nPwvDz3TS9 zice!NV8CPiwD7_5e1MBBjJ(u1P928O@!YN>K$jz37;gf!ac|RGxJZNZKVTD}M(;O5 z6HehCT+=};Nrb`Il53-V@+ZhNJ%k5*b5!`QA|6n%a(-vK&2Sf2)lb*5bbpQzU4K6X z@D=Z)_NjXfQr^l~u_1twtJb&Z#OZYGx_!>uQ@rvJQo$8*2!)C3g%QYCp3udY|4^7K zfre*@h(oqbg=F$@%OzvYpHvZl=7 zI5)wH6$y|}V3Vm3&+pkryB=GV-ss|gm7WQK3WUuzd2WlSf9RKUFiu1A>+q7D_v{Hh zg}fF+w}TcUhUC%u8WOV17&0DuYn;w4h_&*@kmiM$Ekz+JVs>7nh^*n4mw`BI4T zHSp++6xVNX8>fN338-G!N%Y%cL^zBJRD|h{$MqL$#d!Dsq<&M)z%k zOgsJ|^@rOqCVEM^N7uxDy71l9X0oyECNkdhEE^MqGaDZ5JutveeG6SPCC{SU4&AC^ z_x6JNi6grpIV#Fsi5@rc!tg)8mLabLiT}9%QYU9f#)I@!plE8ZxtyhSgSio!sPz)y zr2d9nATJ(Lmne=TTx(BUP$`2FO%aSuZAm0<bHOy7Hz}Z=^Fk?O1NS@jC{y`j_0i zz3bvx=A(8&oQgO}o}+JOt2&Rl@p(`>5T3`$^AF9+dr@G=NJFEpwUwlr^JMKP{99>Z z<<)8>X;z`^`<9+CD?ot6ipqPpXes<$%=|-r&y)@XtkhTSIo)UD_~v-5T_6BmGSt+cYjhaN%6 z!>Ig|`KsvO!SWOPT7C;zh9qkA50?n&#FrZge$2~OQze0?Rm0{O!&z<@TO82=iEQvx9)!y!PUaK63*^iXw?)COfHT0~S(g2gQI@miqH>>J>-r0TBa{4Hi}=6`MbO<-Wn=wd@~}QW5i!enjch@$cAVdXExe%c#RehT zBq4y(sA=%<)XZ)WwZHhg%nu+7V!*k}vCcV;q*$Cl%sD0d7sy^w&G$v#I2}x~9I)u_ zDfxqO4Fd9%AI9bYfE19j!*G3M1v$dw#QEKU!nI*8W)^fT-CF=E;x9jD*DD%cFRO#b*hE?{#q@Q zx(VN_XT8~cm-v-e|CMdq2093jRA#o|>6>uD_{8`I*-d0r-CTN(w^poN!`_SVi;sP7 z%Nz{hL|bao{mWA`u|pr;K&p z#g*-hysNaGAO!eU@3@L7N;JShPzK0`>dXdvT547vX+e`#rRGBcnC{6RkN8+x0AxeM zmP#gzew*z^nTN<%DI&lhODektY*{Z;2)QqlP8};}ufzW<&$?5quM32X2^v$O!Yfas}^au&q0)4@|AMC|`%r!54bfao6nsr5Z zD^#J#xr`@kgs0 zynI3nAA7fd#Cu0xYM>j8j!&MweniXf{s5uKL$x;sYn|48(_ zrR3bLhTLC^YEAS~geVnENdq*hJw5az;<%muU|tGJHGGfwIp^F> zQ<*O!-z4Pl%HKW=gQ^__ILuXWyzMZ*D9=P7OrzUE_tVa7lU;5WL(ByFor(ZFzCcIJx-I?5&q7< z^{>tQQlP!HEXo7UNt)#ZG{k*Hji|0YndG@J9e2(D(iKYj)(Vae(Fh`P9x@9&@7} zSgc$eYIv-DWQYT&uE(y>#$^P$Wy$IN!90SRfbak61%LwCM4j+>yQ`WzU16L69U|cX zbOo-o-1Upc-JhepXt{WD6K(%euG5mm949_7sWDDn?##wd(9R!vUv|-KiH2LEmD(qZ z^@ekPEf8T3fwSrr6r9OnDo|K^RVukV3yTsVDCr$ro9`h0N>7Xkw7UmQ_3l*@bs#J! zeB1hvTzdGBVX6DO6Nw1+_sQ2NXX}AByiIJ~MB8x94uL151L$~mAup&=KIzafJ*{>Q zrHnIKg9QbAgJ_LH_yP#Yqa>QuU|wF^=|8bbBdAbwh`v5EF&7<&?PHR3?OruJs?5Mw z@(gG%mJ0XD6bqeRQa*?me(d7Jx=iIBRxaC5d2-)#swDP`OR?RC%kGGbE;^s zWuY6OT8im_ld__rDTL#8lJ63-{eCRhsai-~L033(jZ>6iti{g|L#Bjq!Jd`dz1bmI z7FvA}1ebeBTspwQ#?4t+fQn5BbzObC8kTb<3ho*66Fsx=Ft>Xol}CQvCw)*mHoBzY znaW}P?e+M4dS-n}ar17{xc-N|VYoN)=%pfbT8^88XE7%ty(S&v9?Ude6Sq;N=9GI) ze-^-{Pcx4PozF1O_%ux#yb)GOC-hw@=a`!oJCB1R_!XNOyL`sQ>}MW?<@E$AegbeRSU# zCTps|+Qw4ku(;`zFB{$}U_(vV;Ua9QV+*s;w2`OFi`|R>Ti>;vE`Q+xIFen8d$G?U z@!cz29J|gC#xPUIuanGI+G<|8B}wBNCRDR+oL(54gKjzLtCt!4wD|0r3S9-uuY{8I zQBMca)Ta8Z6AOEv9@#3(-EU>RWZ z%!k$%#b2U!ppZAi?hv22+;O;IB$CKT^Y2~mbS&T0C-zo8zAImc8>jm;aP4h=^NB`4 zk*rxDBNwXvC_PMFmnEU|C}v1vcHz83;BUNKJjtxMlhN61g}=Lv%wqpg$!R)TD62*5 zxNcm|-Y|sCY=7!DpXno*?jy{MjI2|igu!0jf|fND#*}1L+ED&-B zwEu<7P`&Rb6Nn@uOYuI;h8q==_I^AndSu8*R0jk@ij2oI-<<@vs z!r4?PV@>6{T-RAOX2>RZkZOx2oR7!jVNL5a%5-iLx;#Y`Wx z!u;(^%%ibsi#wo1(2*i56X1KLnx})o2KOBt-p`P>S#F=WBb?vP_;?)mMb^>8sQJ|? zJ&RVlvQyjL2p#n{B!rqDz5Odb?YEgGICmDn-z}4-UbMU6ge??QDhSFx_}Pz5_V6|~ z{`HUheWuc)o#4Wa|C4xt&%`77P9>q4t)2o;z@wQKIdEkz?v)k;lDm0|w? z+u3Mx+xAUa&txGC{L8nBrPoEj-8ZlcF$a1!D+f? z$Iy$ffImK^SBWYkhF98$wxSP*=OzPv=AjbOQ|G=b!&2p^;jsa9q`9~EN`)0S{%?jI zga}>AuO+!J-_#_;EvJqHZtH;(-@{13$RK$}9oshA8YjO3))^0!z8WbIrTSQ~?cIY- zc6jHL{8^zTsS4To0*TZ=Q_jbpafpd;bL@Q*oY&ypx-bap%fxAL)#3_uV&l^|{O1Vv z4~VbN#SPjRyX5)%9o2VIJS^aT6V`4El1@qte*Y|9z4=V<3`~8*@RGKT9Typn$27aK zB(0%WujdbS8tVoYRSh$ZE}?un6|7_etjgZ;@gFhTP8T zhc~?{QCJp@5%rp1TTj88bN6|9^Y$gl*|)#vybIzHw4}PJyY{aC932@WDLm1&IJEh# zZGYHy722Cf zSx_3QpA4j-6{l&!D};!Sh^m3X*RHv{7fKb=<3tQ)@F+4Hj8C+B;{(X`iCB5K>&wTc z!CY}bMXB_5`q)nEfs0GcTFKJWq*PsUnko5op$49xW*H`AgK7)%|uJxMN8>CY>LY6^I)o~9ax_RPNiSy8rFGb zYwy1Vdu_&7={d$aw2HJj@Du;m_E>4TZ_o}52dbu!aJ3PxJT511oE)3Xu%TP~Pi&MeT1l(lotw^u0HhecUKi&GZf??|DC!JT<=8neP6y zCnwjr@{jYAGGEAR9WBGX&OgKwhQ8GmMNhVlj8{qp3+J-hnufnJ8B|twVr-$Wg3PoD#IDleW73X%$ zb;hoI$^4*~IME!roPw79f9B-8ZMOcC-{6Pl@9x`RjLvRbXvc(a@nnH^(p;QELF2CY z}daevgGx))3y?SDfIl5I#<`*?V8FnZnW_oR>lfmzw-^n1V*cq6IQwe?9yF#5%3tmrk zIsap(mGD}q?EFl8((nL)kz*wvrKVG4cz_lrv^CQ1jVulEg5{*9n+?3cHo#ZAD%<1d z!CU1pQ9JG^EJC1=23A2nSp(Q0=y`1!nW4D^8ZA^rT4qOyjDmOh0s>G1JxA$8*dA;D zJX2>O#Tf!rKyGLb8Vjp~%i+aFmG^N)8R7jt2(GaY6cSaBXEf8ZJu)hyZ6{Fq;loni zIx3^@i(28+T7!JF(P%t%1HW#AW1sJhGS+ztVd(jeh4kSwFVQe?_wG(2CK7$=(4@BKmt{tgYSIfy6n#l6(!4&FH{dFmDf()e+E zZuzQZDyMRorgWzw$eWnmN7GNqkISY?l%nY^A_iJq$@+Fan?`CfPT#&-%lVv|9wAwL zQnw3&`1+hety+dYXaD^*WVa^Yk0JGOI=eEU60O3f zG_86)sYWTXak+R@L|UG$L821dTcoc=?%wurY|(a2a9DC>B&tt2J6X`U#=I((_H$%l zc+yb_{p&P;LWt zVsX{s?D(!8mjIn*OA~)We0*A{&@8-Dsm}AKd45f2nXcXot#$>zlg_~L%66_Ii#QC* z`D=gJt3hh(!rankR0m^`rL>SxxfV`d#02c9E|z5DVUbG zh>%gaM8xEuLxbHG%s{EAU@ew22tZjs+0d*3IIA`gcjj<5z+vp7T_zp=uj<@|iL&sl zz2fIDJ3nb%?Tbbl-2tNNS+X`w-cK|AsLGk6lnkGo_1dCNTOehjc{&D?=5rBwuESM} zyFEV&RWEEmkV^&`7z3{;GJn ziscQ6V_2%_)Y5)AT}L6G97mH1vvnSb6S}S|-nMPnA2N+Ww}pm?%C`7@fI9KVeB*W@ zk?JbcpCFb0{1=RIop(R7_{EVud0E@TlQDUARi(w<7>&p3c0wXGYf?2Kg0JHCSpSyx z2Uo2{BN|{~GJJdlBP}XT@E{YN*iIrKn}CYEd`x<-DXNnhGvl$)z*btzD1Ta6)%bwU z;x2!Z+^=u+d_w0%kB<@vAVk%3eruQ~$o*2e5hOx~SQlZ>&f6)o=^Lk4XqY*;&MNa- zWsf^K`3$)9BB;X`Q(phgc##9g$pT}*$fvM&(|ytUod-a`^KP$bWHfv{sG9JkCKd4F z9)!RS5lHCsy2quxm>cI~? z$n^0Z*W)_2^Gm#0Na8C($D*+v0I)D~CMgk5y={w`^6H6rwPoJSV1z4*_aBS37e2Jl zvu@%vJ8Yk@)~R_dG%CPFh**;CnBRkhTpmjy)kINZTAkunski7l=X!CV$w5XZ-=l|3 z9){fHuvih>x zEqzWmG7(AGv?sdn-=OdS|0!pNhI$8|1fA2AQmoYN3$uEgD-3i@lG) z-Q7f)7U1iun5%>FxDbE0UZP>^`3MSQI4HV$5KxsC5m4@WzGwqy{GqsS!+#H1 zU)CST6pbq)a4MKuCMvaX7?zJ^o^pwYQezPdVvP5PHK^&X#D7HO{9?nbVcr=`Ut!yD z+(GHz4~|BdeAVc3tq<6Edug%rO}GQUL7x^pn?d@r2xGmAeV+$TEAd$@U-_gD^@hNfL+Jr$n_I22Q#mu@Va61>fE89APsYCvb zX@!f2eJSnb*M=A5vuYxtfs9d6g!?vsE&@URiC) zdb@$N1cmew(`Lh6O=WipsaszF>mHZ>Ez^s|rcft$4;ff?Syly%c+3W*p?31i>pw$T z3##*(DiYwZWppfAY5oIFx@;y9?IuoE@q*h_AyZT;gPo~2VqUjSk{adI_s`W#9# z{ICI93H4;819>A&vSvWagG0iS<<6)#Lo1!4eqy{p{e8kT+9h$&bNo!Fj$V(PcRLdu3Qer>%S3n-Sl_*9SD z+dCsbdt(3Ajv#1j(Xl~Q`0@JeX}uu!9E+$JGs9EqcECnd+A5ax1m-}}#nZ<|`psyt zRESzxJkU4U?82SA+;y?Ysype+l5#^ z5#@2b?RK`O6K3mvwtQX4Fi|Z$X*X&4xNc9XW@O7HdFv>Gmb@6F^|@$5`9?(!Bo-!0 zChwa#cG{w)(*@LpGNmGWCUbjWJVkt}I%d+TAqqYr-Sr9mC&tj@%?=D$kZ-25cDoPC zHQAL~ZLB#53%#VebdlHhZSMvf<)C2Q%-df8>IO#MIoFTj%qDr9iYn?*erI*fkj1SaMKv~p<-O4b+}3YHKPxGEumw-`!#eZ z3BHEltvP4=%{r@f0L9AK-D<1Qb!kq8cupY^bnMn+@|BHItJOQK3@? zn;5U}Bb{?HxIu~>6PLYc=feFhuBpZ6ASNbONe|vDEPn{V0KJrXQ!$w+RZ(+(GhYlO zD&uy>Ouy-wyfxjlQ6u^?unJ3jk+b#4{F{jRBeE2&L?EDD3DYT%p}R@jT3&6_Opo3u zA;7$OUIi&x@K6b}1ni3xCl+;k3yq85JO7>dDKZN?{Kvf#4m3QlF3M>p0=SfDK-F6uOK&*a((4Tx%Xn;gXM%?r}5phw%jx_-UM?hB`bXUmzRpE?y zrUdm;!m|kheV7u301g-UD@Qw_Kx)IE=+Nimqx#?C5VOhvF+k40uiI~g>Ww3Q9BroT zgyUn4gXUzML>N$Sa z6xAyI6xcFJFovm$@P3z3bQmIuq;k=0!3#|PruBmaF2)P8${v;c>-dbJ#^YkZXdl*IOn{jXePwsGoH>O zTv;SY6t0~$#N@xH{` z1O?z3MZf0l{TUr!XpxH_SaJ7pxmgtqCx2^hyPM2bHmd~lko=I;&B7hvX=uC;Y+q>L z_)D3tg@cFtMmtm+&gL;?JL`+O_jAGR7K?`1fR`W$0kDH|h%XzU;Ek%WU6;;z7=Sv- zJX9vCdXhN~>l%$f%+8xjJ~}pfb9Z5M+#9ga8rqV53~o=FArxQ|s=mo_lON6TEj}n< zD6TiT&`e6>bbIZ49HjA*>cP+PkU)#%$}pnf3N0w%`^;5=9rW-_!08ZpGf{oBnI z9v_~l?Q?bm29|o7OFxd`PuSJBx*QpeitE$<_IPr(&?5A2g)|#U+f!>P$kfH@VI#}@ zcZwh`g78D}Ojr;9(h}wb3gk}}+MXW}QXGXz;y;-kct&dN-aZS&oG8^b%pAygi|y4J zzpl%k+-N;`AZ`+y+9<}g&UB&* zRiWzWQfN_Bf{HyMkg)KmsJyQ8qGCx3feh<{j3ev^5RRy$;~1OVx6d0p2-t@`3Xuw- ziS~qF_9~5F~jZ6cB`_eThKSHtp0Q^2Qu?vo@8GM(Qu&Z{$z%LNpIs%w=dh;^AjPfbuOnD0vbP30oGFjz(Vd%FpZ zx$|&|aSh6s6=rP|*`qj?u3>K3=rJx|7}ky{c)${KgFJ~02u7Nr+$GJInZwZyOmKh# z5gkf3ExFfHdhM+~2|&nb*y;Pob8zoo=$4t?tH&FB^u=khDXb)oWat7^P7DArlJFZ` z(vkMXy__vXCn>e`Dr4CY1d!47LM@d`0S#q`;-7t~C$E{2iE_FRQev!*nB!7AQvWc_lrp#kn_N@&d(Y8Mj0K8T|fyC3*30$LE@J8(~q)Iz%H`ZP5q^ z^XJ$&XL<*!OqcP#Juilp$)G!Evt$AkiGDWHYFPLzG{{$JYlLH=ruV;_&ZD}C^FH~+ z25xMC*$yqfpOw+dSy+3zZF(wb2Um2YUs`^;OQW9)!Btn2CDyK4m+rCu3br z-`|JDBuEnD=#szzH(N-@!}&cmUDJWNBiRk=^eOnzAZ$U2Bk|j_neFolbH~-7coDrv zp{W>n>syQyt`!V4ZVoLcriyz|$=^1$&zw~-)YVA%pV|bzRsYXQ>jC^EOdH|lSVSp4 z0tjT!7%7{X4x%p_7{K-}{r4QvusyJ*s7>dp(hvriS2Aq6L?#|$_5ajw;n2|& z5p_OIE6sMC0N;hpTadyiNGC*!bPX+iF)mrQ<;#T-tj4 zFWNOS_++XpUkI?QWLYCPE{qGvk%Mu?2ayv$D-~lu4R`<{D4-$?@hYrX2@asgq<$q` zvIBuLk>Qw0fK{5C_lll=2J)04B!P60Q-obA1Qh;rlzuv_9Fq@*`}eDR{)I@Y^Ycaf zt<)aoR9XN)z8IZ}SLN_8Y!pR(aq}$wYSe-R#!Pc~PkVz*t22ysByAP*< zsC_%k|J4i7Bjl&Yx5j=73kd=kC3rhZ?T@Aln8;byc-V#7A$1_z7XG(M|Be%>4A*|^ zo9HC7AaSIa+1YF|#D1Q&Y_O{P5nRZ&ks=BJWSuR}S(Xwg4M8D-Eu%O#J*Iusy@--c z+8(p-jYF?8f&seJcnLf`veka^R+fZW*?!1ICrNhy$Z{QWQH_Mamk6Z{OFXp$2L}M8 z3dDwH?Nl@!n8U38E`GJAiOFwiQ(Apk{%*;i!C};j#f;4YIO7mUBW`izgsT98Qn97# zq5-gaDs_~P!2<~GMBC*%PBwRceo<%^mAP)HeK_;l)J~>8mNc%q-YhuGpk7B2SCqQa z_A{f12P7)^p^~(ie%?3;E)yHt%?{T8#!r*RE^t6){j{@-m$WLv<>DNN_eHK;sW}+J z6pE6Fkwyj>3nkEq0Z^-L?d(m=uBhUgJ-LMeTz)LIUObi_-`H(Vs=I8Yw?AaXeCrWg zWD-Jh(Uudf*R-%IYj}R~uBfkHUcR@eudkS&FGa=3B^+hwk%1)gs7lXVZNFIRvzztQ9PBa4J88m0U@W7hZ=`!PG38G0SNNTIC#g~rI&${674JA)N5Kq?aonjomJ#@gZ?BY8k=cL;;B3 z523qTmwxWgJoAju>Dug=#XH)<%VryDJ)@~R-*OBTC1IIjar>1`x>3m`fe%mX`_ByB z;}1Umtb6A&RCEz|ju;vmDy;kh1@PPUkDs0c^}wdlIZg27?Ag2rPMZiHwrV;rxDq*Q z*;0pl1+P5Ag95^ndBw)J@*+@jWvugJ9?Fmr>1_veGxpVud9>+iNPJ@JAI0^Ir47RqK-xql&m%KL-n-w3zlc`zWN< zex17>;vCnr^+0M)f04wYzx9`;LZx&Ne2Ip44Y2FRwR`SbcD0f!6fh*@l?f$;Qjdf3 zBNE5tuV*p)6Ciq(-8qx`(8nrH-clNs7Q~IaPsA@4M=`w zS!XmGDE~RvO=PR@w(8WipMjw^(hA z&K1>$o3o%InEy(+*nXd#Jh^~eJ|CmeR)u&3jRZ2l_j^Tc>M#yIE#Olrg=8bC6(PeX zz($|$vA2NC=a+vdUk-1^|LO(pi3@3>NbDa(FCUeiWCII0_Ukg_OEnFfFS)js#G*4Z zFLlD-nCE@SIz{7`$`_itKuMVTN}K$0raBGq%@+?MB8_hJ6dZ?wfdPyVN>9HAyb9-l zYDN(}S^9EgNw#QOJ}W~#@Kx=BVF4h6Lg^v5fHfnfrCRvFhoHy%N$d)EEP&8_Js$iv=O=rBt|db{H#?sa9h77oWZX(4)3|vmxUbj% z5*fiH&H@ln_7@1=Z=k_th> z0gC%x!Grr-v7}^f`mn4Vm)#KiiWS}7;Z_F@FQv7_arXYJu&gz5+mGiW!8jqsJ&)?( zX{9bQx3}4e1=^csI{f=3Fh`uT7h6Vg`ZY;?)fJhVY@7k1A~>VKh5wDGcMR{N`@V-K zYS@^KZQHgQ+qTUnZPM6wW7|e!+qP{y>HYovpS;X9Gv{otHM2iwS68m7Gupq^hP~Zo zB;+5Yptz?>jl$}Eq=`O%X9WfU+fsx$QR072N(hd*s!QZEALUzPwkzMbH#($6PR!Bf zva&*^M~@KC)}hG7CW&z2kYK~bJivHy?TT~dn!dwAw9!)PQN!0(v#_AdbhTb)QM5b8 zoajKiLe3RS0Y86_Fdr#vJo~8eSE9Kct^Y@;WEk1wTZET5B(yY-Ui;pwPK0Qq+lahd zx?8OURXu~@S|tXgm^mPjxcfYv>Gr+>vL0o`_g@-9?Ab)mu^@6VUBvxR!a=O~0%*jR zN{8cjDo4i9{&#^8F+-E+VU4(ewb&)^1T9>|3<@~mh~rvE=9nMHK8pbp*nfil6f>|7 zo7|(LBDH_B!wCM1{kfWnQMt!XZE)Lotr+G1)ZvWQ`?=nTri|(3vmQN+JZ6M-TGZ{w z16H^-(toRQp?qnC(&->l0$bp1WFX@7Cx8OXxmG`>?4r2F7O}B%j(&WHP6cHy?y9~r zABIv*sN^y(k^X@wlmzwf#sZ1ZfP*H01>BqQy$1Xm~ z|E~;sI9owe%7-6C#dHw=GX_)+eN_4}D8c`9jwqyu_9?b3Z+>D9<|`A?fB(JR+qz*9 zQj)iG90bIqPat)B%!nw3p^AD4iAN_3(jf&Es6WVoeE#-_-DeoP|pGlMY*Cf4WJ(zR54` z%9w!q!RDf_LO!{fsk*IZDtM+k=O{9^?j|^e;X^qIOcpz{hQU{WdoKUc^Pk_6);yk< ziMp9azMiqXuyrc0yH`CRCkbMzqQJ4O=nj#vGtY?%sId_dsLD6ByS55^cm7_MxXpQz zEgvtp;(zODqbi8|XQtTX#XlHhVBWH~jtlJXl8-AayI?D_EQFXP+RsDG+nQI46X;a< z&?zQ@M#{}5f)4xEH zx!Lf<{;{P#chE1rhK<#wh2>f-AA;EO2Yl`IAhy>HF)mrCG|7> zp5%GOiyo8w~JAJv)>ygNI(!-P&!FG{+>x1Oj*K^n021?z08?FmbDRp z`4h32U%hd1LJ)fL{%w5=bn(IeXjz69fIK`{i_@y2kf|&b#kXRH_q%*#r1n=Vmy}&_ zZ+&iay`ODG#(n+XF74rDZt36i85u1^P-JNDhq*V3BwVad^Tl+37og+F37kXf5)nEc zRt=OIZ{GCqig`(Yjk^7Dln@2s_)USEVo)g}ha0n9_l1{TUT@1P0m{m50RPPTm#!n#LN#qX{$d zKlLRP&y&Pr39LAy)ABOVat?(Pq~;|q>x|EN6#{@{o5xs9-~IBP zG)V78fNRO@b;a#I%GsE&X5o6qEeUOdxz_Un1O+3Nm%D3$v+2!^)f500`91sn%QOh} zYklrZOF#gCv?zC|ZAz|@bw0*I4G&WUNr?@@LRr-UeWuhirZ)M!Rd7JQ72m&A@8|D%Z zZAIBE&+3mIj<>Cm1&JIA8+FfaRVP0+Z#oCshM#2BKP`K z(6}`#ZmXtJqV??T!NHRn{1&pCSs_i?5LYa7;PTX`mh6=LX@RH1ynlJCzda+E|EOjW z9N5@$D>XvdN9V60u!?AY(tqfFSPmNH0VYvFfVL>!9T8$-Kjo$Yo?35iv2S zq>!uI68TD|&4ZUHCqWNle$bD&xj)T@D{ZJ4>b#G+NSJnZ3TaD{k)`iN*5k1tohpSIcASeH~e;FlB3#OxSGxEjopdym} zy>!K5TNEf48v?@R8<4O@0so2f~6_HNJ>b*Z~4)GP}I&^`> zlVG1TJTb@}0-K!QnCgWr5Fge4CWi!o=g33pT&Ww-_vtK}04Hg1KfMBJf~y zmO>M`?4Cdu;LpnMrMyo}@~!t1lXSE#hHn zdHWD0bpoYRE_7k7>q9nF7dIp=8zqlQAq*K#L0m*PjHrZn_UN-$i9@W`CwT1t2QNlO zbkN1ADS)QED~}d}`jO+-t7@TNp{kb2cbyuy!;P-$&)P~lVxRJ+K6#C1@hrr@>)ZAR ze79X}ewZM4?VLHnmL=F@fAD}xdI^_sbC+MkW>cF={W;31z)00IXT|^6Nc^&H>y#Bv z8j)7I?&uM^KvFOo2GP0UUS{-QR(=KmLcKvXoi1N#n;1DARO@0vvgX!&{3-9)N!Pd%-ui zp4I3oU@Y3AE?I^EH>3RS;l7UZHE9#{6W+E+{F7N)(IREGrzoaVGF1J&Tw4QFOcDf` zfEj3XTMV9Zs;$D3ou zg2$k!SGqrAYBpQBNl$dc=cf{pq}*Nh6yL=z`c$=7t`>b)A_0jdaMTsVk#r`wsmGsZ zwY5tjGoJ`0O?iU7b+O5Hv+%L@c4S$5 zy7wOlf=2z%ML+ouJ*9{1Pda;RF_Ba(+|IvF+dm>?Ti+FEuOFj7MKlcYU1wHcCO_FG zQ-=Y78iJ>Ev+-`HWk!we5xG@H^<8j$_A9DxdZ>43Rar-t&z)afJ}_^GA_ua;ExQ8& z!|J&CG0mxp#9>bB#Lh0n=2Qey(oe6d%)t+VM^GqIgtsP$Br$ySp{j~zmB%)9r%!IU zCx3rvLFG`#@La|7&ippU<*8dkj>bx0Qi23RlP6y}b26VBcII9^9z>yZmMEE3ss$fj zcY=a_(@VP0yN;kgHV~hgP^qZQBykw0ZX-jOdsTh7FKX4OIq~}&Kc5@EchiZp@QnMW zq!U?rxX6!ibr#c0h6Hq7aNf)1Ke;2U*C260_Gf2!ZImT!NH82ybnnPCIAjU#i85 zL%K;tOca!g_bcPpr6w#e5kdAVoMNTQB@&3Fl^J^wDf1L8T&X~cOO5Zx;Z*z&%U?9^ z+5uGG^Yx)5Y)pYVf2YowBL!#rgO~wYObsMF}%Bkbg<}e_O~K+Yl{w2 z6y=k;{Uef|aUjM7F3XdMhm2tUr>6~E@)ab)f%C6L_UEifnqMhvv|kQnvpSY1`A0#z zSUa^9aCVj)B{aRv+Cp!hk)oeD?aI^k^=QQGi3v2U?x>aBjtOTJ1FS>=-xxr>XOnt36_~Rn80SMym!p z+;P2>#ONY)o%0=R%ZGEfa$jq?@iGBT^cHEY4d0TU;gM`(^v)*J2CwYxrq0Xv+usag z_8z7DMJunCaR=#0xrF5V=N~Cqv48Ru=lEzB(Tkxk3vrPdj@k*GMnkD+;+{9ImfWZRUN_N+d;m%jt~ zUavu?Khu0!oWukXWkIYSW^GH}AM4q&pz6dNF1Q<|=e`CyKL(KITnl`JA;fErEwbAi zVy?A@iu@&QAhv+-{@=& z{v-W#bcOkjX7c^L78@Qua~160EaBle(sL)W^Azjv)fPrW?k;@JZ-^nw8DW|2K9<5; z>!XH$f}}Cct;nzx=lchJLaq zpMR~v`rWxViGF^O#t+sjrl6?=lw5BeW$&R4e(#$_Lh|*>DAM?H^6hMrI+{CRfRvKE zY_f4R+xdf4?4S7$Q{N(|$Bl=xqi+PJ>s(G}jbZMkRx?3_p#DT5@%dOkRCF%hvjgB1 zJb9Ce^c6piD?U1^b+bT2mZ{abu=5NvWn5Sq!FQ-GG`$4K8Qa&JZP^HnV^eOE9Y+DY9zkd`WB5$xmPt_ zea~uM*-P{O2KV3l8ViXEugYU$#kT$XzIu6j%}EQ+ci*=h8y{V~cnj!XPIWGoc*~7e z67e}MW8Zcn0$%x>iyXqEI_#*miJV@<6_)`lc zwxx!Sn6|Hh{=>deYva8na1K`f!X$jrO3y}F)G<5;20#n#X`!{UA%r_0sbtRmiX`bf zW*=tro16#{Xv0l?*RFUmA6e-vzkkf}@*mN{#Z5x2_|+Z5rZjZ+c=}fu%|s4MpIf}& zm_D_h=(UzM4zdx>0Lrw@dKwX!ZxPwH7N^X zcAtj)ggXofKDRQWQ8v3F8D$k$V)G_{LB#p=hS`qNbXVd==F5@aZe z(KsT_#MTm|q(C;#jFSj5#1z^l^>v8z*b5oinw zxZp9B%?aV>8X*4J55vIf%eOJa~3-hnP{MM46z*+)1O)J z%&zE|^*8(d_jWNK`K`m~gUW7wfzilg_z!oi+D9iTNXc84?<6)8^>^`+>c3cSg@qB; z#q#s9R0=3Cldu4RJ8wpA3@tD?HV{7kV(6$Abir#4n~e1hd&K!;;1HRBl8B*8fRQ=w z;z@RPu;93fK&Tw5K+crz-kmCvyU&Sd^-BA|VPR06Giz-aI`%Hv#hA>DGP_AXdo5l+X&~e^%)P=5~%-d(-_CaRbE+HG~157keqgO?2C0L7C;0GngBy~ zfn6In4*-Cq*cT-#O~F!-HUNke8zB&DzyJbQqy;hXb-mR**8`yPyBgx_&O9pTtkFOO zaM8Ffu#0PxL{8>559{a7EUDj`f-ykMEzjeqZ~D5y^2bve3kyvwY-ELl*Go!xwt@~X z?cN(GNJSx~o?;qpqdm?i@gw6;ald3Eqm!Yp#U>_}qoil<`{=xE*s`<|5)huhe^A$5 zls;dSp3xv6qP~u)B}Lzj?X4|qUC7RtLaoW_=kL<~zg~bazYay?*4B^fT9_oK?Z-sL z0t@hbYepp{iNL_GH&N7Y_vyXn- zu>1dJ#v}N|;RNGyH#zL130|HTA2+eh4`%p09A%2pK+VE#^=%a2pvJTI8K0ltMblcp zXkN$ik9j%2_0zt-u6_R=W7-Qo&CgsBYb*g&&RHEfMcFPN9CP+HE-zO1de@u6DvBbr zbS*_7@kw5W8bi5MWI${!j=bQWY1~xGYhLxmnmoXFzU+1c;RPti#u6-kSv?(6B^n84 zv)gDApPU(4)m=ApE!ba0Y_|#KJn6^uThRB4zy*|H6wyT&vPYP>zG2Yt!n;nMx`Kqq z!zxMWV8YqbbGgXuK5x*6BJ5i}+*kc1vT!+nrnvfeZ&XP`^m(ugQzHJm%SN7x zzSpIm3xwdT;I-8+eZT00^VT(qiHzl9zwMS~j=HnR5e|M~_Gx}KbHlOAxoKJLb@Fu7 z++rqd4cAsSBuMwIT-nQIWeUu8-I_lk>f9Rng8R1e+X8O0lVV88!%1+u;|4VUWIUZ9 zewhOk3_x)E<9T!Tur(9fsV?o?{T&&tY}@-$mBzy(t5ijK%|;Af^W~P|(An~JjOdr& zdTD+eMp)y|KXS2;4<|QY({83=Ky}}AQ>4LlJV)968W~iNtaw%z&dGb6h~{4%C7nNo z|Ckv81Mf2jb9pUhL`N-$j+{Rht`9J|TnzHu-d|1ObX*drbq$-;*-1Y=^LD|`;vI!o znr@~-DEyLtFt?_S2uH7itzll!BQf_W2d<_Hk&DE95`{0=nUIKbVMyWCJtGW#e zoT?!a7}E@E#z4?o#}#qg@201aFWpP3CI%2>HVSzY9J5{?BGiNTcZv9b zL@F62vH&PRrig@CdU-Rd+52Iyn$lYm&d&8nzmVRgz~?KU?LY0b|(u(b!h?XS2U7R||3lQWW@3vH56a zqQ!pq%t_Q3r~RRBt?g?+!sgUFK3){i*9QK_+o^Pg5&((<(bwW=TwUKzF!tmc!BOXq zXx{GwEt)0oOk_KVD^)O1>9wxUtOp>+^V!ANI^6O~rpB(%g~(YHtm=%!BUIq zAX-+7r_W@5`u+DkQxE5_@hVfUz2N15U(tC6&y~2f!9FWHRoj~_nf>Yw7-4IRj;>&0 z?e_Vr!DQ(MzGKwMkt9`o7=A`+WyMiRLsfR$R?2n@d4qvHEYPiiBt0*pW@C%}?KXr7 zEgd~2C8q%!Ql0&P?&PG=#EfR>lMJnKcYz983e8%IHQalVTd`pkvB7hrm~L=VbAVE< zpH{&FfUwPchcDk&L40z1K{sJ1R36v&{F#9IjhBS$LOCHMq-t-U{dx9f9bY0V6Hjl< zspqL^mZuPjRQOO;FIl{-tcTm=4Bc#tSj4x80m#J4admg$#|8w*RlFEQ#vsIm)B7dd zxCqra&4xRAo#^J%7#Z4wid8e*kU~glul5nA0~%?I6LY6l5k6L;!wh8(s;BpH|M6{s zKiXTItVmnfu4AoRH_utRtXA%-OXa2HP$+A|7~B9@Z8T8I`BK-kp9l zI@mAvL7Is4oit6jx-|>jTifu}(73)opo@*+o?bkZ3f)3C|KPR5^S0XQG7kP`eZ&TD zx|{ba8G-HYoA?3DIq$q`3%li53+KjIAiTiKh$t8I#hwTPXakK@qyKP*Xoxc2ZUZMam;c~U8buC!h(#YSd8H~;E}3A*I82}WQ`vbop+ zk-pUv9GcFvcPkLcsB^>{~W4#*$C{97bcD+XWrH^`ZA*uG_W10yW zATt5g*tnFQ7?U8RF9n6e)!Lsfp`OagoV9e1LG0&hR4&%O9rA>gm)|%wJ2RG9|6J0w zqK)=Zo@QNMUv2kr*i=8m;x|3XGj)G%xl=gTUz_CBBJ1_;dvDJ<-HIp^%`6e$KBjw|PAIXQ`2^!8VE!SAPDO(U+obiu2jH>%W#C0o^4>`<1lP;RN zsm0t76lrSKojB(Y1Pn;6PoWSPMM?6kUj3r|Q z%fpo;aFAEOMjF&2#-f#Pfk$QBEowvsqL5;S#JXrmQlEz(E~_+NEx5>;bRAz5V9$aB z{sbdHNwfg6f0MuecXVULp`rlF$Iz=C0l$fC#7tD=GLG^(0+7Y@w+vfRWsz>0xj_?! zFJC5f(RNR2HNxot280{uY&H_vuRxtD_fF#ARlA*upcY&D|hEnSH# zVHGA`y_a`k6&^Jl1S^LSqW#z4B^9n8FFvdnEa>Q?dN=&iJvS|@I9SZ=bkyPwhmEX( zZ#Wd=Zy!C_UbwMj+sowFGvPvd7B3;+X1ZnDA6^Nr){}~knNa9sml<@VBKLdo@fl)< z=c0CxaD*>9mZofic~^Gqbkdj~1pJ2RsBblC*%%Gv_RFKp)yI{tT}vmtD)2@+P*e?U zmU|#W|Ae1j#(zMG(mdUFtod%_Qo8YrK=^ zCoNMCOKtjM|M%k)v_;JH`UZdBX}>iemND>H+P))@aA*&8o!gLh5r~4j3XH7DJImK)_=Pk z)Jr|AO3O;#TIVL2AO{Et=sDR(n{V*XV#V4o-?4tIkV#Dl7pc8xGYHhV+-D?2#^^iR z4mV$!o(172urwMPdx=I1ZX0Vvo8ZX%koIie|8Z)(Z+lw&k?%%IIvNHR)p%3842GQs z(lxbs)sN67eJ&?U^;;!2w%qElmtAuhK|=(HHWm-7ryq5pax~&y6$qO%#`Cdxt-7zJ zAahd{sp+4pRr})K;x@dFSvRWnjrZnRSqSlzcRVq}#(85b;m8Au8xZ4;xIHWV*hFxgDp@>*hyin1vwJId z8%GE$eamwROP?+eSViaBxb`P+%&ME7&7+wq5E_J9EQ z!G`ej7z$4-ML>Mu9&SB;@UT+j5p}zqOSgwinj2n@m77>+V#Lqw zUhnozG!oD_7cLRu`xsoVtS)C3b6+T-B(J%fV{(_Mwbs4!dd=`M)HPi-_}snO!L}t3 zxzyKNs>h3_V)>{?vh3znmyY;u8*5Oo6TtaBr$dtvW}{;VpaK2WjmL>$^em&>`HSO* zj)y+HDdy#7@%^7Z6BoHA-Q38TBaUj4N^TaVWCDW2H4}fYR~MHu#@_Jx*^8jRE9RZn zX6Q0#SU(mu*qDV$LE~{#ONm_2OZ6#fyh2>8Cq?0XRgMnWbdbyRhyB;0Hxuf%_`Dt$ ztjf=3wHAiNtw&L5feh-B=i(k9j^X7qF&~5%Z3GZF>V}V-T`2aIwMA6g&SRNx2*CDb zbhOhzWej+=K|X(rP#kaClZjT%SNUbuT{wYnQFa5`5+D)q(}qBe>a*Y?X+*E?hkTil zs#)Obc3gLQ_U8SwTc44+ARo(P7BQXxK4rpXlhX%FH)COdcXAn3>4n;sJ_8E~P?`TS z-2PEgLs3nvlrBB}IPGYAuY7=)f}%a|K#ojWc~=KoEBArrl8H<&=Pe5uD_qMsYxIwE zr|P_qmXb@GWnvKiEC5USzFCXj@|{UO!251Dks#hPh^UL-eEm92nDZ|qkE{h;PWQK= z!vfYXf17Acvf`2qXaWnbYL`j44xu0iD3 zoPe2JHC`TO)d3rimOsx;H`|@!KPMN!0<~DEF1G%%SHNW2Cv>)-{KYp+Wcy4@>W5HS z73S`rJh0%aUum}<|CRiGf`r?IUZOZ;^9qNvJ2uO+>YEp zWp7hi`pcv^@!crU%J~;u+}#>X)J%wvaIiEaF!;Xn77+34Qj*QZVs~VG!(uB5V3;5tdBXa zCdusi#1w(5Y#zM&hJ2sY{CebKKfR|S;M{yU2O)i4Teu-|$P#4bRnP*JlswuZ&z6O3 zY;HRnda;KzaO~>4n&I-1PTELDdSKmek40N>91FZAKtgJ1EnldAs`2dyr9!M989IpQ-g}t|)?#+QM&{_FHPGemd`9 zo%C{YDxd=Pny=6NG+N3yo*;W*u|#4YF&ND`G!(bvNfjCms{oMWgnaImLqV(H<1q0F zRoC@g^u9I+mqa2F96TsBi>DxClde>bWf49`?%Ah>+Il9RfC@ltfzuzM6*{yM zgS1fNW0PN)dLLR5JKwz|b5Y*Bi$b?Y`?4DW%(!2koh*~`!`LEdR^=|q*Evb zB>T*ia^#8(kF#|m?-r=&e^FD~oc{DdbZM=>#|#B;;fzUp%2*TRRb$!!*b^@_na z9W)7MR8dA2%IAg;Z?z?)lj5w*-x`t&{K)jo~1tk}xtf=RjMv3{W}x z%NRS^xU&OdQBo+2Fcv01GUKN9l@pgJUuB}%@BURwiS7OI=Gpc9mD>*~UNEDPYuvjn z-)#~S*sQ_f-fycQ;H0c;clvXL^;xYl#^!Cg-hJoHSjk5Glek+Ss%ey8Yuk+Uil!~F zwIn<(U2ioaRClP!o^FTW&)yQx`}LP+v})^nSHrC!J?5yKc*j&X?uwQorHOrp2=aAmSx#VzIs>%I0 zp&;@RRD%nC9ngfxjYAhe%r756f6ck2Hq}WZy1NZeTNTeAPQg&VFP!#))HcgN%?UvS z&o#jOCZdY@(Iile85IAj8>3HApNjnYnqp)Q{oNduh4N+fpi(MFC0s}n%J+xSfSe#A zfd_Bvhi6{SvN%QZX&TG|e@ctKi}#7%3I~=1X?eDBry2=`V!jbcBL9m;kODItSb8u< zKg4lffNHU1H@ST-3Qr&x2NSQTMrZp5XX>s99tQ)Iv{J0;7nk#H9-B{kEC^nB(`R;& z9wi=MMq7A*-I&_gW|?WP43+5e$fSt<^lTSbuhWSj>S{G8PzotNh<${7iDeY|jaKmo#;sBU@ z4IHPwUQIbrxkcrAsLj0dq61KR=my^}g$MdIEg)YYZM6GGHGX(8G>Lxd8EFvosPwC% z$%^=N6|uAJpEUH0&>K5;S$%siR)gd}+=^U$MOHRu#2DnH?luFFE8;=fhw*R_LOTtq z@^LJJKP-a`J&*wZ#-fwj4XRxj#V{#3u?T(2Xr-)7B`r@~EyAWRP4-LWM? z08}(|Bqk20Zs;iY{e(sdlpP#f`+8!>hwa>rS_1i+_p`Al6|gq+7VP&zBEHiPp@Dj@ z{d}gX&ps0v98@bO_o=K~L9269FAwTKJQn4Typgqa&iU)plY6b;pSR610Ehi2PMQ=Y zh_&_tRt%Dl9kY*wI~+}OdN=Q>kfXmbGym|p*yB?u)N?-=CCO>*D42#t6-5csw=tGN z%*i`lJKx*Tkzq8+vcu(Sjevz>;-LJF*@sTvDK>`Nk zC}XT;WK~Ns^nDpH!5T%&@Zvw`R$vSQ7P^fFa##EtrtJcMWCH7Nfmls22q0VWNOaPS52NZ7TWykpvKbjaZ1BqoGz1IBzjDwQEjxgNUBQeq&3osumgT$(uFb z>KoV&@Nxo=fk!Be&*LH*+Ps0yn|nQy?&ZUljs=kWD#yns<_G`Ch(cob)WPCY%#wnNa*b5y{M?8E531^C~LJ1{+sAB?cQ|BZT27)q^cWoV84gkxd|3lyGNyKh0>kAe57(XHexy+0N0Gxrek9X(t1LNuH==8yhwua+fDWU?7 zvx*Pe-!Me&a&o995np6>?h{C#W`#>g+&$m{C;$pUEt2D2?!YU`Z~gn3d}r%s1-@}v2Yv1PQR)>W_KVgvhYn6oo(o`H7aC8x zp~2Z596A5-0CDtuVZ!^UT9Th*xA38&s>~%I_&x3`v?;}0A2s502}=sJG&&`G$J{X& z_mi85fM)Wl!UZZhLc36`Q4K8WoK|c4dI&p=WQbI_5%q&6nYOIrPv_?;i*mzv9gR1y zG;S_2am2%IP^W9qW9jhokRVhUDM3oo5HvE%mgTC~wCaQpn}(JS0k-?-r=eP+#W$^I z^>^*=!|+x|v<#mF@iLTKGsB`$w5z~;v9yO>sSMlo2V+2UVTu~rXv@f}JVE5^L?q)0-C+XNGx&@IS=Hr!kze6~v;a$xwVyIhN! zEn{%kgAr=m5Q2qDSVF8*8aWm>M)U8!cW%Dy>~!%Uz|;tLdD&<*qcm}RkpJsmF(V_D z4)^x0!T;+8P>!z1Z*7rIX(Tc@)gux%A<^+N>e+qrLHw2<4&QVh65zk}L(O*O_H`^x zujveB=a-Ai!=nfmh0AV}X0s%pU5z-ZhwZ~fL#O=;dExup6=bmI%LFDmU1OV?*KHNA zqsM;ws$>o2cg;XSLN5+%fAf8l0ORD^5(tfoqnTqh+l|{KJsh_q;R|;QhZ^)QdT73o zyrUUdNkniE-ErT2Ld0jy$y!^!VU(AthQeHbY+JH z>Ippeb76y$T5oSD#UabJ2z+=B{f*qL&svq0qgln=UeZ#iq=zfG}y&}ezfdNI@xf4u>PA`3-{P-NZD5vYy_@>K< znHeRh>1>7b_7nI?-tVgpDMsbOe7ezb7^9i2BX3isw7~bPXNReQ%v?br2Z;&|4OKu3 z9uEHgNgay?i7?fPS2MC&WvLxB=6iAxoz2x%4H=R5dXE4ynR(F_9=_umeq1_|kGmT+ zcTFZiyrpG8M*y-`d$Cn_>{4x|Y?-Y!)|z@DwdS{mw_e@Egg{f#KC%)V*$gtE#AT3L zd~YI>X2a~jBpYryK!wpItIm;y^aWyl#Kn7EITrUbMG^}M=j5tguDFwF=7IlYNZZ8z(@T`unoC+EW@J*4r6;@5=Eks z54VX;O;PZ9os0+Nnd5O#b7DDuKr#OuI101lTvb$G~^Nn7q?sMXt^5p;b)LBS=!Pf=^_nyd@}>!gQ!q=|{HY zd#fj9G|_}jib57n%qo90dQKFAnKjf~CQNM^`yCt#ibOR!YS{@w@v43mP|CUTl&@TK zt69@Z!Y^=9Z{a;gLl|Qq3ATD`=+I>(60O{6W8GuJ^Cu8B%WykIjiqr2*f@g#oi%6y za7iU=>K!I43<8k9a%t*#yGbo1wv?1O$yo;$&;}61e=FF0-VOhgJYVzfbHN5zw+vxh zQs^drSn{L$Ohp6*$#=jA%Y;7RUW>#ARJi87ArP#=pmSNqtWr(o{Mf!_urBT9o!`q1 z3xB|c4(=68o2=aR@2Igxjj>k2Vr0gmf$b)l#mqX}!+ygUZCj)L%zc4uvt+X@B^*3Q zwb6hzmN7E(j#Q}*Ei+sPK6s+>kn40_!Oh20pqttL=&00kirKhRrjmf%sn-Nj#$0ED zx3JXWX-v$igp0h4g_t*4t=qwDMl)5QiDOSL?zps*)L;VT?hehq`BXufEZx-DP@?r% zxKbzvGnQVJSzdFq{oiuw^Ek^>Iz}TE%XHmc45^=P_ocQwD~+&xY%gS-XWLDapITZK|1eH?!TPHPbB1hT-Oh7|BA zlHy^BrvWlL9#Q%LZ|CBLd?zzct0*pa`zM~i58g&9gVhV8hfYq_&ud1t$j^if#{68y z10=VJS;lpC+;jZHdGP~-k_uMw-xZgmOTJ|A)zY}`3VT`y>_Gsa3wf4F8z~0-d`wlH z2+kpHZ{n*V{B_ktg2%h}spqNlPjlDBJ-d*6S^Ex-Q;fcEMv`dkq^_@fkC`(f7GLyk zT2%6&kqJH`g(7TD`;gdyg5PR?kDww^Km<&`tF0!_I=A2s=OyHq~&&0CI zmr+cZY`pu;^%g(@gNi6@>q6}xZ(nBYNj!{Pk$3o%cG90>zZdqeUjDs}DX7&0%S-$U z6I&u4N|r`48(M>{^yS_6wH=pD0UY2dBb%S)5kb`P7oJQ4`U+eH)bXLj0R|Z~V%nA1m`<+Zv#O)V zw6#RvhbOmSf<2{vUV(w?#7Us+cNQBpGDBgffcH#r#s_vg-zNH~t~_{1S6?3NF0-`nT4B06bw5E+6c1r*JPK)N3)o z9|7FW_X6rBpHwuVm~zT~A#+~1eRiHcU(A~Z5FsXf5E;ZU76JGWSMSz($Hl`ED`eXZ zP-w+4or25D``MOMP#wT|QNXb?J>$n)LCw~&M?H90*^_Wwpa8)4p@Ba#UN@`dkI?y1 zW5>tAxKi*MK=9~&;rEcd;{-8MAuUhrE)>oX=qok$pSL8UfE&0)iqqOCsOL9o|2&Tt^D+2uc?tT22NtjE20Dx~Iu(WM zVIshP`sL=Yk@gu9JM15`zFfnQcUOJ@Q!OcuZe%Jq(*svG7PWUCd)rFy)IJDYG{|7@ z>yW0D5Ovj~3FXy@faUk{Cf53wyU3q4@jsa)bTeWOnb{Xw3IZkDE(;9v3tOM}rhe{O zFa}f>c8`UWc=>Ag-#yHpW*`FB7ve9DZ&0p?S$$bc zV3dT->z>%bx#@hkS%$zcz$8R_!c_uM@!%}5LpjlvO(mIsHit;7PQj|=D> z)wB#23nC`mSn3k4l3#o@DZLn+u^X@H^m@MQgcnVzH6ceCnLf(N92a~g1AxmrE|5aS z#A7r^P(aZ!52l^UPX&2U#p>dB>6@01^v$ab^R8y^;_FJ*YM7I?vFb&hU*FU4PU~MN z?x!$}L#ED~*`Laipaa2RG=%tEw2pBp0foNaML$q`W~TJI4BrNfTALruL>NnmxYgR0x1_ZyS5PRhw5}i9e4Igo# zvdSBY;k+kbONr0I`9T?63T=7U7M={EL_(bm*pT_W0&!hh;CbDSXE!WxM92mi!l3{# zuU4_hdubE!--fdjRWtHeV0T97@`9R@q0V}4BH#c6dOlU3gcpL8s{o$`rpBFqu>yYR zM7T;m=pZV!t>meDbxwVjEQ`P(n*Afd;?zLEdhFsxj_0>$yoiBUfuDr~liFti3!BGV z*iWdd?c2V;XeS3BVc&Cm*W>Ew>|L8WKj?&fiQ9P`MJdDb)6D0R2QD zGL9ft(?#@`@d7isY-F)r@T2UKdWO?A#E!|{No}cdVBtv*M4BN@FysxMh9yCBF+WAF zYPkwJoqXuEu~hZ4$_caWAj<{s}sUuUm`b$?)(^7o*CWg5|Y0JA}gy@OllK|@W@#LJ~`&{&}$_!gUG zm2bBGQp~1Sj}@NeB^?}TQu$Kjk*&$BXva5mJ8@J+dEV{Hf*EERlJ`g(9+rV9B$?6q z5hJs@Rk)f$$g>cJj#5JLYsoR4RK=|pkIFCIi~`NvP}dfM-DmYZGe*8|*z5jFD3PE5 zBC=wB%w@Md1qGClyM1!!`BXq;WqUodN9+mD=x`IU`^h5yE#mjIwL`-&*iW)BY4*3WRm_L7{%s&! z1-z%@g4i3dA!hn@B40JFoU~a{Z@X0cpmQT6=N)?b*z0>&edPrc;#0sx*GkB7@cgA1 zAw=w64h&uAdAnp;UjZ=0j<%!H1sUYBhI>XP-i4y6xWq`JvZ-=8@Y99i=)2|b^fwDDjd9$>mLNUBx?sYH2@B=XziBu(MJ&>$YYp|J670>bVK$h{Z zIg^=@sVCQ%!yoOxWX1=!!|0fLdB^WWqOo%HVV<<_j5p19Wih2mP%_D|O}#km{6FwN zvmN4p+0G3AdN|H7QKcVCX%`te-3U)=`}KA~>*J36CqWWFeQA? z9rM98AlN&}qN#0LTb-;vyde@R8)1;hiKM8IJ|YkHer-V*j|fLTWXn zl�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

  • 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

    Zv6k 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�ys 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 YUnFoqUjzao0erat1Rn$e-4p2l0Y~afZvX%Q literal 0 HcmV?d00001 diff --git a/docs/pic/arch-II.png b/docs/pic/arch-II.png new file mode 100644 index 0000000000000000000000000000000000000000..4f04d8fef21615c12a139428819f8c2c36f8a7df GIT binary patch literal 142683 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ÏTu0PuDW{5Kd{utu5!#8{b? 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�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 BA_@Qi literal 0 HcmV?d00001 diff --git a/patch/c-spiffe_patch b/patch/c-spiffe_patch new file mode 100644 index 0000000..d3f52bf --- /dev/null +++ b/patch/c-spiffe_patch @@ -0,0 +1,507 @@ +diff -Nur c-spiffe_orign/cmake/cmake.sh c-spiffe/cmake/cmake.sh +--- c-spiffe_orign/cmake/cmake.sh 1970-01-01 08:00:00.000000000 +0800 ++++ c-spiffe/cmake/cmake.sh 2022-08-29 21:33:28.000000000 +0800 +@@ -0,0 +1,3 @@ ++# cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR .. ++cmake -DCMAKE_BUILD_TYPE=Debug .. ++ +diff -Nur c-spiffe_orign/cmake/config.h.in c-spiffe/cmake/config.h.in +--- c-spiffe_orign/cmake/config.h.in 2022-08-29 22:07:28.600000000 +0800 ++++ c-spiffe/cmake/config.h.in 1970-01-01 08:00:00.000000000 +0800 +@@ -1,24 +0,0 @@ +-/*-*- mode:C; -*- */ +-/* config.h. Generated from build/cmake/config.h.in by cmake configure */ +- +-/* +- * Ensure we have C99-style int64_t, etc, all defined. +- */ +- +-/* First, we need to know if the system has already defined them. */ +-#cmakedefine HAVE_INTMAX_T +-#cmakedefine HAVE_UINTMAX_T +- +-/* Define to `int' if doesn't define. */ +-#cmakedefine pid_t ${pid_t} +- +-/* Define intmax_t and uintmax_t if they are not already defined. */ +-#if !defined(HAVE_INTMAX_T) +-typedef int64_t intmax_t; +-#define INTMAX_MIN INT64_MIN +-#define INTMAX_MAX INT64_MAX +-#endif +- +-#if !defined(HAVE_UINTMAX_T) +-typedef uint64_t uintmax_t; +-#endif +diff -Nur c-spiffe_orign/cmake/COPYING-CMAKE-SCRIPTS.txt c-spiffe/cmake/COPYING-CMAKE-SCRIPTS.txt +--- c-spiffe_orign/cmake/COPYING-CMAKE-SCRIPTS.txt 2022-08-29 22:07:28.600000000 +0800 ++++ c-spiffe/cmake/COPYING-CMAKE-SCRIPTS.txt 1970-01-01 08:00:00.000000000 +0800 +@@ -1,22 +0,0 @@ +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions +-are met: +- +-1. Redistributions of source code must retain the copyright +- notice, this list of conditions and the following disclaimer. +-2. Redistributions in binary form must reproduce the copyright +- notice, this list of conditions and the following disclaimer in the +- documentation and/or other materials provided with the distribution. +-3. The name of the author may not be used to endorse or promote products +- derived from this software without specific prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +diff -Nur c-spiffe_orign/cmake/FindCheck.cmake c-spiffe/cmake/FindCheck.cmake +--- c-spiffe_orign/cmake/FindCheck.cmake 2022-08-29 22:07:28.600000000 +0800 ++++ c-spiffe/cmake/FindCheck.cmake 1970-01-01 08:00:00.000000000 +0800 +@@ -1,57 +0,0 @@ +-# - Try to find the CHECK libraries +-# Once done this will define +-# +-# CHECK_FOUND - system has check +-# CHECK_INCLUDE_DIR - the check include directory +-# CHECK_LIBRARIES - check library +-# +-# This configuration file for finding libcheck is originally from +-# the opensync project. The originally was downloaded from here: +-# opensync.org/browser/branches/3rd-party-cmake-modules/modules/FindCheck.cmake +-# +-# Copyright (c) 2007 Daniel Gollub +-# Copyright (c) 2007 Bjoern Ricks +-# +-# Redistribution and use is allowed according to the terms of the New +-# BSD license. +-# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +- +- +-INCLUDE( FindPkgConfig ) +- +-# Take care about check.pc settings +-PKG_SEARCH_MODULE( CHECK Check ) +- +-# Look for CHECK include dir and libraries +-IF( NOT CHECK_FOUND ) +- IF ( CHECK_INSTALL_DIR ) +- MESSAGE ( STATUS "Using override CHECK_INSTALL_DIR to find Check" ) +- SET ( CHECK_INCLUDE_DIR "${CHECK_INSTALL_DIR}/include" ) +- SET ( CHECK_INCLUDE_DIRS "${CHECK_INCLUDE_DIR}" ) +- FIND_LIBRARY( CHECK_LIBRARY NAMES check PATHS "${CHECK_INSTALL_DIR}/lib" ) +- FIND_LIBRARY( COMPAT_LIBRARY NAMES compat PATHS "${CHECK_INSTALL_DIR}/lib" ) +- SET ( CHECK_LIBRARIES "${CHECK_LIBRARY}" "${COMPAT_LIBRARY}" ) +- ELSE ( CHECK_INSTALL_DIR ) +- FIND_PATH( CHECK_INCLUDE_DIR check.h ) +- FIND_LIBRARY( CHECK_LIBRARIES NAMES check ) +- ENDIF ( CHECK_INSTALL_DIR ) +- +- IF ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) +- SET( CHECK_FOUND 1 ) +- IF ( NOT Check_FIND_QUIETLY ) +- MESSAGE ( STATUS "Found CHECK: ${CHECK_LIBRARIES}" ) +- ENDIF ( NOT Check_FIND_QUIETLY ) +- ELSE ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) +- IF ( Check_FIND_REQUIRED ) +- MESSAGE( FATAL_ERROR "Could NOT find CHECK" ) +- ELSE ( Check_FIND_REQUIRED ) +- IF ( NOT Check_FIND_QUIETLY ) +- MESSAGE( STATUS "Could NOT find CHECK" ) +- ENDIF ( NOT Check_FIND_QUIETLY ) +- ENDIF ( Check_FIND_REQUIRED ) +- ENDIF ( CHECK_INCLUDE_DIR AND CHECK_LIBRARIES ) +-ENDIF( NOT CHECK_FOUND ) +- +-# Hide advanced variables from CMake GUIs +-MARK_AS_ADVANCED( CHECK_INCLUDE_DIR CHECK_LIBRARIES ) +- +diff -Nur c-spiffe_orign/CMakeLists.txt c-spiffe/CMakeLists.txt +--- c-spiffe_orign/CMakeLists.txt 2022-08-29 22:07:28.596000000 +0800 ++++ c-spiffe/CMakeLists.txt 2022-08-29 21:33:28.000000000 +0800 +@@ -28,33 +28,10 @@ + set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + + set(CMAKE_CXX_STANDARD 14) +-set(protobuf_MODULE_COMPATIBLE TRUE) + +-find_package(Protobuf 3.13.0 REQUIRED) +-find_package(gRPC 1.34.0 REQUIRED) + +-message(STATUS "Using protobuf ${Protobuf_VERSION}") ++include(common.cmake) + +-set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) +-set(_REFLECTION gRPC::grpc++_reflection) +- +-if(CMAKE_CROSSCOMPILING) +- find_program(_PROTOBUF_PROTOC protoc) +-else() +- set(_PROTOBUF_PROTOC $) +-endif() +- +-# Find gRPC installation +-# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. +-find_package(gRPC CONFIG REQUIRED) +-message(STATUS "Using gRPC ${gRPC_VERSION}") +- +-set(_GRPC_GRPCPP gRPC::grpc++) +-if(CMAKE_CROSSCOMPILING) +- find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) +-else() +- set(_GRPC_CPP_PLUGIN_EXECUTABLE $) +-endif() + + # Enable Coverage Tests + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -g -O0") +diff -Nur c-spiffe_orign/common.cmake c-spiffe/common.cmake +--- c-spiffe_orign/common.cmake 1970-01-01 08:00:00.000000000 +0800 ++++ c-spiffe/common.cmake 2022-08-29 21:33:28.000000000 +0800 +@@ -0,0 +1,129 @@ ++# Copyright 2018 gRPC authors. ++# ++# Licensed under the Apache License, Version 2.0 (the "License"); ++# you may not use this file except in compliance with the License. ++# You may obtain a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under the License is distributed on an "AS IS" BASIS, ++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++# See the License for the specific language governing permissions and ++# limitations under the License. ++# ++# cmake build file for C++ route_guide example. ++# Assumes protobuf and gRPC have been installed using cmake. ++# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build ++# that automatically builds all the dependencies before building route_guide. ++ ++cmake_minimum_required(VERSION 3.5.1) ++ ++# set (CMAKE_CXX_STANDARD 11) ++set (CMAKE_CXX_STANDARD 14) ++ ++set (GRPC_FETCHCONTENT 1) ++ ++ ++if(MSVC) ++ add_definitions(-D_WIN32_WINNT=0x600) ++endif() ++ ++find_package(Threads REQUIRED) ++ ++if(GRPC_AS_SUBMODULE) ++ # One way to build a projects that uses gRPC is to just include the ++ # entire gRPC project tree via "add_subdirectory". ++ # This approach is very simple to use, but the are some potential ++ # disadvantages: ++ # * it includes gRPC's CMakeLists.txt directly into your build script ++ # without and that can make gRPC's internal setting interfere with your ++ # own build. ++ # * depending on what's installed on your system, the contents of submodules ++ # in gRPC's third_party/* might need to be available (and there might be ++ # additional prerequisites required to build them). Consider using ++ # the gRPC_*_PROVIDER options to fine-tune the expected behavior. ++ # ++ # A more robust approach to add dependency on gRPC is using ++ # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt). ++ ++ # Include the gRPC's cmake build (normally grpc source code would live ++ # in a git submodule called "third_party/grpc", but this example lives in ++ # the same repository as gRPC sources, so we just look a few directories up) ++ add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) ++ message(STATUS "Using gRPC via add_subdirectory.") ++ ++ # After using add_subdirectory, we can now use the grpc targets directly from ++ # this build. ++ set(_PROTOBUF_LIBPROTOBUF libprotobuf) ++ set(_REFLECTION grpc++_reflection) ++ if(CMAKE_CROSSCOMPILING) ++ find_program(_PROTOBUF_PROTOC protoc) ++ else() ++ set(_PROTOBUF_PROTOC $) ++ endif() ++ set(_GRPC_GRPCPP grpc++) ++ if(CMAKE_CROSSCOMPILING) ++ find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) ++ else() ++ set(_GRPC_CPP_PLUGIN_EXECUTABLE $) ++ endif() ++elseif(GRPC_FETCHCONTENT) ++ # Another way is to use CMake's FetchContent module to clone gRPC at ++ # configure time. This makes gRPC's source code available to your project, ++ # similar to a git submodule. ++ message(STATUS "Using gRPC via add_subdirectory (FetchContent).") ++ include(FetchContent) ++ FetchContent_Declare( ++ grpc ++ GIT_REPOSITORY https://github.com/grpc/grpc.git ++ # when using gRPC, you will actually set this to an existing tag, such as ++ # v1.25.0, v1.26.0 etc.. ++ # For the purpose of testing, we override the tag used to the commit ++ # that's currently under test. ++ # GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE) ++ GIT_TAG v1.48.0 ++ ) ++ FetchContent_MakeAvailable(grpc) ++ ++ # Since FetchContent uses add_subdirectory under the hood, we can use ++ # the grpc targets directly from this build. ++ set(_PROTOBUF_LIBPROTOBUF libprotobuf) ++ set(_REFLECTION grpc++_reflection) ++ set(_PROTOBUF_PROTOC $) ++ set(_GRPC_GRPCPP grpc++) ++ if(CMAKE_CROSSCOMPILING) ++ find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) ++ else() ++ set(_GRPC_CPP_PLUGIN_EXECUTABLE $) ++ endif() ++else() ++ # This branch assumes that gRPC and all its dependencies are already installed ++ # on this system, so they can be located by find_package(). ++ ++ # Find Protobuf installation ++ # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation. ++ set(protobuf_MODULE_COMPATIBLE TRUE) ++ find_package(Protobuf CONFIG REQUIRED) ++ message(STATUS "Using protobuf ${Protobuf_VERSION}") ++ ++ set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) ++ set(_REFLECTION gRPC::grpc++_reflection) ++ if(CMAKE_CROSSCOMPILING) ++ find_program(_PROTOBUF_PROTOC protoc) ++ else() ++ set(_PROTOBUF_PROTOC $) ++ endif() ++ ++ # Find gRPC installation ++ # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. ++ find_package(gRPC CONFIG REQUIRED) ++ message(STATUS "Using gRPC ${gRPC_VERSION}") ++ ++ set(_GRPC_GRPCPP gRPC::grpc++) ++ if(CMAKE_CROSSCOMPILING) ++ find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) ++ else() ++ set(_GRPC_CPP_PLUGIN_EXECUTABLE $) ++ endif() ++endif() +diff -Nur c-spiffe_orign/protos/google/protobuf/struct.proto c-spiffe/protos/google/protobuf/struct.proto +--- c-spiffe_orign/protos/google/protobuf/struct.proto 1970-01-01 08:00:00.000000000 +0800 ++++ c-spiffe/protos/google/protobuf/struct.proto 2022-08-29 21:33:28.000000000 +0800 +@@ -0,0 +1,95 @@ ++// Protocol Buffers - Google's data interchange format ++// Copyright 2008 Google Inc. All rights reserved. ++// https://developers.google.com/protocol-buffers/ ++// ++// 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 Google Inc. 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. ++ ++syntax = "proto3"; ++ ++package google.protobuf; ++ ++option csharp_namespace = "Google.Protobuf.WellKnownTypes"; ++option cc_enable_arenas = true; ++option go_package = "google.golang.org/protobuf/types/known/structpb"; ++option java_package = "com.google.protobuf"; ++option java_outer_classname = "StructProto"; ++option java_multiple_files = true; ++option objc_class_prefix = "GPB"; ++ ++// `Struct` represents a structured data value, consisting of fields ++// which map to dynamically typed values. In some languages, `Struct` ++// might be supported by a native representation. For example, in ++// scripting languages like JS a struct is represented as an ++// object. The details of that representation are described together ++// with the proto support for the language. ++// ++// The JSON representation for `Struct` is JSON object. ++message Struct { ++ // Unordered map of dynamically typed values. ++ map fields = 1; ++} ++ ++// `Value` represents a dynamically typed value which can be either ++// null, a number, a string, a boolean, a recursive struct value, or a ++// list of values. A producer of value is expected to set one of these ++// variants. Absence of any variant indicates an error. ++// ++// The JSON representation for `Value` is JSON value. ++message Value { ++ // The kind of value. ++ oneof kind { ++ // Represents a null value. ++ NullValue null_value = 1; ++ // Represents a double value. ++ double number_value = 2; ++ // Represents a string value. ++ string string_value = 3; ++ // Represents a boolean value. ++ bool bool_value = 4; ++ // Represents a structured value. ++ Struct struct_value = 5; ++ // Represents a repeated `Value`. ++ ListValue list_value = 6; ++ } ++} ++ ++// `NullValue` is a singleton enumeration to represent the null value for the ++// `Value` type union. ++// ++// The JSON representation for `NullValue` is JSON `null`. ++enum NullValue { ++ // Null value. ++ NULL_VALUE = 0; ++} ++ ++// `ListValue` is a wrapper around a repeated field of values. ++// ++// The JSON representation for `ListValue` is JSON array. ++message ListValue { ++ // Repeated field of dynamically typed values. ++ repeated Value values = 1; ++} +diff -Nur c-spiffe_orign/spiffetls/CMakeLists.txt c-spiffe/spiffetls/CMakeLists.txt +--- c-spiffe_orign/spiffetls/CMakeLists.txt 2022-08-29 22:07:28.628000000 +0800 ++++ c-spiffe/spiffetls/CMakeLists.txt 2022-08-29 21:33:28.000000000 +0800 +@@ -49,7 +49,7 @@ + + target_link_libraries(${TARGET_NAME} + svid +- ssl ++ # ssl + spiffeid + internal + bundle +@@ -61,7 +61,10 @@ + rt + m + pthread +- crypto) ++ # crypto ++ libcrypto.so ++ libssl.so ++ ) + + # Install Headers: + set(HEADERS_SPIFFETLS +diff -Nur c-spiffe_orign/svid/jwtsvid/parse.c c-spiffe/svid/jwtsvid/parse.c +--- c-spiffe_orign/svid/jwtsvid/parse.c 2022-08-29 22:07:28.632000000 +0800 ++++ c-spiffe/svid/jwtsvid/parse.c 2022-08-29 21:33:28.000000000 +0800 +@@ -85,6 +85,17 @@ + payload_str_len, 0, NULL); + + char *signature = strtok(NULL, dot); ++ ////////////////////////////////////////////////////////////////////// ++ // fjyu@whu.edu.cn debug 2022.07.08 ++ if (signature == NULL) { ++ printf("%s %d: parsed signature is null \n", __FILE__, __LINE__); ++ jwtsvid_JWT_Free(jwt); ++ *err = ERR_PARSING; ++ return NULL; ++ } else { ++ // printf("%s %d: parsed signature is %s \n", __FILE__, __LINE__, signature); ++ } ++ ////////////////////////////////////////////////////////////////////// + signature[-1] = '.'; + jwt->signature = string_new(signature); + free(header_str); +diff -Nur c-spiffe_orign/workload/client.cc c-spiffe/workload/client.cc +--- c-spiffe_orign/workload/client.cc 2022-08-29 22:07:28.636000000 +0800 ++++ c-spiffe/workload/client.cc 2022-08-29 21:33:28.000000000 +0800 +@@ -244,6 +244,7 @@ + return NO_ERROR; + } + ++ + err_t workloadapi_Client_Connect(workloadapi_Client *client) + { + if(!client) { +@@ -252,7 +253,7 @@ + // if client already has a stub, we don't create a new one. + if(!client->stub) { + std::shared_ptr chan = grpc::CreateChannel( +- client->address, grpc::InsecureChannelCredentials()); ++ client->address, grpc::InsecureChannelCredentials()); + if(!chan) { + return ERR_NULL; + } +@@ -737,7 +738,13 @@ + char *token, char *audience, + err_t *err) + { +- grpc::ClientContext ctx; ++ // grpc::ClientContext ctx; ++ grpc::ClientContext *ctx = new grpc::ClientContext(); ++ ++ if(client->headers) { ++ for(int i = 0; i < arrlen(client->headers); i += 2) ++ ctx->AddMetadata(client->headers[i], client->headers[i + 1]); ++ } + + ValidateJWTSVIDRequest req; + req.set_svid(token); +@@ -745,9 +752,10 @@ + + ValidateJWTSVIDResponse resp; + grpc::Status status = ((SpiffeWorkloadAPI::StubInterface *) client->stub) +- ->ValidateJWTSVID(&ctx, req, &resp); +- ++ ->ValidateJWTSVID(ctx, req, &resp); ++ // ->ValidateJWTSVID(&ctx, req, &resp); + if(status.ok()) { ++ // printf("%s %d: workloadapi_Client_ValidateJWTSVID, status ok \n", __FILE__, __LINE__); + // parse response + string_arr_t audiences_array = NULL; + arrput(audiences_array, audience); +@@ -757,6 +765,7 @@ + + return svid; + } else { ++ // printf("%s %d: workloadapi_Client_ValidateJWTSVID, err = %d \n", __FILE__, __LINE__, (int)ERR_BAD_REQUEST); + // could not validate jwt svid + *err = ERR_BAD_REQUEST; + return NULL; +diff -Nur c-spiffe_orign/workload/CMakeLists.txt c-spiffe/workload/CMakeLists.txt +--- c-spiffe_orign/workload/CMakeLists.txt 2022-08-29 22:07:28.636000000 +0800 ++++ c-spiffe/workload/CMakeLists.txt 2022-08-29 21:33:28.000000000 +0800 +@@ -70,7 +70,9 @@ + rt + m + pthread +-crypto) ++# crypto ++libcrypto.so ++) + + + # Install Headers: diff --git a/teeproxy/gpproxy/CMakeLists.txt b/teeproxy/gpproxy/CMakeLists.txt new file mode 100644 index 0000000..2b333c5 --- /dev/null +++ b/teeproxy/gpproxy/CMakeLists.txt @@ -0,0 +1,107 @@ +# +# + +cmake_minimum_required(VERSION 3.5.1) + +project(gpp C CXX) + +include(common.cmake) + +# Proto file +get_filename_component(gt_proto "./protos/gt.proto" ABSOLUTE) +get_filename_component(gt_proto_path "${gt_proto}" PATH) +# [[get_filename_component(proto "../protos/${proto_name}.proto" ABSOLUTE) +# get_filename_component(proto_dir "${proto}" DIRECTORY)]] + +# Generated sources +set(gt_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/gt.pb.cc") +set(gt_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gt.pb.h") +set(gt_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/gt.grpc.pb.cc") +set(gt_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gt.grpc.pb.h") + +add_custom_command( + OUTPUT "${gt_proto_srcs}" "${gt_proto_hdrs}" "${gt_grpc_srcs}" "${gt_grpc_hdrs}" + COMMAND ${_PROTOBUF_PROTOC} + ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" + --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" + -I "${gt_proto_path}" + --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" + "${gt_proto}" + DEPENDS "${gt_proto}" +) + +# Include generated *.pb.h files +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +include_directories(/usr/include/dbus-1.0/) +include_directories(/usr/lib64/dbus-1.0/include/) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include) + +# Introduce variables: +# - CMAKE_INSTALL_LIBDIR +# - CMAKE_INSTALL_BINDIR +# - CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + +# gt_grpc_proto +add_library(gt_grpc_proto + ${gt_grpc_srcs} + ${gt_grpc_hdrs} + ${gt_proto_srcs} + ${gt_proto_hdrs} +) +target_link_libraries(gt_grpc_proto + ${_REFLECTION} + ${_GRPC_GRPCPP} + ${_PROTOBUF_LIBPROTOBUF} +) + + +add_executable(gpproxy + "gpproxy.cc" + ${gt_grpc_srcs} + ${gt_proto_srcs} +) +target_link_libraries(gpproxy + gt_grpc_proto + ${_REFLECTION} + ${_GRPC_GRPCPP} + ${_PROTOBUF_LIBPROTOBUF} + libdbusc_gpw.so + libdbusc_jwt.so + yaml-cpp.a +) + +# Install bin +install( + TARGETS gpproxy + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" +) +# Install config file +set(gpp_config_dir "$ENV{HOME}/.gpp") +install( + FILES "conf/gpproxy_config.yaml" + DESTINATION ${gpp_config_dir} +) +# Install certs +set(gpp_certs_dir "$ENV{HOME}/.gpp/certs") +install( + FILES + "certs/server_key.pem" + "certs/server_crt.pem" + "certs/ca_key.pem" + "certs/ca_crt.pem" + "certs/gen_ca_keycrt.sh" + "certs/gen_server_keycrt.sh" + "certs/gen_client_keycsr.sh" + "certs/msg.txt" + "certs/check_ca_key.sh" + "certs/check_ca_crt.sh" + "certs/check_server_key.sh" + "certs/check_server_crt.sh" + "certs/check_client_key.sh" + "certs/check_client_crt.sh" + "certs/gen_ca_crt.sh" + "certs/gen_server_crt.sh" + "certs/gen_client_crt.sh" + DESTINATION ${gpp_certs_dir} +) diff --git a/teeproxy/gpproxy/build/cmake.sh b/teeproxy/gpproxy/build/cmake.sh new file mode 100644 index 0000000..4511f00 --- /dev/null +++ b/teeproxy/gpproxy/build/cmake.sh @@ -0,0 +1,3 @@ +# cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR .. +cmake -DCMAKE_BUILD_TYPE=Debug .. + diff --git a/teeproxy/gpproxy/certs/ca_crt.pem b/teeproxy/gpproxy/certs/ca_crt.pem new file mode 100644 index 0000000..c1f851a --- /dev/null +++ b/teeproxy/gpproxy/certs/ca_crt.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDozCCAougAwIBAgIUZoRrQX6TrtP0Reyf9DbHVJRNDoQwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1YmVpMQ4wDAYDVQQHDAVXdWhh +bjESMBAGA1UECgwJVHJ1c3RDdXRlMQ0wCwYDVQQLDARnUlBDMQ8wDQYDVQQDDAZj +YS5vcmcwHhcNMjIwODIwMDQ1OTUyWhcNMzIwODE3MDQ1OTUyWjBhMQswCQYDVQQG +EwJDTjEOMAwGA1UECAwFSHViZWkxDjAMBgNVBAcMBVd1aGFuMRIwEAYDVQQKDAlU +cnVzdEN1dGUxDTALBgNVBAsMBGdSUEMxDzANBgNVBAMMBmNhLm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYdYD9GChLzSOWmaIcHMqx8itp/7Zvx +7y2qgb23EWCWIz01kPQaCXpuSOi38dFipXFBWo5o3GaezIoSCp66eN3kHGpcluu2 +0nbyh7zdUVCSXhNWbEiwlhC53DDs2SBYWr2KGTRDEcJEXli110v8sEGZQvkj3XGF +B6IbTczMbhpVfJ82RMqGqNYSJ5jCvqw3XOX6xoN4CP3PuAKC6MtEkLLkXQOS72oL +TSE9XoZNqlyhmymAVwQwCV1zT28W/hwKbCN4tVoO+1bwc3togNYO0W7x1GgOoNoZ +va1UNDX1sfW6B041TgSTGQ0OhGzgKWadKHm2UpG2d5NLkaiBUPpvuokCAwEAAaNT +MFEwHQYDVR0OBBYEFKrFU5qoBe2AkvvTiOfwY24T36zTMB8GA1UdIwQYMBaAFKrF +U5qoBe2AkvvTiOfwY24T36zTMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACjfqOa6G596NbFfAAhBFFS+RIueRWdDkBxR7kk+eQ3Z5j4hIBmrA0OS +R6KCrvmvnXxqSBRmuwRfs0e7G76jkUAFFHkslTPLwgklWCarsGXeAkrdgQU7WL4n +NYBNnjUNK11JREUdAXgvzyuLOhjf4l5UvhujWivhviChFB8xpTQfq2d1oE9jsotv +r2opic4ynu69LXd8HZiShabXgQ60/BNOX8D+wb1YzoZlUCKzSH15QRuuEbkj4/Hy +R2+qxUODbuwfqI4fkOvQIIrD2NO89nHpWFtui4ByQEQaeTesus8M8corCekrxr08 +VkxuOGg2U3zWUlLuSZMD2G7KWuDXU78= +-----END CERTIFICATE----- diff --git a/teeproxy/gpproxy/certs/ca_key.pem b/teeproxy/gpproxy/certs/ca_key.pem new file mode 100644 index 0000000..8a1fb51 --- /dev/null +++ b/teeproxy/gpproxy/certs/ca_key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,39D9C0B289197FF4451BD03C066C8895 + +HZGExFo0mzCidPeXEb1DWkawC2XnTOZfZoHw7+aZGdTXnnbK8x72UuX7CgfyqVrQ +nVgGHJioD/0TpwhhRhgFCs8xPPVmKWIHssgXKz1ZzSHwQSamby/1aGq1bJtVY7VL +qAgUjkMVClErKIiR4ZAAC/Z95BW3ap/K9GmagAFdcGlaiLyXImS/gC3KRxkTZLNn +5Zfq7+XwBp3tWDjM6SLHvYtvsALs2+g8bJUXZFA9OvRZogPnL9EEaTfrjlYBuN2z +0lf2NSQhuAxPN/Qo80l7u6wKIojM+OnWZITbiMit/QmYAEa6znJbt9EWNEYdnIXr +P1NP0zU9ycBDFELNJwZcEUj+Ua9BxPwN01NgBBbPDuFikpyojzcNzm++ZG/uFc5s +LuSYm3lLuhsENVAXx7iwBTBAAWbQxYf8XOP3Nnhj83K/hgL5rfIKMkaFC2+FMvfo +SnIWitAImbn0IB9XncdRkJ9BTOLks/2VOWuVPknNCEGcNEJuL5p/FWCBHQa0eqeT +a84FdLXhN9wSjPaskb8gk+QDSh0L0bTByJC584u2P4Wwb/aJNPzicBBJWVc2DObL +OUYfad1NOvl7uXoe8vRsdYGQOtcUYjfw82MB1855JsuFj7CQwp+ZnO2tu7crnf0Q +v3YL4FAAIHFUi+/w5w6Vp2By86BTApCiStFuSxI+1VabbfpWLk/rtQE9uMTfFLaF +LFQszev4POfEC1u3XegJc+ccYcADxuXseHj07UtCKQkoqAX/lahvOCK2hk2BYQdh +sHtrcJjZqSjDtm4Ec08pfjSKjISVoT5aWlFK0W9RJFsQNoWip7ZIAZwRy8ZPrVOx +bvBiSTYeuwa3Z7J5uGJZKH0Y0zYbwtsWvfIH8jgB+BRSBLQPKqlbPCCSNSfR8iVy +x446hB/a9HONTot5TCDuJ5T12Kw61mTupWGRLzImg6cm+anTXNSHDopTN9eugHE7 +eUvbzzpVYZ1AJduIdPYvzznOYq6T+jbBPiDTg1zUr3R3eLqOBpYJABnDxJlcOyCD +YHL2Ns/EFSMjLm0EyRGNP6a5NdsYljAFqrHMU2MHdj/GqNKWDzdVtMSZXG/1Xui7 +/Iu5xRMPtE7qEudVIupDFfgMzj9hZfM984N6B5exq6ZGMhwlJ/YBB8VpxRuW4Adi +32VTO5nF4M7m71jcOfFmaKz85u2g6RIctEIzJRZ0F4YmI33bj8HPTodV2bmtxd9V +6jipxZ4gO3zuKUsOUnmCkAp3Y9WgPZXsTS3WksFY4+Q3+vjQAlx3xMsTXpi2wKvi +uxYflNKeWPJQzBsdUAhEsffbIN+RTomnZh9ze4nO+8i1B/Hob3mxlTOVzIP6udvc +6NaZV6n42z1cv/X+5mexB74umFkpicMveNpaSGZO43v8ai6gppI4SaO9Wa7T3gWu +d6dchs+/gG0nZWsrq8XZmoEqywxqUEI/OR2dp/298cQYZug+psw4QJ3kXmRwu8qG +l3qjxpFyak64GLGNcfsd4KYOmsAtEZY/EDfVhVG4lexMInxDNMSziBEphocHbQlR +LpxryE9vfZZHOtbQuN1Bp/6KiH3kuVVLMNvIWrik6aeO8xc7vnT6ExKk8PENGo1L +-----END RSA PRIVATE KEY----- diff --git a/teeproxy/gpproxy/certs/check_ca_crt.sh b/teeproxy/gpproxy/certs/check_ca_crt.sh new file mode 100644 index 0000000..83cffa1 --- /dev/null +++ b/teeproxy/gpproxy/certs/check_ca_crt.sh @@ -0,0 +1,42 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the cert expiry date in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +# REGENCRTSCRIPT=${HOME}/gen_ca_crt.sh +CUR_DIR=$( dirname -- "$0"; ) +CACRTPEM=$CUR_DIR/ca_crt.pem +REGENCRTSCRIPT=${CUR_DIR}/gen_ca_crt.sh + +# 7 days in seconds +DAYS="604800" + +# Email settings +_sub=$CACRTPEM" will expire within $DAYS seconds (7 days)" +# _sub="${CACRTPEM} will expire within $DAYS seconds (7 days)" +_from="system-account@your-dommain" +_to="sysadmin@your-domain" + +echo -e '\n'get date of $CACRTPEM: +openssl x509 -in $CACRTPEM -noout -dates + +echo -e '\n'check expiry of $CACRTPEM: +$_openssl x509 -enddate -noout -in "$CACRTPEM" -checkend "$DAYS" +$_openssl x509 -enddate -noout -in "$CACRTPEM" -checkend "$DAYS" | grep -q 'Certificate will expire' +# If will expire, regenerate key and certifcate +# // , and send email +if [ $? -eq 0 ] +then + echo "${_sub}" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${REGENCRTSCRIPT} +fi diff --git a/teeproxy/gpproxy/certs/check_ca_key.sh b/teeproxy/gpproxy/certs/check_ca_key.sh new file mode 100644 index 0000000..4461e1f --- /dev/null +++ b/teeproxy/gpproxy/certs/check_ca_key.sh @@ -0,0 +1,63 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the interity of key in advance +# Author: under license +# ------------------------------------------------------------------------------- + +_openssl="openssl" + + +CUR_DIR=$( dirname -- "$0"; ) + + +# KEYPEM=$HOME/.gpp/certs/ca_key.pem +# PUBPEM=$HOME/.gpp/certs/ca_pubkey.pem +# CRTPEM=$HOME/.gpp/certs/ca_crt.pem +# MSGTXT=$HOME/.gpp/certs/msg.txt +# MSGSIG=$HOME/.gpp/certs/msg.sig +# GENKEYCRTSCRIPT=${HOME}/.gpp/certs/gen_ca_keycrt.sh +KEYPEM=$CUR_DIR/ca_key.pem +PUBPEM=$CUR_DIR/ca_pubkey.pem +CRTPEM=$CUR_DIR/ca_crt.pem +MSGTXT=${CUR_DIR}/msg.txt +MSGSIG=${CUR_DIR}/msg.sig +GENKEYCRTSCRIPT=${CUR_DIR}/gen_ca_keycrt.sh + +echo -e '\n'check integrity of ${KEYPEM}: +# ${_openssl} rsa -in ${KEYPEM} -passin pass:111111 -check -noout +# ${_openssl} rsa -in ${KEYPEM} -check -noout +${_openssl} rsa -in ${KEYPEM} -check -noout | grep -q 'RSA key ok' +if [ $? -ne 0 ] +then + echo "the integrity of "${KEYPEM}" is broken" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +else + echo -e "RSA key ok" +fi + +echo -e '\n'use private ${KEYPEM} to sign ${MSGTXT}: +# ${_openssl} dgst -sha256 -sign ${KEYPEM} -passin pass:111111 -out msg.sig msg.txt +${_openssl} dgst -sha256 -sign ${KEYPEM} -out ${MSGSIG} ${MSGTXT} + +echo -e '\n'get public key from ${CRTPEM}: +${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + +echo -e '\n'use public key in ${CRTPEM} to verify signature of ${MSGTXT}: +# ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} | grep -q 'Verified OK' +if [ $? -ne 0 ] +then + echo ${KEYPEM}" is not matched with "${CRTPEM} + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +fi +rm -f ${PUBPEM} diff --git a/teeproxy/gpproxy/certs/check_client_crt.sh b/teeproxy/gpproxy/certs/check_client_crt.sh new file mode 100644 index 0000000..769041a --- /dev/null +++ b/teeproxy/gpproxy/certs/check_client_crt.sh @@ -0,0 +1,43 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the cert expiry date in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# CRTPEM=$HOME/.gpp/certs/client_crt.pem +# REGENCRTSCRIPT=${HOME}/gen_client_crt.sh +CUR_DIR=$( dirname -- "$0"; ) +CRTPEM=$CUR_DIR/client_crt.pem +REGENCRTSCRIPT=${CUR_DIR}/gen_client_crt.sh + +# 7 days in seconds +DAYS="604800" + +# Email settings +_sub=$CRTPEM" will expire within $DAYS seconds (7 days)" +# _sub="${CRTPEM} will expire within $DAYS seconds (7 days)" +_from="system-account@your-dommain" +_to="sysadmin@your-domain" + + +echo -e '\n'get date of $CRTPEM: +openssl x509 -in $CRTPEM -noout -dates + +echo -e '\n'check expiry of $CRTPEM: +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" | grep -q 'Certificate will expire' +# If will expire, regenerate key and certifcate +# // , and send email +if [ $? -eq 0 ] +then + echo "${_sub}" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${REGENCRTSCRIPT} +fi diff --git a/teeproxy/gpproxy/certs/check_client_key.sh b/teeproxy/gpproxy/certs/check_client_key.sh new file mode 100644 index 0000000..c62d32c --- /dev/null +++ b/teeproxy/gpproxy/certs/check_client_key.sh @@ -0,0 +1,62 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the interity of key in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# KEYPEM=$HOME/.gpp/certs/client_key.pem +# PUBPEM=$HOME/.gpp/certs/client_pubkey.pem +# CRTPEM=$HOME/.gpp/certs/client_crt.pem +# MSGTXT=$HOME/.gpp/certs/msg.txt +# MSGSIG=$HOME/.gpp/certs/msg.sig +# GENKEYCRTSCRIPT=${HOME}/.gpp/certs/gen_client_keycrt.sh +CUR_DIR=$( dirname -- "$0"; ) +KEYPEM=$CUR_DIR/client_key.pem +PUBPEM=$CUR_DIR/client_pubkey.pem +CRTPEM=$CUR_DIR/client_crt.pem +MSGTXT=${CUR_DIR}/msg.txt +MSGSIG=${CUR_DIR}/msg.sig +GENKEYCRTSCRIPT=${CUR_DIR}/gen_client_keycrt.sh + +echo -e '\n'check integrity of ${KEYPEM}: +# ${_openssl} rsa -in ${KEYPEM} -passin pass:111111 -check -noout +# ${_openssl} rsa -in ${KEYPEM} -check -noout +${_openssl} rsa -in ${KEYPEM} -check -noout | grep -q 'RSA key ok' +if [ $? -ne 0 ] +then + echo "the integrity of "${KEYPEM}" is broken" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +else + echo -e "RSA key ok" +fi + +echo -e '\n'use private ${KEYPEM} to sign ${MSGTXT}: +# ${_openssl} dgst -sha256 -sign ${KEYPEM} -passin pass:111111 -out msg.sig msg.txt +${_openssl} dgst -sha256 -sign ${KEYPEM} -out ${MSGSIG} ${MSGTXT} + +echo -e '\n'get public key from ${CRTPEM}: +${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + +echo -e '\n'use public key in ${CRTPEM} to verify signature of ${MSGTXT}: +# ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} | grep -q 'Verified OK' +if [ $? -ne 0 ] +then + echo ${KEYPEM}" is not matched with "${CRTPEM} + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +fi +rm -f ${PUBPEM} diff --git a/teeproxy/gpproxy/certs/check_server_crt.sh b/teeproxy/gpproxy/certs/check_server_crt.sh new file mode 100644 index 0000000..acedfce --- /dev/null +++ b/teeproxy/gpproxy/certs/check_server_crt.sh @@ -0,0 +1,43 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the cert expiry date in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# CRTPEM=$HOME/.gpp/certs/server_crt.pem +# REGENCRTSCRIPT=${HOME}/gen_server_crt.sh +CUR_DIR=$( dirname -- "$0"; ) +CRTPEM=$CUR_DIR/server_crt.pem +REGENCRTSCRIPT=${CUR_DIR}/gen_server_crt.sh + +# 7 days in seconds +DAYS="604800" + +# Email settings +_sub=$CRTPEM" will expire within $DAYS seconds (7 days)" +# _sub="${CRTPEM} will expire within $DAYS seconds (7 days)" +_from="system-account@your-dommain" +_to="sysadmin@your-domain" + + +echo -e '\n'get date of $CRTPEM: +openssl x509 -in $CRTPEM -noout -dates + +echo -e '\n'check expiry of $CRTPEM: +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" | grep -q 'Certificate will expire' +# If will expire, regenerate key and certifcate +# // , and send email +if [ $? -eq 0 ] +then + echo "${_sub}" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${REGENCRTSCRIPT} +fi diff --git a/teeproxy/gpproxy/certs/check_server_key.sh b/teeproxy/gpproxy/certs/check_server_key.sh new file mode 100644 index 0000000..9445f55 --- /dev/null +++ b/teeproxy/gpproxy/certs/check_server_key.sh @@ -0,0 +1,62 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the interity of key in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# KEYPEM=$HOME/.gpp/certs/server_key.pem +# PUBPEM=$HOME/.gpp/certs/server_pubkey.pem +# CRTPEM=$HOME/.gpp/certs/server_crt.pem +# MSGTXT=$HOME/.gpp/certs/msg.txt +# MSGSIG=$HOME/.gpp/certs/msg.sig +# GENKEYCRTSCRIPT=${HOME}/.gpp/certs/gen_server_keycrt.sh +CUR_DIR=$( dirname -- "$0"; ) +KEYPEM=$CUR_DIR/server_key.pem +PUBPEM=$CUR_DIR/server_pubkey.pem +CRTPEM=$CUR_DIR/server_crt.pem +MSGTXT=${CUR_DIR}/msg.txt +MSGSIG=${CUR_DIR}/msg.sig +GENKEYCRTSCRIPT=${CUR_DIR}/gen_server_keycrt.sh + +echo -e '\n'check integrity of ${KEYPEM}: +# ${_openssl} rsa -in ${KEYPEM} -passin pass:111111 -check -noout +# ${_openssl} rsa -in ${KEYPEM} -check -noout +${_openssl} rsa -in ${KEYPEM} -check -noout | grep -q 'RSA key ok' +if [ $? -ne 0 ] +then + echo "the integrity of "${KEYPEM}" is broken" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +else + echo -e "RSA key ok" +fi + +echo -e '\n'use private ${KEYPEM} to sign ${MSGTXT}: +# ${_openssl} dgst -sha256 -sign ${KEYPEM} -passin pass:111111 -out msg.sig msg.txt +${_openssl} dgst -sha256 -sign ${KEYPEM} -out ${MSGSIG} ${MSGTXT} + +echo -e '\n'get public key from ${CRTPEM}: +${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + +echo -e '\n'use public key in ${CRTPEM} to verify signature of ${MSGTXT}: +# ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} | grep -q 'Verified OK' +if [ $? -ne 0 ] +then + echo ${KEYPEM}" is not matched with "${CRTPEM} + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +fi +rm -f ${PUBPEM} diff --git a/teeproxy/gpproxy/certs/gen_ca_crt.sh b/teeproxy/gpproxy/certs/gen_ca_crt.sh new file mode 100644 index 0000000..267cac5 --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_ca_crt.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# CAKEYPEM=$HOME/.gpp/certs/ca_key.pem +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +CAKEYPEM=$CUR_DIR/ca_key.pem +CACRTPEM=$CUR_DIR/ca_crt.pem +RSAKEYLEN=2048 +EXPIREDAYS=3650 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=ca.org" + +# echo -e '\n'generate $CAKEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $CAKEYPEM ${RSAKEYLEN} +# $_openssl genrsa -aes192 -out $CAKEYPEM ${RSAKEYLEN} + +echo -e '\n'generate $CACRTPEM: +# $_openssl req -passin pass:111111 -new -x509 -days 3650 -key $CAKEYPEM -out $CACRTPEM -subj ${SUBSTR} +$_openssl req -new -x509 -days ${EXPIREDAYS} -key $CAKEYPEM -out $CACRTPEM -subj ${SUBSTR} diff --git a/teeproxy/gpproxy/certs/gen_ca_keycrt.sh b/teeproxy/gpproxy/certs/gen_ca_keycrt.sh new file mode 100644 index 0000000..5110ba9 --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_ca_keycrt.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# CAKEYPEM=$HOME/.gpp/certs/ca_key.pem +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +CAKEYPEM=$CUR_DIR/ca_key.pem +CACRTPEM=$CUR_DIR/ca_crt.pem +RSAKEYLEN=2048 +EXPIREDAYS=3650 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=ca.org" + +echo -e '\n'generate $CAKEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $CAKEYPEM ${RSAKEYLEN} +$_openssl genrsa -aes192 -out $CAKEYPEM ${RSAKEYLEN} + +echo -e '\n'generate $CACRTPEM: +# $_openssl req -passin pass:111111 -new -x509 -days 3650 -key $CAKEYPEM -out $CACRTPEM -subj ${SUBSTR} +$_openssl req -new -x509 -days ${EXPIREDAYS} -key $CAKEYPEM -out $CACRTPEM -subj ${SUBSTR} diff --git a/teeproxy/gpproxy/certs/gen_client_crt.sh b/teeproxy/gpproxy/certs/gen_client_crt.sh new file mode 100644 index 0000000..8bfa94f --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_client_crt.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# CAKEYPEM=$HOME/.gpp/certs/ca_key.pem +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +# CSRPEM=$HOME/.gpp/certs/client_csr.pem +# CRTPEM=$HOME/.gpp/certs/client_crt.pem +CAKEYPEM=$CUR_DIR/ca_key.pem +CACRTPEM=$CUR_DIR/ca_crt.pem +CSRPEM=$CUR_DIR/client_csr.pem +CRTPEM=$CUR_DIR/client_crt.pem +RSAKEYLEN=2048 +EXPIREDAYS=3650 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=gpclient.org" + +echo -e '\n'generate $CRTPEM: +# ${_openssl} x509 -req -passin pass:111111 -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM +${_openssl} x509 -req -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM diff --git a/teeproxy/gpproxy/certs/gen_client_keycsr.sh b/teeproxy/gpproxy/certs/gen_client_keycsr.sh new file mode 100644 index 0000000..cbf8077 --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_client_keycsr.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# KEYPEM=$HOME/.teecc/certs/client_key.pem +# CSRPEM=$HOME/.teecc/certs/client_csr.pem +KEYPEM=$CUR_DIR/client_key.pem +CSRPEM=$CUR_DIR/client_csr.pem +RSAKEYLEN=2048 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=gpclient.org" + +echo -e '\n'generate $KEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $KEYPEM ${RSAKEYLEN} +$_openssl genrsa -aes192 -out $KEYPEM ${RSAKEYLEN} + +echo -e '\n'generate certgen request $CSRPEM: +# $_openssl req -passin pass:111111 -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} +$_openssl req -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} + diff --git a/teeproxy/gpproxy/certs/gen_server_crt.sh b/teeproxy/gpproxy/certs/gen_server_crt.sh new file mode 100644 index 0000000..56399b0 --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_server_crt.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# CAKEYPEM=$HOME/.gpp/certs/ca_key.pem +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +# KEYPEM=$HOME/.gpp/certs/server_key.pem +# CSRPEM=$HOME/.gpp/certs/server_csr.pem +# CRTPEM=$HOME/.gpp/certs/server_crt.pem +CAKEYPEM=$CUR_DIR/ca_key.pem +CACRTPEM=$CUR_DIR/ca_crt.pem +KEYPEM=$CUR_DIR/server_key.pem +CSRPEM=$CUR_DIR/server_csr.pem +CRTPEM=$CUR_DIR/server_crt.pem +RSAKEYLEN=2048 +EXPIREDAYS=3650 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=gpserver.org" + +# echo -e '\n'generate $KEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $KEYPEM ${RSAKEYLEN} +# $_openssl genrsa -aes192 -out $KEYPEM ${RSAKEYLEN} + +echo -e '\n'generate certgen request $CSRPEM: +# $_openssl req -passin pass:111111 -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} +$_openssl req -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} + +echo -e '\n'generate $CRTPEM: +# ${_openssl} x509 -req -passin pass:111111 -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM +${_openssl} x509 -req -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM diff --git a/teeproxy/gpproxy/certs/gen_server_keycrt.sh b/teeproxy/gpproxy/certs/gen_server_keycrt.sh new file mode 100644 index 0000000..977c6fd --- /dev/null +++ b/teeproxy/gpproxy/certs/gen_server_keycrt.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# CAKEYPEM=$HOME/.gpp/certs/ca_key.pem +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +# KEYPEM=$HOME/.gpp/certs/server_key.pem +# CSRPEM=$HOME/.gpp/certs/server_csr.pem +# CRTPEM=$HOME/.gpp/certs/server_crt.pem +CAKEYPEM=$CUR_DIR/ca_key.pem +CACRTPEM=$CUR_DIR/ca_crt.pem +KEYPEM=$CUR_DIR/server_key.pem +CSRPEM=$CUR_DIR/server_csr.pem +CRTPEM=$CUR_DIR/server_crt.pem +RSAKEYLEN=2048 +EXPIREDAYS=3650 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=gpserver.org" + +echo -e '\n'generate $KEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $KEYPEM ${RSAKEYLEN} +$_openssl genrsa -aes192 -out $KEYPEM ${RSAKEYLEN} + +echo -e '\n'generate certgen request $CSRPEM: +# $_openssl req -passin pass:111111 -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} +$_openssl req -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} + +echo -e '\n'generate $CRTPEM: +# ${_openssl} x509 -req -passin pass:111111 -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM +${_openssl} x509 -req -days ${EXPIREDAYS} -in $CSRPEM -CA $CACRTPEM -CAkey $CAKEYPEM -CAcreateserial -out $CRTPEM diff --git a/teeproxy/gpproxy/certs/msg.txt b/teeproxy/gpproxy/certs/msg.txt new file mode 100644 index 0000000..93388ad --- /dev/null +++ b/teeproxy/gpproxy/certs/msg.txt @@ -0,0 +1 @@ +verify the integrity of a certificate and private key pair diff --git a/teeproxy/gpproxy/certs/server_crt.pem b/teeproxy/gpproxy/certs/server_crt.pem new file mode 100644 index 0000000..7c4aef6 --- /dev/null +++ b/teeproxy/gpproxy/certs/server_crt.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTzCCAjcCFD3UsYh/aU1yUsNsej6x2MjHaxBNMA0GCSqGSIb3DQEBCwUAMGEx +CzAJBgNVBAYTAkNOMQ4wDAYDVQQIDAVIdWJlaTEOMAwGA1UEBwwFV3VoYW4xEjAQ +BgNVBAoMCVRydXN0Q3V0ZTENMAsGA1UECwwEZ1JQQzEPMA0GA1UEAwwGY2Eub3Jn +MB4XDTIyMDgyMDA1MDAwN1oXDTMyMDgxNzA1MDAwN1owZzELMAkGA1UEBhMCQ04x +DjAMBgNVBAgMBUh1YmVpMQ4wDAYDVQQHDAVXdWhhbjESMBAGA1UECgwJVHJ1c3RD +dXRlMQ0wCwYDVQQLDARnUlBDMRUwEwYDVQQDDAxncHNlcnZlci5vcmcwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGXHn+5sLRKB2RUG3PF+rzLbCVfrfW +2Lgq6PB11M0Qg7+yHCKuZJPZYo1M4DyAjVaF/h24IMr7Vg5j/MqVjwW2Q84DMkmI +WkaHgo+7bqfZ2fIOlrRiUo9ilALRDL2S/NJfRF2Z5e6lu4XvchjnRpC+Pu3YrxhB ++2LJ7F061OyKal5ylXfbb0+/TE4zM30nrJR8R4OvPeQvrmea//s5m1DLy6p5R6ZJ +YZH33xRo2zCYLmID6RwHChJHQX6f48e2u2nqXk20Q6wIrBh5jY2ATL3l6b/mqZ5K +U0IdzrPPGrtUz9hiT8H0tnjarnvIp6ffEqx9cBAulNocIAfBSAiOK2zfAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBACS+qheuLHDKewqkyFBoDOy4T16b7ula9oRl0NsZ +Veh7jiu6BT5xcAbSUIAS5oxlhGb+CEzwMHT9r5D5ZBmSk6MWeG8my5SfWq7GKa6Y +DsjwNM2Wm0lM9brQZObr4BWorSYhHz6rfiSc5IfpiDPe7wluTJX0RuHUsp2rbjwO +EPdiEISQYu8ugMbMc8uyTV9L0/3X9Hy210FDIgZ+B9Z7udqsgZkQ/DjmWITXpgd5 +1T8O91v3lp9LuFKv2PvzlD6h3fSc5ITlRqlzY52ql3Xece7jfNCpDsuGEWO00//q +x3hM5EYI8qp0FCLvfxD16TBIq34yCXq3NmdinGc/1PGulLU= +-----END CERTIFICATE----- diff --git a/teeproxy/gpproxy/certs/server_key.pem b/teeproxy/gpproxy/certs/server_key.pem new file mode 100644 index 0000000..be30821 --- /dev/null +++ b/teeproxy/gpproxy/certs/server_key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,FE8794441B351ACA7569D5F49605C874 + +YYmoW3nUds/a4CumjFwyZEyXcT5qVXOX3nxpFKnAQRu0oA83CmyLPxxKksKfpmu5 +RbTFCS06XP+1jKpnP7Bx9gT31WdfMdwlb1xQaQJkxWBqAQZNPdUHoY2aiyqy7Mzt +j5P6wmFdVsauOnfvh+lcIDP6AjxGfsLtqTXe7JXtxyR+VVXlNcyRewwRfcy5eEUT +OnSfcsgY9lgHkUT2gbzttvmUfWWhCHU4U+IMpC1pGFZx5njJV/pkKXNzESvoYmeb +PrKu0PN9oKg8i0Iina3/G5/uiRgUl3+EfhpUm2XtTXimNeVJ/s4/9yB/ysFIrura +QqzFMVxyMESD+eoGrcelX1Ow0bj8JKMzGvcQNRIE9dHuZ8htyhd5QV3N7jKzEiAE +wDoQdvOHzhblepibm0pfndi6BTy7tSRYC3wINF2e8rmxoMSVT+jIfTnpRG4finj+ +0ZTFHoDCyitgqvEAztG9+b4gel3lK5Xm1CayyGkBoFLDhl3iWlUIfDkd2mEaUyjf +N/mjs/AXZKZCT9ApNm6X2hzVrNPZBbOgTPdeQfstVJjxj4heCGn/kn2wciEpmZPG +geXAh357+wGngs+kzAy0p/nso1Lp2fYUui3uh5o8Acbc0/D1b1ysWyxvlE3vtkJ3 +uXqz3hgJNFmLLOk1/K8akGnQd9Hc15pQrNoE6of5w9FvkO7r3pIMNOptJDlz/ogj +Jn2TP2UJGC6EwCSJM+lUxum6BKt6nz+4n8Sl8aPGiBpr4tQIrEodWRHsixd+Vy6u +yUffB0DfL41X28O7bGOIpdhcIQG25mE65/idMoTYAtrvExQymZjCCBsbzlBiQcwk +4bzA+Wv5tCWyJjwJKJBKSYFBVcNf3P9micB5YDyIcpDmgwqYZxo5KAj4K4Fmm7er +hYMA+Jzd3SYemH/lUSDSlK438bv9d7P7qIm27QC6TngKW9or4b2F/gDy7iYjXm5Q +Gk7C39xTlIUwSQR/WMVCG8MhkkamuDWTiaj9BEydO8VeIQf7jWEsY5ShGTr+VxtI +3SeUjkmD6whqRrKJBgdlIINuBUpB8dVzVufchhtR9GNPqCWdaMFquVK1JcgWISb6 +LuXAGPmumhFER4oK7xmITmlIRxjgXkld5Qcj9wzmmISO7ChxCWhXKNd/fabPRrO1 +gNO2C41/JbNoshF9qZfyR/0uVJZGLFy+/YsHh0Hk6s7o+g1SxpWYc2QG1fcvPvIS +vPI/I0+J8MUzL0BjdJf8lb/A2kCGRRn2P7AfGiUsbkGT3lnshudWQDe+sEdxJpm4 +OcrFpbyghiJuxYoE6LwDb2wgMbujsHDccL8eKpBvdlqcxU48dl3sF1C6rTjFgRPT +KI8KMcyWxVNfjYn1pMPPLkz3TEQd/mwu8g7yU2JAe3oH79pZE5Qdjji5uPRXSqF/ +c2FAFH10cyct5UISeMofFnECecx7XbxaurjiDQ0wCzcKZ1aO07XIyfLtWoQZHFOi +UlceygZQgISxsofxNLXfx4mur1yI6snOg/BH8dBKzmi7UvaffGv1o0U4JMAGavXT +DyZPod78wf3DImX/FQT1QVCVXH11igUUQl0RrHUc0y+dAKxxFxevSmedNP++wkNm +-----END RSA PRIVATE KEY----- diff --git a/teeproxy/gpproxy/changelog.md b/teeproxy/gpproxy/changelog.md new file mode 100644 index 0000000..f66c4e1 --- /dev/null +++ b/teeproxy/gpproxy/changelog.md @@ -0,0 +1,7 @@ +# 更新日志 + +## [1.0.0] - 2022-10-11 + +### 新增 + +* 项目初始化,上传第一版 diff --git a/teeproxy/gpproxy/common.cmake b/teeproxy/gpproxy/common.cmake new file mode 100644 index 0000000..62099c5 --- /dev/null +++ b/teeproxy/gpproxy/common.cmake @@ -0,0 +1,129 @@ +# Copyright 2018 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# cmake build file for C++ route_guide example. +# Assumes protobuf and gRPC have been installed using cmake. +# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build +# that automatically builds all the dependencies before building route_guide. + +cmake_minimum_required(VERSION 3.5.1) + +# set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD 14) + +set (GRPC_FETCHCONTENT 1) + + +if(MSVC) + add_definitions(-D_WIN32_WINNT=0x600) +endif() + +find_package(Threads REQUIRED) + +if(GRPC_AS_SUBMODULE) + # One way to build a projects that uses gRPC is to just include the + # entire gRPC project tree via "add_subdirectory". + # This approach is very simple to use, but the are some potential + # disadvantages: + # * it includes gRPC's CMakeLists.txt directly into your build script + # without and that can make gRPC's internal setting interfere with your + # own build. + # * depending on what's installed on your system, the contents of submodules + # in gRPC's third_party/* might need to be available (and there might be + # additional prerequisites required to build them). Consider using + # the gRPC_*_PROVIDER options to fine-tune the expected behavior. + # + # A more robust approach to add dependency on gRPC is using + # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt). + + # Include the gRPC's cmake build (normally grpc source code would live + # in a git submodule called "third_party/grpc", but this example lives in + # the same repository as gRPC sources, so we just look a few directories up) + add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) + message(STATUS "Using gRPC via add_subdirectory.") + + # After using add_subdirectory, we can now use the grpc targets directly from + # this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $) + endif() + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +elseif(GRPC_FETCHCONTENT) + # Another way is to use CMake's FetchContent module to clone gRPC at + # configure time. This makes gRPC's source code available to your project, + # similar to a git submodule. + message(STATUS "Using gRPC via add_subdirectory (FetchContent).") + include(FetchContent) + FetchContent_Declare( + grpc + GIT_REPOSITORY https://github.com/grpc/grpc.git + # when using gRPC, you will actually set this to an existing tag, such as + # v1.25.0, v1.26.0 etc.. + # For the purpose of testing, we override the tag used to the commit + # that's currently under test. + # GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE + GIT_TAG v1.48.0 + ) + FetchContent_MakeAvailable(grpc) + + # Since FetchContent uses add_subdirectory under the hood, we can use + # the grpc targets directly from this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + set(_PROTOBUF_PROTOC $) + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +else() + # This branch assumes that gRPC and all its dependencies are already installed + # on this system, so they can be located by find_package(). + + # Find Protobuf installation + # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation. + set(protobuf_MODULE_COMPATIBLE TRUE) + find_package(Protobuf CONFIG REQUIRED) + message(STATUS "Using protobuf ${Protobuf_VERSION}") + + set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) + set(_REFLECTION gRPC::grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $) + endif() + + # Find gRPC installation + # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. + find_package(gRPC CONFIG REQUIRED) + message(STATUS "Using gRPC ${gRPC_VERSION}") + + set(_GRPC_GRPCPP gRPC::grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +endif() diff --git a/teeproxy/gpproxy/conf/gpproxy_config.yaml b/teeproxy/gpproxy/conf/gpproxy_config.yaml new file mode 100644 index 0000000..978cc84 --- /dev/null +++ b/teeproxy/gpproxy/conf/gpproxy_config.yaml @@ -0,0 +1,19 @@ +GPPROXY_ADDRESS: "[::]:50051" + +NAME_SERVER_KEY: "server_key.pem" +NAME_SERVER_CERT: "server_crt.pem" +NAME_CLIENTCA_CERT: "ca_crt.pem" + +# 0, no tls +# 1, only server certificate +# 2, server and client certificates +GRPC_TLS: 1 + +# 0, do not validate jwt +# 1, foreced to validate jwt +FORCE_VALIDATE_JWT: 1 + +MAX_NUM_THREAD: 128 +MAX_NUM_WORKER: 128 +TIMEDOUT_SESSION: 60 +TIMEDOUT_CONTEXT: 90 diff --git a/teeproxy/gpproxy/gpproxy.cc b/teeproxy/gpproxy/gpproxy.cc new file mode 100644 index 0000000..b510d08 --- /dev/null +++ b/teeproxy/gpproxy/gpproxy.cc @@ -0,0 +1,4195 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gt.grpc.pb.h" +#include "gt.pb.h" + +#include "gpproxy.h" + +extern "C" { +#include "dbusc_gpw.h" +} + +#include "dbusc_jwt.h" +#include "yaml-cpp/yaml.h" + + +using grpc::Server; +using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; +using grpc::ServerCompletionQueue; +using grpc::ServerAsyncResponseWriter; +using grpc::ServerAsyncReader; + +using grpc::experimental::AltsServerCredentials; +using grpc::experimental::AltsServerCredentialsOptions; + +using gt::gpp; +using gt::Inicont_Request; +using gt::Inicont_Reply; +using gt::Fincont_Request; +using gt::Fincont_Reply; +using gt::Opes_Reply; +using gt::Opes_Request; +using gt::Close_Reply; +using gt::Close_Request; +using gt::Invo_Reply; +using gt::Invo_Request; +using gt::TA_Chunk; +using gt::TA_Reply; +using gt::Setjwt_Request; +using gt::Setjwt_Reply; + + +#define NO_ERROR 0 + +std::string global_strcfgfiletemp = getenv("HOME"); +std::string global_strcfgfile = global_strcfgfiletemp + "/.gpp/gpproxy_config.yaml"; +YAML::Node glo_config = YAML::LoadFile(global_strcfgfile); +std::string gpproxy_address = glo_config["GPPROXY_ADDRESS"].as(); +std::string global_servercert_path = + global_strcfgfiletemp + "/.gpp/certs/" + glo_config["NAME_SERVER_CERT"].as(); +std::string global_serverkey_path = + global_strcfgfiletemp + "/.gpp/certs/" + glo_config["NAME_SERVER_KEY"].as(); +std::string global_clientcacert_path = + global_strcfgfiletemp + "/.gpp/certs/" + glo_config["NAME_CLIENTCA_CERT"].as(); +int grpc_tls = glo_config["GRPC_TLS"].as(); +int global_force_valideta_jwt = glo_config["FORCE_VALIDATE_JWT"].as(); + +int global_max_num_thread = glo_config["MAX_NUM_THREAD"].as(); +int global_max_num_worker = glo_config["MAX_NUM_WORKER"].as(); +int global_timeout_session = glo_config["TIMEDOUT_SESSION"].as(); +int global_timeout_context = glo_config["TIMEDOUT_CONTEXT"].as(); + + +static std::string get_file_contents(std::string fpath) +{ + std::ifstream finstream(fpath); + std::string contents; + contents.assign((std::istreambuf_iterator(finstream)), + std::istreambuf_iterator()); + finstream.close(); + return contents; +} + +bool utf8_check_is_valid(std::string &string) +{ + int c, i, ix, n, j; + for (i = 0, ix = string.length(); i < ix; i++) + { + c = (unsigned char) string[i]; + //if (c==0x09 || c==0x0a || c==0x0d || (0x20 <= c && c <= 0x7e) ) n = 0; // is_printable_ascii + if (0x00 <= c && c <= 0x7f) n = 0; // 0bbbbbbb + else if ((c & 0xE0) == 0xC0) n = 1; // 110bbbbb + else if (c == 0xed && i < (ix - 1) && ((unsigned char) string[i + 1] & 0xa0) == 0xa0) + return false; //U+d800 to U+dfff + else if ((c & 0xF0) == 0xE0) n = 2; // 1110bbbb + else if ((c & 0xF8) == 0xF0) n = 3; // 11110bbb + //else if (($c & 0xFC) == 0xF8) n=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8 + //else if (($c & 0xFE) == 0xFC) n=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8 + else return false; + for (j = 0; j < n && i < ix; j++) + { // n bytes matching 10bbbbbb follow ? + if ((++i == ix) || (((unsigned char) string[i] & 0xC0) != 0x80)) + return false; + } + } + return true; +} + + +#define MAX_DATA_LEN 50*1024 +#define SHA256_LENTH 32 + +int get_file_sha256(char *file_path, char *val) +{ + SHA256_CTX sha256_ctx; + FILE *fp = NULL; + char *strFilePath = file_path; + unsigned char SHA256result[SHA256_LENTH]; + char DataBuff[MAX_DATA_LEN]; + int len; + int t = 0; + int i; + std::string sha256; + + fp = fopen(strFilePath, "rb"); + + SHA256_Init(&sha256_ctx); + + while (!feof(fp)) + { + memset(DataBuff, 0x00, sizeof(DataBuff)); + + len = fread(DataBuff, 1, MAX_DATA_LEN, fp); + if (len) + { + t += len; + SHA256_Update(&sha256_ctx, DataBuff, len); + } + } + + fclose(fp); + SHA256_Final(SHA256result, &sha256_ctx); + + if (val == NULL || (sizeof(val) * 4) < SHA256_LENTH) + { + return -1; + } else + { + memset(val, 0, sizeof(val)); + memcpy(val, SHA256result, SHA256_LENTH); + } + + return 0; +} + +bool isFileExists_ifstream(std::string &name) +{ + std::ifstream f(name.c_str()); + return f.good(); +} + +void check_config() +{ + if (grpc_tls != 0 && grpc_tls != 1 && grpc_tls != 2) + { + std::cout << global_strcfgfile << " grpc_tls should be 0 or 1 or 2 " << std::endl; + exit(-1); + } + if (global_force_valideta_jwt != 0 && global_force_valideta_jwt != 1) + { + std::cout << global_strcfgfile << " global_force_valideta_jwt should be 0 or 1 " << std::endl; + exit(-1); + } + if (global_max_num_thread < 0 || global_max_num_thread > 128) + { + std::cout << global_strcfgfile << " global_max_num_thread should between 0 and 128 " << std::endl; + exit(-1); + } + if (global_max_num_worker < 0 || global_max_num_worker > 128) + { + std::cout << global_strcfgfile << " global_max_num_worker should between 0 and 128 " << std::endl; + exit(-1); + } + if (global_timeout_session <= 0) + { + std::cout << global_strcfgfile << " global_timeout_session should > 0 " << std::endl; + exit(-1); + } + if (global_timeout_context <= 0) + { + std::cout << global_strcfgfile << " global_timeout_context should > 0 " << std::endl; + exit(-1); + } + if (grpc_tls == 2) + { + if (!isFileExists_ifstream(global_servercert_path)) + { + std::cout << "error file : " << global_servercert_path << " is not exist " << std::endl; + exit(-1); + } + if (!isFileExists_ifstream(global_serverkey_path)) + { + std::cout << "error file : " << global_serverkey_path << " is not exist " << std::endl; + exit(-1); + } + if (!isFileExists_ifstream(global_clientcacert_path)) + { + std::cout << "error file : " << global_clientcacert_path << " is not exist " << std::endl; + exit(-1); + } + } + if (grpc_tls == 1) + { + if (!isFileExists_ifstream(global_servercert_path)) + { + std::cout << "error file : " << global_servercert_path << " is not exist " << std::endl; + exit(-1); + } + if (!isFileExists_ifstream(global_serverkey_path)) + { + std::cout << "error file : " << global_serverkey_path << " is not exist " << std::endl; + exit(-1); + } + } +} + +class ServerImpl final +{ +public: + ~ServerImpl() + { + server_->Shutdown(); + for (auto &cq: cq_) + cq->Shutdown(); + delete[] workerrec; + } + + ServerImpl() + { + pthread_mutex_init(&mutex_workerrec, NULL); + pthread_cond_init(&cond_notbusy, NULL); + for (int iworker = 0; iworker < global_max_num_worker; iworker++) + { + workerrec[iworker].busy = 0; + workerrec[iworker].context_fd = 0; + workerrec[iworker].context_addr = 0xffffffff; + workerrec[iworker].sessionid_count = 0; + workerrec[iworker].first = NULL; + workerrec[iworker].last = NULL; + } + } + + class CallData + { + + public: + + enum ServiceType + { + SS_TEECC_InitializeContext = 0, + SS_TEECC_FinalizeContext = 1, + SS_TEECC_OpenSession = 2, + SS_TEECC_CloseSession = 3, + SS_TEECC_InvokeCommand = 4, + SS_TEECC_TA = 5, + SS_TEECC_SetJwt = 6 + }; + + ~CallData() + { + + } + + CallData(gpp::AsyncService *service, + ServerCompletionQueue *cq, + ServiceType s_type, + pthread_mutex_t *mutex_workerrec, + pthread_cond_t *cond_notbusy, + wr_t *workerrec) + : service_(service), + cq_(cq), + s_type_(s_type), + mutex_workerrec_(mutex_workerrec), + cond_notbusy_(cond_notbusy), + workerrec_(workerrec), + inicont_response(&ctx_), + fincont_response(&ctx_), + opes_response(&ctx_), + close_response(&ctx_), + invo_response(&ctx_), + ta_response(&ctx_), + setjwt_response(&ctx_), + status_(CREATE) + { + Process(); + } + + void Process() + { + if (status_ == CREATE) + { + status_ = PROCESS; + switch (s_type_) + { + case ServerImpl::CallData::SS_TEECC_InitializeContext: + service_->RequestTEECC_InitializeContext(&ctx_, &inicont_request, &inicont_response, cq_, cq_, + this); + break; + case ServerImpl::CallData::SS_TEECC_FinalizeContext: + service_->RequestTEECC_FinalizeContext(&ctx_, &fincont_request, &fincont_response, cq_, cq_, this); + break; + case ServerImpl::CallData::SS_TEECC_OpenSession: + service_->RequestTEECC_OpenSession(&ctx_, &opes_request, &opes_response, cq_, cq_, this); + break; + case ServerImpl::CallData::SS_TEECC_InvokeCommand: + service_->RequestTEECC_InvokeCommand(&ctx_, &invo_request, &invo_response, cq_, cq_, this); + break; + case ServerImpl::CallData::SS_TEECC_CloseSession: + service_->RequestTEECC_CloseSession(&ctx_, &close_request, &close_response, cq_, cq_, this); + break; + case ServerImpl::CallData::SS_TEECC_TA: + service_->RequestTEECC_TA(&ctx_, &ta_chunk, &ta_response, cq_, cq_, this); + break; + case ServerImpl::CallData::SS_TEECC_SetJwt: + service_->RequestTEECC_SetJwt(&ctx_, &setjwt_request, &setjwt_response, cq_, cq_, this); + break; + default: + break; + } + + } else if (status_ == PROCESS) + { + status_ = FINISH; + new CallData(service_, cq_, this->s_type_, mutex_workerrec_, cond_notbusy_, workerrec_); + + switch (s_type_) + { + case ServerImpl::CallData::SS_TEECC_InitializeContext: + { + struct timeval start, end, jwt_validate_start, jwt_validate_end; + gettimeofday(&start, NULL); + + std::string name; + const uint8_t *name_temp = reinterpret_cast(name.c_str()); + std::size_t name_size; + std::int32_t in_context_fd; + std::string in_context_tapath; + const uint8_t *in_context_tapath_temp = NULL; + std::int32_t in_context_tapath_size; + unsigned char *charp = NULL; + std::string charpp; + std::uint64_t in_context_sessionlist_next; + std::uint64_t in_context_sessionlist_prev; + std::uint64_t in_context_shrdmemlist_next; + std::uint64_t in_context_shrdmemlist_prev; + std::uint64_t in_context_sharebuffer_buffer; + std::int64_t in_context_sharebuffer_bufferbarrier; + + std::uint32_t teecresult; + std::int32_t fd; + + unsigned char *ta_path = NULL; + std::int32_t ta_path_size = 0; + + std::uint64_t session_list_next; + std::uint64_t session_list_prev; + std::uint64_t shrd_mem_list_next; + std::uint64_t shrd_mem_list_prev; + std::uint64_t share_buffer_buffer; + std::int64_t share_buffer_buffer_barrier; + std::uint64_t context_addr; + + in_context_fd = 0; + in_context_tapath_size = 0; + in_context_sessionlist_next = 0; + in_context_sessionlist_prev = 0; + in_context_shrdmemlist_next = 0; + in_context_shrdmemlist_prev = 0; + in_context_sharebuffer_buffer = 0; + in_context_sharebuffer_bufferbarrier = 0; + + name_size = inicont_request.name_size(); + if (name_size > 0) + { + name = inicont_request.name(); + std::cout << "gpp received name: " << name << std::endl; + } + + std::uint32_t serial = 0; + std::int32_t flag = 0; + + std::string token; + token = inicont_request.token(); + + std::string noToken("noToken"); + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + + gettimeofday(&jwt_validate_start, NULL); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + gettimeofday(&jwt_validate_end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (jwt_validate_end.tv_sec - jwt_validate_start.tv_sec) * 1000000 + + (jwt_validate_end.tv_usec - jwt_validate_start.tv_usec); + printf("gpp initcont validate jwt used time: %ld us. \n", i64Time_jwt); + + std::cout << "gpp validate initcont jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate initcont jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate initcont jwtsvid or validate jwt succed" << std::endl; + std::cout << "gpp received init context" << std::endl; + std::cout << "gpp received namesize: " << name_size << std::endl; + + ta_path = (unsigned char *) malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *) ta_path, 0, 1024); + uint32_t context_tapath_outsize; + + char workername[1024]; + memset((char *) workername, 0, 1024); + int ifound = 0; + int iworker; + + for (;;) + { + pthread_mutex_lock(mutex_workerrec_); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec_[iworker].busy == 0) + { + sprintf(workername, "%s%d", "gpworker", iworker); + std::cout << "gpp method call worker No: " << std::dec << iworker << std::endl; + workerrec_[iworker].busy = 1; + ifound = 1; + break; + } + } + if (ifound == 0) + { + pthread_cond_wait(cond_notbusy_, mutex_workerrec_); + } + pthread_mutex_unlock(mutex_workerrec_); + + if (ifound == 1) + { + break; + } + } + + method_call_teec_inicont( + workername, + + name_temp, + name_size, + in_context_fd, + in_context_tapath_temp, + in_context_tapath_size, + in_context_sessionlist_next, + in_context_sessionlist_prev, + in_context_shrdmemlist_next, + in_context_shrdmemlist_prev, + in_context_sharebuffer_buffer, + in_context_sharebuffer_bufferbarrier, + + &teecresult, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + &context_addr, + &context_tapath_outsize + ); + + if (teecresult == 0) + { + pthread_mutex_lock(mutex_workerrec_); + workerrec_[iworker].context_fd = fd; + workerrec_[iworker].context_addr = context_addr; + workerrec_[iworker].first = NULL; + workerrec_[iworker].last = NULL; + workerrec_[iworker].sessionid_count = 0; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + workerrec_[iworker].context_createtime = tvcreate; + pthread_mutex_unlock(mutex_workerrec_); + } else + { + workerrec_[iworker].busy = 0; + } + + if (ta_path_size >= context_tapath_outsize) + { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } else + { + ta_path_size = 0; + charp = NULL; + } + inicont_reply.set_teecresult(teecresult); + inicont_reply.set_context_fd(fd); + inicont_reply.set_context_tapath_outsize(ta_path_size); + + if (ta_path_size > 0 && + charp != NULL && + strlen((const char *) charp) > 0 + ) + { + charpp = (const char *) charp; + if (utf8_check_is_valid(charpp)) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + if (ta_path_size > 0) + { + inicont_reply.set_context_tapath(charpp); + } + + inicont_reply.set_context_sessionlist_next(session_list_next); + inicont_reply.set_context_sessionlist_prev(session_list_prev); + inicont_reply.set_context_shrdmemlist_prev(shrd_mem_list_prev); + inicont_reply.set_context_shrdmemlist_next(shrd_mem_list_next); + inicont_reply.set_context_sharebuffer_buffer(share_buffer_buffer); + inicont_reply.set_context_sharebuffer_bufferbarrier(share_buffer_buffer_barrier); + inicont_reply.set_context_addr(context_addr); + + status_ = FINISH; + gettimeofday(&end, NULL); + int64_t i64Time; + i64Time = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("gpp initcont used time: %ld us. \n", i64Time); + + inicont_response.Finish(inicont_reply, Status::OK, this); + } else + { + std::cout << "gpp receive no initcont jwtsvid or validate jwt failed" << std::endl; + flag = 2; + inicont_reply.set_flag(flag); + status_ = FINISH; + + inicont_response.Finish(inicont_reply, Status::OK, this); + } + break; + } + + case ServerImpl::CallData::SS_TEECC_FinalizeContext: + { + struct timeval start, end, jwt_validate_start, jwt_validate_end; + gettimeofday(&start, NULL); + + std::int32_t in_context_fd; + std::string in_context_tapath; + const uint8_t *in_context_tapath_temp = NULL; + std::int32_t in_context_tapath_size; + unsigned char *charp = NULL; + std::string charpp; + std::uint64_t in_context_sessionlist_next; + std::uint64_t in_context_sessionlist_prev; + std::uint64_t in_context_shrdmemlist_next; + std::uint64_t in_context_shrdmemlist_prev; + std::uint64_t in_context_sharebuffer_buffer; + std::int64_t in_context_sharebuffer_bufferbarrier; + std::uint64_t in_context_addr; + + std::uint32_t teecresult; + std::int32_t fd; + + unsigned char *ta_path = NULL; + std::int32_t ta_path_size = 0; + + std::uint64_t session_list_next; + std::uint64_t session_list_prev; + std::uint64_t shrd_mem_list_next; + std::uint64_t shrd_mem_list_prev; + std::uint64_t share_buffer_buffer; + std::int64_t share_buffer_buffer_barrier; + + std::uint32_t serial = 0; + std::int32_t flag = 0; + std::string token; + token = fincont_request.token(); + std::string noToken("noToken"); + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + + gettimeofday(&jwt_validate_start, NULL); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + gettimeofday(&jwt_validate_end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (jwt_validate_end.tv_sec - jwt_validate_start.tv_sec) * 1000000 + + (jwt_validate_end.tv_usec - jwt_validate_start.tv_usec); + printf("gpp finacont validate jwt used time: %ld us. \n", i64Time_jwt); + + std::cout << "gpp validate finacont jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate finacont jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate finacont jwtsvid or validate jwt succed" << std::endl; + std::cout << "gpp received fincontext" << std::endl; + in_context_fd = fincont_request.in_context_fd(); + in_context_tapath_size = fincont_request.in_context_tapath_size(); + if (in_context_tapath_size > 0) + { + in_context_tapath = fincont_request.in_context_tapath(); + in_context_tapath_temp = reinterpret_cast(in_context_tapath.c_str()); + std::cout << "gpp received in_context_tapath_temp: " << in_context_tapath_temp + << std::endl; + } + + std::cout << "gpp received in_context_fd: " << in_context_fd << std::endl; + in_context_sessionlist_next = fincont_request.in_context_sessionlist_next(); + in_context_sessionlist_prev = fincont_request.in_context_sessionlist_prev(); + in_context_shrdmemlist_next = fincont_request.in_context_shrdmemlist_next(); + in_context_shrdmemlist_prev = fincont_request.in_context_shrdmemlist_prev(); + in_context_sharebuffer_buffer = fincont_request.in_context_shrdmemlist_prev(); + in_context_sharebuffer_bufferbarrier = fincont_request.in_context_sharebuffer_bufferbarrier(); + in_context_addr = fincont_request.in_context_addr(); + + + ta_path = (unsigned char *) malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *) ta_path, 0, 1024); + uint32_t context_tapath_outsize; + + char workername[1024]; + memset((char *) workername, 0, 1024); + int ifound = 0; + int iworker; + pthread_mutex_lock(mutex_workerrec_); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec_[iworker].context_fd == in_context_fd && + workerrec_[iworker].context_addr == in_context_addr + ) + { + sprintf(workername, "%s%d", "gpworker", iworker); + std::cout << "gpp method call worker No: " << std::dec << iworker << std::endl; + ifound = 1; + break; + } + } + pthread_mutex_unlock(mutex_workerrec_); + + if (ifound == 0) + { + printf("gpp can't find the worker for the context. \n"); + + fd = 0; + ta_path_size = 0; + charp = NULL; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + + fincont_reply.set_context_fd(fd); + fincont_reply.set_context_tapath_outsize(ta_path_size); + fincont_reply.set_context_sessionlist_prev(session_list_prev); + fincont_reply.set_context_shrdmemlist_prev(shrd_mem_list_prev); + fincont_reply.set_context_shrdmemlist_next(shrd_mem_list_next); + fincont_reply.set_context_sharebuffer_buffer(share_buffer_buffer); + fincont_reply.set_context_sharebuffer_bufferbarrier(share_buffer_buffer_barrier); + + status_ = FINISH; + + fincont_response.Finish(fincont_reply, Status::OK, this); + } else + { + pthread_mutex_unlock(mutex_workerrec_); + sin_t *sinIns = NULL; + sin_t *sinInsPrev = NULL; + sinIns = workerrec_[iworker].last; + if (sinIns != NULL) + { + uint32_t in_session_seesionid; + uint32_t in_session_serviceid_timelow = 0; + uint32_t in_session_serviceid_timemid = 0; + uint32_t in_session_serviceid_timehiandver = 0; + uint32_t in_session_serviceid_clockseqandnode_size = 8; + uint32_t in_session_serviceid_clockseqandnode[8]; + uint32_t in_session_opscnt = 0; + uint64_t in_session_head_next = 0; + uint64_t in_session_head_prev = 0; + uint64_t in_session_context; + + uint32_t seesionid; + uint32_t serviceid_timelow; + uint32_t serviceid_timemid; + uint32_t serviceid_timehiandver; + uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + uint32_t opscnt; + uint64_t head_next; + uint64_t head_prev; + uint64_t session_context; + + for (;;) + { + in_session_seesionid = sinIns->session_id; + in_session_context = workerrec_[iworker].context_addr; + + pthread_mutex_unlock(mutex_workerrec_); + + for (int iind = 0; iind < 8; iind++) + { + in_session_serviceid_clockseqandnode[iind] = 0; + } + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + + printf("\ngpp self method call teec closesession before finalizecontext \n"); + method_call_teec_closesession( + workername, + + in_session_seesionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &session_context + ); + + if (serviceid_clockseqandnode != NULL) + { + free(serviceid_clockseqandnode); + } + + pthread_mutex_lock(mutex_workerrec_); + + sinInsPrev = sinIns->prev; + free(sinIns); + if (sinInsPrev == NULL) + { + break; + } + sinIns = sinInsPrev; + } + } + pthread_mutex_unlock(mutex_workerrec_); + + method_call_teec_fincont( + workername, + + in_context_fd, + in_context_tapath_temp, + in_context_tapath_size, + in_context_sessionlist_next, + in_context_sessionlist_prev, + in_context_shrdmemlist_next, + in_context_shrdmemlist_prev, + in_context_sharebuffer_buffer, + in_context_sharebuffer_bufferbarrier, + in_context_addr, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + &context_tapath_outsize + ); + + pthread_mutex_lock(mutex_workerrec_); + workerrec_[iworker].busy = 0; + pthread_cond_signal(cond_notbusy_); + workerrec_[iworker].context_fd = 0; + workerrec_[iworker].context_addr = 0xffffffff; + workerrec_[iworker].sessionid_count = 0; + workerrec_[iworker].first = NULL; + workerrec_[iworker].last = NULL; + pthread_mutex_unlock(mutex_workerrec_); + + if (ta_path_size >= context_tapath_outsize) + { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } else + { + ta_path_size = 0; + charp = NULL; + } + fincont_reply.set_context_fd(fd); + fincont_reply.set_context_tapath_outsize(ta_path_size); + + if (ta_path_size > 0 && + charp != NULL && + strlen((const char *) charp) > 0 + ) + { + charpp = (const char *) charp; + if (utf8_check_is_valid(charpp)) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + if (ta_path_size > 0) + { + fincont_reply.set_context_tapath(charpp); + } + + fincont_reply.set_context_sessionlist_next(session_list_next); + fincont_reply.set_context_sessionlist_prev(session_list_prev); + fincont_reply.set_context_shrdmemlist_prev(shrd_mem_list_prev); + fincont_reply.set_context_shrdmemlist_next(shrd_mem_list_next); + fincont_reply.set_context_sharebuffer_buffer(share_buffer_buffer); + fincont_reply.set_context_sharebuffer_bufferbarrier(share_buffer_buffer_barrier); + + status_ = FINISH; + gettimeofday(&end, NULL); + int64_t i64Time; + i64Time = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("gpp finalcontext used time: %ld us. \n", i64Time); + + fincont_response.Finish(fincont_reply, Status::OK, this); + } + }else + { + std::cout << "gpp receive no finacont jwtsvid or validate jwt failed" << std::endl; + flag = 2; + fincont_reply.set_flag(flag); + status_ = FINISH; + fincont_response.Finish(fincont_reply, Status::OK, this); + } + break; + } + + case ServerImpl::CallData::SS_TEECC_OpenSession: + { + struct timeval start, end, jwt_validate_start, jwt_validate_end; + gettimeofday(&start, NULL); + + std::int32_t in_context_fd; + std::string in_context_tapath; + const uint8_t *in_context_tapath_temp = NULL; + std::int32_t in_context_tapath_size; + unsigned char *charp = NULL; + std::string charpp; + std::uint64_t in_context_sessionlist_next; + std::uint64_t in_context_sessionlist_prev; + std::uint64_t in_context_shrdmemlist_next; + std::uint64_t in_context_shrdmemlist_prev; + std::uint64_t in_context_sharebuffer_buffer; + std::int64_t in_context_sharebuffer_bufferbarrier; + + std::uint32_t teecresult; + std::int32_t fd; + + std::uint32_t in_destination_timelow; + std::uint32_t in_destination_timemid; + std::uint32_t in_destination_timehiandver; + + std::uint32_t in_connectionmethod; + std::uint64_t in_connectiondata; + std::uint32_t in_operation_started; + std::uint32_t in_operation_paramtypes; + std::int32_t in_destination_clockseqandnode_size; + std::uint32_t *in_destination_clockseqandnode; + + std::uint64_t in_operation_param1_tmpref_buffer; + std::uint32_t in_operation_param1_tmpref_size; + std::uint64_t in_operation_param1_memref_parent; + std::uint32_t in_operation_param1_memref_size; + std::uint32_t in_operation_param1_memref_offset; + std::uint32_t in_operation_param1_value_a; + std::uint32_t in_operation_param1_value_b; + std::int32_t in_operation_param1_ionref_ionsharefd; + std::uint32_t in_operation_param1_ionref_ionsize; + + std::uint64_t in_operation_param2_tmpref_buffer; + std::uint32_t in_operation_param2_tmpref_size; + std::uint64_t in_operation_param2_memref_parent; + std::uint32_t in_operation_param2_memref_size; + std::uint32_t in_operation_param2_memref_offset; + std::uint32_t in_operation_param2_value_a; + std::uint32_t in_operation_param2_value_b; + std::int32_t in_operation_param2_ionref_ionsharefd; + std::uint32_t in_operation_param2_ionref_ionsize; + + std::uint64_t in_operation_param3_tmpref_buffer; + std::uint32_t in_operation_param3_tmpref_size; + std::uint64_t in_operation_param3_memref_parent; + std::uint32_t in_operation_param3_memref_size; + std::uint32_t in_operation_param3_memref_offset; + std::uint32_t in_operation_param3_value_a; + std::uint32_t in_operation_param3_value_b; + std::int32_t in_operation_param3_ionref_ionsharefd; + std::uint32_t in_operation_param3_ionref_ionsize; + + std::uint64_t in_operation_param4_tmpref_buffer; + std::uint32_t in_operation_param4_tmpref_size; + std::uint64_t in_operation_param4_memref_parent; + std::uint32_t in_operation_param4_memref_size; + std::uint32_t in_operation_param4_memref_offset; + std::uint32_t in_operation_param4_value_a; + std::uint32_t in_operation_param4_value_b; + std::int32_t in_operation_param4_ionref_ionsharefd; + std::uint32_t in_operation_param4_ionref_ionsize; + + std::uint64_t in_operation_session; + std::int32_t in_operation_cancelflag; + std::uint32_t in_returnorigin; + + std::uint64_t in_context_addr; + + unsigned char *ta_path = NULL; + std::int32_t ta_path_size = 0; + + std::uint64_t session_list_next; + std::uint64_t session_list_prev; + std::uint64_t shrd_mem_list_next; + std::uint64_t shrd_mem_list_prev; + std::uint64_t share_buffer_buffer; + std::int64_t share_buffer_buffer_barrier; + + std::uint32_t sessionid; + std::uint32_t serviceid_timelow; + std::uint32_t serviceid_timemid; + std::uint32_t serviceid_timehiandver; + std::uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + std::int32_t serviceid_clockseqandnode_outsize; + std::uint32_t opscnt; + std::uint64_t head_next; + std::uint64_t head_prev; + std::uint64_t session_context; + std::uint32_t started; + std::uint32_t paramtypes; + std::uint64_t operation_param1_tmpref_buffer; + std::uint32_t operation_param1_tmpref_size; + std::uint64_t operation_param1_memref_parent; + std::uint32_t operation_param1_memref_size; + std::uint32_t operation_param1_memref_offset; + std::uint32_t operation_param1_value_a; + std::uint32_t operation_param1_value_b; + std::int32_t operation_param1_ionref_ionsharefd; + std::uint32_t operation_param1_ionref_ionsize; + std::uint64_t operation_param2_tmpref_buffer; + std::uint32_t operation_param2_tmpref_size; + std::uint64_t operation_param2_memref_parent; + std::uint32_t operation_param2_memref_size; + std::uint32_t operation_param2_memref_offset; + std::uint32_t operation_param2_value_a; + std::uint32_t operation_param2_value_b; + std::int32_t operation_param2_ionref_ionsharefd; + std::uint32_t operation_param2_ionref_ionsize; + std::uint64_t operation_param3_tmpref_buffer; + std::uint32_t operation_param3_tmpref_size; + std::uint64_t operation_param3_memref_parent; + std::uint32_t operation_param3_memref_size; + std::uint32_t operation_param3_memref_offset; + std::uint32_t operation_param3_value_a; + std::uint32_t operation_param3_value_b; + std::int32_t operation_param3_ionref_ionsharefd; + std::uint32_t operation_param3_ionref_ionsize; + std::uint64_t operation_param4_tmpref_buffer; + std::uint32_t operation_param4_tmpref_size; + std::uint64_t operation_param4_memref_parent; + std::uint32_t operation_param4_memref_size; + std::uint32_t operation_param4_memref_offset; + std::uint32_t operation_param4_value_a; + std::uint32_t operation_param4_value_b; + std::int32_t operation_param4_ionref_ionsharefd; + std::uint32_t operation_param4_ionref_ionsize; + std::uint64_t operation_session; + std::int32_t operation_cancelflag; + std::uint32_t returnorigin; + + std::uint32_t serial = 0; + std::int32_t flag = 0; + std::string token; + token = opes_request.token(); + + std::string noToken("noToken"); + + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + gettimeofday(&jwt_validate_start, NULL); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + gettimeofday(&jwt_validate_end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (jwt_validate_end.tv_sec - jwt_validate_start.tv_sec) * 1000000 + + (jwt_validate_end.tv_usec - jwt_validate_start.tv_usec); + printf("gpp opensession validate jwt used time: %ld us. \n", i64Time_jwt); + std::cout << "gpp validate opensession jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate opensession jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate opensession jwtsvid or validate jwt succed" + << std::endl; + std::cout << "gpp received OpenSession" << std::endl; + in_context_fd = opes_request.in_context_fd(); + in_context_tapath_size = opes_request.in_context_tapath_size(); + if (in_context_tapath_size > 0) + { + in_context_tapath = opes_request.in_context_tapath(); + in_context_tapath_temp = reinterpret_cast(in_context_tapath.c_str()); + std::cout << "gpp received in_context_tapath_temp: " << in_context_tapath_temp + << std::endl; + } + std::cout << "gpp received in_context_fd: " << std::dec << in_context_fd + << std::endl; + std::cout << "gpp received in_context_tapath_size: " << std::dec + << in_context_tapath_size + << std::endl; + in_context_sessionlist_next = opes_request.in_context_sessionlist_next(); + in_context_sessionlist_prev = opes_request.in_context_sessionlist_prev(); + in_context_shrdmemlist_next = opes_request.in_context_shrdmemlist_next(); + in_context_shrdmemlist_prev = opes_request.in_context_shrdmemlist_prev(); + in_context_sharebuffer_buffer = opes_request.in_context_shrdmemlist_prev(); + in_context_sharebuffer_bufferbarrier = opes_request.in_context_sharebuffer_bufferbarrier(); + in_destination_timelow = opes_request.in_destination_timelow(); + in_destination_timemid = opes_request.in_destination_timemid(); + + in_destination_timehiandver = opes_request.in_destination_timehiandver(); + in_destination_clockseqandnode_size = opes_request.in_destination_clockseqandnode_size(); + if (in_destination_clockseqandnode_size > 0) + { + in_destination_clockseqandnode = new uint32_t[in_destination_clockseqandnode_size]; + for (int i = 0; i < in_destination_clockseqandnode_size; i++) + { + in_destination_clockseqandnode[i] = opes_request.in_destination_clockseqandnode( + i); + } + } + + in_connectionmethod = opes_request.in_connectionmethod(); + in_connectiondata = opes_request.in_connectiondata(); + in_operation_started = opes_request.in_operation_started(); + in_operation_paramtypes = opes_request.in_operation_paramtypes(); + in_operation_param1_tmpref_buffer = opes_request.in_operation_param1_tmpref_buffer(); + in_operation_param1_tmpref_size = opes_request.in_operation_param1_tmpref_size(); + in_operation_param1_memref_parent = opes_request.in_operation_param1_memref_parent(); + in_operation_param1_memref_size = opes_request.in_operation_param1_memref_size(); + in_operation_param1_memref_offset = opes_request.in_operation_param1_memref_offset(); + in_operation_param1_value_a = opes_request.in_operation_param1_value_a(); + in_operation_param1_value_b = opes_request.in_operation_param1_value_b(); + in_operation_param1_ionref_ionsharefd = opes_request.in_operation_param1_ionref_ionsharefd(); + in_operation_param1_ionref_ionsize = opes_request.in_operation_param1_ionref_ionsize(); + + in_operation_param2_tmpref_buffer = opes_request.in_operation_param2_tmpref_buffer(); + in_operation_param2_tmpref_size = opes_request.in_operation_param2_tmpref_size(); + in_operation_param2_memref_parent = opes_request.in_operation_param2_memref_parent(); + in_operation_param2_memref_size = opes_request.in_operation_param2_memref_size(); + in_operation_param2_memref_offset = opes_request.in_operation_param2_memref_offset(); + in_operation_param2_value_a = opes_request.in_operation_param2_value_a(); + in_operation_param2_value_b = opes_request.in_operation_param2_value_b(); + in_operation_param2_ionref_ionsharefd = opes_request.in_operation_param2_ionref_ionsharefd(); + in_operation_param2_ionref_ionsize = opes_request.in_operation_param2_ionref_ionsize(); + + in_operation_param3_tmpref_buffer = opes_request.in_operation_param3_tmpref_buffer(); + in_operation_param3_tmpref_size = opes_request.in_operation_param3_tmpref_size(); + in_operation_param3_memref_parent = opes_request.in_operation_param3_memref_parent(); + in_operation_param3_memref_size = opes_request.in_operation_param3_memref_size(); + in_operation_param3_memref_offset = opes_request.in_operation_param3_memref_offset(); + in_operation_param3_value_a = opes_request.in_operation_param3_value_a(); + in_operation_param3_value_b = opes_request.in_operation_param3_value_b(); + in_operation_param3_ionref_ionsharefd = opes_request.in_operation_param3_ionref_ionsharefd(); + in_operation_param3_ionref_ionsize = opes_request.in_operation_param3_ionref_ionsize(); + + in_operation_param4_tmpref_buffer = opes_request.in_operation_param4_tmpref_buffer(); + in_operation_param4_tmpref_size = opes_request.in_operation_param4_tmpref_size(); + in_operation_param4_memref_parent = opes_request.in_operation_param4_memref_parent(); + in_operation_param4_memref_size = opes_request.in_operation_param4_memref_size(); + in_operation_param4_memref_offset = opes_request.in_operation_param4_memref_offset(); + in_operation_param4_value_a = opes_request.in_operation_param4_value_a(); + in_operation_param4_value_b = opes_request.in_operation_param4_value_b(); + in_operation_param4_ionref_ionsharefd = opes_request.in_operation_param4_ionref_ionsharefd(); + in_operation_param4_ionref_ionsize = opes_request.in_operation_param4_ionref_ionsize(); + + in_operation_session = opes_request.in_operation_session(); + in_operation_cancelflag = opes_request.in_operation_cancelflag(); + in_returnorigin = opes_request.in_returnorigin(); + in_context_addr = opes_request.in_context_addr(); +#if 0 + printf(" in_session_list_next = 0x %16.16lx \n", in_context_sessionlist_next); + printf(" in_session_list_prev = 0x %16.16lx \n", in_context_sessionlist_prev); + printf(" in_shrd_mem_list_next = 0x %16.16lx \n", in_context_shrdmemlist_next); + printf(" in_shrd_mem_list_prev = 0x %16.16lx \n", in_context_shrdmemlist_prev); + printf(" in_share_buffer_buffer = 0x %16.16lx \n", in_context_sharebuffer_buffer); + printf(" in_share_buffer_buffer_barrier = 0x %16.16lx \n", in_context_sharebuffer_bufferbarrier); + + printf(" in_destination_timelow = 0x %8.8x \n", in_destination_timelow); + printf(" in_destination_timemid = 0x %8.8x \n", in_destination_timemid); + printf(" in_destination_timehiandver = 0x %8.8x \n", in_destination_timehiandver); + if ( in_destination_clockseqandnode_size > 0 ) + { + printf(" in_destination_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_destination_clockseqandnode_size; i++) { + printf(" %8.8x", in_destination_clockseqandnode[i]); + } + printf("\n"); + } + else + { + printf(" in_destination_clockseqandnode addr = 0x %16.16lx \n", + (long unsigned int)in_destination_clockseqandnode + ); + } + printf(" in_destination_clockseqandnode_size = 0x %8.8x \n", in_destination_clockseqandnode_size); + + printf(" in_connectionmethod = 0x %8.8x \n", in_connectionmethod); + printf(" in_connectiondata = 0x %16.16lx \n", in_connectiondata); + + printf(" in_operation_started = 0x %8.8x \n", in_operation_started); + printf(" in_operation_paramtypes = 0x %8.8x \n", in_operation_paramtypes); + + printf(" in_operation_param1_tmpref_buffer = 0x %16.16lx \n", in_operation_param1_tmpref_buffer); + printf(" in_operation_param1_tmpref_size = 0x %8.8x \n", in_operation_param1_tmpref_size); + printf(" in_operation_param1_memref_parent = 0x %16.16lx \n", in_operation_param1_memref_parent); + printf(" in_operation_param1_memref_size = 0x %8.8x \n", in_operation_param1_memref_size); + printf(" in_operation_param1_memref_offset = 0x %8.8x \n", in_operation_param1_memref_offset); + printf(" in_operation_param1_value_a = 0x %8.8x \n", in_operation_param1_value_a); + printf(" in_operation_param1_value_b = 0x %8.8x \n", in_operation_param1_value_b); + printf(" in_operation_param1_ionref_ionsharefd = 0x %8.8x \n", + in_operation_param1_ionref_ionsharefd); + printf(" in_operation_param1_ionref_ionsize = 0x %8.8x \n", in_operation_param1_ionref_ionsize); + + printf(" in_operation_param2_tmpref_buffer = 0x %16.16lx \n", in_operation_param2_tmpref_buffer); + printf(" in_operation_param2_tmpref_size = 0x %8.8x \n", in_operation_param2_tmpref_size); + printf(" in_operation_param2_memref_parent = 0x %16.16lx \n", in_operation_param2_memref_parent); + printf(" in_operation_param2_memref_size = 0x %8.8x \n", in_operation_param2_memref_size); + printf(" in_operation_param2_memref_offset = 0x %8.8x \n", in_operation_param2_memref_offset); + printf(" in_operation_param2_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param2_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param2_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param2_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param3_tmpref_buffer = 0x %16.16lx \n", in_operation_param3_tmpref_buffer); + printf(" in_operation_param3_tmpref_size = 0x %8.8x \n", in_operation_param3_tmpref_size); + printf(" in_operation_param3_memref_parent = 0x %16.16lx \n", in_operation_param3_memref_parent); + printf(" in_operation_param3_memref_size = 0x %8.8x \n", in_operation_param3_memref_size); + printf(" in_operation_param3_memref_offset = 0x %8.8x \n", in_operation_param3_memref_offset); + printf(" in_operation_param3_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param3_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param3_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param3_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param4_tmpref_buffer = 0x %16.16lx \n", in_operation_param4_tmpref_buffer); + printf(" in_operation_param4_tmpref_size = 0x %8.8x \n", in_operation_param4_tmpref_size); + printf(" in_operation_param4_memref_parent = 0x %16.16lx \n", in_operation_param4_memref_parent); + printf(" in_operation_param4_memref_size = 0x %8.8x \n", in_operation_param4_memref_size); + printf(" in_operation_param4_memref_offset = 0x %8.8x \n", in_operation_param4_memref_offset); + printf(" in_operation_param4_value_a = 0x %8.8x \n", in_operation_param4_value_a); + printf(" in_operation_param4_value_b = 0x %8.8x \n", in_operation_param4_value_b); + printf(" in_operation_param4_ionref_ionsharefd = 0x %8.8x \n", in_operation_param4_ionref_ionsharefd); + printf(" in_operation_param4_ionref_ionsize = 0x %8.8x \n", in_operation_param4_ionref_ionsize); + + printf(" in_operation_session = 0x %16.16lx \n", in_operation_session); + printf(" in_operation_cancelflag = 0x %8.8x \n", in_operation_cancelflag); + + printf(" in_returnorigin = 0x %8.8x \n", in_returnorigin); +#endif + std::cout << "gpp received in_context_addr: 0x " << std::hex << std::setfill('0') + << std::setw(16) << in_context_addr << std::endl; + ta_path = (unsigned char *) malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *) ta_path, 0, 1024); + + uint32_t context_tapath_outsize; + uint32_t serviceid_clockseqandnode_outsize_temp; + uint32_t returnorigin_temp; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (std::uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(std::uint32_t) + ); + + char workername[1024]; + memset((char *) workername, 0, 1024); + int ifound = 0; + int iworker; + + pthread_mutex_lock(mutex_workerrec_); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec_[iworker].context_fd == in_context_fd && + workerrec_[iworker].context_addr == in_context_addr + ) + { + sprintf(workername, "%s%d", "gpworker", iworker); + std::cout << "gpp method call worker No: " << std::dec << iworker << std::endl; + ifound = 1; + break; + } + } + pthread_mutex_unlock(mutex_workerrec_); + if (ifound == 0) + { + printf("gpp can't find the woker for the context. \n"); + + teecresult = 0xAAAA0017; + + fd = 0x0; + ta_path = NULL; + charp = ta_path; + session_list_next = 0x0; + session_list_prev = 0x0; + shrd_mem_list_next = 0x0; + shrd_mem_list_prev = 0x0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0x0; + + sessionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize; i++) + { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + session_context = 0x0; + + started = 0x0; + paramtypes = 0x0; + + operation_param1_tmpref_buffer = 0x0; + operation_param1_tmpref_size = 0x0; + operation_param1_memref_parent = 0x0; + operation_param1_memref_size = 0x0; + operation_param1_memref_offset = 0x0; + operation_param1_value_a = 0x0; + operation_param1_value_b = 0x0; + operation_param1_ionref_ionsharefd = 0x0; + operation_param1_ionref_ionsize = 0x0; + + operation_param2_tmpref_buffer = 0x0; + operation_param2_tmpref_size = 0x0; + operation_param2_memref_parent = 0x0; + operation_param2_memref_size = 0x0; + operation_param2_memref_offset = 0x0; + operation_param2_value_a = 0x0; + operation_param2_value_b = 0x0; + operation_param2_ionref_ionsharefd = 0x0; + operation_param2_ionref_ionsize = 0x0; + + operation_param3_tmpref_buffer = 0x0; + operation_param3_tmpref_size = 0x0; + operation_param3_memref_parent = 0x0; + operation_param3_memref_size = 0x0; + operation_param3_memref_offset = 0x0; + operation_param3_value_a = 0x0; + operation_param3_value_b = 0x0; + operation_param3_ionref_ionsharefd = 0x0; + operation_param3_ionref_ionsize = 0x0; + + operation_param4_tmpref_buffer = 0x0; + operation_param4_tmpref_size = 0x0; + operation_param4_memref_parent = 0x0; + operation_param4_memref_size = 0x0; + operation_param4_memref_offset = 0x0; + operation_param4_value_a = 0x0; + operation_param4_value_b = 0x0; + operation_param4_ionref_ionsharefd = 0x0; + operation_param4_ionref_ionsize = 0x0; + + operation_session = 0x0; + operation_cancelflag = 0x0; + + returnorigin = 0x0; + + opes_reply.set_teecresult(teecresult); + opes_reply.set_context_fd(fd); + opes_reply.set_context_tapath_outsize(ta_path_size); + opes_reply.set_context_sessionlist_next(session_list_next); + opes_reply.set_context_sessionlist_prev(session_list_prev); + opes_reply.set_context_shrdmemlist_prev(shrd_mem_list_prev); + opes_reply.set_context_shrdmemlist_next(shrd_mem_list_next); + opes_reply.set_context_sharebuffer_buffer(share_buffer_buffer); + opes_reply.set_context_sharebuffer_bufferbarrier(share_buffer_buffer_barrier); + opes_reply.set_session_sessionid(sessionid); + opes_reply.set_session_serviceid_timelow(serviceid_timelow); + opes_reply.set_session_serviceid_timemid(serviceid_timemid); + opes_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + opes_reply.set_session_serviceid_clockseqandnode_outsize( + serviceid_clockseqandnode_outsize); + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + opes_reply.add_session_serviceid_clockseqandnode( + serviceid_clockseqandnode[i]); + } + opes_reply.set_session_opscnt(opscnt); + opes_reply.set_session_head_next(head_next); + opes_reply.set_session_head_prev(head_prev); + opes_reply.set_session_context(session_context); + opes_reply.set_operation_started(started); + opes_reply.set_operation_paramtypes(paramtypes); + opes_reply.set_operation_param1_tmpref_buffer(operation_param1_tmpref_buffer); + opes_reply.set_operation_param1_tmpref_size(operation_param1_tmpref_size); + opes_reply.set_operation_param1_memref_parent(operation_param1_memref_parent); + opes_reply.set_operation_param1_memref_size(operation_param1_memref_size); + opes_reply.set_operation_param1_memref_offset(operation_param1_memref_offset); + opes_reply.set_operation_param1_value_a(operation_param1_value_a); + opes_reply.set_operation_param1_value_b(operation_param1_value_b); + opes_reply.set_operation_param1_ionref_ionsharefd( + operation_param1_ionref_ionsharefd); + opes_reply.set_operation_param1_ionref_ionsize(operation_param1_ionref_ionsize); + + opes_reply.set_operation_param2_tmpref_buffer(operation_param2_tmpref_buffer); + opes_reply.set_operation_param2_tmpref_size(operation_param2_tmpref_size); + opes_reply.set_operation_param2_memref_parent(operation_param2_memref_parent); + opes_reply.set_operation_param2_memref_size(operation_param2_memref_size); + opes_reply.set_operation_param2_memref_offset(operation_param2_memref_offset); + opes_reply.set_operation_param2_value_a(operation_param2_value_a); + opes_reply.set_operation_param2_value_b(operation_param2_value_b); + opes_reply.set_operation_param2_ionref_ionsharefd( + operation_param2_ionref_ionsharefd); + opes_reply.set_operation_param2_ionref_ionsize(operation_param2_ionref_ionsize); + + opes_reply.set_operation_param3_tmpref_buffer(operation_param3_tmpref_buffer); + opes_reply.set_operation_param3_tmpref_size(operation_param3_tmpref_size); + opes_reply.set_operation_param3_memref_parent(operation_param3_memref_parent); + opes_reply.set_operation_param3_memref_size(operation_param3_memref_size); + opes_reply.set_operation_param3_memref_offset(operation_param3_memref_offset); + opes_reply.set_operation_param3_value_a(operation_param3_value_a); + opes_reply.set_operation_param3_value_b(operation_param3_value_b); + opes_reply.set_operation_param3_ionref_ionsharefd( + operation_param3_ionref_ionsharefd); + opes_reply.set_operation_param3_ionref_ionsize(operation_param3_ionref_ionsize); + + opes_reply.set_operation_param4_tmpref_buffer(operation_param4_tmpref_buffer); + opes_reply.set_operation_param4_tmpref_size(operation_param4_tmpref_size); + opes_reply.set_operation_param4_memref_parent(operation_param4_memref_parent); + opes_reply.set_operation_param4_memref_size(operation_param4_memref_size); + opes_reply.set_operation_param4_memref_offset(operation_param4_memref_offset); + opes_reply.set_operation_param4_value_a(operation_param4_value_a); + opes_reply.set_operation_param4_value_b(operation_param4_value_b); + opes_reply.set_operation_param4_ionref_ionsharefd( + operation_param4_ionref_ionsharefd); + opes_reply.set_operation_param4_ionref_ionsize(operation_param4_ionref_ionsize); + + opes_reply.set_operation_session(operation_session); + opes_reply.set_operation_cancelflag(operation_cancelflag); + opes_reply.set_returnorigin(returnorigin); + + status_ = FINISH; + + opes_response.Finish(opes_reply, Status::OK, this); + } else + { + method_call_teec_opensession( + workername, + + in_context_fd, + in_context_tapath_temp, + in_context_tapath_size, + in_context_sessionlist_next, + in_context_sessionlist_prev, + in_context_shrdmemlist_next, + in_context_shrdmemlist_prev, + in_context_sharebuffer_buffer, + in_context_sharebuffer_bufferbarrier, + + in_destination_timelow, + in_destination_timemid, + in_destination_timehiandver, + in_destination_clockseqandnode, + in_destination_clockseqandnode_size, + + in_connectionmethod, + in_connectiondata, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + + in_returnorigin, + + in_context_addr, + + + &teecresult, + + &fd, + ta_path, + ta_path_size, + &context_tapath_outsize, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + + &sessionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &session_context, + + &started, + ¶mtypes, + + &operation_param1_tmpref_buffer, + &operation_param1_tmpref_size, + &operation_param1_memref_parent, + &operation_param1_memref_size, + &operation_param1_memref_offset, + &operation_param1_value_a, + &operation_param1_value_b, + &operation_param1_ionref_ionsharefd, + &operation_param1_ionref_ionsize, + + &operation_param2_tmpref_buffer, + &operation_param2_tmpref_size, + &operation_param2_memref_parent, + &operation_param2_memref_size, + &operation_param2_memref_offset, + &operation_param2_value_a, + &operation_param2_value_b, + &operation_param2_ionref_ionsharefd, + &operation_param2_ionref_ionsize, + + &operation_param3_tmpref_buffer, + &operation_param3_tmpref_size, + &operation_param3_memref_parent, + &operation_param3_memref_size, + &operation_param3_memref_offset, + &operation_param3_value_a, + &operation_param3_value_b, + &operation_param3_ionref_ionsharefd, + &operation_param3_ionref_ionsize, + + &operation_param4_tmpref_buffer, + &operation_param4_tmpref_size, + &operation_param4_memref_parent, + &operation_param4_memref_size, + &operation_param4_memref_offset, + &operation_param4_value_a, + &operation_param4_value_b, + &operation_param4_ionref_ionsharefd, + &operation_param4_ionref_ionsize, + + &operation_session, + &operation_cancelflag, + + &returnorigin_temp + ); + if (teecresult == 0) + { + pthread_mutex_lock(mutex_workerrec_); + sin_t *sinIns = (sin_t *) malloc(sizeof(sin_t)); + sinIns->session_id = sessionid; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + sinIns->session_createtime = tvcreate; + workerrec_[iworker].context_createtime = tvcreate; + if (workerrec_[iworker].first == NULL) + { + sinIns->next = NULL; + sinIns->prev = NULL; + workerrec_[iworker].first = sinIns; + workerrec_[iworker].last = sinIns; + workerrec_[iworker].sessionid_count = 1; + } else + { + sinIns->prev = workerrec_[iworker].last; + sinIns->next = NULL; + workerrec_[iworker].last->next = sinIns; + workerrec_[iworker].last = sinIns; + workerrec_[iworker].sessionid_count = + workerrec_[iworker].sessionid_count + 1; + } + pthread_mutex_unlock(mutex_workerrec_); + } + serviceid_clockseqandnode_outsize = + serviceid_clockseqandnode_outsize_temp; + returnorigin = returnorigin_temp; + + if (ta_path_size >= context_tapath_outsize) + { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } else + { + ta_path_size = 0; + charp = NULL; + } + + if ( + serviceid_clockseqandnode_realsize >= serviceid_clockseqandnode_outsize && + 8 >= serviceid_clockseqandnode_outsize + ) + { + serviceid_clockseqandnode_realsize = serviceid_clockseqandnode_outsize; + } else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode_outsize = 0; + } + opes_reply.set_teecresult(teecresult); + opes_reply.set_context_fd(fd); + opes_reply.set_context_tapath_outsize(ta_path_size); + + if (ta_path_size > 0 && + charp != NULL && + strlen((const char *) charp) > 0 + ) + { + charpp = (const char *) charp; + if (utf8_check_is_valid(charpp)) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + if (ta_path_size > 0) + { + opes_reply.set_context_tapath(charpp); + } + + opes_reply.set_context_sessionlist_next(session_list_next); + opes_reply.set_context_sessionlist_prev(session_list_prev); + opes_reply.set_context_shrdmemlist_prev(shrd_mem_list_prev); + opes_reply.set_context_shrdmemlist_next(shrd_mem_list_next); + opes_reply.set_context_sharebuffer_buffer(share_buffer_buffer); + opes_reply.set_context_sharebuffer_bufferbarrier(share_buffer_buffer_barrier); + opes_reply.set_session_sessionid(sessionid); + opes_reply.set_session_serviceid_timelow(serviceid_timelow); + opes_reply.set_session_serviceid_timemid(serviceid_timemid); + opes_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + opes_reply.set_session_serviceid_clockseqandnode_outsize( + serviceid_clockseqandnode_outsize); + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + opes_reply.add_session_serviceid_clockseqandnode( + serviceid_clockseqandnode[i]); + } + opes_reply.set_session_opscnt(opscnt); + opes_reply.set_session_head_next(head_next); + opes_reply.set_session_head_prev(head_prev); + opes_reply.set_session_context(session_context); + opes_reply.set_operation_started(started); + opes_reply.set_operation_paramtypes(paramtypes); + opes_reply.set_operation_param1_tmpref_buffer(operation_param1_tmpref_buffer); + opes_reply.set_operation_param1_tmpref_size(operation_param1_tmpref_size); + opes_reply.set_operation_param1_memref_parent(operation_param1_memref_parent); + opes_reply.set_operation_param1_memref_size(operation_param1_memref_size); + opes_reply.set_operation_param1_memref_offset(operation_param1_memref_offset); + opes_reply.set_operation_param1_value_a(operation_param1_value_a); + opes_reply.set_operation_param1_value_b(operation_param1_value_b); + opes_reply.set_operation_param1_ionref_ionsharefd( + operation_param1_ionref_ionsharefd); + opes_reply.set_operation_param1_ionref_ionsize(operation_param1_ionref_ionsize); + + opes_reply.set_operation_param2_tmpref_buffer(operation_param2_tmpref_buffer); + opes_reply.set_operation_param2_tmpref_size(operation_param2_tmpref_size); + opes_reply.set_operation_param2_memref_parent(operation_param2_memref_parent); + opes_reply.set_operation_param2_memref_size(operation_param2_memref_size); + opes_reply.set_operation_param2_memref_offset(operation_param2_memref_offset); + opes_reply.set_operation_param2_value_a(operation_param2_value_a); + opes_reply.set_operation_param2_value_b(operation_param2_value_b); + opes_reply.set_operation_param2_ionref_ionsharefd( + operation_param2_ionref_ionsharefd); + opes_reply.set_operation_param2_ionref_ionsize(operation_param2_ionref_ionsize); + + opes_reply.set_operation_param3_tmpref_buffer(operation_param3_tmpref_buffer); + opes_reply.set_operation_param3_tmpref_size(operation_param3_tmpref_size); + opes_reply.set_operation_param3_memref_parent(operation_param3_memref_parent); + opes_reply.set_operation_param3_memref_size(operation_param3_memref_size); + opes_reply.set_operation_param3_memref_offset(operation_param3_memref_offset); + opes_reply.set_operation_param3_value_a(operation_param3_value_a); + opes_reply.set_operation_param3_value_b(operation_param3_value_b); + opes_reply.set_operation_param3_ionref_ionsharefd( + operation_param3_ionref_ionsharefd); + opes_reply.set_operation_param3_ionref_ionsize(operation_param3_ionref_ionsize); + + opes_reply.set_operation_param4_tmpref_buffer(operation_param4_tmpref_buffer); + opes_reply.set_operation_param4_tmpref_size(operation_param4_tmpref_size); + opes_reply.set_operation_param4_memref_parent(operation_param4_memref_parent); + opes_reply.set_operation_param4_memref_size(operation_param4_memref_size); + opes_reply.set_operation_param4_memref_offset(operation_param4_memref_offset); + opes_reply.set_operation_param4_value_a(operation_param4_value_a); + opes_reply.set_operation_param4_value_b(operation_param4_value_b); + opes_reply.set_operation_param4_ionref_ionsharefd( + operation_param4_ionref_ionsharefd); + opes_reply.set_operation_param4_ionref_ionsize(operation_param4_ionref_ionsize); + + opes_reply.set_operation_session(operation_session); + opes_reply.set_operation_cancelflag(operation_cancelflag); + opes_reply.set_returnorigin(returnorigin); + + status_ = FINISH; + gettimeofday(&end, NULL); + int64_t i64Time; + i64Time = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("gpp opensession used time: %ld us. \n", i64Time); + + status_ = FINISH; + + opes_response.Finish(opes_reply, Status::OK, this); + } + }else + { + std::cout << "gpp receive no opensession jwtsvid or validate jwt failed" << std::endl; + flag = 2; + opes_reply.set_flag(flag); + status_ = FINISH; + opes_response.Finish(opes_reply, Status::OK, this); + } + break; + } + + case ServerImpl::CallData::SS_TEECC_CloseSession: + { + struct timeval start, end, jwt_validate_start, jwt_validate_end; + gettimeofday(&start, NULL); + + std::uint32_t in_session_sessionid; + std::uint32_t in_session_serviceid_timelow; + std::uint32_t in_session_serviceid_timemid; + std::uint32_t in_session_serviceid_timehiandver; + std::uint32_t in_session_serviceid_clockseqandnode_size; + std::uint32_t *in_session_serviceid_clockseqandnode; + std::uint32_t in_session_opscnt; + std::uint64_t in_session_head_next; + std::uint64_t in_session_head_prev; + std::uint64_t in_session_context; + + std::uint32_t sessionid; + std::uint32_t serviceid_timelow; + std::uint32_t serviceid_timemid; + std::uint32_t serviceid_timehiandver; + std::uint32_t *serviceid_clockseqandnode; + std::uint32_t serviceid_clockseqandnode_outsize; + int serviceid_clockseqandnode_realsize; + std::uint32_t opscnt; + std::uint64_t head_next; + std::uint64_t head_prev; + std::uint64_t session_context; + + std::uint32_t serial = 0; + std::int32_t flag = 0; + + std::string token; + token = close_request.token(); + + std::string noToken("noToken"); + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + gettimeofday(&jwt_validate_start, NULL); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + gettimeofday(&jwt_validate_end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (jwt_validate_end.tv_sec - jwt_validate_start.tv_sec) * 1000000 + + (jwt_validate_end.tv_usec - jwt_validate_start.tv_usec); + printf("gpp closesession validate jwt used time: %ld us. \n", i64Time_jwt); + std::cout << "gpp validate closesession jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate closesession jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate closesession jwtsvid or validate jwt succed" + << std::endl; + std::cout << "gpp received CloseSesssion " << std::endl; + in_session_sessionid = close_request.in_session_sessionid(); + in_session_serviceid_timelow = close_request.in_session_serviceid_timelow(); + in_session_serviceid_timemid = close_request.in_session_serviceid_timemid(); + in_session_serviceid_timehiandver = close_request.in_session_serviceid_timehiandver(); + in_session_serviceid_clockseqandnode_size = close_request.in_session_serviceid_clockseqandnode_size(); + if (in_session_serviceid_clockseqandnode_size > 0) + { + in_session_serviceid_clockseqandnode = new uint32_t[in_session_serviceid_clockseqandnode_size]; + for (int i = 0; i < in_session_serviceid_clockseqandnode_size; i++) + { + in_session_serviceid_clockseqandnode[i] = close_request.in_session_serviceid_clockseqandnode( + i); + } + } + in_session_opscnt = close_request.in_session_opscnt(); + in_session_head_next = close_request.in_session_head_next(); + in_session_head_prev = close_request.in_session_head_prev(); + in_session_context = close_request.in_session_context(); +#if 0 + printf(" in_session_serviceid_timelow = 0x %8.8x \n", in_session_serviceid_timelow); + printf(" in_session_serviceid_timemid = 0x %8.8x \n", in_session_serviceid_timemid); + printf(" in_session_serviceid_timehiandver = 0x %8.8x \n", + in_session_serviceid_timehiandver); + printf(" in_session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_session_serviceid_clockseqandnode_size; i++) { + printf(" %8.8x", in_session_serviceid_clockseqandnode[i]); + } + printf("\n"); + printf(" in_session_serviceid_clockseqandnode_size = 0x %8.8x \n", + in_session_serviceid_clockseqandnode_size); + printf(" in_session_opscnt = 0x %8.8x \n", in_session_opscnt); + printf(" in_session_head_next = 0x %16.16lx \n", in_session_head_next); + printf(" in_session_head_prev = 0x %16.16lx \n", in_session_head_prev); +#endif + std::cout << "gpp received in_session_sessionid: 0x " << std::hex << std::setfill('0') + << std::setw(8) << in_session_sessionid << std::endl; + std::cout << "gpp received in_session_context: 0x " << std::hex << std::setfill('0') + << std::setw(16) << in_session_context << std::endl; + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (std::uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(std::uint32_t) + ); + char workername[1024]; + memset((char *) workername, 0, 1024); + int ifound = 0; + int iworker; + sin_t *sinIns; + + pthread_mutex_lock(mutex_workerrec_); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec_[iworker].context_addr == in_session_context) + { + sinIns = NULL; + if (workerrec_[iworker].first != NULL) + { + sinIns = workerrec_[iworker].first; + do + { + if (sinIns->session_id == in_session_sessionid) + { + sprintf(workername, "%s%d", "gpworker", iworker); + std::cout << "gpp method call worker No: " << std::dec << iworker << std::endl; + ifound = 1; + break; + } + sinIns = sinIns->next; + } while (sinIns != NULL); + + if (ifound == 1) + { + break; + } + } + } + } + pthread_mutex_unlock(mutex_workerrec_); + if (ifound == 0) + { + printf("gpp can't find the worker for the session and the context. \n"); + + sessionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + session_context = 0x0; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize; i++) + { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + close_reply.set_session_sessionid(sessionid); + close_reply.set_session_serviceid_timelow(serviceid_timelow); + close_reply.set_session_serviceid_timemid(serviceid_timemid); + close_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + close_reply.set_session_serviceid_cad_outsize(serviceid_clockseqandnode_outsize); + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + close_reply.add_session_serviceid_clockseqandnode(serviceid_clockseqandnode[i]); + } + close_reply.set_session_opscnt(opscnt); + close_reply.set_session_head_next(head_next); + close_reply.set_session_head_prev(head_prev); + close_reply.set_session_context(session_context); + + status_ = FINISH; + + close_response.Finish(close_reply, Status::OK, this); + } else + { + method_call_teec_closesession( + workername, + + in_session_sessionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &sessionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &session_context + ); + pthread_mutex_lock(mutex_workerrec_); + sin_t *sinTemp; + sinTemp = sinIns->prev; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + workerrec_[iworker].context_createtime = tvcreate; + if (sinTemp != NULL) + { + sinTemp->next = sinIns->next; + } + sinTemp = sinIns->next; + if (sinTemp != NULL) + { + sinTemp->prev = sinIns->prev; + } + if (workerrec_[iworker].last == sinIns) + { + workerrec_[iworker].last = sinIns->prev; + } + if (workerrec_[iworker].first == sinIns) + { + workerrec_[iworker].first = sinIns->next; + } + free(sinIns); + workerrec_[iworker].sessionid_count = + workerrec_[iworker].sessionid_count - 1; + pthread_mutex_unlock(mutex_workerrec_); + + serviceid_clockseqandnode_outsize = serviceid_clockseqandnode_outsize_temp; + + if ( + serviceid_clockseqandnode_realsize >= serviceid_clockseqandnode_outsize && + 8 >= serviceid_clockseqandnode_outsize + ) + { + serviceid_clockseqandnode_realsize = serviceid_clockseqandnode_outsize; + } else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode_outsize = 0; + } + close_reply.set_session_sessionid(sessionid); + close_reply.set_session_serviceid_timelow(serviceid_timelow); + close_reply.set_session_serviceid_timemid(serviceid_timemid); + close_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + close_reply.set_session_serviceid_cad_outsize(serviceid_clockseqandnode_outsize); + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + close_reply.add_session_serviceid_clockseqandnode(serviceid_clockseqandnode[i]); + } + close_reply.set_session_opscnt(opscnt); + close_reply.set_session_head_next(head_next); + close_reply.set_session_head_prev(head_prev); + close_reply.set_session_context(session_context); + + gettimeofday(&end, NULL); + int64_t i64Time; + i64Time = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("gpp closesession used time: %ld us. \n", i64Time); + + status_ = FINISH; + + close_response.Finish(close_reply, Status::OK, this); + } + }else + { + std::cout << "gpp receive no closesession jwtsvid or validate jwt failed" << std::endl; + flag = 2; + close_reply.set_flag(flag); + status_ = FINISH; + + close_response.Finish(close_reply, Status::OK, this); + } + + break; + } + + case ServerImpl::CallData::SS_TEECC_InvokeCommand: + { + struct timeval start, end, jwt_validate_start, jwt_validate_end; + gettimeofday(&start, NULL); + + std::uint32_t in_session_sessionid; + std::uint32_t in_session_serviceid_timelow; + std::uint32_t in_session_serviceid_timemid; + std::uint32_t in_session_serviceid_timehiandver; + std::uint32_t in_session_serviceid_clockseqandnode_size; + std::uint32_t *in_session_serviceid_clockseqandnode; + int in_session_serviceid_clockseqandnode_realsize; + std::uint32_t in_session_opscnt; + std::uint64_t in_session_head_next; + std::uint64_t in_session_head_prev; + std::uint64_t in_session_context; + + std::uint32_t in_commandid; + + std::uint32_t in_operation_started; + std::uint32_t in_operation_paramtypes; + + std::uint64_t in_operation_param1_tmpref_buffer; + std::uint32_t in_operation_param1_tmpref_size; + std::uint64_t in_operation_param1_memref_parent; + std::uint32_t in_operation_param1_memref_parent_flag; + std::uint32_t in_operation_param1_memref_size; + std::uint32_t in_operation_param1_memref_offset; + std::uint32_t in_operation_param1_value_a; + std::uint32_t in_operation_param1_value_b; + std::int32_t in_operation_param1_ionref_ionsharefd; + std::uint32_t in_operation_param1_ionref_ionsize; + + std::uint64_t in_operation_param2_tmpref_buffer; + std::uint32_t in_operation_param2_tmpref_size; + std::uint64_t in_operation_param2_memref_parent; + std::uint32_t in_operation_param2_memref_parent_flag; + std::uint32_t in_operation_param2_memref_size; + std::uint32_t in_operation_param2_memref_offset; + std::uint32_t in_operation_param2_value_a; + std::uint32_t in_operation_param2_value_b; + std::int32_t in_operation_param2_ionref_ionsharefd; + std::uint32_t in_operation_param2_ionref_ionsize; + + std::uint64_t in_operation_param3_tmpref_buffer; + std::uint32_t in_operation_param3_tmpref_size; + std::uint64_t in_operation_param3_memref_parent; + std::uint32_t in_operation_param3_memref_parent_flag; + std::uint32_t in_operation_param3_memref_size; + std::uint32_t in_operation_param3_memref_offset; + std::uint32_t in_operation_param3_value_a; + std::uint32_t in_operation_param3_value_b; + std::int32_t in_operation_param3_ionref_ionsharefd; + std::uint32_t in_operation_param3_ionref_ionsize; + + std::uint64_t in_operation_param4_tmpref_buffer; + std::uint32_t in_operation_param4_tmpref_size; + std::uint64_t in_operation_param4_memref_parent; + std::uint32_t in_operation_param4_memref_parent_flag; + std::uint32_t in_operation_param4_memref_size; + std::uint32_t in_operation_param4_memref_offset; + std::uint32_t in_operation_param4_value_a; + std::uint32_t in_operation_param4_value_b; + std::int32_t in_operation_param4_ionref_ionsharefd; + std::uint32_t in_operation_param4_ionref_ionsize; + + std::uint64_t in_operation_session; + std::int32_t in_operation_cancelflag; + + std::uint32_t in_returnorigin; + + std::uint32_t in_buffer1_size; + std::uint32_t *in_buffer1; + int in_buffer1_realsize; + std::uint32_t in_buffer2_size; + std::uint32_t *in_buffer2; + int in_buffer2_realsize; + std::uint32_t in_buffer3_size; + std::uint32_t *in_buffer3; + int in_buffer3_realsize; + std::uint32_t in_buffer4_size; + std::uint32_t *in_buffer4; + int in_buffer4_realsize; + + std::uint32_t teecresult; + + std::uint32_t sessionid; + std::uint32_t serviceid_timelow; + std::uint32_t serviceid_timemid; + std::uint32_t serviceid_timehiandver; + std::uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + std::int32_t serviceid_clockseqandnode_outsize; + std::uint32_t opscnt; + std::uint64_t head_next; + std::uint64_t head_prev; + std::uint64_t session_context; + std::uint32_t started; + std::uint32_t paramtypes; + std::uint64_t operation_param1_tmpref_buffer; + std::uint32_t operation_param1_tmpref_size; + std::uint64_t operation_param1_memref_parent; + std::uint32_t operation_param1_memref_parent_flag; + std::uint32_t operation_param1_memref_size; + std::uint32_t operation_param1_memref_offset; + std::uint32_t operation_param1_value_a; + std::uint32_t operation_param1_value_b; + std::int32_t operation_param1_ionref_ionsharefd; + std::uint32_t operation_param1_ionref_ionsize; + std::uint64_t operation_param2_tmpref_buffer; + std::uint32_t operation_param2_tmpref_size; + std::uint64_t operation_param2_memref_parent; + std::uint32_t operation_param2_memref_parent_flag; + std::uint32_t operation_param2_memref_size; + std::uint32_t operation_param2_memref_offset; + std::uint32_t operation_param2_value_a; + std::uint32_t operation_param2_value_b; + std::int32_t operation_param2_ionref_ionsharefd; + std::uint32_t operation_param2_ionref_ionsize; + std::uint64_t operation_param3_tmpref_buffer; + std::uint32_t operation_param3_tmpref_size; + std::uint64_t operation_param3_memref_parent; + std::uint32_t operation_param3_memref_parent_flag; + std::uint32_t operation_param3_memref_size; + std::uint32_t operation_param3_memref_offset; + std::uint32_t operation_param3_value_a; + std::uint32_t operation_param3_value_b; + std::int32_t operation_param3_ionref_ionsharefd; + std::uint32_t operation_param3_ionref_ionsize; + std::uint64_t operation_param4_tmpref_buffer; + std::uint32_t operation_param4_tmpref_size; + std::uint64_t operation_param4_memref_parent; + std::uint32_t operation_param4_memref_parent_flag; + std::uint32_t operation_param4_memref_size; + std::uint32_t operation_param4_memref_offset; + std::uint32_t operation_param4_value_a; + std::uint32_t operation_param4_value_b; + std::int32_t operation_param4_ionref_ionsharefd; + std::uint32_t operation_param4_ionref_ionsize; + std::uint64_t operation_session; + std::int32_t operation_cancelflag; + std::uint32_t returnorigin; + + std::uint32_t *buffer1; + int buffer1_realsize; + std::uint32_t buffer1_outsize; + std::uint32_t *buffer2; + int buffer2_realsize; + std::uint32_t buffer2_outsize; + std::uint32_t *buffer3; + int buffer3_realsize; + std::uint32_t buffer3_outsize; + std::uint32_t *buffer4; + int buffer4_realsize; + std::uint32_t buffer4_outsize; + + std::uint32_t serial = 0; + std::int32_t flag = 0; + std::string token; + token = invo_request.token(); + + std::string noToken("noToken"); + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + gettimeofday(&jwt_validate_start, NULL); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + gettimeofday(&jwt_validate_end, NULL); + int64_t i64Time_jwt; + i64Time_jwt = (jwt_validate_end.tv_sec - jwt_validate_start.tv_sec) * 1000000 + + (jwt_validate_end.tv_usec - jwt_validate_start.tv_usec); + printf("gpp invokecommand validate jwt used time: %ld us. \n", i64Time_jwt); + std::cout << "gpp validate invokecommand jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate invokecommand jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate invokecommand jwtsvid or validate jwt succed" + << std::endl; + + in_session_sessionid = invo_request.in_session_sessionid(); + in_session_serviceid_timelow = invo_request.in_session_serviceid_timelow(); + in_session_serviceid_timemid = invo_request.in_session_serviceid_timemid(); + in_session_serviceid_timehiandver = invo_request.in_session_serviceid_timehiandver(); + + in_session_serviceid_clockseqandnode_size = invo_request.in_session_serviceid_clockseqandnode_size(); + in_session_serviceid_clockseqandnode_realsize = in_session_serviceid_clockseqandnode_size; + if (in_session_serviceid_clockseqandnode_size > 0) + { + in_session_serviceid_clockseqandnode = new uint32_t[in_session_serviceid_clockseqandnode_size]; + for (int i = 0; i < in_session_serviceid_clockseqandnode_size; i++) + { + in_session_serviceid_clockseqandnode[i] = invo_request.in_session_serviceid_clockseqandnode( + i); + } + } + in_session_opscnt = invo_request.in_session_opscnt(); + in_session_head_next = invo_request.in_session_head_next(); + in_session_head_prev = invo_request.in_session_head_prev(); + in_session_context = invo_request.in_session_context(); + in_commandid = invo_request.in_commandid(); + in_operation_started = invo_request.in_operation_started(); + in_operation_paramtypes = invo_request.in_operation_paramtypes(); + in_operation_param1_tmpref_buffer = invo_request.in_operation_param1_tmpref_buffer(); + in_operation_param1_tmpref_size = invo_request.in_operation_param1_tmpref_size(); + in_operation_param1_memref_parent_flag = invo_request.in_operation_param1_memref_parent_flag(); + in_operation_param1_memref_parent = invo_request.in_operation_param1_memref_parent(); + in_operation_param1_memref_size = invo_request.in_operation_param1_memref_size(); + in_operation_param1_memref_offset = invo_request.in_operation_param1_memref_offset(); + in_operation_param1_value_a = invo_request.in_operation_param1_value_a(); + in_operation_param1_value_b = invo_request.in_operation_param1_value_b(); + in_operation_param1_ionref_ionsharefd = invo_request.in_operation_param1_ionref_ionsharefd(); + in_operation_param1_ionref_ionsize = invo_request.in_operation_param1_ionref_ionsize(); + + in_operation_param2_tmpref_buffer = invo_request.in_operation_param2_tmpref_buffer(); + in_operation_param2_tmpref_size = invo_request.in_operation_param2_tmpref_size(); + in_operation_param2_memref_parent = invo_request.in_operation_param2_memref_parent(); + in_operation_param2_memref_parent_flag = invo_request.in_operation_param2_memref_parent_flag(); + in_operation_param2_memref_size = invo_request.in_operation_param2_memref_size(); + in_operation_param2_memref_offset = invo_request.in_operation_param2_memref_offset(); + in_operation_param2_value_a = invo_request.in_operation_param2_value_a(); + in_operation_param2_value_b = invo_request.in_operation_param2_value_b(); + in_operation_param2_ionref_ionsharefd = invo_request.in_operation_param2_ionref_ionsharefd(); + in_operation_param2_ionref_ionsize = invo_request.in_operation_param2_ionref_ionsize(); + + in_operation_param3_tmpref_buffer = invo_request.in_operation_param3_tmpref_buffer(); + in_operation_param3_tmpref_size = invo_request.in_operation_param3_tmpref_size(); + in_operation_param3_memref_parent = invo_request.in_operation_param3_memref_parent(); + in_operation_param3_memref_parent_flag = invo_request.in_operation_param3_memref_parent_flag(); + in_operation_param3_memref_size = invo_request.in_operation_param3_memref_size(); + in_operation_param3_memref_offset = invo_request.in_operation_param3_memref_offset(); + in_operation_param3_value_a = invo_request.in_operation_param3_value_a(); + in_operation_param3_value_b = invo_request.in_operation_param3_value_b(); + in_operation_param3_ionref_ionsharefd = invo_request.in_operation_param3_ionref_ionsharefd(); + in_operation_param3_ionref_ionsize = invo_request.in_operation_param3_ionref_ionsize(); + + in_operation_param4_tmpref_buffer = invo_request.in_operation_param4_tmpref_buffer(); + in_operation_param4_tmpref_size = invo_request.in_operation_param4_tmpref_size(); + in_operation_param4_memref_parent = invo_request.in_operation_param4_memref_parent(); + in_operation_param4_memref_parent_flag = invo_request.in_operation_param4_memref_parent_flag(); + in_operation_param4_memref_size = invo_request.in_operation_param4_memref_size(); + in_operation_param4_memref_offset = invo_request.in_operation_param4_memref_offset(); + in_operation_param4_value_a = invo_request.in_operation_param4_value_a(); + in_operation_param4_value_b = invo_request.in_operation_param4_value_b(); + in_operation_param4_ionref_ionsharefd = invo_request.in_operation_param4_ionref_ionsharefd(); + in_operation_param4_ionref_ionsize = invo_request.in_operation_param4_ionref_ionsize(); + + in_operation_session = invo_request.in_operation_session(); + in_operation_cancelflag = invo_request.in_operation_cancelflag(); + in_returnorigin = invo_request.in_returnorigin(); + + in_buffer1_size = invo_request.in_buffer1_size(); + in_buffer1_realsize = in_buffer1_size; + if (in_buffer1_size > 0) + { + in_buffer1 = new uint32_t[in_buffer1_size]; + for (int i = 0; i < in_buffer1_size; i++) + { + in_buffer1[i] = invo_request.in_buffer1(i); + } + } + + in_buffer2_size = invo_request.in_buffer2_size(); + in_buffer2_realsize = in_buffer2_size; + if (in_buffer2_size > 0) + { + in_buffer2 = new uint32_t[in_buffer2_size]; + for (int i = 0; i < in_buffer2_size; i++) + { + in_buffer2[i] = invo_request.in_buffer2(i); + } + } + + in_buffer3_size = invo_request.in_buffer3_size(); + in_buffer3_realsize = in_buffer3_size; + if (in_buffer3_size > 0) + { + in_buffer3 = new uint32_t[in_buffer3_size]; + for (int i = 0; i < in_buffer3_size; i++) + { + in_buffer3[i] = invo_request.in_buffer3(i); + } + } + + in_buffer4_size = invo_request.in_buffer4_size(); + in_buffer4_realsize = in_buffer4_size; + if (in_buffer4_size > 0) + { + in_buffer4 = new uint32_t[in_buffer4_size]; + for (int i = 0; i < in_buffer4_size; i++) + { + in_buffer4[i] = invo_request.in_buffer4(i); + } + } + + std::cout << "gpp received InvokeCommand " << std::endl; + std::cout << "gpp received in_session_sessionid: 0x " + << std::hex << std::setfill('0') << std::setw(8) << in_session_sessionid << std::endl; +#if 0 + printf(" in_session_serviceid_timelow = 0x %8.8x \n", in_session_serviceid_timelow); + printf(" in_session_serviceid_timemid = 0x %8.8x \n", in_session_serviceid_timemid); + printf(" in_session_serviceid_timehiandver = 0x %8.8x \n", + in_session_serviceid_timehiandver); + printf(" in_session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", in_session_serviceid_clockseqandnode[i]); + } + printf("\n"); + printf(" in serviceid_clockseqandnode_size = 0x %8.8x \n", + in_session_serviceid_clockseqandnode_size); + printf(" in_session_opscnt = 0x %8.8x \n", in_session_opscnt); + printf(" in_session_head_next = 0x %16.16lx \n", in_session_head_next); + printf(" in_session_head_prev = 0x %16.16lx \n", in_session_head_prev); +#endif + std::cout << "gpp received in_session_context: 0x " << std::hex << std::setfill('0') + << std::setw(16) << in_session_context << std::endl; + +#if 0 + printf(" commandid = 0x %8.8x \n", in_commandid); + printf(" in_operation_started = 0x %8.8x \n", in_operation_started); + printf(" in_operation_paramtypes = 0x %8.8x \n", in_operation_paramtypes); + printf(" in_operation_param1_tmpref_buffer = 0x %16.16lx \n", in_operation_param1_tmpref_buffer); + printf(" in_operation_param1_tmpref_size = 0x %8.8x \n", in_operation_param1_tmpref_size); + printf(" in_operation_param1_memref_parent = 0x %16.16lx \n", in_operation_param1_memref_parent); + printf(" in_operation_param1_memref_size = 0x %8.8x \n", in_operation_param1_memref_size); + printf(" in_operation_param1_memref_offset = 0x %8.8x \n", in_operation_param1_memref_offset); + printf(" in_operation_param1_value_a = 0x %8.8x \n", in_operation_param1_value_a); + printf(" in_operation_param1_value_b = 0x %8.8x \n", in_operation_param1_value_b); + printf(" in_operation_param1_ionref_ionsharefd = 0x %8.8x \n",in_operation_param2_ionref_ionsharefd); + printf(" in_operation_param1_ionref_ionsize = 0x %8.8x \n", in_operation_param2_ionref_ionsize); + + printf(" in_operation_param2_tmpref_buffer = 0x %16.16lx \n", in_operation_param2_tmpref_buffer); + printf(" in_operation_param2_tmpref_size = 0x %8.8x \n", in_operation_param2_tmpref_size); + printf(" in_operation_param2_memref_parent = 0x %16.16lx \n", in_operation_param2_memref_parent); + printf(" in_operation_param2_memref_size = 0x %8.8x \n", in_operation_param2_memref_size); + printf(" in_operation_param2_memref_offset = 0x %8.8x \n", in_operation_param2_memref_offset); + printf(" in_operation_param2_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param2_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param2_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param2_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param3_tmpref_buffer = 0x %16.16lx \n", in_operation_param3_tmpref_buffer); + printf(" in_operation_param3_tmpref_size = 0x %8.8x \n", in_operation_param3_tmpref_size); + printf(" in_operation_param3_memref_parent = 0x %16.16lx \n", in_operation_param3_memref_parent); + printf(" in_operation_param3_memref_size = 0x %8.8x \n", in_operation_param3_memref_size); + printf(" in_operation_param3_memref_offset = 0x %8.8x \n", in_operation_param3_memref_offset); + printf(" in_operation_param3_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param3_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param3_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param3_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param4_tmpref_buffer = 0x %16.16lx \n", in_operation_param4_tmpref_buffer); + printf(" in_operation_param4_tmpref_size = 0x %8.8x \n", in_operation_param4_tmpref_size); + printf(" in_operation_param4_memref_parent = 0x %16.16lx \n", in_operation_param4_memref_parent); + printf(" in_operation_param4_memref_size = 0x %8.8x \n", in_operation_param4_memref_size); + printf(" in_operation_param4_memref_offset = 0x %8.8x \n", in_operation_param4_memref_offset); + printf(" in_operation_param4_value_a = 0x %8.8x \n", in_operation_param4_value_a); + printf(" in_operation_param4_value_b = 0x %8.8x \n", in_operation_param4_value_b); + printf(" in_operation_param4_ionref_ionsharefd = 0x %8.8x \n", in_operation_param4_ionref_ionsharefd); + printf(" in_operation_param4_ionref_ionsize = 0x %8.8x \n", in_operation_param4_ionref_ionsize); + + printf(" in_operation_session = 0x %16.16lx \n", in_operation_session); + printf(" in_operation_cancelflag = 0x %8.8x \n", in_operation_cancelflag); + + printf(" in_returnorigin = 0x %8.8x \n", in_returnorigin); + + printf(" in_buffer1 = \n"); + if (in_buffer1_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer1_realsize; i++) { + printf(" %2.2x", in_buffer1[i]); + } + printf("\n"); + } +#endif + +#if 0 + printf(" in_buffer1_size = 0x %8.8x \n", + in_buffer1_size); +#endif + +#if 0 + printf(" in_buffer2 = \n"); + if (in_buffer2_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer2_realsize; i++) { + printf(" %2.2x", in_buffer2[i]); + } + printf("\n"); + } + printf(" in_buffer2_size = 0x %8.8x \n", + in_buffer2_size); + + printf(" in_buffer3 = \n"); + if (in_buffer3_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer3_realsize; i++) { + printf(" %2.2x", in_buffer3[i]); + } + printf("\n"); + } + printf(" in_buffer3_size = 0x %8.8x \n", + in_buffer3_size); + + printf(" in_buffer4 = \n"); + if (in_buffer4_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer4_realsize; i++) { + printf(" %2.2x", in_buffer4[i]); + } + printf("\n"); + } + printf(" in_buffer4_size = 0x %8.8x \n", + in_buffer4_size); + +#endif + if (in_buffer1_size > 0) + { + } else + { + in_buffer1_realsize = 0; + } + if (in_buffer2_size > 0) + { + } else + { + in_buffer2_realsize = 0; + } + if (in_buffer3_size > 0) + { + } else + { + in_buffer3_realsize = 0; + } + if (in_buffer4_size > 0) + { + } else + { + in_buffer4_realsize = 0; + } + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + uint32_t serviceid_clockseqandnode_outsize_temp; + uint32_t returnorigin_temp; + + uint32_t *buffer1_temp = NULL; + uint32_t buffer1_size = 4096; + uint32_t buffer1_outsize_temp; + buffer1_temp = + (uint32_t *) malloc(buffer1_size * sizeof(uint32_t)); + + uint32_t buffer2_size = 4096; + uint32_t *buffer2_temp = NULL; + uint32_t buffer2_outsize_temp; + buffer2_temp = + (uint32_t *) malloc(buffer2_size * sizeof(uint32_t)); + + uint32_t buffer3_size = 4096; + uint32_t *buffer3_temp = NULL; + uint32_t buffer3_outsize_temp; + buffer3_temp = + (uint32_t *) malloc(buffer3_size * sizeof(uint32_t)); + + uint32_t buffer4_size = 4096; + uint32_t *buffer4_temp = NULL; + uint32_t buffer4_outsize_temp; + buffer4_temp = + (uint32_t *) malloc(buffer4_size * sizeof(uint32_t)); + + char workername[1024]; + memset((char *) workername, 0, 1024); + int ifound = 0; + int iworker; + sin_t *sinIns; + + pthread_mutex_lock(mutex_workerrec_); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec_[iworker].context_addr == in_session_context) + { + sinIns = NULL; + if (workerrec_[iworker].first != NULL) + { + sinIns = workerrec_[iworker].first; + do + { + if (sinIns->session_id == in_session_sessionid) + { + sprintf(workername, "%s%d", "gpworker", iworker); + std::cout << "gpp method call worker No: " << std::dec << iworker << std::endl; + ifound = 1; + break; + } + sinIns = sinIns->next; + } while (sinIns != NULL); + if (ifound == 1) + { + break; + } + } + } + } + pthread_mutex_unlock(mutex_workerrec_); + + if (ifound == 0) + { + printf("gpp can't find the worker for the session and the context. \n"); + + teecresult = 0xAAAA0017; + + sessionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + session_context = 0x0; + started = 0x0; + paramtypes = 0x0; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize; i++) + { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + + operation_param1_tmpref_buffer = 0x0; + operation_param1_tmpref_size = 0x0; + operation_param1_memref_parent = 0x0; + operation_param1_memref_size = 0x0; + operation_param1_memref_offset = 0x0; + operation_param1_value_a = 0x0; + operation_param1_value_b = 0x0; + operation_param1_ionref_ionsharefd = 0x0; + operation_param1_ionref_ionsize = 0x0; + + operation_param2_tmpref_buffer = 0x0; + operation_param2_tmpref_size = 0x0; + operation_param2_memref_parent = 0x0; + operation_param2_memref_size = 0x0; + operation_param2_memref_offset = 0x0; + operation_param2_value_a = 0x0; + operation_param2_value_b = 0x0; + operation_param2_ionref_ionsharefd = 0x0; + operation_param2_ionref_ionsize = 0x0; + + operation_param3_tmpref_buffer = 0x0; + operation_param3_tmpref_size = 0x0; + operation_param3_memref_parent = 0x0; + operation_param3_memref_size = 0x0; + operation_param3_memref_offset = 0x0; + operation_param3_value_a = 0x0; + operation_param3_value_b = 0x0; + operation_param3_ionref_ionsharefd = 0x0; + operation_param3_ionref_ionsize = 0x0; + + operation_param4_tmpref_buffer = 0x0; + operation_param4_tmpref_size = 0x0; + operation_param4_memref_parent = 0x0; + operation_param4_memref_size = 0x0; + operation_param4_memref_offset = 0x0; + operation_param4_value_a = 0x0; + operation_param4_value_b = 0x0; + operation_param4_ionref_ionsharefd = 0x0; + operation_param4_ionref_ionsize = 0x0; + + operation_session = 0x0; + operation_cancelflag = 0x0; + + returnorigin = 0x0; + + buffer1_realsize = 0; + buffer1_outsize = buffer1_realsize; + + buffer2_realsize = 0; + buffer2_outsize = buffer2_realsize; + + buffer3_realsize = 0; + buffer3_outsize = buffer3_realsize; + + buffer4_realsize = 0; + buffer4_outsize = buffer4_realsize; + + invo_reply.set_teecresult(teecresult); + invo_reply.set_session_sessionid(sessionid); + invo_reply.set_session_serviceid_timelow(serviceid_timelow); + invo_reply.set_session_serviceid_timemid(serviceid_timemid); + invo_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + invo_reply.set_session_serviceid_clockseqandnode_outsize(serviceid_clockseqandnode_outsize); + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + invo_reply.add_session_serviceid_clockseqandnode(serviceid_clockseqandnode[i]); + } + invo_reply.set_session_opscnt(opscnt); + invo_reply.set_session_head_next(head_next); + invo_reply.set_session_head_prev(head_prev); + invo_reply.set_session_context(session_context); + invo_reply.set_operation_started(started); + invo_reply.set_operation_paramtypes(paramtypes); + + invo_reply.set_operation_param1_tmpref_buffer(operation_param1_tmpref_buffer); + invo_reply.set_operation_param1_tmpref_size(operation_param1_tmpref_size); + invo_reply.set_operation_param1_memref_parent(operation_param1_memref_parent); + invo_reply.set_operation_param1_memref_parent_flag(in_operation_param1_memref_parent_flag); + invo_reply.set_operation_param1_memref_size(operation_param1_memref_size); + invo_reply.set_operation_param1_memref_offset(operation_param1_memref_offset); + invo_reply.set_operation_param1_value_a(operation_param1_value_a); + invo_reply.set_operation_param1_value_b(operation_param1_value_b); + invo_reply.set_operation_param1_ionref_ionsharefd(operation_param1_ionref_ionsharefd); + invo_reply.set_operation_param1_ionref_ionsize(operation_param1_ionref_ionsize); + + invo_reply.set_operation_param2_tmpref_buffer(operation_param2_tmpref_buffer); + invo_reply.set_operation_param2_tmpref_size(operation_param2_tmpref_size); + invo_reply.set_operation_param2_memref_parent(operation_param2_memref_parent); + invo_reply.set_operation_param2_memref_parent_flag(in_operation_param2_memref_parent_flag); + invo_reply.set_operation_param2_memref_size(operation_param2_memref_size); + invo_reply.set_operation_param2_memref_offset(operation_param2_memref_offset); + invo_reply.set_operation_param2_value_a(operation_param2_value_a); + invo_reply.set_operation_param2_value_b(operation_param2_value_b); + invo_reply.set_operation_param2_ionref_ionsharefd(operation_param2_ionref_ionsharefd); + invo_reply.set_operation_param2_ionref_ionsize(operation_param2_ionref_ionsize); + + invo_reply.set_operation_param3_tmpref_buffer(operation_param3_tmpref_buffer); + invo_reply.set_operation_param3_tmpref_size(operation_param3_tmpref_size); + invo_reply.set_operation_param3_memref_parent(operation_param3_memref_parent); + invo_reply.set_operation_param3_memref_parent_flag(in_operation_param3_memref_parent_flag); + invo_reply.set_operation_param3_memref_size(operation_param3_memref_size); + invo_reply.set_operation_param3_memref_offset(operation_param3_memref_offset); + invo_reply.set_operation_param3_value_a(operation_param3_value_a); + invo_reply.set_operation_param3_value_b(operation_param3_value_b); + invo_reply.set_operation_param3_ionref_ionsharefd(operation_param3_ionref_ionsharefd); + invo_reply.set_operation_param3_ionref_ionsize(operation_param3_ionref_ionsize); + + invo_reply.set_operation_param4_tmpref_buffer(operation_param4_tmpref_buffer); + invo_reply.set_operation_param4_tmpref_size(operation_param4_tmpref_size); + invo_reply.set_operation_param4_memref_parent(operation_param4_memref_parent); + invo_reply.set_operation_param4_memref_parent_flag(in_operation_param4_memref_parent_flag); + invo_reply.set_operation_param4_memref_size(operation_param4_memref_size); + invo_reply.set_operation_param4_memref_offset(operation_param4_memref_offset); + invo_reply.set_operation_param4_value_a(operation_param4_value_a); + invo_reply.set_operation_param4_value_b(operation_param4_value_b); + invo_reply.set_operation_param4_ionref_ionsharefd(operation_param4_ionref_ionsharefd); + invo_reply.set_operation_param4_ionref_ionsize(operation_param4_ionref_ionsize); + + invo_reply.set_operation_session(operation_session); + invo_reply.set_operation_cancelflag(operation_cancelflag); + invo_reply.set_returnorigin(returnorigin); + + invo_reply.set_buffer1_outsize(buffer1_realsize); + invo_reply.set_buffer2_outsize(buffer2_realsize); + invo_reply.set_buffer3_outsize(buffer3_realsize); + invo_reply.set_buffer4_outsize(buffer4_realsize); + + if (buffer1_realsize > 0 && + buffer1 != NULL + ) + { + for (int i = 0; i < buffer1_realsize; i++) + + invo_reply.add_buffer1(buffer1[i]); + } + + if (buffer2_realsize > 0 && + buffer2 != NULL + ) + { + for (int i = 0; i < buffer2_realsize; i++) + invo_reply.add_buffer2(buffer2[i]); + } + + if (buffer3_realsize > 0 && + buffer3 != NULL + ) + { + for (int i = 0; i < buffer3_realsize; i++) + invo_reply.add_buffer3(buffer3[i]); + } + + if (buffer4_realsize > 0 && + buffer4 != NULL + ) + { + for (int i = 0; i < buffer4_realsize; i++) + invo_reply.add_buffer4(buffer4[i]); + } + status_ = FINISH; + + invo_response.Finish(invo_reply, Status::OK, this); + } else + { + method_call_teec_invokecommand( + workername, + + in_session_sessionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_realsize, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + in_commandid, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_parent_flag, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_parent_flag, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_parent_flag, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_parent_flag, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + + in_returnorigin, + + in_buffer1, + in_buffer1_realsize, + in_buffer2, + in_buffer2_realsize, + in_buffer3, + in_buffer3_realsize, + in_buffer4, + in_buffer4_realsize, + + + &teecresult, + + &sessionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + + &opscnt, + &head_next, + &head_prev, + &session_context, + + &started, + ¶mtypes, + + &operation_param1_tmpref_buffer, + &operation_param1_tmpref_size, + &operation_param1_memref_parent, + &operation_param1_memref_parent_flag, + &operation_param1_memref_size, + &operation_param1_memref_offset, + &operation_param1_value_a, + &operation_param1_value_b, + &operation_param1_ionref_ionsharefd, + &operation_param1_ionref_ionsize, + + &operation_param2_tmpref_buffer, + &operation_param2_tmpref_size, + &operation_param2_memref_parent, + &operation_param2_memref_parent_flag, + &operation_param2_memref_size, + &operation_param2_memref_offset, + &operation_param2_value_a, + &operation_param2_value_b, + &operation_param2_ionref_ionsharefd, + &operation_param2_ionref_ionsize, + + &operation_param3_tmpref_buffer, + &operation_param3_tmpref_size, + &operation_param3_memref_parent, + &operation_param3_memref_parent_flag, + &operation_param3_memref_size, + &operation_param3_memref_offset, + &operation_param3_value_a, + &operation_param3_value_b, + &operation_param3_ionref_ionsharefd, + &operation_param3_ionref_ionsize, + + &operation_param4_tmpref_buffer, + &operation_param4_tmpref_size, + &operation_param4_memref_parent, + &operation_param4_memref_parent_flag, + &operation_param4_memref_size, + &operation_param4_memref_offset, + &operation_param4_value_a, + &operation_param4_value_b, + &operation_param4_ionref_ionsharefd, + &operation_param4_ionref_ionsize, + + &operation_session, + &operation_cancelflag, + + &returnorigin_temp, + + buffer1_temp, + buffer1_size, + &buffer1_outsize_temp, + buffer2_temp, + buffer2_size, + &buffer2_outsize_temp, + buffer3_temp, + buffer3_size, + &buffer3_outsize_temp, + buffer4_temp, + buffer4_size, + &buffer4_outsize_temp + ); + + pthread_mutex_lock(mutex_workerrec_); + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + workerrec_[iworker].context_createtime = tvcreate; + sinIns->session_createtime = tvcreate; + pthread_mutex_unlock(mutex_workerrec_); + + serviceid_clockseqandnode_outsize = + serviceid_clockseqandnode_outsize_temp; + + returnorigin = returnorigin_temp; + + buffer1_outsize = buffer1_outsize_temp; + buffer2_outsize = buffer2_outsize_temp; + buffer3_outsize = buffer3_outsize_temp; + buffer4_outsize = buffer4_outsize_temp; + + + buffer1_realsize = buffer1_outsize; + if (buffer1_realsize > 0) + { + buffer1 = + (uint32_t *) malloc( + buffer1_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < buffer1_realsize; i++) + { + buffer1[i] = (uint32_t) buffer1_temp[i]; + } + } + buffer2_realsize = buffer2_outsize; + if (buffer2_realsize > 0) + { + buffer2 = + (uint32_t *) malloc( + buffer2_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < buffer2_realsize; i++) + { + buffer2[i] = (uint32_t) buffer2_temp[i]; + } + } + + buffer3_realsize = buffer3_outsize; + if (buffer3_realsize > 0) + { + buffer3 = + (uint32_t *) malloc( + buffer3_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < buffer3_realsize; i++) + { + buffer3[i] = (uint32_t) buffer3_temp[i]; + } + } + + buffer4_realsize = buffer4_outsize; + if (buffer4_realsize > 0) + { + buffer4 = + (uint32_t *) malloc( + buffer4_realsize * sizeof(uint32_t) + ); + for (int i = 0; i < buffer4_realsize; i++) + { + buffer4[i] = (uint32_t) buffer4_temp[i]; + } + } + if (buffer1_temp != NULL) + { + free(buffer1_temp); + } + if (buffer2_temp != NULL) + { + free(buffer2_temp); + } + if (buffer3_temp != NULL) + { + free(buffer3_temp); + } + if (buffer4_temp != NULL) + { + free(buffer4_temp); + } + + invo_reply.set_teecresult(teecresult); + invo_reply.set_session_sessionid(sessionid); + invo_reply.set_session_serviceid_timelow(serviceid_timelow); + invo_reply.set_session_serviceid_timemid(serviceid_timemid); + invo_reply.set_session_serviceid_timehiandver(serviceid_timehiandver); + invo_reply.set_session_serviceid_clockseqandnode_outsize(serviceid_clockseqandnode_outsize); + + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < serviceid_clockseqandnode_outsize; i++) + invo_reply.add_session_serviceid_clockseqandnode(serviceid_clockseqandnode[i]); + } + invo_reply.set_session_opscnt(opscnt); + invo_reply.set_session_head_next(head_next); + invo_reply.set_session_head_prev(head_prev); + invo_reply.set_session_context(session_context); + invo_reply.set_operation_started(started); + invo_reply.set_operation_paramtypes(paramtypes); + + invo_reply.set_operation_param1_tmpref_buffer(operation_param1_tmpref_buffer); + invo_reply.set_operation_param1_tmpref_size(operation_param1_tmpref_size); + invo_reply.set_operation_param1_memref_parent(operation_param1_memref_parent); + invo_reply.set_operation_param1_memref_parent_flag(in_operation_param1_memref_parent_flag); + invo_reply.set_operation_param1_memref_size(operation_param1_memref_size); + invo_reply.set_operation_param1_memref_offset(operation_param1_memref_offset); + invo_reply.set_operation_param1_value_a(operation_param1_value_a); + invo_reply.set_operation_param1_value_b(operation_param1_value_b); + invo_reply.set_operation_param1_ionref_ionsharefd(operation_param1_ionref_ionsharefd); + invo_reply.set_operation_param1_ionref_ionsize(operation_param1_ionref_ionsize); + + invo_reply.set_operation_param2_tmpref_buffer(operation_param2_tmpref_buffer); + invo_reply.set_operation_param2_tmpref_size(operation_param2_tmpref_size); + invo_reply.set_operation_param2_memref_parent(operation_param2_memref_parent); + invo_reply.set_operation_param2_memref_parent_flag(in_operation_param2_memref_parent_flag); + invo_reply.set_operation_param2_memref_size(operation_param2_memref_size); + invo_reply.set_operation_param2_memref_offset(operation_param2_memref_offset); + invo_reply.set_operation_param2_value_a(operation_param2_value_a); + invo_reply.set_operation_param2_value_b(operation_param2_value_b); + invo_reply.set_operation_param2_ionref_ionsharefd(operation_param2_ionref_ionsharefd); + invo_reply.set_operation_param2_ionref_ionsize(operation_param2_ionref_ionsize); + + invo_reply.set_operation_param3_tmpref_buffer(operation_param3_tmpref_buffer); + invo_reply.set_operation_param3_tmpref_size(operation_param3_tmpref_size); + invo_reply.set_operation_param3_memref_parent(operation_param3_memref_parent); + invo_reply.set_operation_param3_memref_parent_flag(in_operation_param3_memref_parent_flag); + invo_reply.set_operation_param3_memref_size(operation_param3_memref_size); + invo_reply.set_operation_param3_memref_offset(operation_param3_memref_offset); + invo_reply.set_operation_param3_value_a(operation_param3_value_a); + invo_reply.set_operation_param3_value_b(operation_param3_value_b); + invo_reply.set_operation_param3_ionref_ionsharefd(operation_param3_ionref_ionsharefd); + invo_reply.set_operation_param3_ionref_ionsize(operation_param3_ionref_ionsize); + + invo_reply.set_operation_param4_tmpref_buffer(operation_param4_tmpref_buffer); + invo_reply.set_operation_param4_tmpref_size(operation_param4_tmpref_size); + invo_reply.set_operation_param4_memref_parent(operation_param4_memref_parent); + invo_reply.set_operation_param4_memref_parent_flag(in_operation_param4_memref_parent_flag); + invo_reply.set_operation_param4_memref_size(operation_param4_memref_size); + invo_reply.set_operation_param4_memref_offset(operation_param4_memref_offset); + invo_reply.set_operation_param4_value_a(operation_param4_value_a); + invo_reply.set_operation_param4_value_b(operation_param4_value_b); + invo_reply.set_operation_param4_ionref_ionsharefd(operation_param4_ionref_ionsharefd); + invo_reply.set_operation_param4_ionref_ionsize(operation_param4_ionref_ionsize); + + invo_reply.set_operation_session(operation_session); + invo_reply.set_operation_cancelflag(operation_cancelflag); + invo_reply.set_returnorigin(returnorigin); + + invo_reply.set_buffer1_outsize(buffer1_realsize); + invo_reply.set_buffer2_outsize(buffer2_realsize); + invo_reply.set_buffer3_outsize(buffer3_realsize); + invo_reply.set_buffer4_outsize(buffer4_realsize); + + if (buffer1_realsize > 0 && + buffer1 != NULL + ) + { + for (int i = 0; i < buffer1_realsize; i++) + + invo_reply.add_buffer1(buffer1[i]); + } + + if (buffer2_realsize > 0 && + buffer2 != NULL + ) + { + for (int i = 0; i < buffer2_realsize; i++) + invo_reply.add_buffer2(buffer2[i]); + } + + if (buffer3_realsize > 0 && + buffer3 != NULL + ) + { + for (int i = 0; i < buffer3_realsize; i++) + invo_reply.add_buffer3(buffer3[i]); + } + + if (buffer4_realsize > 0 && + buffer4 != NULL + ) + { + for (int i = 0; i < buffer4_realsize; i++) + invo_reply.add_buffer4(buffer4[i]); + } + status_ = FINISH; + gettimeofday(&end, NULL); + int64_t i64Time; + i64Time = (end.tv_sec - start.tv_sec) * 1000000 + + (end.tv_usec - start.tv_usec); + printf("gpp invokecommand used time: %ld us. \n", i64Time); + + invo_response.Finish(invo_reply, Status::OK, this); + } + }else + { + std::cout << "gpp receive no invokecommand jwtsvid or validate jwt failed" << std::endl; + flag = 2; + invo_reply.set_flag(flag); + status_ = FINISH; + + invo_response.Finish(invo_reply, Status::OK, this); + } + break; + } + + case ServerImpl::CallData::SS_TEECC_TA: + { + std::string token; + token = ta_chunk.token(); + std::int32_t flag = 0; + + std::string noToken("noToken"); + int ivaljwtResult = -1; + int iforceValidateJwt = global_force_valideta_jwt; + + if + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + ) + { + char Token[1024]; + strcpy(Token, (char *) token.data()); + ivaljwtResult = + dbusmethodcall_validate_jwt( + Token + ); + std::cout << "gpp validate deployta jwtsvid" << std::endl; + } else + { + std::cout << "gpp no validate deployta jwtsvid" << std::endl; + } + + if + ( + iforceValidateJwt != 1 + || + ( + iforceValidateJwt == 1 + && + token.compare(noToken) != 0 + && + ivaljwtResult == NO_ERROR + ) + ) + { + std::cout << "gpp does not need validate deployta jwtsvid or validate jwt succed" << std::endl; + std::cout << "gpp received deployta " << std::endl; + + std::string remote_sha256 = ta_chunk.sha256(); + + std::string subdir = ta_chunk.subdir(); + + std::string name = ta_chunk.name(); + name = "/data/" + subdir + "/" + name; + const char *filename = name.data(); + + std::cout << "gpp deployta, full namepath: " << name << std::endl; + + if (access(name.c_str(), F_OK) != -1) + { + std::cout << "gpp deloyta: ta file exist" << std::endl; + + char *name_temp = const_cast(name.data()); + char local_sha256_temp[SHA256_LENTH]; + int iRet; + iRet = get_file_sha256((char *) name_temp, local_sha256_temp); + if (iRet != 0) + { + ta_reply.set_code(-2); + status_ = FINISH; + + ta_response.Finish(ta_reply, Status::OK, this); + } else + { + + char remote_sha256_temp[SHA256_LENTH + 1]; + strcpy(remote_sha256_temp, remote_sha256.c_str()); + + + + if (memcmp(local_sha256_temp, remote_sha256_temp, SHA256_LENTH) == 0) + { + std::cout << "gpp deloyta: sha256 vals are the same" << std::endl; + + status_ = FINISH; + ta_reply.set_code(0); + + ta_response.Finish(ta_reply, Status::OK, this); + } else + { + std::cout << "gpp deloyta: sha256 vals are different, replace " << filename + << std::endl; + + std::ofstream outfile; + outfile.open(filename, + std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); + + const char *data; + data = ta_chunk.buffer().c_str(); + outfile.write(data, ta_chunk.buffer().length()); + outfile.close(); + + status_ = FINISH; + ta_reply.set_code(0); + + ta_response.Finish(ta_reply, Status::OK, this); + } + + } + } else + { + std::string wholedir; + wholedir = "/data/" + subdir; + const char *charwholedir = wholedir.data(); + + std::cout << "gpp deployta, wholedir: " << wholedir << std::endl; + + struct stat st = {0}; + if (stat(charwholedir, &st) == -1) + { + std::cout << "gpp deployta, make a new dir " << wholedir << std::endl; + + int iResult; + iResult = mkdir(charwholedir, 0600); + + if (iResult != 0) + { + std::cout << "gpp deployta, make a new dir falied" << wholedir << std::endl; + } + } + + if (stat(charwholedir, &st) == 0) + { + std::cout << "gpp deloyta: write a new file " << filename << std::endl; + + std::ofstream outfile; + outfile.open(filename, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); + + const char *data; + data = ta_chunk.buffer().c_str(); + outfile.write(data, ta_chunk.buffer().length()); + outfile.close(); + + status_ = FINISH; + ta_reply.set_code(0); + + ta_response.Finish(ta_reply, Status::OK, this); + } else + { + ta_reply.set_code(-3); + status_ = FINISH; + + ta_response.Finish(ta_reply, Status::OK, this); + } + } + + }else + { + std::cout << "gpp receive no deployta jwtsvid or validate jwt failed" << std::endl; + ta_reply.set_code(-1); + ta_reply.set_flag(flag); + status_ = FINISH; + + ta_response.Finish(ta_reply, Status::OK, this); + } + + break; + } + + default: + break; + } + } else + { + GPR_ASSERT(status_ == FINISH); + delete this; + std::cout << std::endl; + } + } + + private: + gpp::AsyncService *service_; + ServerCompletionQueue *cq_; + ServerContext ctx_; + ServiceType s_type_; + Inicont_Request inicont_request; + Inicont_Reply inicont_reply; + ServerAsyncResponseWriter inicont_response; + Fincont_Request fincont_request; + Fincont_Reply fincont_reply; + ServerAsyncResponseWriter fincont_response; + Opes_Request opes_request; + Opes_Reply opes_reply; + ServerAsyncResponseWriter opes_response; + Close_Request close_request; + Close_Reply close_reply; + ServerAsyncResponseWriter close_response; + Invo_Request invo_request; + Invo_Reply invo_reply; + ServerAsyncResponseWriter invo_response; + TA_Chunk ta_chunk; + TA_Reply ta_reply; + ServerAsyncResponseWriter ta_response; + Setjwt_Request setjwt_request; + Setjwt_Reply setjwt_reply; + ServerAsyncResponseWriter setjwt_response; + + enum CallStatus + { + CREATE, PROCESS, CHECKCANCEL, FINISH + }; + CallStatus status_; + + pthread_mutex_t *mutex_workerrec_; + pthread_cond_t *cond_notbusy_; + wr_t *workerrec_; + }; + + void RunServer() + { + std::string server_address(gpproxy_address); + grpc::EnableDefaultHealthCheckService(true); + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + + + ServerBuilder builder; + builder.SetMaxReceiveMessageSize(50 * 1024 * 1024); + + std::cout << "gpproxy server key path = " << global_serverkey_path << std::endl; + std::cout << "gpproxy server cert path = " << global_servercert_path << std::endl; + std::cout << "gpproxy client ca cert path = " << global_clientcacert_path << std::endl; + + int igrpctls = grpc_tls; + switch (igrpctls) + { + case 0: + { + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + + break; + } + + case 1: + { + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strcmd = "openssl rsa -in " + global_serverkey_path + " -out " + + global_serverkey_path + ".nopass"; + std::string nopass_serverkey_path = global_serverkey_path + ".nopass"; + + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + + + strcmd = "openssl rsa -in " + nopass_serverkey_path + " -check -noout"; + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string keyok("RSA key ok\n"); + + if (result.compare(keyok) != 0) + { + std::cout << "gpp '" + global_serverkey_path + "' integrity is broken" << std::endl; + exit(1); + } + + std::string sigfile_path = global_strcfgfiletemp + "/.gpp/certs/msg.sig"; + std::string msgfile_path = global_strcfgfiletemp + "/.gpp/certs/msg.txt"; + strcmd = + "openssl dgst -sha256 -sign " + nopass_serverkey_path + " -out " + sigfile_path + " " + msgfile_path; + system(strcmd.c_str()); + // ${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + std::string pubkeyfile_path = global_strcfgfiletemp + "/.gpp/certs/server_pubkey.pem"; + strcmd = "openssl x509 -in " + global_servercert_path + " -pubkey -out " + pubkeyfile_path; + system(strcmd.c_str()); + + // ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt + strcmd = "openssl dgst -sha256 -verify " + pubkeyfile_path + " -signature " + sigfile_path + " " + + msgfile_path; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string verifyok("Verified OK\n"); + if (result.compare(verifyok) != 0) + { + std::cout << "gpp '" + global_serverkey_path + "' is not matched with '" + global_servercert_path + "'" + << std::endl; + exit(1); + } + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercert_path + " -checkend " + strdayseconds; + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); +; + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "gpp '" << global_servercert_path << "' will expire in 7 days, please reget it" + << std::endl; + exit(1); + } + + auto serverkey = get_file_contents(nopass_serverkey_path); + strcmd = "rm -f " + global_serverkey_path + ".nopass"; + system(strcmd.c_str()); + strcmd = "rm -f " + pubkeyfile_path; + system(strcmd.c_str()); + strcmd = "rm -f " + sigfile_path; + system(strcmd.c_str()); + + auto servercert = get_file_contents(global_servercert_path); + grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = { + serverkey.c_str(), servercert.c_str() + }; + + grpc::SslServerCredentialsOptions ssl_opts(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE); + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + std::shared_ptr creds; + creds = grpc::SslServerCredentials(ssl_opts); + + builder.AddListeningPort(server_address, creds); + + break; + } + + case 2: + { + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strcmd = "openssl rsa -in " + global_serverkey_path + " -out " + + global_serverkey_path + ".nopass"; + std::string nopass_serverkey_path = global_serverkey_path + ".nopass"; + system(strcmd.c_str()); + + strcmd = "openssl rsa -in " + nopass_serverkey_path + " -check -noout"; + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string keyok("RSA key ok\n"); + if (result.compare(keyok) != 0) + { + std::cout << "gpp '" + global_serverkey_path + "' integrity is broken" << std::endl; + exit(1); + } + + std::string sigfile_path = global_strcfgfiletemp + "/.gpp/certs/msg.sig"; + std::string msgfile_path = global_strcfgfiletemp + "/.gpp/certs/msg.txt"; + strcmd = + "openssl dgst -sha256 -sign " + nopass_serverkey_path + " -out " + sigfile_path + " " + msgfile_path; + system(strcmd.c_str()); + // ${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + std::string pubkeyfile_path = global_strcfgfiletemp + "/.gpp/certs/server_pubkey.pem"; + strcmd = "openssl x509 -in " + global_servercert_path + " -pubkey -out " + pubkeyfile_path; + system(strcmd.c_str()); + + // ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt + strcmd = "openssl dgst -sha256 -verify " + pubkeyfile_path + " -signature " + sigfile_path + " " + + msgfile_path; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string verifyok("Verified OK\n"); + if (result.compare(verifyok) != 0) + { + std::cout << "gpp '" + global_serverkey_path + "' is not matched with '" + global_servercert_path + "'" + << std::endl; + exit(1); + } + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "gpp '" << global_servercert_path << "' will expire in 7 days, please reget it" + << std::endl; + exit(1); + } + + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_clientcacert_path + " -checkend " + strdayseconds; + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "gpp popen '" << strcmd << "' failed" << std::endl; + exit(1); + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "gpp '" << global_clientcacert_path << "' will expire in 7 days, please reget it" + << std::endl; + exit(1); + } + + auto serverkey = get_file_contents(nopass_serverkey_path); + strcmd = "rm -f " + global_serverkey_path + ".nopass"; + system(strcmd.c_str()); + strcmd = "rm -f " + pubkeyfile_path; + system(strcmd.c_str()); + strcmd = "rm -f " + sigfile_path; + system(strcmd.c_str()); + + auto servercert = get_file_contents(global_servercert_path); + auto clientcacert = get_file_contents(global_clientcacert_path); // for verifying clients + grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp = { + serverkey.c_str(), servercert.c_str() + }; + + grpc::SslServerCredentialsOptions ssl_opts(GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY); + ssl_opts.pem_root_certs = clientcacert; + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + std::shared_ptr creds; + creds = grpc::SslServerCredentials(ssl_opts); + + builder.AddListeningPort(server_address, creds); + + break; + } + + default: + { + builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); + } + } + + + // Register "service" as the instance through which we'll communicate with + // clients. In this case it corresponds to an *synchronous* service. + builder.RegisterService(&service_); + + for (int i = 0; i < global_max_num_thread; i++) + { + cq_.emplace_back(builder.AddCompletionQueue()); + } + server_ = builder.BuildAndStart(); + //Finally assemble the server. + std::cout << "gpproxy is listening on " << server_address << std::endl; + + server_threads_.emplace_back(std::thread( + [this] + { + this->session_timeout_process(&mutex_workerrec, workerrec); + } + )); + server_threads_.emplace_back(std::thread( + [this] + { + this->context_timeout_process(&mutex_workerrec, &cond_notbusy, workerrec); + } + )); + + for (unsigned int i = 0; i < global_max_num_thread; i++) + { + server_threads_.emplace_back(std::thread( + [this, i] + { + this->HandleRpcs(i); + })); + std::cout << "thread " << i << " created." << std::endl; + } + std::this_thread::sleep_until(std::chrono::time_point::max()); + } + + void HandleRpcs(int i) + { + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_InitializeContext, + &mutex_workerrec, + &cond_notbusy, + workerrec); + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_FinalizeContext, + &mutex_workerrec, &cond_notbusy, + workerrec); + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_OpenSession, + &mutex_workerrec, + &cond_notbusy, + workerrec); + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_CloseSession, + &mutex_workerrec, + &cond_notbusy, + workerrec); + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_InvokeCommand, + &mutex_workerrec, + &cond_notbusy, + workerrec); + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_TA, + &mutex_workerrec, + &cond_notbusy, + workerrec); + + new CallData(&service_, + cq_[i].get(), + ServerImpl::CallData::SS_TEECC_SetJwt, + &mutex_workerrec, + &cond_notbusy, + workerrec); + + void *tag; + bool ok; + + while (true) + { + GPR_ASSERT(cq_[i]->Next(&tag, &ok)); + std::cout << "gpp thread[" << i << "], cq_[" << i << "]" + << std::endl; + + static_cast(tag)->Process(); + } + } + + void + session_timeout_process( + pthread_mutex_t *mutex_workerrec, + wr_t *workerrec + ) + { + struct timeval tv; + uint64_t u64time; + + char workername[1024]; + memset((char *) workername, 0, 1024); + int iworker; + + uint32_t in_session_seesionid; + uint32_t in_session_serviceid_timelow = 0; + uint32_t in_session_serviceid_timemid = 0; + uint32_t in_session_serviceid_timehiandver = 0; + uint32_t in_session_serviceid_clockseqandnode_size = 8; + uint32_t in_session_serviceid_clockseqandnode[8]; + uint32_t in_session_opscnt = 0; + uint64_t in_session_head_next = 0; + uint64_t in_session_head_prev = 0; + uint64_t in_session_context; + + uint32_t seesionid; + uint32_t serviceid_timelow; + uint32_t serviceid_timemid; + uint32_t serviceid_timehiandver; + uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + uint32_t opscnt; + uint64_t head_next; + uint64_t head_prev; + uint64_t session_context; + + sin_t *sinIns; + + while (1) + { + sleep(global_timeout_session); + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec[iworker].busy == 1) + { + sinIns = NULL; + if (workerrec[iworker].first != NULL) + { + sinIns = workerrec[iworker].first; + do + { + gettimeofday(&tv, NULL); + u64time = (long unsigned int) (tv.tv_sec - + sinIns->session_createtime.tv_sec + ); + sin_t *sinTemp = NULL; + + if (u64time > global_timeout_session) + { + sprintf(workername, "%s%d", "gpworker", iworker); + + in_session_seesionid = sinIns->session_id; + in_session_context = workerrec[iworker].context_addr; + + for (int iind = 0; iind < 8; iind++) + { + in_session_serviceid_clockseqandnode[iind] = 0; + } + + pthread_mutex_unlock(mutex_workerrec); + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + + printf("\ngpp method call teec closesession for timeout process \n"); + method_call_teec_closesession( + workername, + + in_session_seesionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &session_context + ); + + if (serviceid_clockseqandnode != NULL) + { + free(serviceid_clockseqandnode); + } + + pthread_mutex_lock(mutex_workerrec); + + sinTemp = sinIns->prev; + if (sinTemp != NULL) + { + sinTemp->next = sinIns->next; + } + sinTemp = sinIns->next; + if (sinTemp != NULL) + { + sinTemp->prev = sinIns->prev; + } + if (workerrec[iworker].last == sinIns) + { + workerrec[iworker].last = sinIns->prev; + } + if (workerrec[iworker].first == sinIns) + { + workerrec[iworker].first = sinIns->next; + } + + sinTemp = sinIns; + workerrec[iworker].sessionid_count = + workerrec[iworker].sessionid_count - 1; + + } // end of if timedout + sinIns = sinIns->next; + if (sinTemp != NULL) + { + free(sinTemp); + } + } while (sinIns != NULL); + + } // end of the first not null + } // end of the busy = 1 + } // end of the for iworker + pthread_mutex_unlock(mutex_workerrec); + } // end of while 1 + // return NULL; + } + + void + context_timeout_process( + pthread_mutex_t *mutex_workerrec, + pthread_cond_t *cond_notbusy, + wr_t *workerrec + ) + { + struct timeval tv; + uint64_t u64time; + + char workername[1024]; + memset((char *) workername, 0, 1024); + int iworker; + + int32_t in_fd; + unsigned char *in_ta_path = NULL; + int32_t in_ta_path_size = 0; + uint64_t in_session_list_next = 0; + uint64_t in_session_list_prev = 0; + uint64_t in_shrd_mem_list_next = 0; + uint64_t in_shrd_mem_list_prev = 0; + uint64_t in_share_buffer_buffer = 0; + int64_t in_share_buffer_buffer_barrier = 0; + uint64_t in_context_addr; + + int32_t fd; + unsigned char *ta_path; + int32_t ta_path_size; + uint64_t session_list_next; + uint64_t session_list_prev; + uint64_t shrd_mem_list_next; + uint64_t shrd_mem_list_prev; + uint64_t share_buffer_buffer; + int64_t share_buffer_buffer_barrier; + uint32_t context_tapath_outsize; + + while (1) + { + sleep(global_timeout_context); + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < global_max_num_worker; iworker++) + { + if (workerrec[iworker].busy == 1) + { + sprintf(workername, "%s%d", "gpworker", iworker); + gettimeofday(&tv, NULL); + u64time = (long unsigned int) (tv.tv_sec - + workerrec[iworker].context_createtime.tv_sec + ); + + if (u64time > global_timeout_context + && + workerrec[iworker].sessionid_count == 0 + ) + { + in_fd = workerrec[iworker].context_fd; + in_context_addr = workerrec[iworker].context_addr; + ta_path = (unsigned char *) malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *) ta_path, 0, 1024); + + pthread_mutex_unlock(mutex_workerrec); + + printf("\ngpp method call teec finalizecontext for timeout process \n"); + method_call_teec_fincont( + workername, + + in_fd, + in_ta_path, + in_ta_path_size, + in_session_list_next, + in_session_list_prev, + in_shrd_mem_list_next, + in_shrd_mem_list_prev, + in_share_buffer_buffer, + in_share_buffer_buffer_barrier, + in_context_addr, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + + &context_tapath_outsize + ); + + if (ta_path != NULL) + { + free(ta_path); + } + + pthread_mutex_lock(mutex_workerrec); + + workerrec[iworker].busy = 0; + pthread_cond_signal(cond_notbusy); + workerrec[iworker].context_fd = 0; + workerrec[iworker].context_addr = 0xffffffff; + workerrec[iworker].sessionid_count = 0; + sin_t *sinIns; + sin_t *sinInsPrev; + sinIns = workerrec[iworker].last; + if (sinIns != NULL) + { + for (;;) + { + sinInsPrev = sinIns->prev; + free(sinIns); + sinIns = sinInsPrev; + if (sinIns == NULL) + { + break; + } + } + } + + } // end of the if timeed out + } // end of the if busy = 1 + } // end of the for iworker + pthread_mutex_unlock(mutex_workerrec); + + } // end of while 1 + } + +private: + std::vector > cq_; + gpp::AsyncService service_; + std::unique_ptr server_; + std::vector server_threads_; + + pthread_mutex_t mutex_workerrec; + pthread_cond_t cond_notbusy; + wr_t *workerrec = new wr_t[global_max_num_worker]; +}; + + +int main(int argc, char **argv) +{ + std::cout << "gpproxy glo_config file = " << global_strcfgfile << std::endl; + check_config(); + ServerImpl server; + + server.RunServer(); + + return 0; +} diff --git a/teeproxy/gpproxy/gpproxy.h b/teeproxy/gpproxy/gpproxy.h new file mode 100644 index 0000000..18fe311 --- /dev/null +++ b/teeproxy/gpproxy/gpproxy.h @@ -0,0 +1,21 @@ +#ifndef _GPPROXY_H +#define _GPPROXY_H +typedef struct sessionid_node +{ + uint32_t session_id; + struct timeval session_createtime; + struct sessionid_node *next; + struct sessionid_node *prev; +} sin_t; + +typedef struct worker_rec +{ + uint8_t busy; + int32_t context_fd; + uint64_t context_addr; + struct timeval context_createtime; + int sessionid_count; + sin_t *first; + sin_t *last; +} wr_t; +#endif // _GPPROXY_H diff --git a/teeproxy/gpproxy/protos/gt.proto b/teeproxy/gpproxy/protos/gt.proto new file mode 100644 index 0000000..3eeff06 --- /dev/null +++ b/teeproxy/gpproxy/protos/gt.proto @@ -0,0 +1,392 @@ +// + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.gt"; +option java_outer_classname = "gtProto"; +option objc_class_prefix = "HLW"; + +package gt; + +// The gpp service definition. +service gpp { + rpc TEECC_InitializeContext (Inicont_Request) returns (Inicont_Reply) {} + rpc TEECC_FinalizeContext (Fincont_Request) returns (Fincont_Reply) {} + rpc TEECC_OpenSession (Opes_Request) returns (Opes_Reply) {} + rpc TEECC_InvokeCommand (Invo_Request) returns (Invo_Reply) {} + rpc TEECC_CloseSession (Close_Request) returns (Close_Reply) {} + rpc TEECC_TA(TA_Chunk) returns (TA_Reply) {} + rpc TEECC_SetJwt(Setjwt_Request) returns (Setjwt_Reply) {} +} + + +message Inicont_Request { + uint64 name_size = 1; + string name = 2; + string token = 3; + string taname = 4; +} + +message Inicont_Reply { + uint32 teecresult = 1; + int32 context_fd = 2; + uint64 context_tapath_outsize = 3; + bytes context_tapath = 4; + uint64 context_sessionlist_next = 5; + uint64 context_sessionlist_prev = 6; + uint64 context_shrdmemlist_next = 7; + uint64 context_shrdmemlist_prev = 8; + uint64 context_sharebuffer_buffer = 9; + int64 context_sharebuffer_bufferbarrier = 10; + uint64 context_addr = 11; + int32 flag = 12; +} + +message Fincont_Request { + int32 in_context_fd = 1; + uint64 in_context_tapath_size= 2; + bytes in_context_tapath = 3; + uint64 in_context_sessionlist_next = 4; + uint64 in_context_sessionlist_prev = 5; + uint64 in_context_shrdmemlist_next = 6; + uint64 in_context_shrdmemlist_prev = 7; + uint64 in_context_sharebuffer_buffer = 8; + int64 in_context_sharebuffer_bufferbarrier = 9; + uint64 in_context_addr = 10; + string token = 11; + string taname = 12; +} + +message Fincont_Reply { + int32 context_fd = 1; + uint64 context_tapath_outsize = 2; + bytes context_tapath = 3; + uint64 context_sessionlist_next = 4; + uint64 context_sessionlist_prev = 5; + uint64 context_shrdmemlist_next = 6; + uint64 context_shrdmemlist_prev = 7; + uint64 context_sharebuffer_buffer = 8; + int64 context_sharebuffer_bufferbarrier = 9; + uint64 context_addr = 10; + int32 flag = 11; +} + +message Opes_Request { + int32 in_context_fd = 1; + uint64 in_context_tapath_size= 2; + bytes in_context_tapath = 3; + uint64 in_context_sessionlist_next = 4; + uint64 in_context_sessionlist_prev = 5; + uint64 in_context_shrdmemlist_next = 6; + uint64 in_context_shrdmemlist_prev = 7; + uint64 in_context_sharebuffer_buffer = 8; + int64 in_context_sharebuffer_bufferbarrier = 9; + uint32 in_destination_timelow = 10; + uint32 in_destination_timemid = 11; + uint32 in_destination_timehiandver = 12; + uint64 in_destination_cad_size = 13; + repeated uint32 in_destination_clockseqandnode = 14; + uint32 in_connectionmethod = 15; + uint64 in_connectiondata = 16; + uint32 in_operation_started = 17; + uint32 in_operation_paramtypes = 18; + uint64 in_operation_param1_tmpref_buffer = 19; + uint32 in_operation_param1_tmpref_size = 20; + uint64 in_operation_param1_memref_parent = 21; + uint32 in_operation_param1_memref_size = 22; + uint32 in_operation_param1_memref_offset = 23; + uint32 in_operation_param1_value_a = 24; + uint32 in_operation_param1_value_b = 25; + int32 in_operation_param1_ionref_ionsharefd = 26; + uint32 in_operation_param1_ionref_ionsize = 27; + uint64 in_operation_param2_tmpref_buffer = 28; + uint32 in_operation_param2_tmpref_size = 29; + uint64 in_operation_param2_memref_parent = 30; + uint32 in_operation_param2_memref_size = 31; + uint32 in_operation_param2_memref_offset = 32; + uint32 in_operation_param2_value_a = 33; + uint32 in_operation_param2_value_b = 34; + int32 in_operation_param2_ionref_ionsharefd = 35; + uint32 in_operation_param2_ionref_ionsize = 36; + uint64 in_operation_param3_tmpref_buffer = 37; + uint32 in_operation_param3_tmpref_size = 38; + uint64 in_operation_param3_memref_parent = 39; + uint32 in_operation_param3_memref_size = 40; + uint32 in_operation_param3_memref_offset = 41; + uint32 in_operation_param3_value_a = 42; + uint32 in_operation_param3_value_b = 43; + int32 in_operation_param3_ionref_ionsharefd = 44; + uint32 in_operation_param3_ionref_ionsize = 45; + uint64 in_operation_param4_tmpref_buffer = 46; + uint32 in_operation_param4_tmpref_size = 47; + uint64 in_operation_param4_memref_parent = 48; + uint32 in_operation_param4_memref_size = 49; + uint32 in_operation_param4_memref_offset = 50; + uint32 in_operation_param4_value_a = 51; + uint32 in_operation_param4_value_b = 52; + int32 in_operation_param4_ionref_ionsharefd = 53; + uint32 in_operation_param4_ionref_ionsize = 54; + uint64 in_operation_session = 55; + int32 in_operation_cancelflag = 56; + uint32 in_returnorigin = 57; + uint64 in_context_addr = 58; + string token = 59; + string taname = 60; +} + +message Opes_Reply { + uint32 teecresult = 1; + int32 context_fd = 2; + bytes context_tapath = 3 ; + uint64 context_tapath_outsize = 4; + uint64 context_sessionlist_next = 5; + uint64 context_sessionlist_prev = 6; + uint64 context_shrdmemlist_next = 7; + uint64 context_shrdmemlist_prev = 8; + uint64 context_sharebuffer_buffer = 9; + int64 context_sharebuffer_bufferbarrier = 10; + uint32 session_sessionid = 11; + uint32 session_serviceid_timelow = 12; + uint32 session_serviceid_timemid = 13; + uint32 session_serviceid_timehiandver = 14; + uint64 session_serviceid_clockseqandnode_outsize = 15; + repeated uint32 session_serviceid_clockseqandnode = 16; + uint32 session_opscnt = 17; + uint64 session_head_next = 18; + uint64 session_head_prev = 19; + uint64 session_context = 20; + uint32 operation_started = 21; + uint32 operation_paramtypes = 22; + uint64 operation_param1_tmpref_buffer = 23; + uint32 operation_param1_tmpref_size = 24; + uint64 operation_param1_memref_parent = 25; + uint32 operation_param1_memref_size = 26; + uint32 operation_param1_memref_offset = 27; + uint32 operation_param1_value_a = 28; + uint32 operation_param1_value_b = 29; + int32 operation_param1_ionref_ionsharefd = 30; + uint32 operation_param1_ionref_ionsize = 31; + uint64 operation_param2_tmpref_buffer = 32; + uint32 operation_param2_tmpref_size = 33; + uint64 operation_param2_memref_parent = 34; + uint32 operation_param2_memref_size = 35; + uint32 operation_param2_memref_offset = 36; + uint32 operation_param2_value_a = 37; + uint32 operation_param2_value_b = 38; + int32 operation_param2_ionref_ionsharefd = 39; + uint32 operation_param2_ionref_ionsize = 40; + uint64 operation_param3_tmpref_buffer = 41; + uint32 operation_param3_tmpref_size = 42; + uint64 operation_param3_memref_parent = 43; + uint32 operation_param3_memref_size = 44; + uint32 operation_param3_memref_offset = 45; + uint32 operation_param3_value_a = 46; + uint32 operation_param3_value_b = 47; + int32 operation_param3_ionref_ionsharefd = 48; + uint32 operation_param3_ionref_ionsize = 49; + uint64 operation_param4_tmpref_buffer = 50; + uint32 operation_param4_tmpref_size = 51; + uint64 operation_param4_memref_parent = 52; + uint32 operation_param4_memref_size = 53; + uint32 operation_param4_memref_offset = 54; + uint32 operation_param4_value_a = 55; + uint32 operation_param4_value_b = 56; + int32 operation_param4_ionref_ionsharefd = 57; + uint32 operation_param4_ionref_ionsize = 58; + uint64 operation_session = 59; + int32 operation_cancelflag = 60; + uint32 returnorigin = 61; + int32 flag = 62; +} + +message Invo_Request { + uint32 in_session_sessionid = 1; + uint32 in_session_serviceid_timelow = 2; + uint32 in_session_serviceid_timemid = 3; + uint32 in_session_serviceid_timehiandver = 4; + uint64 in_session_serviceid_cad_size = 5; + repeated uint32 in_session_serviceid_clockseqandnode = 6; + uint32 in_session_opscnt = 7; + uint64 in_session_head_next = 8; + uint64 in_session_head_prev = 9; + uint64 in_session_context = 10; + uint32 in_commandid = 11; + uint32 in_operation_started = 12; + uint32 in_operation_paramtypes = 13; + uint64 in_operation_param1_tmpref_buffer = 14; + uint32 in_operation_param1_tmpref_size = 15; + uint64 in_operation_param1_memref_parent = 16; + uint32 in_operation_param1_memref_parent_flag = 17; + uint32 in_operation_param1_memref_size = 18; + uint32 in_operation_param1_memref_offset = 19; + uint32 in_operation_param1_value_a = 20; + uint32 in_operation_param1_value_b = 21; + int32 in_operation_param1_ionref_ionsharefd = 22; + uint32 in_operation_param1_ionref_ionsize = 23; + uint64 in_operation_param2_tmpref_buffer = 24; + uint32 in_operation_param2_tmpref_size = 25; + uint64 in_operation_param2_memref_parent = 26; + uint32 in_operation_param2_memref_parent_flag = 27; + uint32 in_operation_param2_memref_size = 28; + uint32 in_operation_param2_memref_offset = 29; + uint32 in_operation_param2_value_a = 30; + uint32 in_operation_param2_value_b = 31; + int32 in_operation_param2_ionref_ionsharefd = 32; + uint32 in_operation_param2_ionref_ionsize = 33; + uint64 in_operation_param3_tmpref_buffer = 34; + uint32 in_operation_param3_tmpref_size = 35; + uint64 in_operation_param3_memref_parent = 36; + uint32 in_operation_param3_memref_parent_flag = 37; + uint32 in_operation_param3_memref_size = 38; + uint32 in_operation_param3_memref_offset = 39; + uint32 in_operation_param3_value_a = 40; + uint32 in_operation_param3_value_b = 41; + int32 in_operation_param3_ionref_ionsharefd = 42; + uint32 in_operation_param3_ionref_ionsize = 43; + uint64 in_operation_param4_tmpref_buffer = 44; + uint32 in_operation_param4_tmpref_size = 45; + uint64 in_operation_param4_memref_parent = 46; + uint32 in_operation_param4_memref_parent_flag = 47; + uint32 in_operation_param4_memref_size = 48; + uint32 in_operation_param4_memref_offset = 49; + uint32 in_operation_param4_value_a = 50; + uint32 in_operation_param4_value_b = 51; + int32 in_operation_param4_ionref_ionsharefd = 52; + uint32 in_operation_param4_ionref_ionsize = 53; + uint64 in_operation_session = 54; + int32 in_operation_cancelflag = 55; + uint32 in_returnorigin = 56; + uint64 in_bufer1_size = 57; + repeated uint32 in_buffer1 = 58; + uint64 in_bufer2_size = 59; + repeated uint32 in_buffer2 = 60; + uint64 in_bufer3_size = 61; + repeated uint32 in_buffer3 = 62; + uint64 in_bufer4_size = 63; + repeated uint32 in_buffer4 = 64; + string token = 65; + string taname = 66; +} + +message Invo_Reply { + uint32 teecresult = 1; + uint32 session_sessionid = 2; + uint32 session_serviceid_timelow = 3; + uint32 session_serviceid_timemid = 4; + uint32 session_serviceid_timehiandver = 5; + uint64 session_serviceid_clockseqandnode_outsize = 6; + repeated uint32 session_serviceid_clockseqandnode = 7; + uint32 session_opscnt = 8; + uint64 session_head_next = 9; + uint64 session_head_prev = 10; + uint64 session_context = 11; + uint32 operation_started = 12; + uint32 operation_paramtypes = 13; + uint64 operation_param1_tmpref_buffer = 14; + uint32 operation_param1_tmpref_size = 15; + uint64 operation_param1_memref_parent = 16; + uint32 operation_param1_memref_parent_flag = 17; + uint32 operation_param1_memref_size = 18; + uint32 operation_param1_memref_offset = 19; + uint32 operation_param1_value_a = 20; + uint32 operation_param1_value_b = 21; + int32 operation_param1_ionref_ionsharefd = 22; + uint32 operation_param1_ionref_ionsize = 23; + uint64 operation_param2_tmpref_buffer = 24; + uint32 operation_param2_tmpref_size = 25; + uint64 operation_param2_memref_parent = 26; + uint32 operation_param2_memref_parent_flag = 27; + uint32 operation_param2_memref_size = 28; + uint32 operation_param2_memref_offset = 29; + uint32 operation_param2_value_a = 30; + uint32 operation_param2_value_b = 31; + int32 operation_param2_ionref_ionsharefd = 32; + uint32 operation_param2_ionref_ionsize = 33; + uint64 operation_param3_tmpref_buffer = 34; + uint32 operation_param3_tmpref_size = 35; + uint64 operation_param3_memref_parent = 36; + uint32 operation_param3_memref_parent_flag = 37; + uint32 operation_param3_memref_size = 38; + uint32 operation_param3_memref_offset = 39; + uint32 operation_param3_value_a = 40; + uint32 operation_param3_value_b = 41; + int32 operation_param3_ionref_ionsharefd = 42; + uint32 operation_param3_ionref_ionsize = 43; + uint64 operation_param4_tmpref_buffer = 44; + uint32 operation_param4_tmpref_size = 45; + uint64 operation_param4_memref_parent = 46; + uint32 operation_param4_memref_parent_flag = 47; + uint32 operation_param4_memref_size = 48; + uint32 operation_param4_memref_offset = 49; + uint32 operation_param4_value_a = 50; + uint32 operation_param4_value_b = 51; + int32 operation_param4_ionref_ionsharefd = 52; + uint32 operation_param4_ionref_ionsize = 53; + uint64 operation_session = 54; + int32 operation_cancelflag = 55; + uint32 returnorigin = 56; + + uint64 buffer1_outsize = 57; + uint64 buffer2_outsize = 58; + uint64 buffer3_outsize = 59; + uint64 buffer4_outsize = 60; + + repeated uint32 buffer1 = 61; + repeated uint32 buffer2 = 62; + repeated uint32 buffer3 = 63; + repeated uint32 buffer4 = 64; + int32 flag = 65; +} + +message Close_Request { + uint32 in_session_sessionid = 1; + uint32 in_session_serviceid_timelow = 2; + uint32 in_session_serviceid_timemid = 3; + uint32 in_session_serviceid_timehiandver = 4; + uint64 in_session_serviceid_cad_size = 5; + repeated uint32 in_session_serviceid_clockseqandnode = 6; + uint32 in_session_opscnt = 7; + uint64 in_session_head_next = 8; + uint64 in_session_head_prev = 9; + uint64 in_session_context = 10; + string token = 11; + string taname = 12; +} + +message Close_Reply { + uint32 session_sessionid = 1; + uint32 session_serviceid_timelow = 2; + uint32 session_serviceid_timemid = 3; + uint32 session_serviceid_timehiandver = 4; + uint64 session_serviceid_cad_outsize = 5; + repeated uint32 session_serviceid_clockseqandnode = 6; + uint32 session_opscnt = 7; + uint64 session_head_next = 8; + uint64 session_head_prev = 9; + uint64 session_context = 10; + int32 flag = 11; +} + +message TA_Chunk{ + string name = 1; + bytes buffer = 2; + string token = 3; + string taname = 4; + bytes sha256 = 5; + string subdir = 6; +} + +message TA_Reply{ + int32 code = 1; + int32 flag = 2; +} + +message Setjwt_Request{ + string taname = 1; + string token = 2; +} + +message Setjwt_Reply{ + int32 retcode = 1; +} diff --git a/teeproxy/gpworker/README b/teeproxy/gpworker/README new file mode 100644 index 0000000..28ceb87 --- /dev/null +++ b/teeproxy/gpworker/README @@ -0,0 +1,8 @@ +DBus IPC + +packages installed: +dbus +libdbus-1-3 +libdbus-1-dev +libdbus-glib-1-2 + diff --git a/teeproxy/gpworker/build/Makefile b/teeproxy/gpworker/build/Makefile new file mode 100644 index 0000000..45cd212 --- /dev/null +++ b/teeproxy/gpworker/build/Makefile @@ -0,0 +1,28 @@ +CUR_DIR=$(shell pwd) +iTrustee_SDK_PATH=${CUR_DIR}/../../../.. + +TARGET_APP := gpworker + +APP_SOURCES := ../gpworker.c ../threadpool.c ../condition.c ../tzcp_dbus.c + +# APP_SOURCES += $(iTrustee_SDK_PATH)/src/CA/cloud/libteec_adaptor.c + +APP_CFLAGS += -fstack-protector-strong -fPIC -g + +APP_CFLAGS += -I$(iTrustee_SDK_PATH)/include/CA -I$(iTrustee_SDK_PATH)/thirdparty/open_source/libboundscheck/include + +APP_CFLAGS += -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include + +APP_LDFLAGS += -ldl -lpthread -lboundscheck -lteec -lm + +APP_LDFLAGS += -z text -z now -z relro -z noexecstack -pie + +APP_LDFLAGS += `pkg-config --libs --cflags dbus-1` + +APP_OBJECTS := $(APP_SOURCES:.c=.o) +$(TARGET_APP): $(APP_SOURCES) + @$(CC) $(APP_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS) +# aarch64-linux-gnu-gcc $(APP_CFLAGS) -o $@ $(APP_SOURCES) $(APP_LDFLAGS) + +clean: + rm -f *.o $(TARGET_APP) diff --git a/teeproxy/gpworker/build/r.sh b/teeproxy/gpworker/build/r.sh new file mode 100644 index 0000000..5f02fd2 --- /dev/null +++ b/teeproxy/gpworker/build/r.sh @@ -0,0 +1,7 @@ +#!bin/bash + +pkill gpworker +cp -r gpworker /vendor/bin/gpworker +rm -f *.log + +parallel -j 128 --ungroup /vendor/bin/gpworker gpworker{} ::: {0..127} diff --git a/teeproxy/gpworker/changelog.md b/teeproxy/gpworker/changelog.md new file mode 100644 index 0000000..f66c4e1 --- /dev/null +++ b/teeproxy/gpworker/changelog.md @@ -0,0 +1,7 @@ +# 更新日志 + +## [1.0.0] - 2022-10-11 + +### 新增 + +* 项目初始化,上传第一版 diff --git a/teeproxy/gpworker/condition.c b/teeproxy/gpworker/condition.c new file mode 100644 index 0000000..cf135cc --- /dev/null +++ b/teeproxy/gpworker/condition.c @@ -0,0 +1,55 @@ +#include "condition.h" + +int condition_init(condition_t *cond) +{ + int status; + if ((status = pthread_mutex_init(&cond->pmutex, NULL))) + return status; + + if ((status = pthread_cond_init(&cond->pcond, NULL))) + return status; + + return 0; +} + +int condition_lock(condition_t *cond) +{ + return pthread_mutex_lock(&cond->pmutex); +} + +int condition_unlock(condition_t *cond) +{ + return pthread_mutex_unlock(&cond->pmutex); +} + +int condition_wait(condition_t *cond) +{ + return pthread_cond_wait(&cond->pcond, &cond->pmutex); +} + +int condition_timedwait(condition_t *cond, const struct timespec *abstime) +{ + return pthread_cond_timedwait(&cond->pcond, &cond->pmutex, abstime); +} + +int condition_signal(condition_t *cond) +{ + return pthread_cond_signal(&cond->pcond); +} + +int condition_broadcast(condition_t *cond) +{ + return pthread_cond_broadcast(&cond->pcond); +} + +int condition_destroy(condition_t *cond) +{ + int status; + if ((status = pthread_mutex_destroy(&cond->pmutex))) + return status; + + if ((status = pthread_cond_destroy(&cond->pcond))) + return status; + + return 0; +} diff --git a/teeproxy/gpworker/condition.h b/teeproxy/gpworker/condition.h new file mode 100644 index 0000000..8c89945 --- /dev/null +++ b/teeproxy/gpworker/condition.h @@ -0,0 +1,28 @@ +#ifndef _CONDITION_H_ +#define _CONDITION_H_ + +#include + +typedef struct condition +{ + pthread_mutex_t pmutex; + pthread_cond_t pcond; +} condition_t; + +int condition_init(condition_t *cond); + +int condition_lock(condition_t *cond); + +int condition_unlock(condition_t *cond); + +int condition_wait(condition_t *cond); + +int condition_timedwait(condition_t *cond, const struct timespec *abstime); + +int condition_signal(condition_t *cond); + +int condition_broadcast(condition_t *cond); + +int condition_destroy(condition_t *cond); + +#endif /* _CONDITION_H_ */ diff --git a/teeproxy/gpworker/gpworker.c b/teeproxy/gpworker/gpworker.c new file mode 100644 index 0000000..838a0f9 --- /dev/null +++ b/teeproxy/gpworker/gpworker.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * Description: rsa-demo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tee_client_api.h" + +#include "tzcp_dbus.h" +#include "threadpool.h" + + +int main(int argc, char *argv[]) +{ + threadpool_t pool; + pthread_mutex_t mutex_tcl; + pthread_mutex_t mutex_tsl; + tcl_t tcl; + tsl_t tsl; + + if (argc < 2) + { + printf("There is no argument as a worker name. \n"); + return -1; + } + if (argc > 2) + { + printf("Only need one argument as a worker name. \n"); + return -1; + } + + receive_methodcall( + &pool, + &mutex_tcl, + &mutex_tsl, + &tcl, + &tsl, + argv[1] + ); + + return 0; +} diff --git a/teeproxy/gpworker/threadpool.c b/teeproxy/gpworker/threadpool.c new file mode 100644 index 0000000..265d4b7 --- /dev/null +++ b/teeproxy/gpworker/threadpool.c @@ -0,0 +1,155 @@ +#include "threadpool.h" +#include +#include +#include +#include +#include + + +void *thread_routine(void *arg) +{ + // struct timespec abstime; + int timeout; + printf("\n"); + printf("thread 0x%x is starting\n", (int) pthread_self()); + threadpool_t *pool = (threadpool_t *) arg; + while (1) + { + timeout = 0; + condition_lock(&pool->ready); + pool->idle++; + // 等待队列有任务到来或者线程池销毁通知 + while (pool->first == NULL && !pool->quit) + { + printf("thread 0x%x is waiting\n", (int) pthread_self()); + condition_wait(&pool->ready); + } + + // 等待到条件,处于工作状态 + pool->idle--; + + // 等待到任务 + if (pool->first != NULL) + { + // 从队头取出任务 + task_t *t = pool->first; + pool->first = t->next; + // 执行任务需要一定的时间,所以要先解锁,以便生产者进程 + // 能够往队列中添加任务,其它消费者线程能够进入等待任务 + condition_unlock(&pool->ready); + printf("thread 0x%x is working\n", (int) pthread_self()); + t->run(t->arg); + printf("\n"); + printf("thread 0x%x work done \n", (int) pthread_self()); + free(t); + condition_lock(&pool->ready); + } + // 如果等待到线程池销毁通知, 且任务都执行完毕 + if (pool->quit && pool->first == NULL) + { + pool->counter--; + if (pool->counter == 0) + condition_signal(&pool->ready); + + condition_unlock(&pool->ready); + // 跳出循环之前要记得解锁 + break; + } + + if (timeout && pool->first == NULL) + { + pool->counter--; + condition_unlock(&pool->ready); + // 跳出循环之前要记得解锁 + break; + } + condition_unlock(&pool->ready); + } + + printf("thread 0x%x is exting\n", (int) pthread_self()); + return NULL; + +} + + +// 初始化线程池 +void threadpool_init( + threadpool_t *pool, + int threads, + tcl_t *tcl, + tsl_t *tsl +) +{ + // 对线程池中的各个字段初始化 + condition_init(&pool->ready); + pool->first = NULL; + pool->last = NULL; + pool->counter = 0; + pool->idle = 0; + pool->max_threads = threads; + pool->quit = 0; + + tcl->first = NULL; + tcl->last = NULL; + tcl->count = 0; + + tsl->first = NULL; + tsl->last = NULL; + tsl->count = 0; +} + + +// 往线程池中添加任务 +void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg) +{ + // 生成新任务 + task_t *newtask = (task_t *) malloc(sizeof(task_t)); + newtask->run = run; + newtask->arg = arg; + newtask->next = NULL; + + condition_lock(&pool->ready); + // 将任务添加到队列 + if (pool->first == NULL) + pool->first = newtask; + else + pool->last->next = newtask; + pool->last = newtask; + + // 如果有等待线程,则唤醒其中一个 + if (pool->idle > 0) + condition_signal(&pool->ready); + else if (pool->counter < pool->max_threads) + { + // 没有等待线程,并且当前线程数不超过最大线程数,则创建一个新线程 + pthread_t tid; + pthread_create(&tid, NULL, thread_routine, pool); + pool->counter++; + } + condition_unlock(&pool->ready); +} + + +// 销毁线程池 +void threadpool_destroy(threadpool_t *pool) +{ + if (pool->quit) + { + return; + } + condition_lock(&pool->ready); + pool->quit = 1; + if (pool->counter > 0) + { + if (pool->idle > 0) + condition_broadcast(&pool->ready); + + // 处于执行任务状态中的线程,不会收到广播 + // 线程池需要等待执行任务状态中的线程全部退出 + + while (pool->counter > 0) + condition_wait(&pool->ready); + } + condition_unlock(&pool->ready); + condition_destroy(&pool->ready); +} diff --git a/teeproxy/gpworker/threadpool.h b/teeproxy/gpworker/threadpool.h new file mode 100644 index 0000000..f70b3d1 --- /dev/null +++ b/teeproxy/gpworker/threadpool.h @@ -0,0 +1,108 @@ +#ifndef _THREAD_POOL_H_ +#define _THREAD_POOL_H_ + +#include "condition.h" + +#define GP_WORKER 3 + +#ifdef GP_WORKER + +#include "tee_client_api.h" +#include "tee_client_list.h" + +#endif + + + +#ifdef GP_PROXY +typedef struct sessionid_node +{ + uint32_t session_id; + struct timeval session_createtime; + struct sessionid_node * next; + struct sessionid_node * prev; +} sin_t; + +typedef struct worker_rec +{ + uint8_t busy; + int32_t context_fd; + uint64_t context_addr; + struct timeval context_createtime; + int sessionid_count; + sin_t * first; + sin_t * last; +} wr_t; +#endif + +#ifdef GP_WORKER +typedef struct teec_session_node +{ + TEEC_Session *self; + struct timeval createtime; + struct teec_session_node *next; + struct teec_session_node *prev; +} tsn_t; + +typedef struct teec_session_list +{ + int count; // 线程池中当前线程数 + tsn_t *first; + tsn_t *last; +} tsl_t; + +typedef struct teec_context_node +{ + TEEC_Context *self; + struct timeval createtime; + struct teec_context_node *next; + struct teec_context_node *prev; +} tcn_t; + +typedef struct teec_context_list +{ + int count; // 线程池中当前线程数 + tcn_t *first; + tcn_t *last; +} tcl_t; +#endif + + +// 任务结构体,将任务放入队列由线程池中的线程来执行 +typedef struct task +{ + void *(*run)(void *arg); // 任务回调函数 + void *arg; // 回调函数参数 + struct task *next; +} task_t; + +// 线程池结构体 +typedef struct threadpool +{ + condition_t ready; // mutex and condition var, 任务准备就绪或者线程池销毁通知 + task_t *first; // 任务队列头指针 + task_t *last; // 任务队列尾指针 + int counter; // 线程池中当前线程数 + int idle; // 线程池中当前正在等待任务的线程数 + int max_threads; // 线程池中最大允许的线程数 + int quit; // 销毁线程池的时候置1 +} threadpool_t; + +// 初始化线程池 +void threadpool_init( + threadpool_t *pool, + int threads +#ifdef GP_WORKER + , + tcl_t *tcl, + tsl_t *tsl +#endif +); + +// 往线程池中添加任务 +void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg), void *arg); + +// 销毁线程池 +void threadpool_destroy(threadpool_t *pool); + +#endif /* _THREAD_POOL_H_ */ diff --git a/teeproxy/gpworker/tzcp_dbus.c b/teeproxy/gpworker/tzcp_dbus.c new file mode 100644 index 0000000..345ece1 --- /dev/null +++ b/teeproxy/gpworker/tzcp_dbus.c @@ -0,0 +1,22889 @@ +/* + * Using low-level D-Bus C API code. + * Written by + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tzcp_dbus.h" + +#ifdef GP_PROXY_WORKER + +#include "threadpool.h" + +#ifdef GP_WORKER + +#include "tee_client_api.h" +#include "tee_client_list.h" + +#endif +#endif + + +/** + * Listens for signals on the bus + */ +void +receive_signal(void) +{ + DBusMessage *msg; + DBusMessageIter args; + DBusConnection *conn; + DBusError err; + int ret; + char *sigvalue; + + printf("Listening for signals\n"); + + // initialise the errors + dbus_error_init(&err); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + exit(1); + } + + // request our name on the bus and check for errors + ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + exit(1); + } + + // add a rule for which messages we want to see + dbus_bus_add_match(conn, "type='signal',interface='test.signal.Type'", &err); + // see signals from the given interface + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Match Error (%s)\n", err.message); + exit(1); + } + // printf("Match rule sent\n"); + + // loop listening for signals being emmitted + while (true) + { + + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't read a message + if (NULL == msg) + { + usleep(10000); + continue; + } + + // check if the message is a signal from the correct interface and with the correct name + if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) + { + + // read the parameters + if (!dbus_message_iter_init(msg, &args)) + fprintf(stderr, "Message Has No Parameters\n"); + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not string!\n"); + else + dbus_message_iter_get_basic(&args, &sigvalue); + + printf("Got Signal with value %s\n", sigvalue); + } + + // free the message + dbus_message_unref(msg); + } +} + + +/** + * Connect to the DBUS bus and send a broadcast signal + */ +void +send_signal( + char *sigvalue +) +{ + DBusMessage *msg; + DBusMessageIter args; + DBusConnection *conn; + DBusError err; + int ret; + dbus_uint32_t sigserial = 0; + + printf("Sending signal with value %s\n", sigvalue); + + // initialise the error value + dbus_error_init(&err); + + // connect to the DBUS system bus, and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + exit(1); + } + + // register our name on the bus, and check for errors + ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + exit(1); + } + + // create a signal & check for errors + msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal + "test.signal.Type", // interface name of the signal + "Test"); // name of the signal + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + // append arguments onto signal + dbus_message_iter_init_append(msg, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) + { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + // send the message and flush the connection + if (!dbus_connection_send(conn, msg, &sigserial)) + { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + dbus_connection_flush(conn); + + printf("Signal Sent\n"); + + // free the message + dbus_message_unref(msg); +} + + +#ifdef GP_PROXY_WORKER + +/** + * Server that exposes a method call and waits for it to be called + */ +void +receive_methodcall( + threadpool_t *pool, + pthread_mutex_t *mutex_tcl, + pthread_mutex_t *mutex_tsl, + tcl_t *tcl, + tsl_t *tsl, + char *workername +) +{ + DBusMessage *msg; + DBusConnection *conn; + DBusError err; + int ret; + dbus_bool_t bResult; + + threadpool_init(pool, +#ifdef GP_PROXY + MAX_NUM_THREAD + 2 +#endif +#ifdef GP_WORKER + MAX_NUM_THREAD, tcl, tsl +#endif + ); + +#ifdef GP_WORKER + pthread_mutex_init(mutex_tcl, NULL); + pthread_mutex_init(mutex_tsl, NULL); +#endif + +#ifdef GP_PROXY + pthread_mutex_init(mutex_workerrec, NULL); + pthread_cond_init(cond_notbusy, NULL); + for (int iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + workerrec[iworker].busy = 0; + workerrec[iworker].context_fd = 0; + // workerrec[iworker].context_addr = 0; + workerrec[iworker].context_addr = 0xffffffff; + workerrec[iworker].sessionid_count = 0; + workerrec[iworker].first = NULL; + workerrec[iworker].last = NULL; + } + + DBusMsgConn* thdfargs_stp = (DBusMsgConn*)malloc(sizeof(DBusMsgConn)); + thdfargs_stp->mutex_workerrec = mutex_workerrec; + thdfargs_stp->workerrec = workerrec; + threadpool_add_task( + pool, + session_timeout_process, + thdfargs_stp + ); + + DBusMsgConn* thdfargs_ctp = (DBusMsgConn*)malloc(sizeof(DBusMsgConn)); + thdfargs_ctp->mutex_workerrec = mutex_workerrec; + thdfargs_ctp->workerrec = workerrec; + thdfargs_ctp->cond_notbusy = cond_notbusy; + threadpool_add_task( + pool, + context_timeout_process, + thdfargs_ctp + ); +#endif + + printf("%s is listening for method calls ... \n", workername); + + // initialise the error + dbus_error_init(&err); + + dbus_threads_init_default(); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + // conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + fprintf(stderr, "Connection Null\n"); + exit(1); + } + + char dbusname[1024]; + memset((char *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + int64_t workernum = 0; + for (int iind = 0; iind < strlen(workername) - 6; iind++) + { + workernum = workernum + + (workername[strlen(workername) - 1 - iind] - '0') * pow(10, iind); +#if 0 + printf( + "workername[%d] = %c. \n", + strlen(workername) - 1 - iind, + workername[strlen(workername) - 1 - iind] + ); +#endif + } + // printf("The worker num is 0x %16.16lx. \n", workernum); + // request our name on the bus and check for errors + ret = + dbus_bus_request_name( + conn, + // "test.method.server", + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + fprintf(stderr, "Not Primary Owner (%d)\n", ret); + exit(1); + } + + // loop, testing for new messages + memset((char *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.Type", workername); + while (true) + { + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't got a message + if (NULL == msg) + { + usleep(10000); + continue; + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "TEEC_InitializeContext" + ); + if (bResult == TRUE) + { + DBusMsgConn *thdfargs = (DBusMsgConn *) malloc(sizeof(DBusMsgConn)); + thdfargs->msg = msg; + thdfargs->conn = conn; +#ifdef GP_PROXY + thdfargs->mutex_workerrec = mutex_workerrec; + thdfargs->cond_notbusy = cond_notbusy; + thdfargs->workerrec = workerrec; +#endif +#ifdef GP_WORKER + thdfargs->workernum = workernum; + thdfargs->mutex_tcl = mutex_tcl; + thdfargs->mutex_tsl = mutex_tsl; + thdfargs->tcl = tcl; + thdfargs->tsl = tsl; +#endif + threadpool_add_task( + pool, + reply_to_method_call_teec_inicont, + thdfargs + ); + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "TEEC_FinalizeContext" + ); + if (bResult == TRUE) + { + DBusMsgConn *thdfargs = (DBusMsgConn *) malloc(sizeof(DBusMsgConn)); + thdfargs->msg = msg; + thdfargs->conn = conn; +#ifdef GP_PROXY + thdfargs->mutex_workerrec = mutex_workerrec; + thdfargs->cond_notbusy = cond_notbusy; + thdfargs->workerrec = workerrec; +#endif +#ifdef GP_WORKER + thdfargs->workernum = workernum; + thdfargs->mutex_tcl = mutex_tcl; + thdfargs->mutex_tsl = mutex_tsl; + thdfargs->tcl = tcl; + thdfargs->tsl = tsl; +#endif + threadpool_add_task( + pool, + reply_to_method_call_teec_fincont, + thdfargs + ); + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "TEEC_OpenSession" + ); + if (bResult == TRUE) + { + DBusMsgConn *thdfargs = (DBusMsgConn *) malloc(sizeof(DBusMsgConn)); + thdfargs->msg = msg; + thdfargs->conn = conn; +#ifdef GP_PROXY + thdfargs->mutex_workerrec = mutex_workerrec; + thdfargs->cond_notbusy = cond_notbusy; + thdfargs->workerrec = workerrec; +#endif +#ifdef GP_WORKER + thdfargs->workernum = workernum; + thdfargs->mutex_tcl = mutex_tcl; + thdfargs->mutex_tsl = mutex_tsl; + thdfargs->tcl = tcl; + thdfargs->tsl = tsl; +#endif + threadpool_add_task( + pool, + reply_to_method_call_teec_opensession, + thdfargs + ); + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "TEEC_CloseSession" + ); + if (bResult == TRUE) + { + DBusMsgConn *thdfargs = (DBusMsgConn *) malloc(sizeof(DBusMsgConn)); + thdfargs->msg = msg; + thdfargs->conn = conn; +#ifdef GP_PROXY + thdfargs->mutex_workerrec = mutex_workerrec; + thdfargs->cond_notbusy = cond_notbusy; + thdfargs->workerrec = workerrec; +#endif +#ifdef GP_WORKER + thdfargs->workernum = workernum; + thdfargs->mutex_tcl = mutex_tcl; + thdfargs->mutex_tsl = mutex_tsl; + thdfargs->tcl = tcl; + thdfargs->tsl = tsl; +#endif + threadpool_add_task( + pool, + reply_to_method_call_teec_closesession, + thdfargs + ); + } + + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "TEEC_InvokeCommand" + ); + if (bResult == TRUE) + { + DBusMsgConn *thdfargs = (DBusMsgConn *) malloc(sizeof(DBusMsgConn)); + thdfargs->msg = msg; + thdfargs->conn = conn; +#ifdef GP_PROXY + thdfargs->mutex_workerrec = mutex_workerrec; + thdfargs->cond_notbusy = cond_notbusy; + thdfargs->workerrec = workerrec; +#endif +#ifdef GP_WORKER + thdfargs->workernum = workernum; + thdfargs->mutex_tcl = mutex_tcl; + thdfargs->mutex_tsl = mutex_tsl; + thdfargs->tcl = tcl; + thdfargs->tsl = tsl; +#endif + threadpool_add_task( + pool, + reply_to_method_call_teec_invokecommand, + thdfargs + ); + } + + // check this is a method call for the right interface & method + bResult = dbus_message_is_method_call( + msg, + // "test.method.Type", + dbusname, + "Destroy" + ); + if (bResult == TRUE) + { + reply_to_method_call_destroy_threadpool( + msg, + conn, + pool +#ifdef GP_WORKER + , + mutex_tcl, + mutex_tsl +#endif + +#ifdef GP_PROXY + , + mutex_workerrec, + cond_notbusy +#endif + ); + } + + // free the message + // dbus_message_unref(msg); + + } // end of the while true +} // end of the function +#endif + + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_inicont( + const char *workername, + + const uint8_t *name, size_t name_size, + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t *teecresult, + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint64_t *context_addr, + uint32_t *context_tapath_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + + // initialiset the errors + dbus_error_init(&err); + + dbus_threads_init_default(); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + // conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_InitializeContext" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = name_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (name_size > 0 && name != NULL) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &name + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Init Contex Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + if (*context_tapath_outsize > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_addr = dui64Temp; + + printf("Got Reply of Method Call Teec Init Contex: \n"); + printf(" teecresult = 0x %8.8x \n", *teecresult); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path = %s \n", context_tapath_temp); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); +#endif + printf(" context addr = 0x %16.16lx \n", + (long unsigned int) *context_addr + ); + + if ( + context_tapath_insize > *context_tapath_outsize && + *context_tapath_outsize > 0 && + context_tapath != NULL && + context_tapath_temp != NULL + ) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + // dbus_message_unref(msg); + // return -1; + *(context_tapath + 0) = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_fincont( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint64_t in_context_addr, + + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint32_t *context_tapath_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_FinalizeContext" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + // fprintf(stderr, "in_context_tapath_size = %ld \n", in_context_tapath_size); + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_addr; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Fin Contex Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + if (*context_tapath_outsize > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + printf("Got Reply of Method Call Teec Fin Contex: \n"); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path = %s \n", context_tapath_temp); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); +#endif + + if ( + context_tapath_insize > *context_tapath_outsize && + *context_tapath_outsize > 0 && + context_tapath != NULL && + context_tapath_temp != NULL + ) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + // dbus_message_unref(msg); + // return -1; + *(context_tapath + 0) = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_opensession( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, + size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t in_destination_timelow, + uint32_t in_destination_timemid, + uint32_t in_destination_timehiandver, + uint32_t *in_destination_clockseqandnode, + int32_t in_destination_clockseqandnode_size, + + uint32_t in_connectionmethod, + uint64_t in_connectiondata, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint64_t in_context_addr, + + + uint32_t *teecresult, + + int32_t *context_fd, + uint8_t *context_tapath, + size_t context_tapath_size, + uint32_t *context_tapath_outsize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_OpenSession" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + // fprintf(stderr, "in_context_tapath_size = %ld \n", in_context_tapath_size); + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_destination_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_destination_clockseqandnode_size > 0 && + in_destination_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_destination_clockseqandnode, + in_destination_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_connectionmethod; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_connectiondata; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = in_operation_started; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_paramtypes; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param1_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param2_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param3_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param4_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_session; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_cancelflag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_returnorigin; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_addr; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + /////////////////////////////////////////////////////////////////// + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Open Session Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + if (*context_tapath_outsize > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_seesionid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + } + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_started = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_paramtypes = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param1_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param2_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param3_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param4_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_session = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_cancelflag = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *returnorigin = dui32Temp; + + printf("Got Reply of Method Call Teec Open Session: \n"); + printf(" teecresult = 0x %8.8x \n", *teecresult); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path = %s \n", context_tapath_temp); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); + printf(" session_seesionid = 0x %8.8x \n", + *session_seesionid + ); +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); + + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + if (*session_serviceid_clockseqandnode_outsize > 0 && + session_serviceid_clockseqandnode_temp != NULL) + { + printf(" "); + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + } + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session operation_started = 0x %8.8x \n", + *operation_started + ); + printf(" TEEC_Session operation_paramtypes = 0x %8.8x \n", + *operation_paramtypes + ); + + printf(" TEEC_Session operation_param1_tmpref_buffer = 0x %16.16lx \n", + *operation_param1_tmpref_buffer + ); + printf(" TEEC_Session operation_param1_tmpref_size = 0x %8.8x \n", + *operation_param1_tmpref_size + ); + printf(" TEEC_Session operation_param1_memref_parent = 0x %16.16lx \n", + *operation_param1_memref_parent + ); + printf(" TEEC_Session operation_param1_memref_size = 0x %8.8x \n", + *operation_param1_memref_size + ); + printf(" TEEC_Session operation_param1_memref_offse = 0x %8.8x \n", + *operation_param1_memref_offset + ); + printf(" TEEC_Session operation_param1_value_a = 0x %8.8x \n", + *operation_param1_value_a + ); + printf(" TEEC_Session operation_param1_value_b = 0x %8.8x \n", + *operation_param1_value_b + ); + printf(" TEEC_Session operation_param1_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param1_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param1_ionref_ionsize = 0x %8.8x \n", + *operation_param1_ionref_ionsize + ); + + printf(" TEEC_Session operation_param2_tmpref_buffer = 0x %16.16lx \n", + *operation_param2_tmpref_buffer + ); + printf(" TEEC_Session operation_param2_tmpref_size = 0x %8.8x \n", + *operation_param2_tmpref_size + ); + printf(" TEEC_Session operation_param2_memref_parent = 0x %16.16lx \n", + *operation_param2_memref_parent + ); + printf(" TEEC_Session operation_param2_memref_size = 0x %8.8x \n", + *operation_param2_memref_size + ); + printf(" TEEC_Session operation_param2_memref_offset = 0x %8.8x \n", + *operation_param2_memref_offset + ); + printf(" TEEC_Session operation_param2_value_a = 0x %8.8x \n", + *operation_param2_value_a + ); + printf(" TEEC_Session operation_param2_value_b = 0x %8.8x \n", + *operation_param2_value_b + ); + printf(" TEEC_Session operation_param2_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param2_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param2_ionref_ionsize = 0x %8.8x \n", + *operation_param2_ionref_ionsize + ); + + printf(" TEEC_Session operation_param3_tmpref_buffer = 0x %16.16lx \n", + *operation_param3_tmpref_buffer + ); + printf(" TEEC_Session operation_param3_tmpref_size = 0x %8.8x \n", + *operation_param3_tmpref_size + ); + printf(" TEEC_Session operation_param3_memref_parent = 0x %16.16lx \n", + *operation_param3_memref_parent + ); + printf(" TEEC_Session operation_param3_memref_size = 0x %8.8x \n", + *operation_param3_memref_size + ); + printf(" TEEC_Session operation_param3_memref_offset = 0x %8.8x \n", + *operation_param3_memref_offset + ); + printf(" TEEC_Session operation_param3_value_a = 0x %8.8x \n", + *operation_param3_value_a + ); + printf(" TEEC_Session operation_param3_value_b = 0x %8.8x \n", + *operation_param3_value_b + ); + printf(" TEEC_Session operation_param3_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param3_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param3_ionref_ionsize = 0x %8.8x \n", + *operation_param3_ionref_ionsize + ); + + printf(" TEEC_Session operation_param4_tmpref_buffer = 0x %16.16lx \n", + *operation_param4_tmpref_buffer + ); + printf(" TEEC_Session operation_param4_tmpref_size = 0x %8.8x \n", + *operation_param4_tmpref_size + ); + printf(" TEEC_Session operation_param4_memref_parent = 0x %16.16lx \n", + *operation_param4_memref_parent + ); + printf(" TEEC_Session operation_param4_memref_size = 0x %8.8x \n", + *operation_param4_memref_size + ); + printf(" TEEC_Session operation_param4_memref_offset = 0x %8.8x \n", + *operation_param4_memref_offset + ); + printf(" TEEC_Session operation_param4_value_a = 0x %8.8x \n", + *operation_param4_value_a + ); + printf(" TEEC_Session operation_param4_value_b = 0x %8.8x \n", + *operation_param4_value_b + ); + printf(" TEEC_Session operation_param4_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param4_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param4_ionref_ionsize = 0x %8.8x \n", + *operation_param4_ionref_ionsize + ); + + printf(" TEEC_Session operation_session = 0x %16.16lx \n", + *operation_session + ); + printf(" TEEC_Session operation_cancelflag = 0x %8.8x \n", + (unsigned int)*operation_cancelflag + ); + printf(" TEEC_Session returnorigin = 0x %8.8x \n", + *returnorigin + ); +#endif + + if (context_tapath_size > *context_tapath_outsize) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + dbus_message_unref(msg); + return -1; + } + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) + { + session_serviceid_clockseqandnode[i] = + session_serviceid_clockseqandnode_temp[i]; + + } + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +int32_t +method_call_teec_closesession( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + int32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_CloseSession" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + dui32Temp = in_session_seesionid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_session_serviceid_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_session_serviceid_clockseqandnode_size > 0 && + in_session_serviceid_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_session_opscnt; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui64Temp = in_session_head_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_context; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Close Session Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_seesionid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + } + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + + printf("Got Reply of Method Call Teec Close Session: \n"); + printf(" session_seesionid = 0x %8.8x \n", + *session_seesionid + ); +#if 0 + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timemid = 0x %8.8x \n", + *session_serviceid_timemid + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); +#endif + printf(" session_context = 0x %16.16lx \n", + *session_context + ); + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + memcpy( + session_serviceid_clockseqandnode, + session_serviceid_clockseqandnode_temp, + session_serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +int32_t +method_call_teec_invokecommand( + const char *workername, + + uint32_t in_session_sessionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + uint32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t commandid, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_parent_flag, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_parent_flag, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_parent_flag, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_parent_flag, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint32_t *in_buffer1, + uint32_t in_buffer1_size, + uint32_t *in_buffer2, + uint32_t in_buffer2_size, + uint32_t *in_buffer3, + uint32_t in_buffer3_size, + uint32_t *in_buffer4, + uint32_t in_buffer4_size, + + + uint32_t *teecresult, + + uint32_t *session_sessionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_parent_flag, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_parent_flag, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_parent_flag, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_parent_flag, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin, + + uint32_t *buffer1, + uint32_t buffer1_size, + uint32_t *buffer1_outsize, + uint32_t *buffer2, + uint32_t buffer2_size, + uint32_t *buffer2_outsize, + uint32_t *buffer3, + uint32_t buffer3_size, + uint32_t *buffer3_outsize, + uint32_t *buffer4, + uint32_t buffer4_size, + uint32_t *buffer4_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + dbus_uint32_t *buffer1_temp = NULL; + int buffer1_realsize; + dbus_uint32_t *buffer2_temp = NULL; + int buffer2_realsize; + dbus_uint32_t *buffer3_temp = NULL; + int buffer3_realsize; + dbus_uint32_t *buffer4_temp = NULL; + int buffer4_realsize; + + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_InvokeCommand" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + + dui32Temp = in_session_sessionid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_session_serviceid_clockseqandnode_size > 0 && + in_session_serviceid_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_session_opscnt; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_context; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = commandid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = in_operation_started; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_paramtypes; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param1_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param2_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param3_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param4_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_session; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_cancelflag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_returnorigin; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_buffer1_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer1_size > 0 && + in_buffer1 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer1, + in_buffer1_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer2_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer2_size > 0 && + in_buffer2 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer2, + in_buffer2_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer3_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer3_size > 0 && + in_buffer3 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer3, + in_buffer3_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer4_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer4_size > 0 && + in_buffer4 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer4, + in_buffer4_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Invoke Command Sent. \n"); + + ///////////////////////////////////////////////////////////////////////////////////// + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_sessionid = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_started = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_paramtypes = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param1_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param2_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param3_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param4_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_session = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_cancelflag = di32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *returnorigin = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer1_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer1_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer1_temp, + &buffer1_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer2_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer2_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer2_temp, + &buffer2_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer3_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer3_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer3_temp, + &buffer3_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer4_outsize = dui32Temp; + + if (*buffer4_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer4_temp, + &buffer4_realsize + ); + } + + + printf("Got Reply of Method Call Teec Invoke Command: \n"); + printf(" teecresult = 0x %8.8x \n", + *teecresult); + printf(" session_seesionid = 0x %8.8x \n", + *session_sessionid + ); +#if 0 + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timemid = 0x %8.8x \n", + *session_serviceid_timemid + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + if ( *session_serviceid_clockseqandnode_outsize > 0 && + session_serviceid_clockseqandnode_temp != NULL + ) + { + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + } + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session operation_started = 0x %8.8x \n", + *operation_started + ); + printf(" TEEC_Session operation_paramtypes = 0x %8.8x \n", + *operation_paramtypes + ); + printf(" TEEC_Session operation_param1_tmpref_buffer = 0x %16.16lx \n", + *operation_param1_tmpref_buffer + ); + printf(" TEEC_Session operation_param1_tmpref_size = 0x %8.8x \n", + *operation_param1_tmpref_size + ); + printf(" TEEC_Session operation_param1_memref_parent = 0x %16.16lx \n", + *operation_param1_memref_parent + ); + printf(" TEEC_Session operation_param1_memref_size = 0x %8.8x \n", + *operation_param1_memref_size + ); + printf(" TEEC_Session operation_param1_memref_offse = 0x %8.8x \n", + *operation_param1_memref_offset + ); + printf(" TEEC_Session operation_param1_value_a = 0x %8.8x \n", + *operation_param1_value_a + ); + printf(" TEEC_Session operation_param1_value_b = 0x %8.8x \n", + *operation_param1_value_b + ); + printf(" TEEC_Session operation_param1_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param1_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param1_ionref_ionsize = 0x %8.8x \n", + *operation_param1_ionref_ionsize + ); + + printf(" TEEC_Session operation_param2_tmpref_buffer = 0x %16.16lx \n", + *operation_param2_tmpref_buffer + ); + printf(" TEEC_Session operation_param2_tmpref_size = 0x %8.8x \n", + *operation_param2_tmpref_size + ); + printf(" TEEC_Session operation_param2_memref_parent = 0x %16.16lx \n", + *operation_param2_memref_parent + ); + printf(" TEEC_Session operation_param2_memref_size = 0x %8.8x \n", + *operation_param2_memref_size + ); + printf(" TEEC_Session operation_param2_memref_offset = 0x %8.8x \n", + *operation_param2_memref_offset + ); + printf(" TEEC_Session operation_param2_value_a = 0x %8.8x \n", + *operation_param2_value_a + ); + printf(" TEEC_Session operation_param2_value_b = 0x %8.8x \n", + *operation_param2_value_b + ); + printf(" TEEC_Session operation_param2_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param2_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param2_ionref_ionsize = 0x %8.8x \n", + *operation_param2_ionref_ionsize + ); + + printf(" TEEC_Session operation_param3_tmpref_buffer = 0x %16.16lx \n", + *operation_param3_tmpref_buffer + ); + printf(" TEEC_Session operation_param3_tmpref_size = 0x %8.8x \n", + *operation_param3_tmpref_size + ); + printf(" TEEC_Session operation_param3_memref_parent = 0x %16.16lx \n", + *operation_param3_memref_parent + ); + printf(" TEEC_Session operation_param3_memref_size = 0x %8.8x \n", + *operation_param3_memref_size + ); + printf(" TEEC_Session operation_param3_memref_offset = 0x %8.8x \n", + *operation_param3_memref_offset + ); + printf(" TEEC_Session operation_param3_value_a = 0x %8.8x \n", + *operation_param3_value_a + ); + printf(" TEEC_Session operation_param3_value_b = 0x %8.8x \n", + *operation_param3_value_b + ); + printf(" TEEC_Session operation_param3_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param3_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param3_ionref_ionsize = 0x %8.8x \n", + *operation_param3_ionref_ionsize + ); + + printf(" TEEC_Session operation_param4_tmpref_buffer = 0x %16.16lx \n", + *operation_param4_tmpref_buffer + ); + printf(" TEEC_Session operation_param4_tmpref_size = 0x %8.8x \n", + *operation_param4_tmpref_size + ); + printf(" TEEC_Session operation_param4_memref_parent = 0x %16.16lx \n", + *operation_param4_memref_parent + ); + printf(" TEEC_Session operation_param4_memref_size = 0x %8.8x \n", + *operation_param4_memref_size + ); + printf(" TEEC_Session operation_param4_memref_offset = 0x %8.8x \n", + *operation_param4_memref_offset + ); + printf(" TEEC_Session operation_param4_value_a = 0x %8.8x \n", + *operation_param4_value_a + ); + printf(" TEEC_Session operation_param4_value_b = 0x %8.8x \n", + *operation_param4_value_b + ); + printf(" TEEC_Session operation_param4_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param4_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param4_ionref_ionsize = 0x %8.8x \n", + *operation_param4_ionref_ionsize + ); + + printf(" TEEC_Session operation_session = 0x %16.16lx \n", + *operation_session + ); + printf(" TEEC_Session operation_cancelflag = 0x %8.8x \n", + (unsigned int)*operation_cancelflag + ); + printf(" returnorigin = 0x %8.8x \n", + *returnorigin + ); + + printf(" buffer1 = \n"); + if (buffer1_temp != NULL) + { + for (int i = 0; i < buffer1_realsize; i++) { + printf(" %2.2x", + buffer1_temp[i] + ); + } + printf("\n"); + } + printf(" buffer1_outsize = 0x %8.8x \n", + *buffer1_outsize + ); + + printf(" buffer2 = \n"); + if (buffer2_temp != NULL) + { + for (int i = 0; i < buffer2_realsize; i++) { + printf(" %2.2x", + buffer2_temp[i] + ); + } + printf("\n"); + } + printf(" buffer2_outsize = 0x %8.8x \n", + *buffer2_outsize + ); + + printf(" buffer3 = \n"); + if (buffer3_temp != NULL) + { + for (int i = 0; i < buffer3_realsize; i++) { + printf(" %2.2x", + buffer3_temp[i] + ); + } + printf("\n"); + } + printf(" buffer3_outsize = 0x %8.8x \n", + *buffer3_outsize + ); + + if (buffer4_temp != NULL) + { + printf(" buffer4 = \n"); + for (int i = 0; i < buffer4_realsize; i++) { + printf(" %2.2x", + buffer4_temp[i] + ); + } + printf("\n"); + } + printf(" buffer4_outsize = 0x %8.8x \n", + *buffer4_outsize + ); +#endif + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode != NULL && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + memcpy( + session_serviceid_clockseqandnode, + session_serviceid_clockseqandnode_temp, + session_serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + if (buffer1_size >= (uint32_t) buffer1_realsize && + buffer1 != NULL && + buffer1_temp != NULL && + buffer1_realsize > 0 + ) + { + memcpy( + buffer1, + buffer1_temp, + buffer1_realsize * sizeof(uint32_t) + ); + *buffer1_outsize = buffer1_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer1_outsize = 0; + } + + if (buffer2_size >= (uint32_t) buffer2_realsize && + buffer2 != NULL && + buffer2_temp != NULL && + buffer2_realsize > 0 + ) + { + memcpy( + buffer2, + buffer2_temp, + buffer2_realsize * sizeof(uint32_t) + ); + *buffer2_outsize = buffer2_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer2_outsize = 0; + } + + if (buffer3_size >= (uint32_t) buffer3_realsize && + buffer3 != NULL && + buffer3_temp != NULL && + buffer3_realsize > 0 + ) + { + memcpy( + buffer3, + buffer3_temp, + buffer3_realsize * sizeof(uint32_t) + ); + *buffer3_outsize = buffer3_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer3_outsize = 0; + } + + if (buffer4_size >= (uint32_t) buffer4_realsize && + buffer4 != NULL && + buffer4_temp != NULL && + buffer4_realsize > 0 + ) + { + memcpy( + buffer4, + buffer4_temp, + buffer4_realsize * sizeof(uint32_t) + ); + *buffer4_outsize = buffer4_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer4_outsize = 0; + } + + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +void +method_call_destroy_threadpool( + const char *workername +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + // DBusConnection* conn; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + int ret; + int iType; + unsigned char name[] = "threadpool"; + unsigned char *charp; + dbus_uint32_t retcode; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "Destroy" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return; + } + + + // append arguments + dbus_message_iter_init_append(msg, &args); + + charp = name; + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &charp)) + { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + exit(1); + } + dbus_connection_flush(conn); + + printf("\n"); + printf("Method Call Destroy Threadpool Sent. \n"); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + exit(1); + } + // free the pending message handle + dbus_pending_call_unref(pending); + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + exit(1); + } + + iType = + dbus_message_iter_get_arg_type( + &args + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + exit(1); + } + dbus_message_iter_get_basic( + &args, + &retcode + ); + + printf("Got Reply of Method Call Destroy Threadpool: \n"); + printf(" retcode = 0x%8x \n", retcode); + + // free reply + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); +} + + +#ifdef GP_PROXY_WORKER + +void * +reply_to_method_call_teec_inicont( + // DBusMessage* msg, + // DBusConnection* conn + void *thdfargs +) +{ + DBusMsgConn *DBusMCP; + DBusMessage *msg; + DBusConnection *conn; + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + DBusMessageIter structIter; + int iType; + unsigned char *charp; + // char* param = ""; + unsigned char *name = NULL; + dbus_int32_t name_size; + dbus_int32_t in_fd; + unsigned char *in_ta_path = NULL; + dbus_int32_t in_ta_path_size; + dbus_uint64_t in_session_list_next; + dbus_uint64_t in_session_list_prev; + dbus_uint64_t in_shrd_mem_list_next; + dbus_uint64_t in_shrd_mem_list_prev; + dbus_uint64_t in_share_buffer_buffer; + dbus_int64_t in_share_buffer_buffer_barrier; + dbus_uint32_t teecresult; + dbus_int32_t fd; + // unsigned char ta_path[] = "/vendor/bin/rsa_demo_ta"; + // dbus_int32_t ta_path_size = strlen((const char *)ta_path); + unsigned char *ta_path = NULL; + dbus_int32_t ta_path_size = 0; + dbus_uint64_t session_list_next; + dbus_uint64_t session_list_prev; + dbus_uint64_t shrd_mem_list_next; + dbus_uint64_t shrd_mem_list_prev; + dbus_uint64_t share_buffer_buffer; + dbus_int64_t share_buffer_buffer_barrier; + dbus_uint64_t context_addr; + dbus_uint32_t serial = 0; + +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + pthread_cond_t * cond_notbusy; + wr_t * workerrec; +#endif + +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl; + pthread_mutex_t *mutex_tsl; + tcl_t *tcl; + tsl_t *tsl; +#endif + + DBusMCP = (DBusMsgConn *) thdfargs; + msg = DBusMCP->msg; + conn = DBusMCP->conn; +#ifdef GP_PROXY + mutex_workerrec = DBusMCP->mutex_workerrec; + cond_notbusy = DBusMCP->cond_notbusy; + workerrec = DBusMCP->workerrec; +#endif +#ifdef GP_WORKER + mutex_tcl = DBusMCP->mutex_tcl; + mutex_tsl = DBusMCP->mutex_tsl; + tcl = DBusMCP->tcl; + tsl = DBusMCP->tsl; +#endif + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &name_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (name_size > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &name); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_fd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path_size + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + // fprintf(stderr, "Debug in_ta_path_size = %d \n", in_ta_path_size); + if (in_ta_path_size > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer_barrier); + + printf("Received method call Teec Initialize Context: \n"); + printf(" in name = %s \n", name); + printf(" in name_size = %d \n", name_size); + printf(" in_fd = 0x %8.8x \n", in_fd); + printf(" in_ta_path = %s \n", in_ta_path); + printf(" in_ta_path_size = %d \n", in_ta_path_size); +#if 0 + printf(" in_session_list_next = 0x %16.16lx \n", in_session_list_next); + printf(" in_session_list_prev = 0x %16.16lx \n", in_session_list_prev); + printf(" in_shrd_mem_list_next = 0x %16.16lx \n", in_shrd_mem_list_next); + printf(" in_shrd_mem_list_prev = 0x %16.16lx \n", in_shrd_mem_list_prev); + printf(" in_share_buffer_buffer = 0x %16.16lx \n", in_share_buffer_buffer); + printf(" in_share_buffer_buffer_barrier = 0x %16.16lx \n", in_share_buffer_buffer_barrier); +#endif + +#ifdef GP_WORKER + //////////////////////////////////////////////////////////////////////////////////////////////// + TEEC_Context *contextIns = (TEEC_Context *) malloc(sizeof(TEEC_Context)); + + TEEC_Result result; + + contextIns->fd = in_fd; + contextIns->ta_path = in_ta_path; + contextIns->session_list.next = (struct ListNode *) in_session_list_next; + contextIns->session_list.prev = (struct ListNode *) in_session_list_prev; + contextIns->shrd_mem_list.next = (struct ListNode *) in_shrd_mem_list_next; + contextIns->shrd_mem_list.prev = (struct ListNode *) in_shrd_mem_list_prev; + contextIns->share_buffer.buffer = (void *) in_share_buffer_buffer; + contextIns->share_buffer.buffer_barrier.__align = (long long int) in_share_buffer_buffer_barrier; + // typedef struct { + // volatile int __val[4*sizeof(long)/sizeof(int)]; + // } sem_t; + // + // typedef union + // { + // char __size[__SIZEOF_SEM_T]; + // long long int __align; + // } sem_t; + struct timeval start, end; + gettimeofday(&start, NULL); + result = TEEC_InitializeContext(NULL, contextIns); + gettimeofday(&end, NULL); + uint32_t cost = 0; + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + if (result != TEEC_SUCCESS) + { + printf("Teec InitilizeContext Failed.\n"); + printf(" teecresult = 0x %8.8x.\n", result); + + teecresult = result; + fd = 0; + ta_path_size = 0; + ta_path = NULL; + charp = ta_path; + session_list_next = 0; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + context_addr = 0; + } else + { + printf("Teec InitilizeContext Succed, cost time: %ld us \n", cost); + + tcn_t *tcnIns = (tcn_t *) malloc(sizeof(tcn_t)); + tcnIns->self = contextIns; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + tcnIns->createtime = tvcreate; + + pthread_mutex_lock(mutex_tcl); + if (tcl->first == NULL) + { + tcnIns->next = NULL; + tcnIns->prev = NULL; + tcl->first = tcnIns; + tcl->last = tcnIns; + tcl->count = 1; + } else + { + tcnIns->prev = tcl->last; + tcnIns->next = NULL; + tcl->last->next = tcnIns; + tcl->last = tcnIns; + tcl->count = tcl->count + 1; + } + pthread_mutex_unlock(mutex_tcl); + + teecresult = result; + fd = contextIns->fd; + if (contextIns->ta_path != NULL) + { + ta_path_size = strlen((const char *) contextIns->ta_path); + } else + { + ta_path_size = 0; + } + ta_path = contextIns->ta_path; + charp = ta_path; + session_list_next = (dbus_uint64_t) contextIns->session_list.next; + session_list_prev = (dbus_uint64_t) contextIns->session_list.prev; + shrd_mem_list_next = (dbus_uint64_t) contextIns->shrd_mem_list.next; + shrd_mem_list_prev = (dbus_uint64_t) contextIns->shrd_mem_list.prev; + share_buffer_buffer = (dbus_uint64_t) contextIns->share_buffer.buffer; + share_buffer_buffer_barrier = contextIns->share_buffer.buffer_barrier.__align; + + // context_addr = (dbus_uint64_t)contextIns; + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + context_addr = (dbus_uint64_t) DBusMCP->workernum + + u64time + + (long unsigned int) rand(); + + printf(" context fd = 0x %8.8x \n", contextIns->fd); + printf(" context address = 0x %16.16lx \n", context_addr); + } + + // TEEC_FinalizeContext(&contextIns); + // printf("Teec FinalizedContext.\n"); + //////////////////////////////////////////////////////////////////////////////////////////////// +#else + ta_path = (unsigned char *)malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *)ta_path, 0, 1024); + uint32_t context_tapath_outsize; + + char workername[1024]; + memset((char *)workername, 0, 1024); + int ifound = 0; + int iworker; + for( ; ; ) + { + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].busy == 0) + { + sprintf(workername, "%s%d", "gpworker", iworker); + workerrec[iworker].busy = 1; + ifound = 1; + break; + } + } + if (ifound == 0) + { + pthread_cond_wait(cond_notbusy, mutex_workerrec); + } + pthread_mutex_unlock(mutex_workerrec); + + if (ifound == 1) + { + break; + } + } + + method_call_teec_inicont( + workername, + + name, + name_size, + in_fd, + in_ta_path, + in_ta_path_size, + in_session_list_next, + in_session_list_prev, + in_shrd_mem_list_next, + in_shrd_mem_list_prev, + in_share_buffer_buffer, + in_share_buffer_buffer_barrier, + + + &teecresult, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + &context_addr, + + &context_tapath_outsize + ); + + if (teecresult == 0) + { + pthread_mutex_lock(mutex_workerrec); + workerrec[iworker].context_fd = fd; + workerrec[iworker].context_addr = context_addr; + workerrec[iworker].first = NULL; + workerrec[iworker].last = NULL; + workerrec[iworker].sessionid_count = 0; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + workerrec[iworker].context_createtime = tvcreate; + pthread_mutex_unlock(mutex_workerrec); + } + else + { + workerrec[iworker].busy = 0; + } + + if (ta_path_size >= context_tapath_outsize) { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } + else + { + ta_path_size = 0; + charp = NULL; + } + + //////////////////////////////////////////////////////////////////////////////////////////////// +#endif + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + +#if 0 + teecresult = 0; + fd = 0x04; + charp = ta_path; + session_list_next = 0xea3500a8; + session_list_prev = 0xea3500a8; + shrd_mem_list_next = 0xea3500b8; + shrd_mem_list_prev = 0xea3500b8; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0xdd901c10; +#endif + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &teecresult + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &fd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + DBusError err; + // initialise the errors + dbus_error_init(&err); + + if (ta_path_size > 0 && + charp != NULL && + strlen((const char *) charp) > 0 + ) + { + if (dbus_validate_utf8((const char *) charp, &err) == true) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &ta_path_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (ta_path_size > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &charp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &share_buffer_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &share_buffer_buffer_barrier + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &context_addr + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send the reply && flush the connection + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_unref(reply); + dbus_message_unref(msg); + dbus_connection_flush(conn); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + + free(thdfargs); + + // sleep(2); + +#if 0 + #ifdef GP_WORKER + +#else + if (ta_path == NULL) + { + free(ta_path); + } +#endif +#endif + + return NULL; +} + + +void * +reply_to_method_call_teec_fincont( + void *thdfargs +) +{ + DBusMsgConn *DBusMCP; + DBusMessage *msg; + DBusConnection *conn; + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + DBusMessageIter structIter; + int iType; + unsigned char *charp; + // char* param = ""; + dbus_int32_t in_fd; + unsigned char *in_ta_path = NULL; + dbus_int32_t in_ta_path_size; + dbus_uint64_t in_session_list_next; + dbus_uint64_t in_session_list_prev; + dbus_uint64_t in_shrd_mem_list_next; + dbus_uint64_t in_shrd_mem_list_prev; + dbus_uint64_t in_share_buffer_buffer; + dbus_int64_t in_share_buffer_buffer_barrier; + dbus_uint64_t in_context_addr; + + dbus_int32_t fd; + dbus_int32_t ta_path_size = 0; + dbus_uint64_t session_list_next; + dbus_uint64_t session_list_prev; + dbus_uint64_t shrd_mem_list_next; + dbus_uint64_t shrd_mem_list_prev; + dbus_uint64_t share_buffer_buffer; + dbus_int64_t share_buffer_buffer_barrier; + dbus_uint32_t serial = 0; + +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + pthread_cond_t * cond_notbusy; + wr_t * workerrec; +#endif + +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl; + tcl_t *tcl; + tsl_t *tsl; +#endif + + DBusMCP = (DBusMsgConn *) thdfargs; + msg = DBusMCP->msg; + conn = DBusMCP->conn; +#ifdef GP_PROXY + mutex_workerrec = DBusMCP->mutex_workerrec; + cond_notbusy = DBusMCP->cond_notbusy; + workerrec = DBusMCP->workerrec; +#endif +#ifdef GP_WORKER + mutex_tcl = DBusMCP->mutex_tcl; + tcl = DBusMCP->tcl; + tsl = DBusMCP->tsl; +#endif + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_fd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path_size + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + // fprintf(stderr, "Debug in_ta_path_size = %d \n", in_ta_path_size); + if (in_ta_path_size > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer_barrier); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_context_addr); + + printf("Received method call Teec Finalize Context: \n"); + printf(" in_fd = 0x %8.8x \n", in_fd); + printf(" in_ta_path_size = %d \n", in_ta_path_size); + + DBusError err; + dbus_error_init(&err); + if (in_ta_path_size > 0 && in_ta_path != NULL && dbus_validate_path((const char *) in_ta_path, &err) == true) + { + printf(" in_ta_path = %s \n", in_ta_path); + } +#if 0 + printf(" in_session_list_next = 0x %16.16lx \n", in_session_list_next); + printf(" in_session_list_prev = 0x %16.16lx \n", in_session_list_prev); + printf(" in_shrd_mem_list_next = 0x %16.16lx \n", in_shrd_mem_list_next); + printf(" in_shrd_mem_list_prev = 0x %16.16lx \n", in_shrd_mem_list_prev); + printf(" in_share_buffer_buffer = 0x %16.16lx \n", in_share_buffer_buffer); + printf(" in_share_buffer_buffer_barrier = 0x %16.16lx \n", in_share_buffer_buffer_barrier); +#endif + printf(" in_context_addr = 0x %16.16lx \n", in_context_addr); + + + unsigned char *ta_path = NULL; +#ifdef GP_WORKER + //////////////////////////////////////////////////////////////////////////////////////////////// + TEEC_Context *contextIns; + tcn_t *tcnIns; + TEEC_Result result; + + contextIns = NULL; + pthread_mutex_lock(mutex_tcl); + if (tcl->first != NULL) + { + tcnIns = tcl->first; + do + { + if (tcnIns->self->fd == in_fd) + { + contextIns = tcnIns->self; + break; + } + tcnIns = tcnIns->next; + } while (tcnIns != NULL); + } + pthread_mutex_unlock(mutex_tcl); + + if (contextIns == NULL) + { + if (tcl->first == NULL) + { + printf("The teec context list is null. \n"); + // teecresult = TEEC_ERROR_CONTEXT_LIST_NULL; + } else + { + printf("Can't find the teec context. \n"); + // teecresult = TEEC_ERROR_NO_CONTEXT_MATCH; + } + + fd = 0; + ta_path_size = 0; + charp = NULL; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + } else + { + // contextIns.fd = in_fd; + contextIns->ta_path = in_ta_path; + contextIns->session_list.next = (struct ListNode *) in_session_list_next; + contextIns->session_list.prev = (struct ListNode *) in_session_list_prev; + contextIns->shrd_mem_list.next = (struct ListNode *) in_shrd_mem_list_next; + contextIns->shrd_mem_list.prev = (struct ListNode *) in_shrd_mem_list_prev; + contextIns->share_buffer.buffer = (void *) in_share_buffer_buffer; + contextIns->share_buffer.buffer_barrier.__align = (long long int) in_share_buffer_buffer_barrier; + // typedef struct { + // volatile int __val[4*sizeof(long)/sizeof(int)]; + // } sem_t; + // + // typedef union + // { + // char __size[__SIZEOF_SEM_T]; + // long long int __align; + // } sem_t; + + struct timeval start, end; + gettimeofday(&start, NULL); + TEEC_FinalizeContext(contextIns); + gettimeofday(&end, NULL); + uint32_t cost = 0; + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + printf("Teec FinalizeContext executed, cost time: %ld us \n", cost); + + fd = contextIns->fd; + if (contextIns->ta_path != NULL) + { + ta_path_size = strlen((const char *) contextIns->ta_path); + ta_path = contextIns->ta_path; + } else + { + ta_path_size = 0; + ta_path = NULL; + } + charp = ta_path; + session_list_next = (dbus_uint64_t) contextIns->session_list.next; + session_list_prev = (dbus_uint64_t) contextIns->session_list.prev; + shrd_mem_list_next = (dbus_uint64_t) contextIns->shrd_mem_list.next; + shrd_mem_list_prev = (dbus_uint64_t) contextIns->shrd_mem_list.prev; + share_buffer_buffer = (dbus_uint64_t) contextIns->share_buffer.buffer; + share_buffer_buffer_barrier = contextIns->share_buffer.buffer_barrier.__align; + + tcn_t *tcnTemp; + tcnTemp = tcnIns->prev; + if (tcnTemp != NULL) + { + tcnTemp->next = tcnIns->next; + } + tcnTemp = tcnIns->next; + if (tcnTemp != NULL) + { + tcnTemp->prev = tcnIns->prev; + } + pthread_mutex_lock(mutex_tcl); + if (tcl->last == tcnIns) + { + tcl->last = tcnIns->prev; + } + if (tcl->first == tcnIns) + { + tcl->first = tcnIns->next; + } + tcl->count = tcl->count - 1; + pthread_mutex_unlock(mutex_tcl); + free(contextIns); + free(tcnIns); + } + //////////////////////////////////////////////////////////////////////////////////////////////// +#else + ta_path = (unsigned char *)malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *)ta_path, 0, 1024); + uint32_t context_tapath_outsize; + + char workername[1024]; + memset((char *)workername, 0, 1024); + int ifound = 0; + int iworker; + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].context_fd == in_fd && + workerrec[iworker].context_addr == in_context_addr + ) + { + sprintf(workername, "%s%d", "gpworker", iworker); + ifound = 1; + break; + } + } + pthread_mutex_unlock(mutex_workerrec); + + if (ifound == 0) + { + printf("Can't find the worker for the context. \n"); + + // teecresult = 0xAAAA0017; + + fd = 0; + ta_path_size = 0; + charp = NULL; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + } + else + { + pthread_mutex_unlock(mutex_workerrec); + sin_t * sinIns = NULL; + sin_t * sinInsPrev = NULL; + sinIns = workerrec[iworker].last; + if (sinIns != NULL) + { + dbus_uint32_t in_session_seesionid; + dbus_uint32_t in_session_serviceid_timelow = 0; + dbus_uint32_t in_session_serviceid_timemid = 0; + dbus_uint32_t in_session_serviceid_timehiandver = 0; + dbus_uint32_t in_session_serviceid_clockseqandnode_size = 8; + dbus_uint32_t in_session_serviceid_clockseqandnode[8]; + dbus_uint32_t in_session_opscnt = 0; + dbus_uint64_t in_session_head_next = 0; + dbus_uint64_t in_session_head_prev = 0; + dbus_uint64_t in_session_context; + + dbus_uint32_t seesionid; + dbus_uint32_t serviceid_timelow; + dbus_uint32_t serviceid_timemid; + dbus_uint32_t serviceid_timehiandver; + dbus_uint32_t * serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + dbus_uint32_t opscnt; + dbus_uint64_t head_next; + dbus_uint64_t head_prev; + dbus_uint64_t context; + + for ( ; ; ) + { + in_session_seesionid = sinIns->session_id; + in_session_context = workerrec[iworker].context_addr; + + pthread_mutex_unlock(mutex_workerrec); + + for (int iind = 0; iind < 8; iind++) + { + in_session_serviceid_clockseqandnode[iind] = 0; + } + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + + printf("\nMethod call teec closesession. (Called by Proxy before fin context) \n"); + + method_call_teec_closesession( + workername, + + in_session_seesionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &context + ); + + if (serviceid_clockseqandnode != NULL) { + free(serviceid_clockseqandnode); + } + + pthread_mutex_lock(mutex_workerrec); + + sinInsPrev = sinIns->prev; + free(sinIns); + if (sinInsPrev == NULL) + // if (sinIns == workerrec[iworker].first) + { + // free(sinIns); + break; + } + sinIns = sinInsPrev; + } + } + pthread_mutex_unlock(mutex_workerrec); + + method_call_teec_fincont( + workername, + + in_fd, + in_ta_path, + in_ta_path_size, + in_session_list_next, + in_session_list_prev, + in_shrd_mem_list_next, + in_shrd_mem_list_prev, + in_share_buffer_buffer, + in_share_buffer_buffer_barrier, + in_context_addr, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + + &context_tapath_outsize + ); + + pthread_mutex_lock(mutex_workerrec); + workerrec[iworker].busy = 0; + pthread_cond_signal(cond_notbusy); + workerrec[iworker].context_fd = 0; + workerrec[iworker].context_addr = 0xffffffff; + workerrec[iworker].sessionid_count = 0; + workerrec[iworker].first = NULL; + workerrec[iworker].last = NULL; + pthread_mutex_unlock(mutex_workerrec); + + if (ta_path_size >= context_tapath_outsize) { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } + else + { + ta_path_size = 0; + charp = NULL; + } + + } // end of else found == 1 + //////////////////////////////////////////////////////////////////////////////////////////////// + +#endif + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &fd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + // DBusError err; + // initialise the errors + // dbus_error_init(&err); + + if (ta_path_size > 0 && + charp != NULL + // && strlen((const char *) charp) > 0 + ) + { + // if (dbus_validate_utf8((const char *) charp, &err) == true) + if (dbus_validate_path((const char *) charp, &err) == true) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &ta_path_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + fprintf(stderr, "%s %d: reply fincont, tapath size = %d \n", __FILE__, __LINE__, ta_path_size); + if (ta_path_size > 0) + { + fprintf(stderr, "%s %d: reply fincont, tapath = %s \n", __FILE__, __LINE__, charp); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &charp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &share_buffer_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &share_buffer_buffer_barrier + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send the reply && flush the connection + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_unref(reply); + dbus_message_unref(msg); + dbus_connection_flush(conn); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + free(thdfargs); + + // sleep(2); + +#if 0 + #ifdef GP_WORKER + +#else + if (ta_path == NULL) + { + free(ta_path); + } +#endif +#endif + + return NULL; +} + + +void * +reply_to_method_call_teec_opensession( + void *thdfargs +) +{ + DBusMsgConn *DBusMCP; + DBusMessage *msg; + DBusConnection *conn; + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int iType; + unsigned char *charp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + // char* param = ""; + dbus_int32_t in_fd; + unsigned char *in_ta_path = NULL; + dbus_int32_t in_ta_path_size; + dbus_uint64_t in_session_list_next; + dbus_uint64_t in_session_list_prev; + dbus_uint64_t in_shrd_mem_list_next; + dbus_uint64_t in_shrd_mem_list_prev; + dbus_uint64_t in_share_buffer_buffer; + dbus_int64_t in_share_buffer_buffer_barrier; + dbus_uint32_t teecresult; + dbus_int32_t fd; + + dbus_uint32_t in_destination_timelow; + dbus_uint32_t in_destination_timemid; + dbus_uint32_t in_destination_timehiandver; + + dbus_uint32_t in_connectionmethod; + dbus_uint64_t in_connectiondata; + dbus_uint32_t in_operation_started; + dbus_uint32_t in_operation_paramtypes; + dbus_int32_t in_destination_clockseqandnode_size; + int in_destination_clockseqandnode_realsize; + dbus_uint32_t *in_destination_clockseqandnode; + + dbus_uint64_t in_operation_param1_tmpref_buffer; + dbus_uint32_t in_operation_param1_tmpref_size; + dbus_uint64_t in_operation_param1_memref_parent; + dbus_uint32_t in_operation_param1_memref_size; + dbus_uint32_t in_operation_param1_memref_offset; + dbus_uint32_t in_operation_param1_value_a; + dbus_uint32_t in_operation_param1_value_b; + dbus_int32_t in_operation_param1_ionref_ionsharefd; + dbus_uint32_t in_operation_param1_ionref_ionsize; + + dbus_uint64_t in_operation_param2_tmpref_buffer; + dbus_uint32_t in_operation_param2_tmpref_size; + dbus_uint64_t in_operation_param2_memref_parent; + dbus_uint32_t in_operation_param2_memref_size; + dbus_uint32_t in_operation_param2_memref_offset; + dbus_uint32_t in_operation_param2_value_a; + dbus_uint32_t in_operation_param2_value_b; + dbus_int32_t in_operation_param2_ionref_ionsharefd; + dbus_uint32_t in_operation_param2_ionref_ionsize; + + dbus_uint64_t in_operation_param3_tmpref_buffer; + dbus_uint32_t in_operation_param3_tmpref_size; + dbus_uint64_t in_operation_param3_memref_parent; + dbus_uint32_t in_operation_param3_memref_size; + dbus_uint32_t in_operation_param3_memref_offset; + dbus_uint32_t in_operation_param3_value_a; + dbus_uint32_t in_operation_param3_value_b; + dbus_int32_t in_operation_param3_ionref_ionsharefd; + dbus_uint32_t in_operation_param3_ionref_ionsize; + + dbus_uint64_t in_operation_param4_tmpref_buffer; + dbus_uint32_t in_operation_param4_tmpref_size; + dbus_uint64_t in_operation_param4_memref_parent; + dbus_uint32_t in_operation_param4_memref_size; + dbus_uint32_t in_operation_param4_memref_offset; + dbus_uint32_t in_operation_param4_value_a; + dbus_uint32_t in_operation_param4_value_b; + dbus_int32_t in_operation_param4_ionref_ionsharefd; + dbus_uint32_t in_operation_param4_ionref_ionsize; + + dbus_uint64_t in_operation_session; + dbus_int32_t in_operation_cancelflag; + dbus_uint32_t in_returnorigin; + + dbus_uint64_t in_context_addr; + + // unsigned char ta_path[] = "/vendor/bin/rsa_demo_ta"; + // dbus_int32_t ta_path_size = strlen((const char *)ta_path); + unsigned char *ta_path; + dbus_int32_t ta_path_size; + dbus_uint64_t session_list_next; + dbus_uint64_t session_list_prev; + dbus_uint64_t shrd_mem_list_next; + dbus_uint64_t shrd_mem_list_prev; + dbus_uint64_t share_buffer_buffer; + dbus_int64_t share_buffer_buffer_barrier; + + dbus_uint32_t seesionid; + dbus_uint32_t serviceid_timelow; + dbus_uint32_t serviceid_timemid; + dbus_uint32_t serviceid_timehiandver; + dbus_uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + dbus_int32_t serviceid_clockseqandnode_outsize; + dbus_uint32_t opscnt; + dbus_uint64_t head_next; + dbus_uint64_t head_prev; + dbus_uint64_t context; + + dbus_uint32_t started; + dbus_uint32_t paramtypes; + + dbus_uint64_t operation_param1_tmpref_buffer; + dbus_uint32_t operation_param1_tmpref_size; + dbus_uint64_t operation_param1_memref_parent; + dbus_uint32_t operation_param1_memref_size; + dbus_uint32_t operation_param1_memref_offset; + dbus_uint32_t operation_param1_value_a; + dbus_uint32_t operation_param1_value_b; + dbus_int32_t operation_param1_ionref_ionsharefd; + dbus_uint32_t operation_param1_ionref_ionsize; + + dbus_uint64_t operation_param2_tmpref_buffer; + dbus_uint32_t operation_param2_tmpref_size; + dbus_uint64_t operation_param2_memref_parent; + dbus_uint32_t operation_param2_memref_size; + dbus_uint32_t operation_param2_memref_offset; + dbus_uint32_t operation_param2_value_a; + dbus_uint32_t operation_param2_value_b; + dbus_int32_t operation_param2_ionref_ionsharefd; + dbus_uint32_t operation_param2_ionref_ionsize; + + dbus_uint64_t operation_param3_tmpref_buffer; + dbus_uint32_t operation_param3_tmpref_size; + dbus_uint64_t operation_param3_memref_parent; + dbus_uint32_t operation_param3_memref_size; + dbus_uint32_t operation_param3_memref_offset; + dbus_uint32_t operation_param3_value_a; + dbus_uint32_t operation_param3_value_b; + dbus_int32_t operation_param3_ionref_ionsharefd; + dbus_uint32_t operation_param3_ionref_ionsize; + + dbus_uint64_t operation_param4_tmpref_buffer; + dbus_uint32_t operation_param4_tmpref_size; + dbus_uint64_t operation_param4_memref_parent; + dbus_uint32_t operation_param4_memref_size; + dbus_uint32_t operation_param4_memref_offset; + dbus_uint32_t operation_param4_value_a; + dbus_uint32_t operation_param4_value_b; + dbus_int32_t operation_param4_ionref_ionsharefd; + dbus_uint32_t operation_param4_ionref_ionsize; + + dbus_uint64_t operation_session; + dbus_int32_t operation_cancelflag; + dbus_uint32_t returnorigin; + dbus_uint32_t serial = 0; + +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + wr_t * workerrec; +#endif + +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl; + pthread_mutex_t *mutex_tsl; + tcl_t *tcl; + tsl_t *tsl; +#endif + + DBusMCP = (DBusMsgConn *) thdfargs; + msg = DBusMCP->msg; + conn = DBusMCP->conn; +#ifdef GP_PROXY + mutex_workerrec = DBusMCP->mutex_workerrec; + workerrec = DBusMCP->workerrec; +#endif +#ifdef GP_WORKER + mutex_tcl = DBusMCP->mutex_tcl; + mutex_tsl = DBusMCP->mutex_tsl; + tcl = DBusMCP->tcl; + tsl = DBusMCP->tsl; +#endif + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_get_basic( + &structIter, + &in_fd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path_size + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + // fprintf(stderr, "Debug in_ta_path_size = %d \n", in_ta_path_size); + if (in_ta_path_size > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_ta_path); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_shrd_mem_list_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_share_buffer_buffer_barrier); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_destination_timelow); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_destination_timemid); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_destination_timehiandver); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_destination_clockseqandnode_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_destination_clockseqandnode_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_destination_clockseqandnode, + &in_destination_clockseqandnode_realsize + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_get_basic( + &structIter, + &in_connectionmethod); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_connectiondata); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_started); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_paramtypes); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_parent); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_size); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_value_a); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_value_b); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_parent); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_parent); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_tmpref_buffer); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_parent); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_size); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_session); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_cancelflag); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_returnorigin); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_context_addr); + + printf("Received method call Teec Open Session: \n"); + printf(" in_fd = 0x %8.8x \n", in_fd); + printf(" in_ta_path = %s \n", in_ta_path); + printf(" in_ta_path_size = %d \n", in_ta_path_size); +#if 0 + printf(" in_session_list_next = 0x %16.16lx \n", in_session_list_next); + printf(" in_session_list_prev = 0x %16.16lx \n", in_session_list_prev); + printf(" in_shrd_mem_list_next = 0x %16.16lx \n", in_shrd_mem_list_next); + printf(" in_shrd_mem_list_prev = 0x %16.16lx \n", in_shrd_mem_list_prev); + printf(" in_share_buffer_buffer = 0x %16.16lx \n", in_share_buffer_buffer); + printf(" in_share_buffer_buffer_barrier = 0x %16.16lx \n", in_share_buffer_buffer_barrier); + + printf(" in_destination_timelow = 0x %8.8x \n", in_destination_timelow); + printf(" in_destination_timemid = 0x %8.8x \n", in_destination_timemid); + printf(" in_destination_timehiandver = 0x %8.8x \n", in_destination_timehiandver); + if ( in_destination_clockseqandnode_realsize > 0 ) + { + printf(" in_destination_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_destination_clockseqandnode_realsize; i++) { + printf(" %8.8x", in_destination_clockseqandnode[i]); + } + printf("\n"); + } + else + { + printf(" in_destination_clockseqandnode addr = 0x %16.16lx \n", + (long unsigned int)in_destination_clockseqandnode + ); + } + printf(" in_destination_clockseqandnode_size = 0x %8.8x \n", in_destination_clockseqandnode_size); + + printf(" in_connectionmethod = 0x %8.8x \n", in_connectionmethod); + printf(" in_connectiondata = 0x %16.16lx \n", in_connectiondata); + + printf(" in_operation_started = 0x %8.8x \n", in_operation_started); + printf(" in_operation_paramtypes = 0x %8.8x \n", in_operation_paramtypes); + + printf(" in_operation_param1_tmpref_buffer = 0x %16.16lx \n", in_operation_param1_tmpref_buffer); + printf(" in_operation_param1_tmpref_size = 0x %8.8x \n", in_operation_param1_tmpref_size); + printf(" in_operation_param1_memref_parent = 0x %16.16lx \n", in_operation_param1_memref_parent); + printf(" in_operation_param1_memref_size = 0x %8.8x \n", in_operation_param1_memref_size); + printf(" in_operation_param1_memref_offset = 0x %8.8x \n", in_operation_param1_memref_offset); + printf(" in_operation_param1_value_a = 0x %8.8x \n", in_operation_param1_value_a); + printf(" in_operation_param1_value_b = 0x %8.8x \n", in_operation_param1_value_b); + printf(" in_operation_param1_ionref_ionsharefd = 0x %8.8x \n", + in_operation_param1_ionref_ionsharefd); + printf(" in_operation_param1_ionref_ionsize = 0x %8.8x \n", in_operation_param1_ionref_ionsize); + + printf(" in_operation_param2_tmpref_buffer = 0x %16.16lx \n", in_operation_param2_tmpref_buffer); + printf(" in_operation_param2_tmpref_size = 0x %8.8x \n", in_operation_param2_tmpref_size); + printf(" in_operation_param2_memref_parent = 0x %16.16lx \n", in_operation_param2_memref_parent); + printf(" in_operation_param2_memref_size = 0x %8.8x \n", in_operation_param2_memref_size); + printf(" in_operation_param2_memref_offset = 0x %8.8x \n", in_operation_param2_memref_offset); + printf(" in_operation_param2_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param2_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param2_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param2_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param3_tmpref_buffer = 0x %16.16lx \n", in_operation_param3_tmpref_buffer); + printf(" in_operation_param3_tmpref_size = 0x %8.8x \n", in_operation_param3_tmpref_size); + printf(" in_operation_param3_memref_parent = 0x %16.16lx \n", in_operation_param3_memref_parent); + printf(" in_operation_param3_memref_size = 0x %8.8x \n", in_operation_param3_memref_size); + printf(" in_operation_param3_memref_offset = 0x %8.8x \n", in_operation_param3_memref_offset); + printf(" in_operation_param3_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param3_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param3_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param3_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param4_tmpref_buffer = 0x %16.16lx \n", in_operation_param4_tmpref_buffer); + printf(" in_operation_param4_tmpref_size = 0x %8.8x \n", in_operation_param4_tmpref_size); + printf(" in_operation_param4_memref_parent = 0x %16.16lx \n", in_operation_param4_memref_parent); + printf(" in_operation_param4_memref_size = 0x %8.8x \n", in_operation_param4_memref_size); + printf(" in_operation_param4_memref_offset = 0x %8.8x \n", in_operation_param4_memref_offset); + printf(" in_operation_param4_value_a = 0x %8.8x \n", in_operation_param4_value_a); + printf(" in_operation_param4_value_b = 0x %8.8x \n", in_operation_param4_value_b); + printf(" in_operation_param4_ionref_ionsharefd = 0x %8.8x \n", in_operation_param4_ionref_ionsharefd); + printf(" in_operation_param4_ionref_ionsize = 0x %8.8x \n", in_operation_param4_ionref_ionsize); + + printf(" in_operation_session = 0x %16.16lx \n", in_operation_session); + printf(" in_operation_cancelflag = 0x %8.8x \n", in_operation_cancelflag); + + printf(" in_returnorigin = 0x %8.8x \n", in_returnorigin); +#endif + printf(" in_context_addr = 0x %16.16lx \n", in_context_addr); + +#ifdef GP_WORKER + //////////////////////////////////////////////////////////////////////////////////////////////// + + TEEC_Context *contextIns; + tcn_t *tcnIns; + + TEEC_UUID destinationIns; + void *in_connectiondata_temp; + TEEC_Operation operationIns; + uint32_t origin; + TEEC_Result result; + + contextIns = NULL; + pthread_mutex_lock(mutex_tcl); + if (tcl->first != NULL) + { + tcnIns = tcl->first; + do + { + if (tcnIns->self->fd == in_fd) + { + contextIns = tcnIns->self; + break; + } + tcnIns = tcnIns->next; + } while (tcnIns != NULL); + } + pthread_mutex_unlock(mutex_tcl); + + if (contextIns == NULL) + { + if (tcl->first == NULL) + { + printf("The teec context list is null. \n"); + teecresult = TEEC_ERROR_CONTEXT_LIST_NULL; + } else + { + printf("Can't find the teec context. \n"); + teecresult = TEEC_ERROR_NO_CONTEXT_MATCH; + } + + fd = 0; + ta_path_size = 0; + ta_path = NULL; + charp = ta_path; + session_list_next = 0; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + + seesionid = 0; + serviceid_timelow = 0; + serviceid_timemid = 0; + serviceid_timehiandver = 0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + opscnt = 0; + head_next = 0; + head_prev = 0; + context = 0; + + started = 0; + paramtypes = 0; + + operation_param1_tmpref_buffer = 0; + operation_param1_tmpref_size = 0; + operation_param1_memref_parent = 0; + operation_param1_memref_size = 0; + operation_param1_memref_offset = 0; + operation_param1_value_a = 0; + operation_param1_value_b = 0; + operation_param1_ionref_ionsharefd = 0; + operation_param1_ionref_ionsize = 0; + + operation_param2_tmpref_buffer = 0; + operation_param2_tmpref_size = 0; + operation_param2_memref_parent = 0; + operation_param2_memref_size = 0; + operation_param2_memref_offset = 0; + operation_param2_value_a = 0; + operation_param2_value_b = 0; + operation_param2_ionref_ionsharefd = 0; + operation_param2_ionref_ionsize = 0; + + operation_param3_tmpref_buffer = 0; + operation_param3_tmpref_size = 0; + operation_param3_memref_parent = 0; + operation_param3_memref_size = 0; + operation_param3_memref_offset = 0; + operation_param3_value_a = 0; + operation_param3_value_b = 0; + operation_param3_ionref_ionsharefd = 0; + operation_param3_ionref_ionsize = 0; + + operation_param4_tmpref_buffer = 0; + operation_param4_tmpref_size = 0; + operation_param4_memref_parent = 0; + operation_param4_memref_size = 0; + operation_param4_memref_offset = 0; + operation_param4_value_a = 0; + operation_param4_value_b = 0; + operation_param4_ionref_ionsharefd = 0; + operation_param4_ionref_ionsize = 0; + + operation_session = 0; + operation_cancelflag = 0; + + returnorigin = 0; + } else + { + TEEC_Session *sessionIns = (TEEC_Session *) malloc(sizeof(TEEC_Session)); + + // contextIns->fd = in_fd; + contextIns->ta_path = in_ta_path; + // typedef struct { + // volatile int __val[4*sizeof(long)/sizeof(int)]; + // } sem_t; + // + // typedef union + // { + // char __size[__SIZEOF_SEM_T]; + // long long int __align; + // } sem_t; + + destinationIns.timeLow = in_destination_timelow; + destinationIns.timeMid = in_destination_timemid; + destinationIns.timeHiAndVersion = in_destination_timehiandver; + for (int i = 0; + i < in_destination_clockseqandnode_size; + i++) + { + destinationIns.clockSeqAndNode[i] = in_destination_clockseqandnode[i]; + } + + in_connectiondata_temp = (void *) in_connectiondata; + // in_connectiondata_temp = NULL; + + + memset(&operationIns, 0, sizeof(operationIns)); + operationIns.started = in_operation_started; + operationIns.paramTypes = in_operation_paramtypes; + + origin = in_returnorigin; + + struct timeval start, end; + gettimeofday(&start, NULL); + result = + TEEC_OpenSession( + contextIns, + sessionIns, + &destinationIns, + in_connectionmethod, + in_connectiondata_temp, // NULL + &operationIns, + &origin + ); + gettimeofday(&end, NULL); + uint32_t cost = 0; + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (result != TEEC_SUCCESS) + { + printf("Teec OpenSession Failed. \n"); + printf(" teecresult = 0x %8.8x.\n", result); + + teecresult = result; + + fd = 0; + ta_path_size = 0; + ta_path = NULL; + charp = ta_path; + session_list_next = 0; + session_list_prev = 0; + shrd_mem_list_next = 0; + shrd_mem_list_prev = 0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0; + + seesionid = 0; + serviceid_timelow = 0; + serviceid_timemid = 0; + serviceid_timehiandver = 0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + opscnt = 0; + head_next = 0; + head_prev = 0; + context = 0; + + started = 0; + paramtypes = 0; + + operation_param1_tmpref_buffer = 0; + operation_param1_tmpref_size = 0; + operation_param1_memref_parent = 0; + operation_param1_memref_size = 0; + operation_param1_memref_offset = 0; + operation_param1_value_a = 0; + operation_param1_value_b = 0; + operation_param1_ionref_ionsharefd = 0; + operation_param1_ionref_ionsize = 0; + + operation_param2_tmpref_buffer = 0; + operation_param2_tmpref_size = 0; + operation_param2_memref_parent = 0; + operation_param2_memref_size = 0; + operation_param2_memref_offset = 0; + operation_param2_value_a = 0; + operation_param2_value_b = 0; + operation_param2_ionref_ionsharefd = 0; + operation_param2_ionref_ionsize = 0; + + operation_param3_tmpref_buffer = 0; + operation_param3_tmpref_size = 0; + operation_param3_memref_parent = 0; + operation_param3_memref_size = 0; + operation_param3_memref_offset = 0; + operation_param3_value_a = 0; + operation_param3_value_b = 0; + operation_param3_ionref_ionsharefd = 0; + operation_param3_ionref_ionsize = 0; + + operation_param4_tmpref_buffer = 0; + operation_param4_tmpref_size = 0; + operation_param4_memref_parent = 0; + operation_param4_memref_size = 0; + operation_param4_memref_offset = 0; + operation_param4_value_a = 0; + operation_param4_value_b = 0; + operation_param4_ionref_ionsharefd = 0; + operation_param4_ionref_ionsize = 0; + + operation_session = 0; + operation_cancelflag = 0; + + returnorigin = 0; + } else + { + printf("Teec OpenSession Succed, cost time: %ld us \n", cost); + + tsn_t *tsnIns = (tsn_t *) malloc(sizeof(tsn_t)); + tsnIns->self = sessionIns; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + tsnIns->createtime = tvcreate; + pthread_mutex_lock(mutex_tsl); + if (tsl->first == NULL) + { + tsnIns->next = NULL; + tsnIns->prev = NULL; + tsl->first = tsnIns; + tsl->last = tsnIns; + tsl->count = 1; + } else + { + tsnIns->prev = tsl->last; + tsnIns->next = NULL; + tsl->last->next = tsnIns; + tsl->last = tsnIns; + tsl->count = tsl->count + 1; + } + pthread_mutex_unlock(mutex_tsl); + + teecresult = result; + + fd = contextIns->fd; + if (contextIns->ta_path != NULL) + { + ta_path_size = strlen((const char *) contextIns->ta_path); + } else + { + ta_path_size = 0; + } + ta_path = contextIns->ta_path; + charp = ta_path; + session_list_next = (dbus_uint64_t) contextIns->session_list.next; + session_list_prev = (dbus_uint64_t) contextIns->session_list.prev; + shrd_mem_list_next = (dbus_uint64_t) contextIns->shrd_mem_list.next; + shrd_mem_list_prev = (dbus_uint64_t) contextIns->shrd_mem_list.prev; + share_buffer_buffer = (dbus_uint64_t) contextIns->share_buffer.buffer; + share_buffer_buffer_barrier = contextIns->share_buffer.buffer_barrier.__align; + + seesionid = sessionIns->session_id; + serviceid_timelow = sessionIns->service_id.timeLow; + serviceid_timemid = sessionIns->service_id.timeMid; + serviceid_timehiandver = sessionIns->service_id.timeHiAndVersion; + if (sessionIns->service_id.clockSeqAndNode != NULL) + { + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < 8; iind++) + { + uint8_t u8Temp; + u8Temp = sessionIns->service_id.clockSeqAndNode[iind]; + serviceid_clockseqandnode[iind] = (dbus_uint32_t) u8Temp; + } + serviceid_clockseqandnode_outsize = 8; + } else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + } + opscnt = sessionIns->ops_cnt; + head_next = (dbus_uint64_t) sessionIns->head.next; + head_prev = (dbus_uint64_t) sessionIns->head.prev; + context = (dbus_uint64_t) sessionIns->context; + + started = operationIns.started; + paramtypes = operationIns.paramTypes; + + operation_param1_tmpref_buffer = (dbus_uint64_t) operationIns.params[0].tmpref.buffer; + operation_param1_tmpref_size = operationIns.params[0].tmpref.size; + operation_param1_memref_parent = (dbus_uint64_t) operationIns.params[0].memref.parent; + operation_param1_memref_size = operationIns.params[0].memref.size; + operation_param1_memref_offset = operationIns.params[0].memref.offset; + operation_param1_value_a = operationIns.params[0].value.a; + operation_param1_value_b = operationIns.params[0].value.b; + operation_param1_ionref_ionsharefd = operationIns.params[0].ionref.ion_share_fd; + operation_param1_ionref_ionsize = operationIns.params[0].ionref.ion_size; + + operation_param2_tmpref_buffer = (dbus_uint64_t) operationIns.params[1].tmpref.buffer; + operation_param2_tmpref_size = operationIns.params[1].tmpref.size; + operation_param2_memref_parent = (dbus_uint64_t) operationIns.params[1].memref.parent; + operation_param2_memref_size = operationIns.params[1].memref.size; + operation_param2_memref_offset = operationIns.params[1].memref.offset; + operation_param2_value_a = operationIns.params[1].value.a; + operation_param2_value_b = operationIns.params[1].value.b; + operation_param2_ionref_ionsharefd = operationIns.params[1].ionref.ion_share_fd; + operation_param2_ionref_ionsize = operationIns.params[1].ionref.ion_size; + + operation_param3_tmpref_buffer = (dbus_uint64_t) operationIns.params[2].tmpref.buffer; + operation_param3_tmpref_size = operationIns.params[2].tmpref.size; + operation_param3_memref_parent = (dbus_uint64_t) operationIns.params[2].memref.parent; + operation_param3_memref_size = operationIns.params[2].memref.size; + operation_param3_memref_offset = operationIns.params[2].memref.offset; + operation_param3_value_a = operationIns.params[2].value.a; + operation_param3_value_b = operationIns.params[2].value.b; + operation_param3_ionref_ionsharefd = operationIns.params[2].ionref.ion_share_fd; + operation_param3_ionref_ionsize = operationIns.params[2].ionref.ion_size; + + operation_param4_tmpref_buffer = (dbus_uint64_t) operationIns.params[3].tmpref.buffer; + operation_param4_tmpref_size = operationIns.params[3].tmpref.size; + operation_param4_memref_parent = (dbus_uint64_t) operationIns.params[3].memref.parent; + operation_param4_memref_size = operationIns.params[3].memref.size; + operation_param4_memref_offset = operationIns.params[3].memref.offset; + operation_param4_value_a = operationIns.params[3].value.a; + operation_param4_value_b = operationIns.params[3].value.b; + operation_param4_ionref_ionsharefd = operationIns.params[3].ionref.ion_share_fd; + operation_param4_ionref_ionsize = operationIns.params[3].ionref.ion_size; + + operation_session = (dbus_uint64_t) operationIns.session; + operation_cancelflag = operationIns.cancel_flag; + + returnorigin = origin; + + printf(" ret sessionid = 0x %8.8x \n", seesionid); + printf(" ret context = 0x %16.16lx \n", context); + +#if 0 + printf("Call TEEC_CloseSession inputs: \n"); + printf(" session_seesionid = 0x %8.8x \n", sessionIns->session_id); + printf(" session_serviceid_timelow = 0x %8.8x \n", sessionIns->service_id.timeLow); + printf(" session_serviceid_timemid = 0x %4.4x \n", sessionIns->service_id.timeMid); + printf(" session_serviceid_timehiandver = 0x %4.4x \n", + sessionIns->service_id.timeHiAndVersion); + printf(" session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < 8; i++) { + printf(" %2.2x", sessionIns->service_id.clockSeqAndNode[i]); + } + printf("\n"); + printf(" session_opscnt = 0x %8.8x \n", sessionIns->ops_cnt); + printf(" session_head_next = 0x %16.16lx \n", sessionIns->head.next); + printf(" session_head_prev = 0x %16.16lx \n", sessionIns->head.prev); + printf(" session_context = 0x %16.16lx \n", sessionIns->context); + + // TEEC_CloseSession(sessionIns); + // printf("Teec CloseSession. \n"); +#endif + } + } + //////////////////////////////////////////////////////////////////////////////////////////////// +#else + ta_path = (unsigned char *)malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *)ta_path, 0, 1024); + uint32_t context_tapath_outsize; + uint32_t serviceid_clockseqandnode_outsize_temp; + uint32_t returnorigin_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + + char workername[1024]; + memset((char *)workername, 0, 1024); + int ifound = 0; + int iworker; + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].context_fd == in_fd && + workerrec[iworker].context_addr == in_context_addr + ) + { + sprintf(workername, "%s%d", "gpworker", iworker); + ifound = 1; + break; + } + } + pthread_mutex_unlock(mutex_workerrec); + + if (ifound == 0) + { + printf("Can't find the woker for the context. \n"); + + teecresult = 0xAAAA0017; + + fd = 0x0; + ta_path = NULL; + charp = ta_path; + session_list_next = 0x0; + session_list_prev = 0x0; + shrd_mem_list_next = 0x0; + shrd_mem_list_prev = 0x0; + share_buffer_buffer = 0; + share_buffer_buffer_barrier = 0x0; + + seesionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize ; i++) { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + context = 0x0; + + started = 0x0; + paramtypes = 0x0; + + operation_param1_tmpref_buffer = 0x0; + operation_param1_tmpref_size = 0x0; + operation_param1_memref_parent = 0x0; + operation_param1_memref_size = 0x0; + operation_param1_memref_offset = 0x0; + operation_param1_value_a = 0x0; + operation_param1_value_b = 0x0; + operation_param1_ionref_ionsharefd = 0x0; + operation_param1_ionref_ionsize = 0x0; + + operation_param2_tmpref_buffer = 0x0; + operation_param2_tmpref_size = 0x0; + operation_param2_memref_parent = 0x0; + operation_param2_memref_size = 0x0; + operation_param2_memref_offset = 0x0; + operation_param2_value_a = 0x0; + operation_param2_value_b = 0x0; + operation_param2_ionref_ionsharefd = 0x0; + operation_param2_ionref_ionsize = 0x0; + + operation_param3_tmpref_buffer = 0x0; + operation_param3_tmpref_size = 0x0; + operation_param3_memref_parent = 0x0; + operation_param3_memref_size = 0x0; + operation_param3_memref_offset = 0x0; + operation_param3_value_a = 0x0; + operation_param3_value_b = 0x0; + operation_param3_ionref_ionsharefd = 0x0; + operation_param3_ionref_ionsize = 0x0; + + operation_param4_tmpref_buffer = 0x0; + operation_param4_tmpref_size = 0x0; + operation_param4_memref_parent = 0x0; + operation_param4_memref_size = 0x0; + operation_param4_memref_offset = 0x0; + operation_param4_value_a = 0x0; + operation_param4_value_b = 0x0; + operation_param4_ionref_ionsharefd = 0x0; + operation_param4_ionref_ionsize = 0x0; + + operation_session = 0x0; + operation_cancelflag = 0x0; + + returnorigin = 0x0; + } + else + { + method_call_teec_opensession( + workername, + + in_fd, + in_ta_path, + in_ta_path_size, + in_session_list_next, + in_session_list_prev, + in_shrd_mem_list_next, + in_shrd_mem_list_prev, + in_share_buffer_buffer, + in_share_buffer_buffer_barrier, + + in_destination_timelow, + in_destination_timemid, + in_destination_timehiandver, + in_destination_clockseqandnode, + in_destination_clockseqandnode_realsize, + + in_connectionmethod, + in_connectiondata, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + + in_returnorigin, + + in_context_addr, + + + &teecresult, + + &fd, + ta_path, + ta_path_size, + &context_tapath_outsize, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &context, + + &started, + ¶mtypes, + + &operation_param1_tmpref_buffer, + &operation_param1_tmpref_size, + &operation_param1_memref_parent, + &operation_param1_memref_size, + &operation_param1_memref_offset, + &operation_param1_value_a, + &operation_param1_value_b, + &operation_param1_ionref_ionsharefd, + &operation_param1_ionref_ionsize, + + &operation_param2_tmpref_buffer, + &operation_param2_tmpref_size, + &operation_param2_memref_parent, + &operation_param2_memref_size, + &operation_param2_memref_offset, + &operation_param2_value_a, + &operation_param2_value_b, + &operation_param2_ionref_ionsharefd, + &operation_param2_ionref_ionsize, + + &operation_param3_tmpref_buffer, + &operation_param3_tmpref_size, + &operation_param3_memref_parent, + &operation_param3_memref_size, + &operation_param3_memref_offset, + &operation_param3_value_a, + &operation_param3_value_b, + &operation_param3_ionref_ionsharefd, + &operation_param3_ionref_ionsize, + + &operation_param4_tmpref_buffer, + &operation_param4_tmpref_size, + &operation_param4_memref_parent, + &operation_param4_memref_size, + &operation_param4_memref_offset, + &operation_param4_value_a, + &operation_param4_value_b, + &operation_param4_ionref_ionsharefd, + &operation_param4_ionref_ionsize, + + &operation_session, + &operation_cancelflag, + + &returnorigin_temp + ); + + if (teecresult == 0) { + pthread_mutex_lock(mutex_workerrec); + + sin_t * sinIns = (sin_t *)malloc(sizeof(sin_t)); + sinIns->session_id = seesionid; + struct timeval tvcreate; + gettimeofday(&tvcreate, NULL); + sinIns->session_createtime = tvcreate; + if (workerrec[iworker].first == NULL) + { + sinIns->next = NULL; + sinIns->prev = NULL; + workerrec[iworker].first = sinIns; + workerrec[iworker].last = sinIns; + workerrec[iworker].sessionid_count = 1; + } + else + { + sinIns->prev = workerrec[iworker].last; + sinIns->next = NULL; + workerrec[iworker].last->next = sinIns; + workerrec[iworker].last = sinIns; + workerrec[iworker].sessionid_count = + workerrec[iworker].sessionid_count + 1; + } + pthread_mutex_unlock(mutex_workerrec); + } + + serviceid_clockseqandnode_outsize = + serviceid_clockseqandnode_outsize_temp; + returnorigin = returnorigin_temp; + + if (ta_path_size >= context_tapath_outsize) { + ta_path_size = context_tapath_outsize; + charp = ta_path; + } + else + { + ta_path_size = 0; + charp = NULL; + } + + if ( + serviceid_clockseqandnode_realsize >= serviceid_clockseqandnode_outsize && + 8 >= serviceid_clockseqandnode_outsize + ) + { + serviceid_clockseqandnode_realsize = serviceid_clockseqandnode_outsize; + } + else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode_outsize = 0; + } + + } // end of else found == 1 + + //////////////////////////////////////////////////////////////////////////////////////////////// +#endif + + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &teecresult + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &fd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + DBusError err; + // initialise the errors + dbus_error_init(&err); + + if (ta_path_size > 0 && + charp != NULL && + strlen((const char *) charp) > 0 + ) + { + if (dbus_validate_utf8((const char *) charp, &err) == true) + { + ta_path_size = strlen((const char *) charp); + } else + { + ta_path_size = 0; + } + } else + { + ta_path_size = 0; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &ta_path_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (ta_path_size > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &charp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &session_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &shrd_mem_list_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &share_buffer_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &share_buffer_buffer_barrier + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &seesionid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timelow + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timemid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timehiandver + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &opscnt + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &context + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &started + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + ¶mtypes + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param1_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param1_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param1_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param2_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param2_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param2_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param3_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param3_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param3_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param4_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param4_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param4_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_session + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_cancelflag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &returnorigin + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send the reply && flush the connection + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + free(thdfargs); + + // sleep(2); + +#if 0 + #ifdef GP_WORKER + +#else + if (ta_path == NULL) + { + free(ta_path); + } + if (serviceid_clockseqandnode == NULL) + { + free(serviceid_clockseqandnode); + } +#endif +#endif + + return NULL; +} + + +void * +reply_to_method_call_teec_closesession( + void *thdfargs +) +{ + DBusMsgConn *DBusMCP; + DBusMessage *msg; + DBusConnection *conn; + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int iType; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + dbus_uint32_t in_session_seesionid; + dbus_uint32_t in_session_serviceid_timelow; + dbus_uint32_t in_session_serviceid_timemid; + dbus_uint32_t in_session_serviceid_timehiandver; + dbus_uint32_t in_session_serviceid_clockseqandnode_size; + dbus_uint32_t *in_session_serviceid_clockseqandnode; + int in_session_serviceid_clockseqandnode_realsize; + dbus_uint32_t in_session_opscnt; + dbus_uint64_t in_session_head_next; + dbus_uint64_t in_session_head_prev; + dbus_uint64_t in_session_context; + + dbus_uint32_t seesionid; + dbus_uint32_t serviceid_timelow; + dbus_uint32_t serviceid_timemid; + dbus_uint32_t serviceid_timehiandver; + dbus_uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + dbus_int32_t serviceid_clockseqandnode_outsize; + dbus_uint32_t opscnt; + dbus_uint64_t head_next; + dbus_uint64_t head_prev; + dbus_uint64_t context; + + dbus_uint32_t serial = 0; + +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + wr_t * workerrec; +#endif + +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl; + pthread_mutex_t *mutex_tsl; + tcl_t *tcl; + tsl_t *tsl; +#endif + + DBusMCP = (DBusMsgConn *) thdfargs; + msg = DBusMCP->msg; + conn = DBusMCP->conn; +#ifdef GP_PROXY + mutex_workerrec = DBusMCP->mutex_workerrec; + workerrec = DBusMCP->workerrec; +#endif +#ifdef GP_WORKER + mutex_tcl = DBusMCP->mutex_tcl; + mutex_tsl = DBusMCP->mutex_tsl; + tcl = DBusMCP->tcl; + tsl = DBusMCP->tsl; +#endif + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_get_basic( + &structIter, + &in_session_seesionid); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timelow + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timemid); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timehiandver); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_clockseqandnode_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_session_serviceid_clockseqandnode_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_session_serviceid_clockseqandnode, + &in_session_serviceid_clockseqandnode_realsize + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_get_basic( + &structIter, + &in_session_opscnt); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_head_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_head_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_context); + + printf("Received method call Teec Close Session: \n"); + printf(" in_session_seesionid = 0x %8.8x \n", in_session_seesionid); +#if 0 + printf(" in_session_serviceid_timelow = 0x %8.8x \n", in_session_serviceid_timelow); + printf(" in_session_serviceid_timemid = 0x %8.8x \n", in_session_serviceid_timemid); + printf(" in_session_serviceid_timehiandver = 0x %8.8x \n", + in_session_serviceid_timehiandver); + printf(" in_session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_session_serviceid_clockseqandnode_realsize; i++) { + printf(" %8.8x", in_session_serviceid_clockseqandnode[i]); + } + printf("\n"); + printf(" in_session_serviceid_clockseqandnode_size = 0x %8.8x \n", + in_session_serviceid_clockseqandnode_size); + printf(" in_session_opscnt = 0x %8.8x \n", in_session_opscnt); + printf(" in_session_head_next = 0x %16.16lx \n", in_session_head_next); + printf(" in_session_head_prev = 0x %16.16lx \n", in_session_head_prev); +#endif + printf(" in_session_context = 0x %16.16lx \n", in_session_context); + + +#ifdef GP_WORKER + //////////////////////////////////////////////////////////////////////////////////////////////// + + + TEEC_Session *sessionIns; + tsn_t *tsnIns; + + sessionIns = NULL; + pthread_mutex_lock(mutex_tsl); + if (tsl->first != NULL) + { + tsnIns = tsl->first; + do + { + if (tsnIns->self->session_id == in_session_seesionid) + { + sessionIns = tsnIns->self; + break; + } + tsnIns = tsnIns->next; + } while (tsnIns != NULL); + } + pthread_mutex_unlock(mutex_tsl); + + if (sessionIns == NULL) + { + if (tsl->first == NULL) + { + printf("The teec session list is null. \n"); + // teecresult = TEEC_ERROR_SESSION_LIST_NULL; + } else + { + printf("Can't find the teec session. \n"); + // teecresult = TEEC_ERROR_NO_SESSION_MATCH; + } + + seesionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + context = 0x0; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize; i++) + { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + } else + { + sessionIns->session_id = in_session_seesionid; +#if 0 + sessionIns->service_id.timeLow = in_session_serviceid_timelow; + sessionIns->service_id.timeMid = in_session_serviceid_timemid; + sessionIns->service_id.timeHiAndVersion = in_session_serviceid_timehiandver; + if ( in_session_serviceid_clockseqandnode_realsize <= 8 && + in_session_serviceid_clockseqandnode_realsize > 0 && + in_session_serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < in_session_serviceid_clockseqandnode_realsize; i++) { + sessionIns->service_id.clockSeqAndNode[i] = + (uint8_t)(in_session_serviceid_clockseqandnode[i] & 0x000000ff); + } + } + else + { + for (int i = 0; i < 8; i++) { + sessionIns->service_id.clockSeqAndNode[i] = 0; + } + } + sessionIns->ops_cnt = in_session_opscnt; + sessionIns->head.next = (struct ListNode *)in_session_head_next; + sessionIns->head.prev = (struct ListNode *)in_session_head_prev; + // sessionIns->context = (TEEC_Context *)in_session_context; +#endif + +#if 0 + printf("Call TEEC_CloseSession inputs: \n"); + printf(" session_seesionid = 0x %8.8x \n", sessionIns->session_id); + printf(" session_serviceid_timelow = 0x %8.8x \n", sessionIns->service_id.timeLow); + printf(" session_serviceid_timemid = 0x %4.4x \n", sessionIns->service_id.timeMid); + printf(" session_serviceid_timehiandver = 0x %4.4x \n", + sessionIns->service_id.timeHiAndVersion); + printf(" session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < 8; i++) { + printf(" %2.2x", sessionIns->service_id.clockSeqAndNode[i]); + } + printf("\n"); + printf(" session_opscnt = 0x %8.8x \n", sessionIns->ops_cnt); + printf(" session_head_next = 0x %16.16lx \n", sessionIns->head.next); + printf(" session_head_prev = 0x %16.16lx \n", sessionIns->head.prev); + printf(" session_context = 0x %16.16lx \n", sessionIns->context); +#endif + struct timeval start, end; + gettimeofday(&start, NULL); + TEEC_CloseSession( + sessionIns + ); + gettimeofday(&end, NULL); + uint32_t cost = 0; + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + printf("Teec CloseSession executed, cost time: %ld us \n", cost); + + seesionid = sessionIns->session_id; + serviceid_timelow = sessionIns->service_id.timeLow; + serviceid_timemid = sessionIns->service_id.timeMid; + serviceid_timehiandver = sessionIns->service_id.timeHiAndVersion; +#if 0 + printf(" in_session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < 8; i++) { + printf(" %2.2x", in_session_serviceid_clockseqandnode[i]); + } + printf("\n"); +#endif + if (sessionIns->service_id.clockSeqAndNode != NULL) + { + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < 8; iind++) + { + uint8_t u8Temp; + u8Temp = sessionIns->service_id.clockSeqAndNode[iind]; + serviceid_clockseqandnode[iind] = (dbus_uint32_t) u8Temp; + } + serviceid_clockseqandnode_outsize = 8; + } else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + } + opscnt = sessionIns->ops_cnt; + head_next = (dbus_uint64_t) sessionIns->head.next; + head_prev = (dbus_uint64_t) sessionIns->head.prev; + context = (dbus_uint64_t) sessionIns->context; + + printf(" ret sessionid = 0x %8.8x \n", seesionid); + printf(" ret context = 0x %16.16lx \n", context); + + tsn_t *tsnTemp; + tsnTemp = tsnIns->prev; + if (tsnTemp != NULL) + { + tsnTemp->next = tsnIns->next; + } + tsnTemp = tsnIns->next; + if (tsnTemp != NULL) + { + tsnTemp->prev = tsnIns->prev; + } + pthread_mutex_lock(mutex_tsl); + if (tsl->last == tsnIns) + { + tsl->last = tsnIns->prev; + } + if (tsl->first == tsnIns) + { + tsl->first = tsnIns->next; + } + tsl->count = tsl->count - 1; + pthread_mutex_unlock(mutex_tsl); + free(sessionIns); + free(tsnIns); + } + //////////////////////////////////////////////////////////////////////////////////////////////// +#else + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + + char workername[1024]; + memset((char *)workername, 0, 1024); + // sprintf(workername, "%s", "gpworker1"); + int ifound = 0; + int iworker; + sin_t * sinIns; + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].context_addr == in_session_context) + { + sinIns = NULL; + if (workerrec[iworker].first != NULL) + { + sinIns = workerrec[iworker].first; + do + { + if (sinIns->session_id == in_session_seesionid) + { + sprintf(workername, "%s%d", "gpworker", iworker); + ifound = 1; + break; + } + sinIns = sinIns->next; + }while (sinIns != NULL); + + + if ( ifound == 1 ) + { + break; + } + } + } + } + pthread_mutex_unlock(mutex_workerrec); + + + if (ifound == 0) + { + printf("Can't find the worker for the session and the context. \n"); + + seesionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + context = 0x0; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize ; i++) { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + } + else + { + method_call_teec_closesession( + workername, + + in_session_seesionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_realsize, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &context + ); + + pthread_mutex_lock(mutex_workerrec); + sin_t * sinTemp; + sinTemp = sinIns->prev; + if (sinTemp != NULL) + { + sinTemp->next = sinIns->next; + } + sinTemp = sinIns->next; + if (sinTemp != NULL) + { + sinTemp->prev = sinIns->prev; + } + if (workerrec[iworker].last == sinIns) + { + workerrec[iworker].last = sinIns->prev; + } + if (workerrec[iworker].first == sinIns) + { + workerrec[iworker].first = sinIns->next; + } + free(sinIns); + workerrec[iworker].sessionid_count = + workerrec[iworker].sessionid_count - 1; + pthread_mutex_unlock(mutex_workerrec); + + serviceid_clockseqandnode_outsize = serviceid_clockseqandnode_outsize_temp; + + if ( + serviceid_clockseqandnode_realsize >= serviceid_clockseqandnode_outsize && + 8 >= serviceid_clockseqandnode_outsize + ) + { + serviceid_clockseqandnode_realsize = serviceid_clockseqandnode_outsize; + } + else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode_outsize = 0; + } + + }// end of else found == 1 +#endif + + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &seesionid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timelow + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timemid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timehiandver + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &opscnt + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &context + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send the reply && flush the connection + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + free(thdfargs); + + // sleep(2); + + return NULL; +} + + +void * +reply_to_method_call_teec_invokecommand( + void *thdfargs +) +{ + DBusMsgConn *DBusMCP; + DBusMessage *msg; + DBusConnection *conn; + DBusMessage *reply; + DBusMessageIter args; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int iType; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + dbus_uint32_t in_session_sessionid; + dbus_uint32_t in_session_serviceid_timelow; + dbus_uint32_t in_session_serviceid_timemid; + dbus_uint32_t in_session_serviceid_timehiandver; + dbus_uint32_t in_session_serviceid_clockseqandnode_size; + dbus_uint32_t *in_session_serviceid_clockseqandnode; + int in_session_serviceid_clockseqandnode_realsize; + dbus_uint32_t in_session_opscnt; + dbus_uint64_t in_session_head_next; + dbus_uint64_t in_session_head_prev; + dbus_uint64_t in_session_context; + + dbus_uint32_t in_commandid; + + dbus_uint32_t in_operation_started; + dbus_uint32_t in_operation_paramtypes; + + dbus_uint64_t in_operation_param1_tmpref_buffer; + dbus_uint32_t in_operation_param1_tmpref_size; + dbus_uint64_t in_operation_param1_memref_parent; + dbus_uint32_t in_operation_param1_memref_parent_flag; + dbus_uint32_t in_operation_param1_memref_size; + dbus_uint32_t in_operation_param1_memref_offset; + dbus_uint32_t in_operation_param1_value_a; + dbus_uint32_t in_operation_param1_value_b; + dbus_int32_t in_operation_param1_ionref_ionsharefd; + dbus_uint32_t in_operation_param1_ionref_ionsize; + + dbus_uint64_t in_operation_param2_tmpref_buffer; + dbus_uint32_t in_operation_param2_tmpref_size; + dbus_uint64_t in_operation_param2_memref_parent; + dbus_uint32_t in_operation_param2_memref_parent_flag; + dbus_uint32_t in_operation_param2_memref_size; + dbus_uint32_t in_operation_param2_memref_offset; + dbus_uint32_t in_operation_param2_value_a; + dbus_uint32_t in_operation_param2_value_b; + dbus_int32_t in_operation_param2_ionref_ionsharefd; + dbus_uint32_t in_operation_param2_ionref_ionsize; + + dbus_uint64_t in_operation_param3_tmpref_buffer; + dbus_uint32_t in_operation_param3_tmpref_size; + dbus_uint64_t in_operation_param3_memref_parent; + dbus_uint32_t in_operation_param3_memref_parent_flag; + dbus_uint32_t in_operation_param3_memref_size; + dbus_uint32_t in_operation_param3_memref_offset; + dbus_uint32_t in_operation_param3_value_a; + dbus_uint32_t in_operation_param3_value_b; + dbus_int32_t in_operation_param3_ionref_ionsharefd; + dbus_uint32_t in_operation_param3_ionref_ionsize; + + dbus_uint64_t in_operation_param4_tmpref_buffer; + dbus_uint32_t in_operation_param4_tmpref_size; + dbus_uint64_t in_operation_param4_memref_parent; + dbus_uint32_t in_operation_param4_memref_parent_flag; + dbus_uint32_t in_operation_param4_memref_size; + dbus_uint32_t in_operation_param4_memref_offset; + dbus_uint32_t in_operation_param4_value_a; + dbus_uint32_t in_operation_param4_value_b; + dbus_int32_t in_operation_param4_ionref_ionsharefd; + dbus_uint32_t in_operation_param4_ionref_ionsize; + + dbus_uint64_t in_operation_session; + dbus_int32_t in_operation_cancelflag; + + dbus_uint32_t in_returnorigin; + + dbus_uint32_t in_buffer1_size; + dbus_uint32_t *in_buffer1; + int in_buffer1_realsize; + dbus_uint32_t in_buffer2_size; + dbus_uint32_t *in_buffer2; + int in_buffer2_realsize; + dbus_uint32_t in_buffer3_size; + dbus_uint32_t *in_buffer3; + int in_buffer3_realsize; + dbus_uint32_t in_buffer4_size; + dbus_uint32_t *in_buffer4; + int in_buffer4_realsize; + + dbus_uint32_t teecresult; + + dbus_uint32_t sessionid; + dbus_uint32_t serviceid_timelow; + dbus_uint32_t serviceid_timemid; + dbus_uint32_t serviceid_timehiandver; + dbus_uint32_t *serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + dbus_uint32_t serviceid_clockseqandnode_outsize; + dbus_uint32_t opscnt; + dbus_uint64_t head_next; + dbus_uint64_t head_prev; + dbus_uint64_t context; + + dbus_uint32_t started; + dbus_uint32_t paramtypes; + + dbus_uint64_t operation_param1_tmpref_buffer; + dbus_uint32_t operation_param1_tmpref_size; + dbus_uint64_t operation_param1_memref_parent; + dbus_uint32_t operation_param1_memref_parent_flag; + dbus_uint32_t operation_param1_memref_size; + dbus_uint32_t operation_param1_memref_offset; + dbus_uint32_t operation_param1_value_a; + dbus_uint32_t operation_param1_value_b; + dbus_int32_t operation_param1_ionref_ionsharefd; + dbus_uint32_t operation_param1_ionref_ionsize; + + dbus_uint64_t operation_param2_tmpref_buffer; + dbus_uint32_t operation_param2_tmpref_size; + dbus_uint64_t operation_param2_memref_parent; + dbus_uint32_t operation_param2_memref_parent_flag; + dbus_uint32_t operation_param2_memref_size; + dbus_uint32_t operation_param2_memref_offset; + dbus_uint32_t operation_param2_value_a; + dbus_uint32_t operation_param2_value_b; + dbus_int32_t operation_param2_ionref_ionsharefd; + dbus_uint32_t operation_param2_ionref_ionsize; + + dbus_uint64_t operation_param3_tmpref_buffer; + dbus_uint32_t operation_param3_tmpref_size; + dbus_uint64_t operation_param3_memref_parent; + dbus_uint32_t operation_param3_memref_parent_flag; + dbus_uint32_t operation_param3_memref_size; + dbus_uint32_t operation_param3_memref_offset; + dbus_uint32_t operation_param3_value_a; + dbus_uint32_t operation_param3_value_b; + dbus_int32_t operation_param3_ionref_ionsharefd; + dbus_uint32_t operation_param3_ionref_ionsize; + + dbus_uint64_t operation_param4_tmpref_buffer; + dbus_uint32_t operation_param4_tmpref_size; + dbus_uint64_t operation_param4_memref_parent; + dbus_uint32_t operation_param4_memref_parent_flag; + dbus_uint32_t operation_param4_memref_size; + dbus_uint32_t operation_param4_memref_offset; + dbus_uint32_t operation_param4_value_a; + dbus_uint32_t operation_param4_value_b; + dbus_int32_t operation_param4_ionref_ionsharefd; + dbus_uint32_t operation_param4_ionref_ionsize; + + dbus_uint64_t operation_session; + dbus_int32_t operation_cancelflag; + + dbus_uint32_t returnorigin; + + dbus_uint32_t *buffer1; + int buffer1_realsize; + dbus_uint32_t buffer1_outsize; + dbus_uint32_t *buffer2; + int buffer2_realsize; + dbus_uint32_t buffer2_outsize; + dbus_uint32_t *buffer3; + int buffer3_realsize; + dbus_uint32_t buffer3_outsize; + dbus_uint32_t *buffer4; + int buffer4_realsize; + dbus_uint32_t buffer4_outsize; + + dbus_uint32_t serial = 0; + +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + wr_t * workerrec; +#endif + +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl; + pthread_mutex_t *mutex_tsl; + tcl_t *tcl; + tsl_t *tsl; +#endif + + DBusMCP = (DBusMsgConn *) thdfargs; + msg = DBusMCP->msg; + conn = DBusMCP->conn; +#ifdef GP_PROXY + mutex_workerrec = DBusMCP->mutex_workerrec; + workerrec = DBusMCP->workerrec; +#endif +#ifdef GP_WORKER + mutex_tcl = DBusMCP->mutex_tcl; + mutex_tsl = DBusMCP->mutex_tsl; + tcl = DBusMCP->tcl; + tsl = DBusMCP->tsl; +#endif + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_sessionid); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timelow + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timemid); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_timehiandver); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_serviceid_clockseqandnode_size); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_session_serviceid_clockseqandnode_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_session_serviceid_clockseqandnode, + &in_session_serviceid_clockseqandnode_realsize + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_get_basic( + &structIter, + &in_session_opscnt); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_head_next); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_head_prev); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_session_context); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_commandid); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_started); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_paramtypes); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_tmpref_size); + + bResult = dbus_message_iter_next(&structIter); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT64) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_parent); + + bResult = dbus_message_iter_next(&structIter); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_parent_flag); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_size); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_value_a); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_value_b); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param1_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_parent); + + bResult = dbus_message_iter_next(&structIter); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_parent_flag); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param2_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_tmpref_buffer); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_parent); + + bResult = dbus_message_iter_next(&structIter); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_parent_flag); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param3_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_tmpref_buffer); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_tmpref_size); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_parent); + + bResult = dbus_message_iter_next(&structIter); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32. \n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_parent_flag); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_size); + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_memref_offset); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_value_a); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_value_b); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_ionref_ionsharefd); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_param4_ionref_ionsize); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_session); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_operation_cancelflag); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_returnorigin); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_buffer1_size); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_buffer1_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_buffer1, + &in_buffer1_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_buffer2_size); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_buffer2_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_buffer2, + &in_buffer2_realsize + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_buffer3_size); + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (in_buffer3_size > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_buffer3, + &in_buffer3_realsize + ); + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_basic( + &structIter, + &in_buffer4_size); + + if (in_buffer4_size > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32, line %d. \n", __LINE__); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &in_buffer4, + &in_buffer4_realsize + ); + } + + printf("Received method call TEEC_InvokeCommand: \n"); + printf(" in_session_sessionid = 0x %8.8x \n", in_session_sessionid); +#if 0 + printf(" in_session_serviceid_timelow = 0x %8.8x \n", in_session_serviceid_timelow); + printf(" in_session_serviceid_timemid = 0x %8.8x \n", in_session_serviceid_timemid); + printf(" in_session_serviceid_timehiandver = 0x %8.8x \n", + in_session_serviceid_timehiandver); + printf(" in_session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < in_session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", in_session_serviceid_clockseqandnode[i]); + } + printf("\n"); + printf(" in serviceid_clockseqandnode_size = 0x %8.8x \n", + in_session_serviceid_clockseqandnode_size); + printf(" in_session_opscnt = 0x %8.8x \n", in_session_opscnt); + printf(" in_session_head_next = 0x %16.16lx \n", in_session_head_next); + printf(" in_session_head_prev = 0x %16.16lx \n", in_session_head_prev); +#endif + printf(" in_session_context = 0x %16.16lx \n", in_session_context); +#if 0 + printf(" commandid = 0x %8.8x \n", in_commandid); + + printf(" in_operation_started = 0x %8.8x \n", in_operation_started); + printf(" in_operation_paramtypes = 0x %8.8x \n", in_operation_paramtypes); + + printf(" in_operation_param1_tmpref_buffer = 0x %16.16lx \n", in_operation_param1_tmpref_buffer); + printf(" in_operation_param1_tmpref_size = 0x %8.8x \n", in_operation_param1_tmpref_size); + printf(" in_operation_param1_memref_parent = 0x %16.16lx \n", in_operation_param1_memref_parent); + printf(" in_operation_param1_memref_size = 0x %8.8x \n", in_operation_param1_memref_size); + printf(" in_operation_param1_memref_offset = 0x %8.8x \n", in_operation_param1_memref_offset); + printf(" in_operation_param1_value_a = 0x %8.8x \n", in_operation_param1_value_a); + printf(" in_operation_param1_value_b = 0x %8.8x \n", in_operation_param1_value_b); + printf(" in_operation_param1_ionref_ionsharefd = 0x %8.8x \n",in_operation_param2_ionref_ionsharefd); + printf(" in_operation_param1_ionref_ionsize = 0x %8.8x \n", in_operation_param2_ionref_ionsize); + + printf(" in_operation_param2_tmpref_buffer = 0x %16.16lx \n", in_operation_param2_tmpref_buffer); + printf(" in_operation_param2_tmpref_size = 0x %8.8x \n", in_operation_param2_tmpref_size); + printf(" in_operation_param2_memref_parent = 0x %16.16lx \n", in_operation_param2_memref_parent); + printf(" in_operation_param2_memref_size = 0x %8.8x \n", in_operation_param2_memref_size); + printf(" in_operation_param2_memref_offset = 0x %8.8x \n", in_operation_param2_memref_offset); + printf(" in_operation_param2_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param2_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param2_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param2_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param3_tmpref_buffer = 0x %16.16lx \n", in_operation_param3_tmpref_buffer); + printf(" in_operation_param3_tmpref_size = 0x %8.8x \n", in_operation_param3_tmpref_size); + printf(" in_operation_param3_memref_parent = 0x %16.16lx \n", in_operation_param3_memref_parent); + printf(" in_operation_param3_memref_size = 0x %8.8x \n", in_operation_param3_memref_size); + printf(" in_operation_param3_memref_offset = 0x %8.8x \n", in_operation_param3_memref_offset); + printf(" in_operation_param3_value_a = 0x %8.8x \n", in_operation_param3_value_a); + printf(" in_operation_param3_value_b = 0x %8.8x \n", in_operation_param3_value_b); + printf(" in_operation_param3_ionref_ionsharefd = 0x %8.8x \n", in_operation_param3_ionref_ionsharefd); + printf(" in_operation_param3_ionref_ionsize = 0x %8.8x \n", in_operation_param3_ionref_ionsize); + + printf(" in_operation_param4_tmpref_buffer = 0x %16.16lx \n", in_operation_param4_tmpref_buffer); + printf(" in_operation_param4_tmpref_size = 0x %8.8x \n", in_operation_param4_tmpref_size); + printf(" in_operation_param4_memref_parent = 0x %16.16lx \n", in_operation_param4_memref_parent); + printf(" in_operation_param4_memref_size = 0x %8.8x \n", in_operation_param4_memref_size); + printf(" in_operation_param4_memref_offset = 0x %8.8x \n", in_operation_param4_memref_offset); + printf(" in_operation_param4_value_a = 0x %8.8x \n", in_operation_param4_value_a); + printf(" in_operation_param4_value_b = 0x %8.8x \n", in_operation_param4_value_b); + printf(" in_operation_param4_ionref_ionsharefd = 0x %8.8x \n", in_operation_param4_ionref_ionsharefd); + printf(" in_operation_param4_ionref_ionsize = 0x %8.8x \n", in_operation_param4_ionref_ionsize); + + printf(" in_operation_session = 0x %16.16lx \n", in_operation_session); + printf(" in_operation_cancelflag = 0x %8.8x \n", in_operation_cancelflag); + + printf(" in_returnorigin = 0x %8.8x \n", in_returnorigin); + + printf(" in_buffer1 = \n"); + if (in_buffer1_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer1_realsize; i++) { + printf(" %2.2x", in_buffer1[i]); + } + printf("\n"); + } +#endif + +#if 0 + printf(" in_buffer1_size = 0x %8.8x \n", + in_buffer1_size); +#endif + +#if 0 + printf(" in_buffer2 = \n"); + if (in_buffer2_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer2_realsize; i++) { + printf(" %2.2x", in_buffer2[i]); + } + printf("\n"); + } + printf(" in_buffer2_size = 0x %8.8x \n", + in_buffer2_size); + + printf(" in_buffer3 = \n"); + if (in_buffer3_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer3_realsize; i++) { + printf(" %2.2x", in_buffer3[i]); + } + printf("\n"); + } + printf(" in_buffer3_size = 0x %8.8x \n", + in_buffer3_size); + + printf(" in_buffer4 = \n"); + if (in_buffer4_size > 0) { + printf(" "); + for (int i = 0; i < in_buffer4_realsize; i++) { + printf(" %2.2x", in_buffer4[i]); + } + printf("\n"); + } + printf(" in_buffer4_size = 0x %8.8x \n", + in_buffer4_size); +#endif + +#ifdef GP_WORKER + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + TEEC_Session *sessionIns; + tsn_t *tsnIns; + + sessionIns = NULL; + pthread_mutex_lock(mutex_tsl); + if (tsl->first != NULL) + { + tsnIns = tsl->first; + do + { + if (tsnIns->self->session_id == in_session_sessionid) + { + sessionIns = tsnIns->self; + break; + } + tsnIns = tsnIns->next; + } while (tsnIns != NULL); + } + pthread_mutex_unlock(mutex_tsl); + + TEEC_Context *contextIns; + tcn_t *tcnIns; + + contextIns = NULL; + if (sessionIns != NULL) + { + pthread_mutex_lock(mutex_tcl); + if (tcl->first != NULL) + { + tcnIns = tcl->first; + do + { + contextIns = tcnIns->self; + if (contextIns == sessionIns->context) + { + break; + } + tcnIns = tcnIns->next; + } while (tcnIns != NULL); + } + pthread_mutex_unlock(mutex_tcl); + } + + if (sessionIns == NULL || contextIns == NULL) + { + if (sessionIns == NULL) + { + if (tsl->first == NULL) + { + printf("The teec session list is null. \n"); + teecresult = TEEC_ERROR_SESSION_LIST_NULL; + } else + { + printf("Can't find the teec session. \n"); + teecresult = TEEC_ERROR_NO_SESSION_MATCH; + } + } + + if (contextIns == NULL) + { + if (tcl->first == NULL) + { + printf("The teec context list is null. \n"); + teecresult = TEEC_ERROR_CONTEXT_LIST_NULL; + } else + { + printf("Can't find the teec context. \n"); + teecresult = TEEC_ERROR_NO_CONTEXT_MATCH; + } + } + + sessionid = 0; + serviceid_timelow = 0; + serviceid_timemid = 0; + serviceid_timehiandver = 0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + opscnt = 0; + head_next = 0; + head_prev = 0; + context = 0; + + started = 0; + paramtypes = 0; + + operation_param1_tmpref_buffer = 0; + operation_param1_tmpref_size = 0; + operation_param1_memref_parent = 0; + operation_param1_memref_parent_flag = 0; + operation_param1_memref_size = 0; + operation_param1_memref_offset = 0; + operation_param1_value_a = 0; + operation_param1_value_b = 0; + operation_param1_ionref_ionsharefd = 0; + operation_param1_ionref_ionsize = 0; + + operation_param2_tmpref_buffer = 0; + operation_param2_tmpref_size = 0; + operation_param2_memref_parent = 0; + operation_param2_memref_parent_flag = 0; + operation_param2_memref_size = 0; + operation_param2_memref_offset = 0; + operation_param2_value_a = 0; + operation_param2_value_b = 0; + operation_param2_ionref_ionsharefd = 0; + operation_param2_ionref_ionsize = 0; + + operation_param3_tmpref_buffer = 0; + operation_param3_tmpref_size = 0; + operation_param3_memref_parent = 0; + operation_param3_memref_parent_flag = 0; + operation_param3_memref_size = 0; + operation_param3_memref_offset = 0; + operation_param3_value_a = 0; + operation_param3_value_b = 0; + operation_param3_ionref_ionsharefd = 0; + operation_param3_ionref_ionsize = 0; + + operation_param4_tmpref_buffer = 0; + operation_param4_tmpref_size = 0; + operation_param4_memref_parent = 0; + operation_param4_memref_parent_flag = 0; + operation_param4_memref_size = 0; + operation_param4_memref_offset = 0; + operation_param4_value_a = 0; + operation_param4_value_b = 0; + operation_param4_ionref_ionsharefd = 0; + operation_param4_ionref_ionsize = 0; + + operation_session = 0; + operation_cancelflag = 0; + + returnorigin = 0xff; + + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } else + { + teecresult = TEEC_SUCCESS; + + sessionIns->session_id = in_session_sessionid; + sessionIns->service_id.timeLow = in_session_serviceid_timelow; + sessionIns->service_id.timeMid = in_session_serviceid_timemid; + sessionIns->service_id.timeHiAndVersion = in_session_serviceid_timehiandver; + if (in_session_serviceid_clockseqandnode_realsize <= 8 && + in_session_serviceid_clockseqandnode_realsize > 0 && + in_session_serviceid_clockseqandnode != NULL + ) + { + for (int i = 0; i < in_session_serviceid_clockseqandnode_realsize; i++) + { + sessionIns->service_id.clockSeqAndNode[i] = + (uint8_t)(in_session_serviceid_clockseqandnode[i] & 0x000000ff); + } + } else + { + for (int i = 0; i < 8; i++) + { + sessionIns->service_id.clockSeqAndNode[i] = 0; + } + } + sessionIns->ops_cnt = in_session_opscnt; + sessionIns->head.next = (struct ListNode *) in_session_head_next; + sessionIns->head.prev = (struct ListNode *) in_session_head_prev; + // sessionIns->context = (TEEC_Context *)in_session_context; + + + TEEC_Operation operationIns; + + operationIns.started = in_operation_started; + operationIns.paramTypes = in_operation_paramtypes; + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + uint8_t *buffer1_temp = NULL; + TEEC_SharedMemory shareBuffer1; + bool sb1AllReged = false; + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 0) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + operationIns.params[0].value.a = in_operation_param1_value_a; + operationIns.params[0].value.b = in_operation_param1_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + in_buffer1 != NULL && + in_buffer1_size > 0 + ) + { + uint32_t buffer1_temp_size; + buffer1_temp_size = in_buffer1_size; + buffer1_temp = (uint8_t *) malloc(buffer1_temp_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + buffer1_temp[isize] = (uint8_t)(in_buffer1[isize] & 0x000000ff); + } + + operationIns.params[0].tmpref.buffer = (void *) buffer1_temp; + operationIns.params[0].tmpref.size = buffer1_temp_size; + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + in_operation_param1_tmpref_size > 0 + ) + { + buffer1_temp = (uint8_t *) malloc(in_operation_param1_tmpref_size * sizeof(uint8_t)); + operationIns.params[0].tmpref.buffer = (void *) buffer1_temp; + operationIns.params[0].tmpref.size = in_operation_param1_tmpref_size; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (in_operation_param1_memref_parent_flag) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + in_buffer1 != NULL && + in_buffer1_size > 0 + ) + { + memset(&shareBuffer1, 0, sizeof(shareBuffer1)); + shareBuffer1.size = in_buffer1_size; + shareBuffer1.flags = in_operation_param1_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer1); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb1AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer1.buffer, 0, shareBuffer1.size); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + *((uint8_t * )(shareBuffer1.buffer) + isize) = + (uint8_t)(in_buffer1[isize] & 0x000000ff); + } + operationIns.params[0].memref.parent = &shareBuffer1; + // operationIns.params[0].memref.parent->flags = + // in_operation_param1_memref_parent_flag; + operationIns.params[0].memref.size = shareBuffer1.size; + } + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + in_operation_param1_memref_size > 0 + ) + { + memset(&shareBuffer1, 0, sizeof(shareBuffer1)); + shareBuffer1.size = in_operation_param1_memref_size; + shareBuffer1.flags = in_operation_param1_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer1); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb1AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[0].memref.parent = &shareBuffer1; + operationIns.params[0].memref.size = shareBuffer1.size; + } + + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if ( + in_buffer1 != NULL && + in_buffer1_size > 0 + ) + { + memset(&shareBuffer1, 0, sizeof(shareBuffer1)); + shareBuffer1.size = in_buffer1_size; + shareBuffer1.flags = in_operation_param1_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer1); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb1AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer1.buffer, 0, shareBuffer1.size); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + *((uint8_t * )(shareBuffer1.buffer) + isize) = + (uint8_t)(in_buffer1[isize] & 0x000000ff); + } + operationIns.params[0].memref.parent = &shareBuffer1; + operationIns.params[0].memref.offset = in_operation_param1_memref_offset; + operationIns.params[0].memref.size = in_operation_param1_memref_size; + } + } + + break; + } + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (in_operation_param1_memref_size > 0) + { + memset(&shareBuffer1, 0, sizeof(shareBuffer1)); + shareBuffer1.size = in_buffer1_size; + shareBuffer1.flags = in_operation_param1_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer1); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb1AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[0].memref.parent = &shareBuffer1; + operationIns.params[0].memref.offset = in_operation_param1_memref_offset; + operationIns.params[0].memref.size = in_operation_param1_memref_size; + } + + } + + break; + } + + + default: + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + uint8_t *buffer2_temp = NULL; + TEEC_SharedMemory shareBuffer2; + bool sb2AllReged = false; + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 1) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + operationIns.params[1].value.a = in_operation_param2_value_a; + operationIns.params[1].value.b = in_operation_param2_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + in_buffer2 != NULL && + in_buffer2_size > 0 + ) + { + uint32_t buffer2_temp_size; + buffer2_temp_size = in_buffer2_size; + buffer2_temp = (uint8_t *) malloc(buffer2_temp_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + buffer2_temp[isize] = (uint8_t)(in_buffer2[isize] & 0x000000ff); + } + + operationIns.params[1].tmpref.buffer = (void *) buffer2_temp; + operationIns.params[1].tmpref.size = buffer2_temp_size; + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + in_operation_param2_tmpref_size > 0 + ) + { + buffer2_temp = (uint8_t *) malloc(in_operation_param2_tmpref_size * sizeof(uint8_t)); + operationIns.params[1].tmpref.buffer = (void *) buffer2_temp; + operationIns.params[1].tmpref.size = in_operation_param2_tmpref_size; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (in_operation_param2_memref_parent_flag) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + in_buffer2 != NULL && + in_buffer2_size > 0 + ) + { + memset(&shareBuffer2, 0, sizeof(shareBuffer2)); + shareBuffer2.size = in_buffer2_size; + shareBuffer2.flags = in_operation_param2_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer2); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb2AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer2.buffer, 0, shareBuffer2.size); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + *((uint8_t * )(shareBuffer2.buffer) + isize) = + (uint8_t)(in_buffer2[isize] & 0x000000ff); + } + operationIns.params[1].memref.parent = &shareBuffer2; + // operationIns.params[1].memref.parent->flags = + // in_operation_param2_memref_parent_flag; + operationIns.params[1].memref.size = shareBuffer2.size; + } + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + in_operation_param2_memref_size > 0 + ) + { + memset(&shareBuffer2, 0, sizeof(shareBuffer2)); + shareBuffer2.size = in_operation_param2_memref_size; + shareBuffer2.flags = in_operation_param2_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer2); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb2AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[1].memref.parent = &shareBuffer2; + // operationIns.params[1].memref.parent->flags = + // in_operation_param2_memref_parent_flag; + operationIns.params[1].memref.size = shareBuffer2.size; + } + + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if ( + in_buffer2 != NULL && + in_buffer2_size > 0 + ) + { + memset(&shareBuffer2, 0, sizeof(shareBuffer2)); + shareBuffer2.size = in_buffer2_size; + shareBuffer2.flags = in_operation_param2_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer2); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb2AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer2.buffer, 0, shareBuffer2.size); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + *((uint8_t * )(shareBuffer2.buffer) + isize) = + (uint8_t)(in_buffer2[isize] & 0x000000ff); + } + operationIns.params[1].memref.parent = &shareBuffer2; + operationIns.params[1].memref.offset = in_operation_param2_memref_offset; + operationIns.params[1].memref.size = in_operation_param2_memref_size; + } + } + + break; + } + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (in_operation_param2_memref_size > 0) + { + memset(&shareBuffer2, 0, sizeof(shareBuffer2)); + shareBuffer2.size = in_buffer2_size; + shareBuffer2.flags = in_operation_param2_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer2); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb2AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[1].memref.parent = &shareBuffer2; + operationIns.params[1].memref.offset = in_operation_param2_memref_offset; + operationIns.params[1].memref.size = in_operation_param2_memref_size; + } + + } + + break; + } + + + default: + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + uint8_t *buffer3_temp = NULL; + TEEC_SharedMemory shareBuffer3; + bool sb3AllReged = false; + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 2) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + operationIns.params[2].value.a = in_operation_param3_value_a; + operationIns.params[2].value.b = in_operation_param3_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + in_buffer3 != NULL && + in_buffer3_size > 0 + ) + { + uint32_t buffer3_temp_size; + buffer3_temp_size = in_buffer3_size; + buffer3_temp = (uint8_t *) malloc(buffer3_temp_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + buffer3_temp[isize] = (uint8_t)(in_buffer3[isize] & 0x000000ff); + } + + operationIns.params[2].tmpref.buffer = (void *) buffer3_temp; + operationIns.params[2].tmpref.size = buffer3_temp_size; + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + in_operation_param3_tmpref_size > 0 + ) + { + buffer3_temp = (uint8_t *) malloc(in_operation_param3_tmpref_size * sizeof(uint8_t)); + operationIns.params[2].tmpref.buffer = (void *) buffer3_temp; + operationIns.params[2].tmpref.size = in_operation_param3_tmpref_size; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (in_operation_param3_memref_parent_flag) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + in_buffer3 != NULL && + in_buffer3_size > 0 + ) + { + memset(&shareBuffer3, 0, sizeof(shareBuffer3)); + shareBuffer3.size = in_buffer3_size; + shareBuffer3.flags = in_operation_param3_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer3); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb3AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer3.buffer, 0, shareBuffer3.size); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + *((uint8_t * )(shareBuffer3.buffer) + isize) = + (uint8_t)(in_buffer3[isize] & 0x000000ff); + } + operationIns.params[2].memref.parent = &shareBuffer3; + // operationIns.params[2].memref.parent->flags = + // in_operation_param3_memref_parent_flag; + operationIns.params[2].memref.size = shareBuffer3.size; + } + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + in_operation_param3_memref_size > 0 + ) + { + memset(&shareBuffer3, 0, sizeof(shareBuffer3)); + shareBuffer3.size = in_operation_param3_memref_size; + shareBuffer3.flags = in_operation_param3_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer3); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb3AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[2].memref.parent = &shareBuffer3; + // operationIns.params[2].memref.parent->flags = + // in_operation_param3_memref_parent_flag; + operationIns.params[2].memref.size = shareBuffer3.size; + } + + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if ( + in_buffer3 != NULL && + in_buffer3_size > 0 + ) + { + memset(&shareBuffer3, 0, sizeof(shareBuffer3)); + shareBuffer3.size = in_buffer3_size; + shareBuffer3.flags = in_operation_param3_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer3); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb3AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer3.buffer, 0, shareBuffer3.size); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + *((uint8_t * )(shareBuffer3.buffer) + isize) = + (uint8_t)(in_buffer3[isize] & 0x000000ff); + } + operationIns.params[2].memref.parent = &shareBuffer3; + operationIns.params[2].memref.offset = in_operation_param3_memref_offset; + operationIns.params[2].memref.size = in_operation_param3_memref_size; + } + } + + break; + } + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (in_operation_param3_memref_size > 0) + { + memset(&shareBuffer3, 0, sizeof(shareBuffer3)); + shareBuffer3.size = in_buffer3_size; + shareBuffer3.flags = in_operation_param3_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer3); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb3AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[2].memref.parent = &shareBuffer3; + operationIns.params[2].memref.offset = in_operation_param3_memref_offset; + operationIns.params[2].memref.size = in_operation_param3_memref_size; + } + + } + + break; + } + + + default: + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + uint8_t *buffer4_temp = NULL; + TEEC_SharedMemory shareBuffer4; + bool sb4AllReged = false; + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 3) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + operationIns.params[3].value.a = in_operation_param4_value_a; + operationIns.params[3].value.b = in_operation_param4_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + in_buffer4 != NULL && + in_buffer4_size > 0 + ) + { + uint32_t buffer4_temp_size; + buffer4_temp_size = in_buffer4_size; + buffer4_temp = (uint8_t *) malloc(buffer4_temp_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + buffer4_temp[isize] = (uint8_t)(in_buffer4[isize] & 0x000000ff); + } + + operationIns.params[3].tmpref.buffer = (void *) buffer4_temp; + operationIns.params[3].tmpref.size = buffer4_temp_size; + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + in_operation_param4_tmpref_size > 0 + ) + { + buffer4_temp = (uint8_t *) malloc(in_operation_param4_tmpref_size * sizeof(uint8_t)); + operationIns.params[3].tmpref.buffer = (void *) buffer4_temp; + operationIns.params[3].tmpref.size = in_operation_param4_tmpref_size; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (in_operation_param4_memref_parent_flag) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + in_buffer4 != NULL && + in_buffer4_size > 0 + ) + { + memset(&shareBuffer4, 0, sizeof(shareBuffer4)); + shareBuffer4.size = in_buffer4_size; + shareBuffer4.flags = in_operation_param4_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer4); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb4AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer4.buffer, 0, shareBuffer4.size); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + *((uint8_t * )(shareBuffer4.buffer) + isize) = + (uint8_t)(in_buffer4[isize] & 0x000000ff); + } + operationIns.params[3].memref.parent = &shareBuffer4; + // operationIns.params[3].memref.parent->flags = + // in_operation_param4_memref_parent_flag; + operationIns.params[3].memref.size = shareBuffer4.size; + } + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + in_operation_param4_memref_size > 0 + ) + { + memset(&shareBuffer4, 0, sizeof(shareBuffer4)); + shareBuffer4.size = in_operation_param4_memref_size; + shareBuffer4.flags = in_operation_param4_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer4); + if (retASM) + { + printf("alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb4AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[3].memref.parent = &shareBuffer4; + // operationIns.params[3].memref.parent->flags = + // in_operation_param4_memref_parent_flag; + operationIns.params[3].memref.size = shareBuffer4.size; + } + + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if ( + in_buffer4 != NULL && + in_buffer4_size > 0 + ) + { + memset(&shareBuffer4, 0, sizeof(shareBuffer4)); + shareBuffer4.size = in_buffer4_size; + shareBuffer4.flags = in_operation_param4_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer4); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb4AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + memset(shareBuffer4.buffer, 0, shareBuffer4.size); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + *((uint8_t * )(shareBuffer4.buffer) + isize) = + (uint8_t)(in_buffer4[isize] & 0x000000ff); + } + operationIns.params[3].memref.parent = &shareBuffer4; + operationIns.params[3].memref.offset = in_operation_param4_memref_offset; + operationIns.params[3].memref.size = in_operation_param4_memref_size; + } + } + + break; + } + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (in_operation_param4_memref_size > 0) + { + memset(&shareBuffer4, 0, sizeof(shareBuffer4)); + shareBuffer4.size = in_buffer4_size; + shareBuffer4.flags = in_operation_param4_memref_parent_flag; + TEEC_Result retASM = 0; + retASM = TEEC_AllocateSharedMemory(contextIns, &shareBuffer4); + if (retASM) + { + printf("Alloc share memory failed, ret=0x%x.\n", retASM); + teecresult = retASM; + } else + { + sb4AllReged = true; + printf("TEEC_AllocateSharedMemory succecced. \n"); + operationIns.params[3].memref.parent = &shareBuffer4; + operationIns.params[3].memref.offset = in_operation_param4_memref_offset; + operationIns.params[3].memref.size = in_operation_param4_memref_size; + } + + } + + break; + } + + + default: + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// + + if (teecresult != TEEC_SUCCESS) + { + sessionid = 0; + serviceid_timelow = 0; + serviceid_timemid = 0; + serviceid_timehiandver = 0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + opscnt = 0; + head_next = 0; + head_prev = 0; + context = 0; + + started = 0; + paramtypes = 0; + + operation_param1_tmpref_buffer = 0; + operation_param1_tmpref_size = 0; + operation_param1_memref_parent = 0; + operation_param1_memref_parent_flag = 0; + operation_param1_memref_size = 0; + operation_param1_memref_offset = 0; + operation_param1_value_a = 0; + operation_param1_value_b = 0; + operation_param1_ionref_ionsharefd = 0; + operation_param1_ionref_ionsize = 0; + + operation_param2_tmpref_buffer = 0; + operation_param2_tmpref_size = 0; + operation_param2_memref_parent = 0; + operation_param2_memref_parent_flag = 0; + operation_param2_memref_size = 0; + operation_param2_memref_offset = 0; + operation_param2_value_a = 0; + operation_param2_value_b = 0; + operation_param2_ionref_ionsharefd = 0; + operation_param2_ionref_ionsize = 0; + + operation_param3_tmpref_buffer = 0; + operation_param3_tmpref_size = 0; + operation_param3_memref_parent = 0; + operation_param3_memref_parent_flag = 0; + operation_param3_memref_size = 0; + operation_param3_memref_offset = 0; + operation_param3_value_a = 0; + operation_param3_value_b = 0; + operation_param3_ionref_ionsharefd = 0; + operation_param3_ionref_ionsize = 0; + + operation_param4_tmpref_buffer = 0; + operation_param4_tmpref_size = 0; + operation_param4_memref_parent = 0; + operation_param4_memref_parent_flag = 0; + operation_param4_memref_size = 0; + operation_param4_memref_offset = 0; + operation_param4_value_a = 0; + operation_param4_value_b = 0; + operation_param4_ionref_ionsharefd = 0; + operation_param4_ionref_ionsize = 0; + + operation_session = 0; + operation_cancelflag = 0; + + returnorigin = 0xff; + + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } else + { //start of the input parameter operation success +#if 0 + operationIns.params[0].ionref.ion_share_fd = in_operation_param1_ionref_ionsharefd; + operationIns.params[0].ionref.ion_size = in_operation_param1_ionref_ionsize; + + operationIns.params[1].ionref.ion_share_fd = in_operation_param2_ionref_ionsharefd; + operationIns.params[1].ionref.ion_size = in_operation_param2_ionref_ionsize; + + operationIns.params[2].ionref.ion_share_fd = in_operation_param3_ionref_ionsharefd; + operationIns.params[2].ionref.ion_size = in_operation_param3_ionref_ionsize; + + operationIns.params[3].ionref.ion_share_fd = in_operation_param4_ionref_ionsharefd; + operationIns.params[3].ionref.ion_size = in_operation_param4_ionref_ionsize; +#endif + + operationIns.session = sessionIns; + operationIns.cancel_flag = in_operation_cancelflag; + + uint32_t origin; + origin = in_returnorigin; + + TEEC_Result result; + + struct timeval start, end; + gettimeofday(&start, NULL); + result = + TEEC_InvokeCommand( + sessionIns, + in_commandid, + &operationIns, + &origin + ); + gettimeofday(&end, NULL); + uint32_t cost = 0; + cost += (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec); + + if (result != TEEC_SUCCESS) + { + printf("Teec InvokeCommand Failed. \n"); + printf(" teecresult = 0x %8.8x.\n", result); + + teecresult = result; + + sessionid = 0; + serviceid_timelow = 0; + serviceid_timemid = 0; + serviceid_timehiandver = 0; + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + opscnt = 0; + head_next = 0; + head_prev = 0; + context = 0; + + started = 0; + paramtypes = 0; + + operation_param1_tmpref_buffer = 0; + operation_param1_tmpref_size = 0; + operation_param1_memref_parent = 0; + operation_param1_memref_parent_flag = 0; + operation_param1_memref_size = 0; + operation_param1_memref_offset = 0; + operation_param1_value_a = 0; + operation_param1_value_b = 0; + operation_param1_ionref_ionsharefd = 0; + operation_param1_ionref_ionsize = 0; + + operation_param2_tmpref_buffer = 0; + operation_param2_tmpref_size = 0; + operation_param2_memref_parent = 0; + operation_param2_memref_parent_flag = 0; + operation_param2_memref_size = 0; + operation_param2_memref_offset = 0; + operation_param2_value_a = 0; + operation_param2_value_b = 0; + operation_param2_ionref_ionsharefd = 0; + operation_param2_ionref_ionsize = 0; + + operation_param3_tmpref_buffer = 0; + operation_param3_tmpref_size = 0; + operation_param3_memref_parent = 0; + operation_param3_memref_parent_flag = 0; + operation_param3_memref_size = 0; + operation_param3_memref_offset = 0; + operation_param3_value_a = 0; + operation_param3_value_b = 0; + operation_param3_ionref_ionsharefd = 0; + operation_param3_ionref_ionsize = 0; + + operation_param4_tmpref_buffer = 0; + operation_param4_tmpref_size = 0; + operation_param4_memref_parent = 0; + operation_param4_memref_parent_flag = 0; + operation_param4_memref_size = 0; + operation_param4_memref_offset = 0; + operation_param4_value_a = 0; + operation_param4_value_b = 0; + operation_param4_ionref_ionsharefd = 0; + operation_param4_ionref_ionsize = 0; + + operation_session = 0; + operation_cancelflag = 0; + + returnorigin = 0xff; + + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } else + { // start of the invoke command success + printf("Teec InvokeCommand Succed, cost time: %ld us \n", cost); + + teecresult = result; + + sessionid = sessionIns->session_id; + serviceid_timelow = sessionIns->service_id.timeLow; + serviceid_timemid = sessionIns->service_id.timeMid; + serviceid_timehiandver = sessionIns->service_id.timeHiAndVersion; + if (sessionIns->service_id.clockSeqAndNode != NULL) + { + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *) malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < 8; iind++) + { + uint8_t u8Temp; + u8Temp = sessionIns->service_id.clockSeqAndNode[iind]; + serviceid_clockseqandnode[iind] = (dbus_uint32_t) u8Temp; + } + serviceid_clockseqandnode_outsize = 8; + } else + { + serviceid_clockseqandnode_realsize = 0; + serviceid_clockseqandnode = NULL; + serviceid_clockseqandnode_outsize = 0; + } + opscnt = sessionIns->ops_cnt; + head_next = (dbus_uint64_t) sessionIns->head.next; + head_prev = (dbus_uint64_t) sessionIns->head.prev; + context = (dbus_uint64_t) sessionIns->context; + + started = operationIns.started; + paramtypes = operationIns.paramTypes; + + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 0) + ) + { + case TEEC_VALUE_INOUT: + case TEEC_VALUE_OUTPUT: + { + operation_param1_value_a = operationIns.params[0].value.a; + operation_param1_value_b = operationIns.params[0].value.b; + + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + + break; + } + + case TEEC_MEMREF_TEMP_INOUT: + case TEEC_MEMREF_TEMP_OUTPUT: + { + if (operationIns.params[0].tmpref.buffer != NULL && + operationIns.params[0].tmpref.size > 0 + ) + { + buffer1_realsize = operationIns.params[0].tmpref.size; + buffer1 = + (dbus_uint32_t *) malloc( + buffer1_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer1_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * )(operationIns.params[0].tmpref.buffer) + iind); + buffer1[iind] = (dbus_uint32_t) u8Temp; + } + buffer1_outsize = buffer1_realsize; + } else + { + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + } + + operation_param1_tmpref_buffer = (dbus_uint64_t) operationIns.params[0].tmpref.buffer; + operation_param1_tmpref_size = operationIns.params[0].tmpref.size; + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operationIns.params[0].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + + if (operationIns.params[0].memref.parent->buffer != NULL && + operationIns.params[0].memref.parent->size > 0 + ) + { + buffer1_realsize = operationIns.params[0].memref.parent->size; + buffer1 = + (dbus_uint32_t *) malloc( + buffer1_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer1_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[0].memref.parent->buffer) + iind); + buffer1[iind] = (dbus_uint32_t) u8Temp; + } + buffer1_outsize = buffer1_realsize; + } else + { + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + } + + operation_param1_memref_parent = + (dbus_uint64_t) operationIns.params[0].memref.parent->buffer; + operation_param1_memref_parent_flag = + (dbus_uint32_t) operationIns.params[0].memref.parent->flags; + operation_param1_memref_size = + operationIns.params[0].memref.parent->size; + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operationIns.params[0].memref.parent->buffer != NULL && + operationIns.params[0].memref.parent->size > 0 + ) + { + buffer1_realsize = operationIns.params[0].memref.parent->size; + buffer1 = + (dbus_uint32_t *) malloc(buffer1_realsize * sizeof(dbus_uint32_t)); + for (int iind = 0; iind < buffer1_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[0].memref.parent->buffer) + iind); + buffer1[iind] = (dbus_uint32_t) u8Temp; + } + buffer1_outsize = buffer1_realsize; + } else + { + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + } + + operation_param1_memref_parent = + (dbus_uint64_t) operationIns.params[0].memref.parent->buffer; + operation_param1_memref_parent_flag = + (dbus_uint32_t) operationIns.params[0].memref.parent->flags; + operation_param1_memref_offset = operationIns.params[0].memref.offset; + operation_param1_memref_size = + operationIns.params[0].memref.size; + + break; + } + + + default: + { + buffer1_realsize = 0; + buffer1 = NULL; + buffer1_outsize = 0; + } + } + + operation_param1_ionref_ionsharefd = operationIns.params[0].ionref.ion_share_fd; + operation_param1_ionref_ionsize = operationIns.params[0].ionref.ion_size; + + ////////////////////////////////////////////////////////////////////////////////// + + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 1) + ) + { + case TEEC_VALUE_INOUT: + case TEEC_VALUE_OUTPUT: + { + operation_param2_value_a = operationIns.params[1].value.a; + operation_param2_value_b = operationIns.params[1].value.b; + + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + + break; + } + + case TEEC_MEMREF_TEMP_INOUT: + case TEEC_MEMREF_TEMP_OUTPUT: + { + if (operationIns.params[1].tmpref.buffer != NULL && + operationIns.params[1].tmpref.size > 0 + ) + { + buffer2_realsize = operationIns.params[1].tmpref.size; + buffer2 = + (dbus_uint32_t *) malloc( + buffer2_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer2_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * )(operationIns.params[1].tmpref.buffer) + iind); + buffer2[iind] = (dbus_uint32_t) u8Temp; + } + buffer2_outsize = buffer2_realsize; + } else + { + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + } + + operation_param2_tmpref_buffer = (dbus_uint64_t) operationIns.params[1].tmpref.buffer; + operation_param2_tmpref_size = operationIns.params[1].tmpref.size; + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operationIns.params[1].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + + if (operationIns.params[1].memref.parent->buffer != NULL && + operationIns.params[1].memref.parent->size > 0 + ) + { + buffer2_realsize = operationIns.params[1].memref.parent->size; + buffer2 = + (dbus_uint32_t *) malloc( + buffer2_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer2_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[1].memref.parent->buffer) + iind); + buffer2[iind] = (dbus_uint32_t) u8Temp; + } + buffer2_outsize = buffer2_realsize; + } else + { + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + } + + operation_param2_memref_parent = + (dbus_uint64_t) operationIns.params[1].memref.parent->buffer; + operation_param2_memref_parent_flag = + (dbus_uint32_t) operationIns.params[1].memref.parent->flags; + operation_param2_memref_size = + operationIns.params[1].memref.parent->size; + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operationIns.params[1].memref.parent->buffer != NULL && + operationIns.params[1].memref.parent->size > 0 + ) + { + buffer2_realsize = operationIns.params[1].memref.parent->size; + buffer2 = + (dbus_uint32_t *) malloc(buffer2_realsize * sizeof(dbus_uint32_t)); + for (int iind = 0; iind < buffer2_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[1].memref.parent->buffer) + iind); + buffer2[iind] = (dbus_uint32_t) u8Temp; + } + buffer2_outsize = buffer2_realsize; + } else + { + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + } + + operation_param2_memref_parent = + (dbus_uint64_t) operationIns.params[1].memref.parent->buffer; + operation_param2_memref_parent_flag = + (dbus_uint32_t) operationIns.params[1].memref.parent->flags; + operation_param2_memref_offset = operationIns.params[1].memref.offset; + operation_param2_memref_size = + operationIns.params[1].memref.size; + + break; + } + + + default: + { + buffer2_realsize = 0; + buffer2 = NULL; + buffer2_outsize = 0; + } + } + + operation_param2_ionref_ionsharefd = operationIns.params[1].ionref.ion_share_fd; + operation_param2_ionref_ionsize = operationIns.params[1].ionref.ion_size; + + ////////////////////////////////////////////////////////////////////////////////// + + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 2) + ) + { + case TEEC_VALUE_INOUT: + case TEEC_VALUE_OUTPUT: + { + operation_param3_value_a = operationIns.params[2].value.a; + operation_param3_value_b = operationIns.params[2].value.b; + + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + + break; + } + + case TEEC_MEMREF_TEMP_INOUT: + case TEEC_MEMREF_TEMP_OUTPUT: + { + if (operationIns.params[2].tmpref.buffer != NULL && + operationIns.params[2].tmpref.size > 0 + ) + { + buffer3_realsize = operationIns.params[2].tmpref.size; + buffer3 = + (dbus_uint32_t *) malloc( + buffer3_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer3_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * )(operationIns.params[2].tmpref.buffer) + iind); + buffer3[iind] = (dbus_uint32_t) u8Temp; + } + buffer3_outsize = buffer3_realsize; + } else + { + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + } + + operation_param3_tmpref_buffer = (dbus_uint64_t) operationIns.params[2].tmpref.buffer; + operation_param3_tmpref_size = operationIns.params[2].tmpref.size; + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operationIns.params[2].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + + if (operationIns.params[2].memref.parent->buffer != NULL && + operationIns.params[2].memref.parent->size > 0 + ) + { + buffer3_realsize = operationIns.params[2].memref.parent->size; + buffer3 = + (dbus_uint32_t *) malloc( + buffer3_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer3_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[2].memref.parent->buffer) + iind); + buffer3[iind] = (dbus_uint32_t) u8Temp; + } + buffer3_outsize = buffer3_realsize; + } else + { + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + } + + operation_param3_memref_parent = + (dbus_uint64_t) operationIns.params[2].memref.parent->buffer; + operation_param3_memref_parent_flag = + (dbus_uint32_t) operationIns.params[2].memref.parent->flags; + operation_param3_memref_size = + operationIns.params[2].memref.parent->size; + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operationIns.params[2].memref.parent->buffer != NULL && + operationIns.params[2].memref.parent->size > 0 + ) + { + buffer3_realsize = operationIns.params[2].memref.parent->size; + buffer3 = + (dbus_uint32_t *) malloc(buffer3_realsize * sizeof(dbus_uint32_t)); + for (int iind = 0; iind < buffer3_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[2].memref.parent->buffer) + iind); + buffer3[iind] = (dbus_uint32_t) u8Temp; + } + buffer3_outsize = buffer3_realsize; + } else + { + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + } + + operation_param3_memref_parent = + (dbus_uint64_t) operationIns.params[2].memref.parent->buffer; + operation_param3_memref_parent_flag = + (dbus_uint32_t) operationIns.params[2].memref.parent->flags; + operation_param3_memref_offset = operationIns.params[2].memref.offset; + operation_param3_memref_size = + operationIns.params[2].memref.size; + + break; + } + + + default: + { + buffer3_realsize = 0; + buffer3 = NULL; + buffer3_outsize = 0; + } + } + + operation_param3_ionref_ionsharefd = operationIns.params[2].ionref.ion_share_fd; + operation_param3_ionref_ionsize = operationIns.params[2].ionref.ion_size; + + ////////////////////////////////////////////////////////////////////////////////// + + switch ( + TEEC_PARAM_TYPE_GET(operationIns.paramTypes, 3) + ) + { + case TEEC_VALUE_INOUT: + case TEEC_VALUE_OUTPUT: + { + operation_param4_value_a = operationIns.params[3].value.a; + operation_param4_value_b = operationIns.params[3].value.b; + + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + + break; + } + + case TEEC_MEMREF_TEMP_INOUT: + case TEEC_MEMREF_TEMP_OUTPUT: + { + if (operationIns.params[3].tmpref.buffer != NULL && + operationIns.params[3].tmpref.size > 0 + ) + { + buffer4_realsize = operationIns.params[3].tmpref.size; + buffer4 = + (dbus_uint32_t *) malloc( + buffer4_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer4_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * )(operationIns.params[3].tmpref.buffer) + iind); + buffer4[iind] = (dbus_uint32_t) u8Temp; + } + buffer4_outsize = buffer4_realsize; + } else + { + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } + + operation_param4_tmpref_buffer = (dbus_uint64_t) operationIns.params[3].tmpref.buffer; + operation_param4_tmpref_size = operationIns.params[3].tmpref.size; + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operationIns.params[3].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + + if (operationIns.params[3].memref.parent->buffer != NULL && + operationIns.params[3].memref.parent->size > 0 + ) + { + buffer4_realsize = operationIns.params[3].memref.parent->size; + buffer4 = + (dbus_uint32_t *) malloc( + buffer4_realsize * sizeof(dbus_uint32_t) + ); + for (int iind = 0; iind < buffer4_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[3].memref.parent->buffer) + iind); + buffer4[iind] = (dbus_uint32_t) u8Temp; + } + buffer4_outsize = buffer4_realsize; + } else + { + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } + + operation_param4_memref_parent = + (dbus_uint64_t) operationIns.params[3].memref.parent->buffer; + operation_param4_memref_parent_flag = + (dbus_uint32_t) operationIns.params[3].memref.parent->flags; + operation_param4_memref_size = + operationIns.params[3].memref.parent->size; + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operationIns.params[3].memref.parent->buffer != NULL && + operationIns.params[3].memref.parent->size > 0 + ) + { + buffer4_realsize = operationIns.params[3].memref.parent->size; + buffer4 = + (dbus_uint32_t *) malloc(buffer4_realsize * sizeof(dbus_uint32_t)); + for (int iind = 0; iind < buffer4_realsize; iind++) + { + uint8_t u8Temp; + u8Temp = (uint8_t) * ((uint8_t * ) + (operationIns.params[3].memref.parent->buffer) + iind); + buffer4[iind] = (dbus_uint32_t) u8Temp; + } + buffer4_outsize = buffer4_realsize; + } else + { + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } + + operation_param4_memref_parent = + (dbus_uint64_t) operationIns.params[3].memref.parent->buffer; + operation_param4_memref_parent_flag = + (dbus_uint32_t) operationIns.params[3].memref.parent->flags; + operation_param4_memref_offset = operationIns.params[3].memref.offset; + operation_param4_memref_size = + operationIns.params[3].memref.size; + + break; + } + + + default: + { + buffer4_realsize = 0; + buffer4 = NULL; + buffer4_outsize = 0; + } + } + + operation_param4_ionref_ionsharefd = operationIns.params[3].ionref.ion_share_fd; + operation_param4_ionref_ionsize = operationIns.params[3].ionref.ion_size; + + ////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////// + + operation_session = (dbus_uint64_t) operationIns.session; + operation_cancelflag = operationIns.cancel_flag; + + returnorigin = origin; + } + + if (buffer1_temp != NULL) + { + free(buffer1_temp); + } + if (buffer2_temp != NULL) + { + free(buffer2_temp); + } + if (buffer3_temp != NULL) + { + free(buffer3_temp); + } + if (buffer4_temp != NULL) + { + free(buffer4_temp); + } + + if (sb1AllReged == true) + { + TEEC_ReleaseSharedMemory(&shareBuffer1); + printf("TEEC_ReleaseSharedMemory. \n"); + } + + if (sb2AllReged == true) + { + TEEC_ReleaseSharedMemory(&shareBuffer2); + printf("TEEC_ReleaseSharedMemory. \n"); + } + + if (sb3AllReged == true) + { + TEEC_ReleaseSharedMemory(&shareBuffer3); + printf("TEEC_ReleaseSharedMemory. \n"); + } + + if (sb4AllReged == true) + { + TEEC_ReleaseSharedMemory(&shareBuffer4); + printf("TEEC_ReleaseSharedMemory. \n"); + } + + } // end of the invoke command success + + } // end of the input parameter operation success + + + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// +#else + if (in_buffer1_size > 0) { + } + else + { + in_buffer1_realsize = 0; + } + if (in_buffer2_size > 0) { + } + else + { + in_buffer2_realsize = 0; + } + if (in_buffer3_size > 0) { + } + else + { + in_buffer3_realsize = 0; + } + if (in_buffer4_size > 0) { + } + else + { + in_buffer4_realsize = 0; + } + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + uint32_t serviceid_clockseqandnode_outsize_temp; + uint32_t returnorigin_temp; + + uint32_t * buffer1_temp = NULL; + uint32_t buffer1_size = 4096; + uint32_t buffer1_outsize_temp; + buffer1_temp = + (uint32_t *)malloc( buffer1_size * sizeof(uint32_t) ); + + uint32_t buffer2_size = 4096; + uint32_t * buffer2_temp = NULL; + uint32_t buffer2_outsize_temp; + buffer2_temp = + (uint32_t *)malloc( buffer2_size * sizeof(uint32_t) ); + + uint32_t buffer3_size = 4096; + uint32_t * buffer3_temp = NULL; + uint32_t buffer3_outsize_temp; + buffer3_temp = + (uint32_t *)malloc( buffer3_size * sizeof(uint32_t) ); + + uint32_t buffer4_size = 4096; + uint32_t * buffer4_temp = NULL; + uint32_t buffer4_outsize_temp; + buffer4_temp = + (uint32_t *)malloc( buffer4_size * sizeof(uint32_t) ); + + char workername[1024]; + memset((char *)workername, 0, 1024); + int ifound = 0; + int iworker; + sin_t * sinIns; + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].context_addr == in_session_context) + { + sinIns = NULL; + if (workerrec[iworker].first != NULL) + { + sinIns = workerrec[iworker].first; + do + { + if (sinIns->session_id == in_session_sessionid) + { + sprintf(workername, "%s%d", "gpworker", iworker); + ifound = 1; + break; + } + sinIns = sinIns->next; + }while (sinIns != NULL); + + if ( ifound == 1 ) + { + break; + } + } + } + } + pthread_mutex_unlock(mutex_workerrec); + + if (ifound == 0) + { + printf("Can't find the worker for the session and the context. \n"); + + teecresult = 0xAAAA0017; + + sessionid = 0x0; + serviceid_timelow = 0x0; + serviceid_timemid = 0x0; + serviceid_timehiandver = 0x0; + opscnt = 0x0; + head_next = 0x0; + head_prev = 0x0; + context = 0x0; + started = 0x0; + paramtypes = 0x0; + + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < serviceid_clockseqandnode_realsize ; i++) { + serviceid_clockseqandnode[i] = 0x0; + } + serviceid_clockseqandnode_outsize = 8; + + operation_param1_tmpref_buffer = 0x0; + operation_param1_tmpref_size = 0x0; + operation_param1_memref_parent = 0x0; + operation_param1_memref_size = 0x0; + operation_param1_memref_offset = 0x0; + operation_param1_value_a = 0x0; + operation_param1_value_b = 0x0; + operation_param1_ionref_ionsharefd = 0x0; + operation_param1_ionref_ionsize = 0x0; + + operation_param2_tmpref_buffer = 0x0; + operation_param2_tmpref_size = 0x0; + operation_param2_memref_parent = 0x0; + operation_param2_memref_size = 0x0; + operation_param2_memref_offset = 0x0; + operation_param2_value_a = 0x0; + operation_param2_value_b = 0x0; + operation_param2_ionref_ionsharefd = 0x0; + operation_param2_ionref_ionsize = 0x0; + + operation_param3_tmpref_buffer = 0x0; + operation_param3_tmpref_size = 0x0; + operation_param3_memref_parent = 0x0; + operation_param3_memref_size = 0x0; + operation_param3_memref_offset = 0x0; + operation_param3_value_a = 0x0; + operation_param3_value_b = 0x0; + operation_param3_ionref_ionsharefd = 0x0; + operation_param3_ionref_ionsize = 0x0; + + operation_param4_tmpref_buffer = 0x0; + operation_param4_tmpref_size = 0x0; + operation_param4_memref_parent = 0x0; + operation_param4_memref_size = 0x0; + operation_param4_memref_offset = 0x0; + operation_param4_value_a = 0x0; + operation_param4_value_b = 0x0; + operation_param4_ionref_ionsharefd = 0x0; + operation_param4_ionref_ionsize = 0x0; + + operation_session = 0x0; + operation_cancelflag = 0x0; + + returnorigin = 0x0; + + buffer1_realsize = 0; + buffer1_outsize = buffer1_realsize; + + buffer2_realsize = 0; + buffer2_outsize = buffer2_realsize; + + buffer3_realsize = 0; + buffer3_outsize = buffer3_realsize; + + buffer4_realsize = 0; + buffer4_outsize = buffer4_realsize; + } + else + { + method_call_teec_invokecommand( + workername, + + in_session_sessionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_realsize, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + in_commandid, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_parent_flag, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_parent_flag, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_parent_flag, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_parent_flag, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + + in_returnorigin, + + in_buffer1, + in_buffer1_realsize, + in_buffer2, + in_buffer2_realsize, + in_buffer3, + in_buffer3_realsize, + in_buffer4, + in_buffer4_realsize, + + + &teecresult, + + &sessionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + + &opscnt, + &head_next, + &head_prev, + &context, + + &started, + ¶mtypes, + + &operation_param1_tmpref_buffer, + &operation_param1_tmpref_size, + &operation_param1_memref_parent, + &operation_param1_memref_parent_flag, + &operation_param1_memref_size, + &operation_param1_memref_offset, + &operation_param1_value_a, + &operation_param1_value_b, + &operation_param1_ionref_ionsharefd, + &operation_param1_ionref_ionsize, + + &operation_param2_tmpref_buffer, + &operation_param2_tmpref_size, + &operation_param2_memref_parent, + &operation_param2_memref_parent_flag, + &operation_param2_memref_size, + &operation_param2_memref_offset, + &operation_param2_value_a, + &operation_param2_value_b, + &operation_param2_ionref_ionsharefd, + &operation_param2_ionref_ionsize, + + &operation_param3_tmpref_buffer, + &operation_param3_tmpref_size, + &operation_param3_memref_parent, + &operation_param3_memref_parent_flag, + &operation_param3_memref_size, + &operation_param3_memref_offset, + &operation_param3_value_a, + &operation_param3_value_b, + &operation_param3_ionref_ionsharefd, + &operation_param3_ionref_ionsize, + + &operation_param4_tmpref_buffer, + &operation_param4_tmpref_size, + &operation_param4_memref_parent, + &operation_param4_memref_parent_flag, + &operation_param4_memref_size, + &operation_param4_memref_offset, + &operation_param4_value_a, + &operation_param4_value_b, + &operation_param4_ionref_ionsharefd, + &operation_param4_ionref_ionsize, + + &operation_session, + &operation_cancelflag, + + &returnorigin_temp, + + buffer1_temp, + buffer1_size, + &buffer1_outsize_temp, + buffer2_temp, + buffer2_size, + &buffer2_outsize_temp, + buffer3_temp, + buffer3_size, + &buffer3_outsize_temp, + buffer4_temp, + buffer4_size, + &buffer4_outsize_temp + ); + + serviceid_clockseqandnode_outsize = + serviceid_clockseqandnode_outsize_temp; + + returnorigin = returnorigin_temp; + + buffer1_outsize = buffer1_outsize_temp; + buffer2_outsize = buffer2_outsize_temp; + buffer3_outsize = buffer3_outsize_temp; + buffer4_outsize = buffer4_outsize_temp; + + buffer1_realsize = buffer1_outsize; + if (buffer1_realsize > 0) + { + buffer1 = + (dbus_uint32_t *)malloc( + buffer1_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < buffer1_realsize ; i++) { + buffer1[i] = (dbus_uint32_t)buffer1_temp[i]; + } + } + + buffer2_realsize = buffer2_outsize; + if (buffer2_realsize > 0) + { + buffer2 = + (dbus_uint32_t *)malloc( + buffer2_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < buffer2_realsize ; i++) { + buffer2[i] = (dbus_uint32_t)buffer2_temp[i]; + } + } + + buffer3_realsize = buffer3_outsize; + if (buffer3_realsize > 0) + { + buffer3 = + (dbus_uint32_t *)malloc( + buffer3_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < buffer3_realsize ; i++) { + buffer3[i] = (dbus_uint32_t)buffer3_temp[i]; + } + } + + buffer4_realsize = buffer4_outsize; + if (buffer4_realsize > 0) + { + buffer4 = + (dbus_uint32_t *)malloc( + buffer4_realsize * sizeof(dbus_uint32_t) + ); + for (int i = 0; i < buffer4_realsize ; i++) { + buffer4[i] = (dbus_uint32_t)buffer4_temp[i]; + } + } + + } // end of the else found == 1 + + if ( buffer1_temp != NULL ) + { + free(buffer1_temp); + } + if ( buffer2_temp != NULL ) + { + free(buffer2_temp); + } + if ( buffer3_temp != NULL ) + { + free(buffer3_temp); + } + if ( buffer4_temp != NULL ) + { + free(buffer4_temp); + } +#endif + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////// + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &teecresult + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &sessionid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timelow + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timemid + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_timehiandver + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (serviceid_clockseqandnode_outsize > 0 && + serviceid_clockseqandnode != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &opscnt + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_next + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &head_prev + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &context + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &started + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + ¶mtypes + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param1_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param1_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_memref_parent_flag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param1_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param1_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param2_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param2_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_memref_parent_flag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param2_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param2_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param3_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param3_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_memref_parent_flag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param3_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param3_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param4_tmpref_buffer + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_tmpref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_param4_memref_parent + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_memref_parent_flag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_memref_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_memref_offset + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_value_a + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_value_b + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_param4_ionref_ionsharefd + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &operation_param4_ionref_ionsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &operation_session + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &operation_cancelflag + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &returnorigin + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &buffer1_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (buffer1_outsize > 0 && + buffer1 != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &buffer1, + buffer1_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &buffer2_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (buffer2_outsize > 0 && + buffer2 != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &buffer2, + buffer2_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &buffer3_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (buffer3_outsize > 0 && + buffer3 != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &buffer3, + buffer3_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &buffer4_outsize + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + if (buffer4_outsize > 0 && + buffer4 != NULL + ) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &buffer4, + buffer4_realsize + ); + + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + // send the reply && flush the connection + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + free(thdfargs); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + free(thdfargs); + + // sleep(2); + + return NULL; +} + + +#ifdef GP_PROXY + void* +session_timeout_process ( + void* thdfargs +) +{ + DBusMsgConn* DBusMCP; + pthread_mutex_t * mutex_workerrec; + wr_t * workerrec; + + DBusMCP = (DBusMsgConn*)thdfargs; + mutex_workerrec = DBusMCP->mutex_workerrec; + workerrec = DBusMCP->workerrec; + + struct timeval tv; + uint64_t u64time; + + char workername[1024]; + memset((char *)workername, 0, 1024); + int iworker; + + dbus_uint32_t in_session_seesionid; + dbus_uint32_t in_session_serviceid_timelow = 0; + dbus_uint32_t in_session_serviceid_timemid = 0; + dbus_uint32_t in_session_serviceid_timehiandver = 0; + dbus_uint32_t in_session_serviceid_clockseqandnode_size = 8; + dbus_uint32_t in_session_serviceid_clockseqandnode[8]; + dbus_uint32_t in_session_opscnt = 0; + dbus_uint64_t in_session_head_next = 0; + dbus_uint64_t in_session_head_prev = 0; + dbus_uint64_t in_session_context; + + dbus_uint32_t seesionid; + dbus_uint32_t serviceid_timelow; + dbus_uint32_t serviceid_timemid; + dbus_uint32_t serviceid_timehiandver; + dbus_uint32_t * serviceid_clockseqandnode; + int serviceid_clockseqandnode_realsize; + dbus_uint32_t opscnt; + dbus_uint64_t head_next; + dbus_uint64_t head_prev; + dbus_uint64_t context; + + sin_t * sinIns; + + while (1) + { + sleep(TIMEDOUT_SESSION); + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].busy == 1) + { + sinIns = NULL; + if (workerrec[iworker].first != NULL) + { + sinIns = workerrec[iworker].first; + do + { + gettimeofday(&tv, NULL); + u64time = (long unsigned int)(tv.tv_sec - + sinIns->session_createtime.tv_sec + ); + sin_t * sinTemp = NULL; + + if (u64time > TIMEDOUT_SESSION) + { + sprintf(workername, "%s%d", "gpworker", iworker); + + in_session_seesionid = sinIns->session_id; + in_session_context = workerrec[iworker].context_addr; + + for (int iind = 0; iind < 8; iind++) + { + in_session_serviceid_clockseqandnode[iind] = 0; + } + + pthread_mutex_unlock(mutex_workerrec); + + uint32_t serviceid_clockseqandnode_outsize_temp; + serviceid_clockseqandnode_realsize = 8; + serviceid_clockseqandnode = + (dbus_uint32_t *)malloc( + serviceid_clockseqandnode_realsize * sizeof(dbus_uint32_t) + ); + + printf("\nMethod call teec closesession. (Called by Proxy for timeout process) \n"); + method_call_teec_closesession( + workername, + + in_session_seesionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + &seesionid, + &serviceid_timelow, + &serviceid_timemid, + &serviceid_timehiandver, + serviceid_clockseqandnode, + serviceid_clockseqandnode_realsize, + &serviceid_clockseqandnode_outsize_temp, + &opscnt, + &head_next, + &head_prev, + &context + ); + + if (serviceid_clockseqandnode != NULL) { + free(serviceid_clockseqandnode); + } + + pthread_mutex_lock(mutex_workerrec); + + sinTemp = sinIns->prev; + if (sinTemp != NULL) + { + sinTemp->next = sinIns->next; + } + sinTemp = sinIns->next; + if (sinTemp != NULL) + { + sinTemp->prev = sinIns->prev; + } + if (workerrec[iworker].last == sinIns) + { + workerrec[iworker].last = sinIns->prev; + } + if (workerrec[iworker].first == sinIns) + { + workerrec[iworker].first = sinIns->next; + } + + // free(sinIns); + sinTemp = sinIns; + workerrec[iworker].sessionid_count = + workerrec[iworker].sessionid_count - 1; + + } // end of if timedout + sinIns = sinIns->next; + if (sinTemp != NULL) + { + free(sinTemp); + } + }while (sinIns != NULL); + + + } // end of the first not null + } // end of the busy = 1 + } // end of the for iworker + pthread_mutex_unlock(mutex_workerrec); + + } // end of while 1 + + + free(thdfargs); + return NULL; +} + + +void* +context_timeout_process ( + void* thdfargs +) +{ + DBusMsgConn* DBusMCP; + pthread_mutex_t * mutex_workerrec; + pthread_cond_t * cond_notbusy; + wr_t * workerrec; + + DBusMCP = (DBusMsgConn*)thdfargs; + mutex_workerrec = DBusMCP->mutex_workerrec; + cond_notbusy = DBusMCP->cond_notbusy; + workerrec = DBusMCP->workerrec; + + + + struct timeval tv; + uint64_t u64time; + + char workername[1024]; + memset((char *)workername, 0, 1024); + int iworker; + + dbus_int32_t in_fd; + unsigned char * in_ta_path = NULL; + dbus_int32_t in_ta_path_size = 0; + dbus_uint64_t in_session_list_next = 0; + dbus_uint64_t in_session_list_prev = 0; + dbus_uint64_t in_shrd_mem_list_next = 0; + dbus_uint64_t in_shrd_mem_list_prev = 0; + dbus_uint64_t in_share_buffer_buffer = 0; + dbus_int64_t in_share_buffer_buffer_barrier = 0; + dbus_uint64_t in_context_addr; + + dbus_int32_t fd; + unsigned char * ta_path; + dbus_int32_t ta_path_size; + dbus_uint64_t session_list_next; + dbus_uint64_t session_list_prev; + dbus_uint64_t shrd_mem_list_next; + dbus_uint64_t shrd_mem_list_prev; + dbus_uint64_t share_buffer_buffer; + dbus_int64_t share_buffer_buffer_barrier; + uint32_t context_tapath_outsize; + + while(1) + { + sleep(TIMEDOUT_CONTEXT); + + pthread_mutex_lock(mutex_workerrec); + for (iworker = 0; iworker < MAX_NUM_WORKER; iworker++) + { + if (workerrec[iworker].busy == 1) + { + sprintf(workername, "%s%d", "gpworker", iworker); + gettimeofday(&tv, NULL); + u64time = (long unsigned int)(tv.tv_sec - + workerrec[iworker].context_createtime.tv_sec + ); + if (u64time > TIMEDOUT_CONTEXT + && + workerrec[iworker].sessionid_count == 0 + ) + { + in_fd = workerrec[iworker].context_fd; + in_context_addr = workerrec[iworker].context_addr; + ta_path = (unsigned char *)malloc(1024 * sizeof(char)); + ta_path_size = 1024; + memset((char *)ta_path, 0, 1024); + + pthread_mutex_unlock(mutex_workerrec); + + printf("\nMethod call teec fincont. (Called by Proxy for timeout process) \n"); + method_call_teec_fincont( + workername, + + in_fd, + in_ta_path, + in_ta_path_size, + in_session_list_next, + in_session_list_prev, + in_shrd_mem_list_next, + in_shrd_mem_list_prev, + in_share_buffer_buffer, + in_share_buffer_buffer_barrier, + in_context_addr, + + &fd, + ta_path, + ta_path_size, + &session_list_next, + &session_list_prev, + &shrd_mem_list_next, + &shrd_mem_list_prev, + &share_buffer_buffer, + &share_buffer_buffer_barrier, + + &context_tapath_outsize + ); + + if (ta_path != NULL) + { + free(ta_path); + } + + pthread_mutex_lock(mutex_workerrec); + + workerrec[iworker].busy = 0; + pthread_cond_signal(cond_notbusy); + workerrec[iworker].context_fd = 0; + workerrec[iworker].context_addr = 0xffffffff; + workerrec[iworker].sessionid_count = 0; + sin_t * sinIns; + sin_t * sinInsPrev; + sinIns = workerrec[iworker].last; + if (sinIns != NULL) + { + for ( ; ; ) + { + sinInsPrev = sinIns->prev; + free(sinIns); + sinIns = sinInsPrev; + if (sinIns == NULL) + { + break; + } + } + } + + } // end of the if timeed out + } // end of the if busy = 1 + } // end of the for iworker + pthread_mutex_unlock(mutex_workerrec); + + } // end of while 1 + + free(thdfargs); + return NULL; +} +#endif + + +void * +reply_to_method_call_destroy_threadpool( + DBusMessage *msg, + DBusConnection *conn, + threadpool_t *pool +#ifdef GP_WORKER + , + pthread_mutex_t *mutex_tcl, + pthread_mutex_t *mutex_tsl +#endif + +#ifdef GP_PROXY + , + pthread_mutex_t * mutex_workerrec, + pthread_cond_t * cond_notbusy +#endif +) +{ + DBusMessage *reply; + DBusMessageIter args; + // char* param = ""; + char *param = NULL; + dbus_bool_t bResult; + dbus_uint32_t retcode; + dbus_uint32_t serial = 0; + + // read the arguments + if (!dbus_message_iter_init(msg, &args)) + fprintf(stderr, "Message has no arguments!\n"); + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not string!\n"); + else + dbus_message_iter_get_basic(&args, ¶m); + + printf("\n"); + printf("Received mechod call Destroy: \n"); + printf(" param = %s \n", param); + printf("\n"); + + // create a reply from the message + reply = dbus_message_new_method_return(msg); + + retcode = 0x00; + + // add the arguments to the reply + dbus_message_iter_init_append(reply, &args); + bResult = + dbus_message_iter_append_basic( + &args, + DBUS_TYPE_UINT32, + &retcode + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + serial = 100; + if (!dbus_connection_send(conn, reply, &serial)) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return NULL; + } + + dbus_message_unref(reply); + dbus_connection_flush(conn); + dbus_message_unref(msg); + // dbus_connection_close(conn); + // dbus_connection_unref(conn); + + + threadpool_destroy(pool); + +#ifdef GP_WORKER + pthread_mutex_destroy(mutex_tcl); + pthread_mutex_destroy(mutex_tsl); +#endif + +#ifdef GP_PROXY + pthread_mutex_destroy(mutex_workerrec); + pthread_cond_destroy(cond_notbusy); +#endif + + printf("\n"); + printf("This process exits. \n"); + printf("\n"); + + exit(1); + + return NULL; +} + +#endif diff --git a/teeproxy/gpworker/tzcp_dbus.h b/teeproxy/gpworker/tzcp_dbus.h new file mode 100644 index 0000000..d92f224 --- /dev/null +++ b/teeproxy/gpworker/tzcp_dbus.h @@ -0,0 +1,550 @@ +#ifndef _TZCP_DBUS_H_ +#define _TZCP_DBUS_H_ + +#include +#include + +#define GP_PROXY_WORKER 1 +// #define GP_PROXY 2 +#define GP_WORKER 3 + +#ifdef GP_PROXY_WORKER + +#include "threadpool.h" + +#define MAX_NUM_THREAD 128 +#define MAX_NUM_WORKER 128 +#define TIMEDOUT_SESSION 60 //seconds +#define TIMEDOUT_CONTEXT 90 //seconds + +#define TEEC_ERROR_CONTEXT_NULL 0xAAAA0001 /* null context */ +#define TEEC_ERROR_CONTEXT_TAPATH_NULL 0xAAAA0002 /* null context ta path */ +#define TEEC_ERROR_PARAM0_TEMPMEM_NULL 0xAAAA0003 /* null param0 tempmem buf */ +#define TEEC_ERROR_PARAM0_TEMPMEM_LESS 0xAAAA0004 /* param0 tempmem buf is less */ +#define TEEC_ERROR_PARAM1_TEMPMEM_NULL 0xAAAA0005 /* null param1 tempmem buf */ +#define TEEC_ERROR_PARAM1_TEMPMEM_LESS 0xAAAA0006 /* param1 tempmem buf is less */ +#define TEEC_ERROR_PARAM2_TEMPMEM_NULL 0xAAAA0007 /* null param2 tempmem buf */ +#define TEEC_ERROR_PARAM2_TEMPMEM_LESS 0xAAAA0008 /* param2 tempmem buf is less */ +#define TEEC_ERROR_PARAM3_TEMPMEM_NULL 0xAAAA0009 /* null param3 tempmem buf */ +#define TEEC_ERROR_PARAM3_TEMPMEM_LESS 0xAAAA000A /* param3 tempmem buf is less */ +#define TEEC_ERROR_CONTEXT_LIST_NULL 0xAAAA000B /* null context list in woker */ +#define TEEC_ERROR_NO_CONTEXT_MATCH 0xAAAA000C /* no context match in woker */ +#define TEEC_ERROR_SESSION_LIST_NULL 0xAAAA000D /* null session list in woker */ +#define TEEC_ERROR_NO_SESSION_MATCH 0xAAAA000E /* no session match in woker */ +#define TEEC_ERROR_PARAM0_MEMREF_NULL 0xAAAA000F /* null param0 memref buf */ +#define TEEC_ERROR_PARAM0_MEMREF_LESS 0xAAAA0010 /* param0 memref buf is less */ +#define TEEC_ERROR_PARAM1_MEMREF_NULL 0xAAAA0011 /* null param1 memref buf */ +#define TEEC_ERROR_PARAM1_MEMREF_LESS 0xAAAA0012 /* param1 memref buf is less */ +#define TEEC_ERROR_PARAM2_MEMREF_NULL 0xAAAA0013 /* null param2 memref buf */ +#define TEEC_ERROR_PARAM2_MEMREF_LESS 0xAAAA0014 /* param2 memref buf is less */ +#define TEEC_ERROR_PARAM3_MEMREF_NULL 0xAAAA0015 /* null param3 memref buf */ +#define TEEC_ERROR_PARAM3_MEMREF_LESS 0xAAAA0016 /* param3 memref buf is less */ +#define TEEC_ERROR_NO_WORKER_MATCHED 0xAAAA0017 /* No woker mateched with the context or/and session */ +#define TEEC_ERROR_SESSION_NULL 0xAAAA0018 /* null session */ +#define TEEC_ERROR_NO_SHAREMEMFLAG 0xAAAA0019 /* no share memmory flag */ + +#endif + + +#ifdef GP_PROXY_WORKER +typedef struct +{ + DBusMessage *msg; + DBusConnection *conn; +#ifdef GP_PROXY + pthread_mutex_t * mutex_workerrec; + pthread_cond_t * cond_notbusy; + wr_t * workerrec; +#endif +#ifdef GP_WORKER + int64_t workernum; + pthread_mutex_t *mutex_tcl; + pthread_mutex_t *mutex_tsl; + tcl_t *tcl; + tsl_t *tsl; +#endif +} DBusMsgConn; +#endif + +void +receive_signal(void); + +void +send_signal( + char *sigvalue +); + +#ifdef GP_PROXY_WORKER + +void +receive_methodcall( + threadpool_t *pool, +#ifdef GP_WORKER + pthread_mutex_t *mutex_tcl, + pthread_mutex_t *mutex_tsl, + tcl_t *tcl, + tsl_t *tsl, +#endif + char *workername + +#ifdef GP_PROXY + , + pthread_mutex_t * mutex_workerrec, + pthread_cond_t * cond_notbusy, + wr_t * workerrec +#endif +); + +#endif + +int32_t +method_call_teec_inicont( + const char *workername, + + const uint8_t *name, size_t name_size, + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t *teecresult, + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint64_t *context_addr, + uint32_t *context_tapath_outsize +); + +int32_t +method_call_teec_fincont( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint64_t in_context_addr, + + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint32_t *context_tapath_outsize +); + +int32_t +method_call_teec_opensession( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, + size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t in_destination_timelow, + uint32_t in_destination_timemid, + uint32_t in_destination_timehiandver, + uint32_t *in_destination_clockseqandnode, + int32_t in_destination_clockseqandnode_size, + uint32_t in_connectionmethod, + uint64_t in_connectiondata, + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint64_t in_context_addr, + + + uint32_t *teecresult, + + int32_t *context_fd, + uint8_t *context_tapath, + size_t context_tapath_size, + uint32_t *context_tapath_outsize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin +); + +int32_t +method_call_teec_closesession( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + int32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context +); + +int32_t +method_call_teec_invokecommand( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + uint32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t commandid, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_parent_flag, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_parent_flag, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_parent_flag, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_parent_flag, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint32_t *in_buffer1, + uint32_t in_buffer1_size, + uint32_t *in_buffer2, + uint32_t in_buffer2_size, + uint32_t *in_buffer3, + uint32_t in_buffer3_size, + uint32_t *in_buffer4, + uint32_t in_buffer4_size, + + + uint32_t *teecresult, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_parent_flag, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_parent_flag, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_parent_flag, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_parent_flag, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin, + + uint32_t *buffer1, + uint32_t buffer1_size, + uint32_t *buffer1_outsize, + uint32_t *buffer2, + uint32_t buffer2_size, + uint32_t *buffer2_outsize, + uint32_t *buffer3, + uint32_t buffer3_size, + uint32_t *buffer3_outsize, + uint32_t *buffer4, + uint32_t buffer4_size, + uint32_t *buffer4_outsize +); + +void +method_call_destroy_threadpool( + const char *workername +); + + +#ifdef GP_PROXY_WORKER + +void * +reply_to_method_call_teec_inicont( + void *thdfargs +); + +void * +reply_to_method_call_teec_fincont( + void *thdfargs +); + +void * +reply_to_method_call_teec_opensession( + void *thdfargs +); + +void * +reply_to_method_call_teec_closesession( + void *thdfargs +); + +void * +reply_to_method_call_teec_invokecommand( + void *thdfargs +); + +#ifdef GP_PROXY +void* +session_timeout_process ( + void* thdfargs +); + +void* +context_timeout_process ( + void* thdfargs +); +#endif + +void * +reply_to_method_call_destroy_threadpool( + DBusMessage *msg, + DBusConnection *conn, + threadpool_t *pool +#ifdef GP_WORKER + , + pthread_mutex_t *mutex_tcl, + pthread_mutex_t *mutex_tsl +#endif +#ifdef GP_PROXY + , + pthread_mutex_t * mutex_workerbusy, + pthread_cond_t * cond_notbusy +#endif +); + +#endif + + +#endif /* _TZCP_DBUS_H_ */ diff --git a/teeproxy/libdbuscgpw/CMakeLists.txt b/teeproxy/libdbuscgpw/CMakeLists.txt new file mode 100644 index 0000000..236a2ec --- /dev/null +++ b/teeproxy/libdbuscgpw/CMakeLists.txt @@ -0,0 +1,45 @@ +# + +cmake_minimum_required(VERSION 3.5.1) + +project(libdbusc_gpw C CXX) + +# set(CMAKE_C_FLAGS "${CMAKE_}") +# set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) + +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +# include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include/) +include_directories(/usr/include/dbus-1.0/) +include_directories(/usr/lib64/dbus-1.0/include/) + +# Introduce variables: +# - CMAKE_INSTALL_LIBDIR +# - CMAKE_INSTALL_BINDIR +# - CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + +set(LIB_DBUSC_GPW + ${PROJECT_SOURCE_DIR}/dbusc_gpw.c +) +# Install Headers: +set(HEADERS_DBUSC_GPW + dbusc_gpw.h +) +install( + FILES ${HEADERS_DBUSC_GPW} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${TARGET_NAME}" +) + +add_library(dbusc_gpw SHARED ${LIB_DBUSC_GPW}) +target_link_libraries(dbusc_gpw + libdbus-1.so +) +# set_target_properties(dbusc_gpw +# PROPERTIES IMPORTED_LOCATION +# ) + +# Install lib: +install( + TARGETS "dbusc_gpw" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) diff --git a/teeproxy/libdbuscgpw/build/cmake.sh b/teeproxy/libdbuscgpw/build/cmake.sh new file mode 100644 index 0000000..bef7b3e --- /dev/null +++ b/teeproxy/libdbuscgpw/build/cmake.sh @@ -0,0 +1 @@ +cmake -DCMAKE_BUILD_TYPE=Debug .. diff --git a/teeproxy/libdbuscgpw/dbusc_gpw.c b/teeproxy/libdbuscgpw/dbusc_gpw.c new file mode 100644 index 0000000..1069929 --- /dev/null +++ b/teeproxy/libdbuscgpw/dbusc_gpw.c @@ -0,0 +1,9291 @@ +/* + * Using low-level D-Bus C API code. + * Written by + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dbusc_gpw.h" + + +/** + * Listens for signals on the bus + */ +void +receive_signal(void) +{ + DBusMessage *msg; + DBusMessageIter args; + DBusConnection *conn; + DBusError err; + int ret; + char *sigvalue; + + printf("Listening for signals\n"); + + // initialise the errors + dbus_error_init(&err); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + exit(1); + } + + // request our name on the bus and check for errors + ret = dbus_bus_request_name(conn, "test.signal.sink", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + exit(1); + } + + // add a rule for which messages we want to see + dbus_bus_add_match(conn, "type='signal',interface='test.signal.Type'", &err); + // see signals from the given interface + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Match Error (%s)\n", err.message); + exit(1); + } + // printf("Match rule sent\n"); + + // loop listening for signals being emmitted + while (true) + { + + // non blocking read of the next available message + dbus_connection_read_write(conn, 0); + msg = dbus_connection_pop_message(conn); + + // loop again if we haven't read a message + if (NULL == msg) + { + usleep(10000); + continue; + } + + // check if the message is a signal from the correct interface and with the correct name + if (dbus_message_is_signal(msg, "test.signal.Type", "Test")) + { + + // read the parameters + if (!dbus_message_iter_init(msg, &args)) + fprintf(stderr, "Message Has No Parameters\n"); + else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) + fprintf(stderr, "Argument is not string!\n"); + else + dbus_message_iter_get_basic(&args, &sigvalue); + + printf("Got Signal with value %s\n", sigvalue); + } + + // free the message + dbus_message_unref(msg); + } +} + + +/** + * Connect to the DBUS bus and send a broadcast signal + */ +void +send_signal( + char *sigvalue +) +{ + DBusMessage *msg; + DBusMessageIter args; + DBusConnection *conn; + DBusError err; + int ret; + dbus_uint32_t sigserial = 0; + + printf("Sending signal with value %s\n", sigvalue); + + // initialise the error value + dbus_error_init(&err); + + // connect to the DBUS system bus, and check for errors + conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + exit(1); + } + + // register our name on the bus, and check for errors + ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + exit(1); + } + + // create a signal & check for errors + msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal + "test.signal.Type", // interface name of the signal + "Test"); // name of the signal + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + exit(1); + } + + // append arguments onto signal + dbus_message_iter_init_append(msg, &args); + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) + { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + + // send the message and flush the connection + if (!dbus_connection_send(conn, msg, &sigserial)) + { + fprintf(stderr, "Out Of Memory!\n"); + exit(1); + } + dbus_connection_flush(conn); + + printf("Signal Sent\n"); + + // free the message + dbus_message_unref(msg); +} + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_inicont( + const char *workername, + + const uint8_t *name, size_t name_size, + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t *teecresult, + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint64_t *context_addr, + uint32_t *context_tapath_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + + // initialiset the errors + dbus_error_init(&err); + + dbus_threads_init_default(); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + // conn = dbus_bus_get(DBUS_BUS_SESSION, &err); + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_InitializeContext" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = name_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (name_size > 0 && name != NULL) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &name + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Init Contex Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + // printf("\n"); + printf("libdbuscgpw method call teec init contex sent. \n"); + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: initcontext send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: initcontext dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + if (*context_tapath_outsize > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_addr = dui64Temp; + + printf("libdbuscgpw got reply of method call teec init contex: \n"); + printf(" teecresult = 0x %8.8x \n", *teecresult); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path = %s \n", context_tapath_temp); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); +#endif + printf(" context addr = 0x %16.16lx \n", + (long unsigned int) *context_addr + ); + + if ( + context_tapath_insize > *context_tapath_outsize && + *context_tapath_outsize > 0 && + context_tapath != NULL && + context_tapath_temp != NULL + ) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + // dbus_message_unref(msg); + // return -1; + *(context_tapath + 0) = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_fincont( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint64_t in_context_addr, + + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint32_t *context_tapath_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_FinalizeContext" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + // if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + if (dbus_validate_path((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + fprintf(stderr, "libdbuscgpw finalizecontext, in_context_tapath_size, di32Temp = %ld \n", di32Temp); + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + fprintf(stderr, "libdbuscgpw finalizecontext, in_context_tapath = %s \n", in_context_tapath); + + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_addr; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + // printf("\n"); + printf("libdbuscgpw method call teec fin contex sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + + // printf("\n"); + printf("libdbuscgpw method call teec fin contex sent. \n"); + + dbus_error_init(&err); + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: finalizecontext send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: finalizecontext dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + if (*context_tapath_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + } + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + printf("libdbuscgpw got reply of method call teec fin contex: \n"); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); + if ((int) *context_tapath_outsize > 0 && context_tapath_temp != NULL && + dbus_validate_path((const char *) context_tapath_temp, &err) == true) + { + printf(" ta_path = %s \n", context_tapath_temp); + } +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); +#endif + + if ( + context_tapath_insize > *context_tapath_outsize && + *context_tapath_outsize > 0 && + context_tapath != NULL && + context_tapath_temp != NULL + ) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + // dbus_message_unref(msg); + // return -1; + *(context_tapath + 0) = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +int32_t +method_call_teec_opensession( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, + size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t in_destination_timelow, + uint32_t in_destination_timemid, + uint32_t in_destination_timehiandver, + uint32_t *in_destination_clockseqandnode, + int32_t in_destination_clockseqandnode_size, + + uint32_t in_connectionmethod, + uint64_t in_connectiondata, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint64_t in_context_addr, + + + uint32_t *teecresult, + + int32_t *context_fd, + uint8_t *context_tapath, + size_t context_tapath_size, + uint32_t *context_tapath_outsize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + unsigned char *context_tapath_temp = NULL; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_int64_t di64Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_OpenSession" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + di32Temp = in_context_fd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_context_tapath_size > 0 && + in_context_tapath != NULL && + strlen((const char *) in_context_tapath) > 0 + ) + { + if (dbus_validate_utf8((const char *) in_context_tapath, &err) == true) + { + di32Temp = strlen((const char *) in_context_tapath); + } else + { + di32Temp = 0; + } + } else + { + di32Temp = 0; + } + + // fprintf(stderr, "in_context_tapath_size = %ld \n", in_context_tapath_size); + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + // if (in_context_tapath_size > 0 && in_context_tapath != NULL) + if (di32Temp > 0) + { + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_STRING, + &in_context_tapath + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + } + + dui64Temp = in_context_sessionlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sessionlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_shrdmemlist_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_sharebuffer_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di64Temp = in_context_sharebuffer_bufferbarrier; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT64, + &di64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_destination_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_destination_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_destination_clockseqandnode_size > 0 && + in_destination_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_destination_clockseqandnode, + in_destination_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_connectionmethod; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_connectiondata; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = in_operation_started; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_paramtypes; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param1_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param2_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param3_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param4_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_session; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_cancelflag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_returnorigin; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_context_addr; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + /////////////////////////////////////////////////////////////////// + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Open Session Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + // printf("\n"); + printf("libdbuscgpw method call teec open session sent. \n"); + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: opensession send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: opensession dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *context_fd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *context_tapath_outsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + if (*context_tapath_outsize > 0) + { + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_STRING + ) + { + fprintf(stderr, "Argument is not STRING.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &context_tapath_temp); + + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sessionlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_shrdmemlist_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *context_sharebuffer_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT64 + ) + { + fprintf(stderr, "Argument is not INT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di64Temp + ); + *context_sharebuffer_bufferbarrier = di64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_seesionid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + } + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_started = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_paramtypes = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param1_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param2_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param3_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_memref_parent = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param4_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_session = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_cancelflag = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *returnorigin = dui32Temp; + + printf("libdbuscgpw got reply of method call teec open session: \n"); + printf(" teecresult = 0x %8.8x \n", *teecresult); + printf(" fd = 0x %8.8x \n", (unsigned int) *context_fd); + printf(" ta_path = %s \n", context_tapath_temp); + printf(" ta_path_size = %d \n", (int) *context_tapath_outsize); + printf(" session_seesionid = 0x %8.8x \n", + *session_seesionid + ); +#if 0 + printf(" TEEC_Context session_list.next = 0x %16.16lx \n", + *context_sessionlist_next + ); + printf(" TEEC_Context session_list.prev = 0x %16.16lx \n", + *context_sessionlist_prev + ); + printf(" TEEC_Context shrd_mem_list.next = 0x %16.16lx \n", + *context_shrdmemlist_next + ); + printf(" TEEC_Context shrd_mem_list.prev = 0x %16.16lx \n", + *context_shrdmemlist_prev + ); + printf(" TEEC_Context share_buffer.buffer = 0x %16.16lx \n", + *context_sharebuffer_buffer + ); + printf(" TEEC_Context share_buffer.buffer_barrier = 0x %16.16lx \n", + (long unsigned int)*context_sharebuffer_bufferbarrier + ); + + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + if (*session_serviceid_clockseqandnode_outsize > 0 && + session_serviceid_clockseqandnode_temp != NULL) + { + printf(" "); + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + } + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session operation_started = 0x %8.8x \n", + *operation_started + ); + printf(" TEEC_Session operation_paramtypes = 0x %8.8x \n", + *operation_paramtypes + ); + + printf(" TEEC_Session operation_param1_tmpref_buffer = 0x %16.16lx \n", + *operation_param1_tmpref_buffer + ); + printf(" TEEC_Session operation_param1_tmpref_size = 0x %8.8x \n", + *operation_param1_tmpref_size + ); + printf(" TEEC_Session operation_param1_memref_parent = 0x %16.16lx \n", + *operation_param1_memref_parent + ); + printf(" TEEC_Session operation_param1_memref_size = 0x %8.8x \n", + *operation_param1_memref_size + ); + printf(" TEEC_Session operation_param1_memref_offse = 0x %8.8x \n", + *operation_param1_memref_offset + ); + printf(" TEEC_Session operation_param1_value_a = 0x %8.8x \n", + *operation_param1_value_a + ); + printf(" TEEC_Session operation_param1_value_b = 0x %8.8x \n", + *operation_param1_value_b + ); + printf(" TEEC_Session operation_param1_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param1_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param1_ionref_ionsize = 0x %8.8x \n", + *operation_param1_ionref_ionsize + ); + + printf(" TEEC_Session operation_param2_tmpref_buffer = 0x %16.16lx \n", + *operation_param2_tmpref_buffer + ); + printf(" TEEC_Session operation_param2_tmpref_size = 0x %8.8x \n", + *operation_param2_tmpref_size + ); + printf(" TEEC_Session operation_param2_memref_parent = 0x %16.16lx \n", + *operation_param2_memref_parent + ); + printf(" TEEC_Session operation_param2_memref_size = 0x %8.8x \n", + *operation_param2_memref_size + ); + printf(" TEEC_Session operation_param2_memref_offset = 0x %8.8x \n", + *operation_param2_memref_offset + ); + printf(" TEEC_Session operation_param2_value_a = 0x %8.8x \n", + *operation_param2_value_a + ); + printf(" TEEC_Session operation_param2_value_b = 0x %8.8x \n", + *operation_param2_value_b + ); + printf(" TEEC_Session operation_param2_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param2_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param2_ionref_ionsize = 0x %8.8x \n", + *operation_param2_ionref_ionsize + ); + + printf(" TEEC_Session operation_param3_tmpref_buffer = 0x %16.16lx \n", + *operation_param3_tmpref_buffer + ); + printf(" TEEC_Session operation_param3_tmpref_size = 0x %8.8x \n", + *operation_param3_tmpref_size + ); + printf(" TEEC_Session operation_param3_memref_parent = 0x %16.16lx \n", + *operation_param3_memref_parent + ); + printf(" TEEC_Session operation_param3_memref_size = 0x %8.8x \n", + *operation_param3_memref_size + ); + printf(" TEEC_Session operation_param3_memref_offset = 0x %8.8x \n", + *operation_param3_memref_offset + ); + printf(" TEEC_Session operation_param3_value_a = 0x %8.8x \n", + *operation_param3_value_a + ); + printf(" TEEC_Session operation_param3_value_b = 0x %8.8x \n", + *operation_param3_value_b + ); + printf(" TEEC_Session operation_param3_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param3_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param3_ionref_ionsize = 0x %8.8x \n", + *operation_param3_ionref_ionsize + ); + + printf(" TEEC_Session operation_param4_tmpref_buffer = 0x %16.16lx \n", + *operation_param4_tmpref_buffer + ); + printf(" TEEC_Session operation_param4_tmpref_size = 0x %8.8x \n", + *operation_param4_tmpref_size + ); + printf(" TEEC_Session operation_param4_memref_parent = 0x %16.16lx \n", + *operation_param4_memref_parent + ); + printf(" TEEC_Session operation_param4_memref_size = 0x %8.8x \n", + *operation_param4_memref_size + ); + printf(" TEEC_Session operation_param4_memref_offset = 0x %8.8x \n", + *operation_param4_memref_offset + ); + printf(" TEEC_Session operation_param4_value_a = 0x %8.8x \n", + *operation_param4_value_a + ); + printf(" TEEC_Session operation_param4_value_b = 0x %8.8x \n", + *operation_param4_value_b + ); + printf(" TEEC_Session operation_param4_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param4_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param4_ionref_ionsize = 0x %8.8x \n", + *operation_param4_ionref_ionsize + ); + + printf(" TEEC_Session operation_session = 0x %16.16lx \n", + *operation_session + ); + printf(" TEEC_Session operation_cancelflag = 0x %8.8x \n", + (unsigned int)*operation_cancelflag + ); + printf(" TEEC_Session returnorigin = 0x %8.8x \n", + *returnorigin + ); +#endif + + if (context_tapath_size > *context_tapath_outsize) + { + memcpy(context_tapath, context_tapath_temp, *context_tapath_outsize); + *(context_tapath + *context_tapath_outsize) = 0; + } else + { + dbus_message_unref(msg); + return -1; + } + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + /* + memcpy( + session_serviceid_clockseqandnode, + session_serviceid_clockseqandnode_temp, + session_serviceid_clockseqandnode_realsize + ); + */ + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) + { + session_serviceid_clockseqandnode[i] = + session_serviceid_clockseqandnode_temp[i]; + + } + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +int32_t +method_call_teec_closesession( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + int32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_CloseSession" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + dui32Temp = in_session_seesionid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_session_serviceid_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_session_serviceid_clockseqandnode_size > 0 && + in_session_serviceid_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_session_opscnt; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui64Temp = in_session_head_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_context; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Close Session Sent. \n"); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + // printf("\n"); + printf("libdbuscgpw method call teec close session sent. \n"); + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: closesession send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: closesession dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_seesionid = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + } + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + + printf("libdbuscgpw got reply of method call teec close session: \n"); + printf(" session_seesionid = 0x %8.8x \n", + *session_seesionid + ); +#if 0 + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timemid = 0x %8.8x \n", + *session_serviceid_timemid + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + printf(" "); + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); +#endif + printf(" session_context = 0x %16.16lx \n", + *session_context + ); + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + memcpy( + session_serviceid_clockseqandnode, + session_serviceid_clockseqandnode_temp, + session_serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +int32_t +method_call_teec_invokecommand( + const char *workername, + + uint32_t in_session_sessionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + uint32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t commandid, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_parent_flag, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_parent_flag, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_parent_flag, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_parent_flag, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint32_t *in_buffer1, + uint32_t in_buffer1_size, + uint32_t *in_buffer2, + uint32_t in_buffer2_size, + uint32_t *in_buffer3, + uint32_t in_buffer3_size, + uint32_t *in_buffer4, + uint32_t in_buffer4_size, + + + uint32_t *teecresult, + + uint32_t *session_sessionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_parent_flag, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_parent_flag, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_parent_flag, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_parent_flag, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin, + + uint32_t *buffer1, + uint32_t buffer1_size, + uint32_t *buffer1_outsize, + uint32_t *buffer2, + uint32_t buffer2_size, + uint32_t *buffer2_outsize, + uint32_t *buffer3, + uint32_t buffer3_size, + uint32_t *buffer3_outsize, + uint32_t *buffer4, + uint32_t buffer4_size, + uint32_t *buffer4_outsize +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + DBusMessageIter structIter; + DBusMessageIter ArrayIter; + int ret; + int iType; + dbus_uint32_t *session_serviceid_clockseqandnode_temp = NULL; + int session_serviceid_clockseqandnode_realsize; + dbus_int32_t di32Temp; + dbus_uint32_t dui32Temp; + dbus_uint64_t dui64Temp; + char buf[2]; + buf[0] = DBUS_TYPE_UINT32; + buf[1] = '\0'; + + dbus_uint32_t *buffer1_temp = NULL; + int buffer1_realsize; + dbus_uint32_t *buffer2_temp = NULL; + int buffer2_realsize; + dbus_uint32_t *buffer3_temp = NULL; + int buffer3_realsize; + dbus_uint32_t *buffer4_temp = NULL; + int buffer4_realsize; + + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return -1; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return -1; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "TEEC_InvokeCommand" + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return -1; + } + + + // append arguments + dbus_message_iter_init_append(msg, &args); + dbus_message_iter_open_container( + &args, + DBUS_TYPE_STRUCT, + NULL, + &structIter + ); + + + dui32Temp = in_session_sessionid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timelow; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timemid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_timehiandver; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_session_serviceid_clockseqandnode_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_session_serviceid_clockseqandnode_size > 0 && + in_session_serviceid_clockseqandnode != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_session_opscnt; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_next; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_head_prev; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_session_context; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = commandid; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + + dui32Temp = in_operation_started; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_paramtypes; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param1_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param1_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param1_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param2_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param2_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param2_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param3_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param3_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param3_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_tmpref_buffer; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_tmpref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_param4_memref_parent; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_parent_flag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_memref_offset; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_a; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_value_b; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_param4_ionref_ionsharefd; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_operation_param4_ionref_ionsize; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui64Temp = in_operation_session; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT64, + &dui64Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + di32Temp = in_operation_cancelflag; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_INT32, + &di32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_returnorigin; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dui32Temp = in_buffer1_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer1_size > 0 && + in_buffer1 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer1, + in_buffer1_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer2_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer2_size > 0 && + in_buffer2 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer2, + in_buffer2_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer3_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer3_size > 0 && + in_buffer3 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer3, + in_buffer3_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dui32Temp = in_buffer4_size; + bResult = + dbus_message_iter_append_basic( + &structIter, + DBUS_TYPE_UINT32, + &dui32Temp + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + if (in_buffer4_size > 0 && + in_buffer4 != NULL) + { + dbus_message_iter_open_container( + &structIter, + DBUS_TYPE_ARRAY, + buf, + &ArrayIter + ); + + bResult = + dbus_message_iter_append_fixed_array( + &ArrayIter, + DBUS_TYPE_UINT32, + &in_buffer4, + in_buffer4_size + ); + if (!bResult) + { + fprintf(stderr, "Out Of Memory!\n"); + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + dbus_message_iter_close_container( + &args, + &structIter + ); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_close_container( + &structIter, + &ArrayIter + ); + } + + dbus_message_iter_close_container( + &args, + &structIter + ); + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + dbus_connection_flush(conn); + dbus_message_unref(msg); + return -1; + } + + dbus_connection_flush(conn); + dbus_message_unref(msg); + + printf("\n"); + printf("Method Call Teec Invoke Command Sent. \n"); + + ///////////////////////////////////////////////////////////////////////////////////// + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return -1; + } + + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + // printf("\n"); + printf("libdbuscgpw method call teec invoke command sent. \n"); + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: invokecommand send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: invokecommand dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return -1; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_iter_recurse( + &args, + &structIter + ); + + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *teecresult = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_sessionid = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timelow = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timemid = dui32Temp; + + + bResult = + dbus_message_iter_next( + &structIter + ); + if (!bResult) + { + fprintf(stderr, "Message has too few arguments!\n"); + dbus_message_unref(msg); + return -1; + } + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_timehiandver = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_serviceid_clockseqandnode_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*session_serviceid_clockseqandnode_outsize > 0) + { + + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &session_serviceid_clockseqandnode_temp, + &session_serviceid_clockseqandnode_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *session_opscnt = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_next = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_head_prev = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *session_context = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_started = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_paramtypes = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param1_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param1_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param1_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param2_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param2_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param2_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param3_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param3_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param3_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_tmpref_buffer = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_tmpref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_param4_memref_parent = dui64Temp; + + bResult = dbus_message_iter_next(&structIter); + iType = dbus_message_iter_get_arg_type(&structIter); + if (iType != DBUS_TYPE_UINT32) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_parent_flag = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_size = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_memref_offset = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_a = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_value_b = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_param4_ionref_ionsharefd = di32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *operation_param4_ionref_ionsize = dui32Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT64 + ) + { + fprintf(stderr, "Argument is not UINT64.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui64Temp + ); + *operation_session = dui64Temp; + + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_INT32 + ) + { + fprintf(stderr, "Argument is not INT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &di32Temp + ); + *operation_cancelflag = di32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *returnorigin = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer1_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer1_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer1_temp, + &buffer1_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer2_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer2_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer2_temp, + &buffer2_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer3_outsize = dui32Temp; + bResult = + dbus_message_iter_next( + &structIter + ); + + if (*buffer3_outsize > 0) + { + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer3_temp, + &buffer3_realsize + ); + bResult = + dbus_message_iter_next( + &structIter + ); + } + + iType = + dbus_message_iter_get_arg_type( + &structIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_basic( + &structIter, + &dui32Temp + ); + *buffer4_outsize = dui32Temp; + + if (*buffer4_outsize > 0) + { + bResult = + dbus_message_iter_next( + &structIter + ); + + dbus_message_iter_recurse( + &structIter, + &ArrayIter + ); + + iType = + dbus_message_iter_get_arg_type( + &ArrayIter + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + dbus_message_unref(msg); + return -1; + } + dbus_message_iter_get_fixed_array( + &ArrayIter, + &buffer4_temp, + &buffer4_realsize + ); + } + + + printf("libdbuscgpw got reply of method call teec invoke command: \n"); + printf(" teecresult = 0x %8.8x \n", + *teecresult); + printf(" session_seesionid = 0x %8.8x \n", + *session_sessionid + ); +#if 0 + printf(" TEEC_Session session_serviceid_timelow = 0x %8.8x \n", + *session_serviceid_timelow + ); + printf(" TEEC_Session session_serviceid_timemid = 0x %8.8x \n", + *session_serviceid_timemid + ); + printf(" TEEC_Session session_serviceid_timehiandver = 0x %8.8x \n", + *session_serviceid_timehiandver + ); + printf(" TEEC_Session session_serviceid_clockseqandnode = \n"); + if ( *session_serviceid_clockseqandnode_outsize > 0 && + session_serviceid_clockseqandnode_temp != NULL + ) + { + for (int i = 0; i < session_serviceid_clockseqandnode_realsize; i++) { + printf(" %2.2x", + session_serviceid_clockseqandnode_temp[i] + ); + } + printf("\n"); + } + printf(" TEEC_Session clockseqandnode_outsize = 0x %8.8x \n", + *session_serviceid_clockseqandnode_outsize + ); + printf(" TEEC_Session session_opscnt = 0x %8.8x \n", + *session_opscnt + ); + printf(" TEEC_Session session_head_next = 0x %16.16lx \n", + *session_head_next + ); + printf(" TEEC_Session session_head_prev = 0x %16.16lx \n", + *session_head_prev + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session session_context = 0x %16.16lx \n", + *session_context + ); + printf(" TEEC_Session operation_started = 0x %8.8x \n", + *operation_started + ); + printf(" TEEC_Session operation_paramtypes = 0x %8.8x \n", + *operation_paramtypes + ); + printf(" TEEC_Session operation_param1_tmpref_buffer = 0x %16.16lx \n", + *operation_param1_tmpref_buffer + ); + printf(" TEEC_Session operation_param1_tmpref_size = 0x %8.8x \n", + *operation_param1_tmpref_size + ); + printf(" TEEC_Session operation_param1_memref_parent = 0x %16.16lx \n", + *operation_param1_memref_parent + ); + printf(" TEEC_Session operation_param1_memref_size = 0x %8.8x \n", + *operation_param1_memref_size + ); + printf(" TEEC_Session operation_param1_memref_offse = 0x %8.8x \n", + *operation_param1_memref_offset + ); + printf(" TEEC_Session operation_param1_value_a = 0x %8.8x \n", + *operation_param1_value_a + ); + printf(" TEEC_Session operation_param1_value_b = 0x %8.8x \n", + *operation_param1_value_b + ); + printf(" TEEC_Session operation_param1_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param1_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param1_ionref_ionsize = 0x %8.8x \n", + *operation_param1_ionref_ionsize + ); + + printf(" TEEC_Session operation_param2_tmpref_buffer = 0x %16.16lx \n", + *operation_param2_tmpref_buffer + ); + printf(" TEEC_Session operation_param2_tmpref_size = 0x %8.8x \n", + *operation_param2_tmpref_size + ); + printf(" TEEC_Session operation_param2_memref_parent = 0x %16.16lx \n", + *operation_param2_memref_parent + ); + printf(" TEEC_Session operation_param2_memref_size = 0x %8.8x \n", + *operation_param2_memref_size + ); + printf(" TEEC_Session operation_param2_memref_offset = 0x %8.8x \n", + *operation_param2_memref_offset + ); + printf(" TEEC_Session operation_param2_value_a = 0x %8.8x \n", + *operation_param2_value_a + ); + printf(" TEEC_Session operation_param2_value_b = 0x %8.8x \n", + *operation_param2_value_b + ); + printf(" TEEC_Session operation_param2_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param2_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param2_ionref_ionsize = 0x %8.8x \n", + *operation_param2_ionref_ionsize + ); + + printf(" TEEC_Session operation_param3_tmpref_buffer = 0x %16.16lx \n", + *operation_param3_tmpref_buffer + ); + printf(" TEEC_Session operation_param3_tmpref_size = 0x %8.8x \n", + *operation_param3_tmpref_size + ); + printf(" TEEC_Session operation_param3_memref_parent = 0x %16.16lx \n", + *operation_param3_memref_parent + ); + printf(" TEEC_Session operation_param3_memref_size = 0x %8.8x \n", + *operation_param3_memref_size + ); + printf(" TEEC_Session operation_param3_memref_offset = 0x %8.8x \n", + *operation_param3_memref_offset + ); + printf(" TEEC_Session operation_param3_value_a = 0x %8.8x \n", + *operation_param3_value_a + ); + printf(" TEEC_Session operation_param3_value_b = 0x %8.8x \n", + *operation_param3_value_b + ); + printf(" TEEC_Session operation_param3_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param3_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param3_ionref_ionsize = 0x %8.8x \n", + *operation_param3_ionref_ionsize + ); + + printf(" TEEC_Session operation_param4_tmpref_buffer = 0x %16.16lx \n", + *operation_param4_tmpref_buffer + ); + printf(" TEEC_Session operation_param4_tmpref_size = 0x %8.8x \n", + *operation_param4_tmpref_size + ); + printf(" TEEC_Session operation_param4_memref_parent = 0x %16.16lx \n", + *operation_param4_memref_parent + ); + printf(" TEEC_Session operation_param4_memref_size = 0x %8.8x \n", + *operation_param4_memref_size + ); + printf(" TEEC_Session operation_param4_memref_offset = 0x %8.8x \n", + *operation_param4_memref_offset + ); + printf(" TEEC_Session operation_param4_value_a = 0x %8.8x \n", + *operation_param4_value_a + ); + printf(" TEEC_Session operation_param4_value_b = 0x %8.8x \n", + *operation_param4_value_b + ); + printf(" TEEC_Session operation_param4_ionref_ionsharefd = 0x %8.8x \n", + (unsigned int)*operation_param4_ionref_ionsharefd + ); + printf(" TEEC_Session operation_param4_ionref_ionsize = 0x %8.8x \n", + *operation_param4_ionref_ionsize + ); + + printf(" TEEC_Session operation_session = 0x %16.16lx \n", + *operation_session + ); + printf(" TEEC_Session operation_cancelflag = 0x %8.8x \n", + (unsigned int)*operation_cancelflag + ); + printf(" returnorigin = 0x %8.8x \n", + *returnorigin + ); + + printf(" buffer1 = \n"); + if (buffer1_temp != NULL) + { + for (int i = 0; i < buffer1_realsize; i++) { + printf(" %2.2x", + buffer1_temp[i] + ); + } + printf("\n"); + } + printf(" buffer1_outsize = 0x %8.8x \n", + *buffer1_outsize + ); + + printf(" buffer2 = \n"); + if (buffer2_temp != NULL) + { + for (int i = 0; i < buffer2_realsize; i++) { + printf(" %2.2x", + buffer2_temp[i] + ); + } + printf("\n"); + } + printf(" buffer2_outsize = 0x %8.8x \n", + *buffer2_outsize + ); + + printf(" buffer3 = \n"); + if (buffer3_temp != NULL) + { + for (int i = 0; i < buffer3_realsize; i++) { + printf(" %2.2x", + buffer3_temp[i] + ); + } + printf("\n"); + } + printf(" buffer3_outsize = 0x %8.8x \n", + *buffer3_outsize + ); + + if (buffer4_temp != NULL) + { + printf(" buffer4 = \n"); + for (int i = 0; i < buffer4_realsize; i++) { + printf(" %2.2x", + buffer4_temp[i] + ); + } + printf("\n"); + } + printf(" buffer4_outsize = 0x %8.8x \n", + *buffer4_outsize + ); +#endif + + if (session_serviceid_clockseqandnode_size >= session_serviceid_clockseqandnode_realsize && + session_serviceid_clockseqandnode != NULL && + session_serviceid_clockseqandnode_temp != NULL && + session_serviceid_clockseqandnode_realsize > 0 + ) + { + memcpy( + session_serviceid_clockseqandnode, + session_serviceid_clockseqandnode_temp, + session_serviceid_clockseqandnode_realsize * sizeof(uint32_t) + ); + *session_serviceid_clockseqandnode_outsize = session_serviceid_clockseqandnode_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *session_serviceid_clockseqandnode_outsize = 0; + } + + if (buffer1_size >= (uint32_t) buffer1_realsize && + buffer1 != NULL && + buffer1_temp != NULL && + buffer1_realsize > 0 + ) + { + memcpy( + buffer1, + buffer1_temp, + buffer1_realsize * sizeof(uint32_t) + ); + *buffer1_outsize = buffer1_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer1_outsize = 0; + } + + if (buffer2_size >= (uint32_t) buffer2_realsize && + buffer2 != NULL && + buffer2_temp != NULL && + buffer2_realsize > 0 + ) + { + memcpy( + buffer2, + buffer2_temp, + buffer2_realsize * sizeof(uint32_t) + ); + *buffer2_outsize = buffer2_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer2_outsize = 0; + } + + if (buffer3_size >= (uint32_t) buffer3_realsize && + buffer3 != NULL && + buffer3_temp != NULL && + buffer3_realsize > 0 + ) + { + memcpy( + buffer3, + buffer3_temp, + buffer3_realsize * sizeof(uint32_t) + ); + *buffer3_outsize = buffer3_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer3_outsize = 0; + } + + if (buffer4_size >= (uint32_t) buffer4_realsize && + buffer4 != NULL && + buffer4_temp != NULL && + buffer4_realsize > 0 + ) + { + memcpy( + buffer4, + buffer4_temp, + buffer4_realsize * sizeof(uint32_t) + ); + *buffer4_outsize = buffer4_realsize; + } else + { + // dbus_message_unref(msg); + // return -1; + *buffer4_outsize = 0; + } + + + // free msg + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); + + return 0; +} + + +/** + * Call a method on a remote object + */ +void +method_call_destroy_threadpool( + const char *workername +) +{ + DBusConnection *conn = NULL; + DBusMessage *msg; + DBusMessageIter args; + // DBusConnection* conn; + DBusError err; + DBusPendingCall *pending; + dbus_bool_t bResult; + int ret; + int iType; + unsigned char name[] = "threadpool"; + unsigned char *charp; + dbus_uint32_t retcode; + + // initialiset the errors + dbus_error_init(&err); + + char dbusname[1024]; + if (conn == NULL) + { + // connect to the system bus and check for errors + conn = dbus_bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Connection Error (%s)\n", err.message); + dbus_error_free(&err); + } + if (NULL == conn) + { + return; + } + + memset((uint8_t *) dbusname, 0, 1024); + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t u64time = (long unsigned int) (tv.tv_sec * 1000000 + tv.tv_usec); + srand(u64time); + sprintf(dbusname, + "%s.method.caller%16.16lx%16.16lx", + workername, + u64time, + (long unsigned int) rand() + ); + // request our name on the bus + ret = + dbus_bus_request_name( + conn, + dbusname, + DBUS_NAME_FLAG_REPLACE_EXISTING, + &err + ); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "Name Error (%s)\n", err.message); + dbus_error_free(&err); + dbus_connection_flush(conn); + } + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) + { + dbus_connection_flush(conn); + return; + } + } + + // create a new method call and check for errors + char objname[1024]; + char interfacename[1024]; + memset((uint8_t *) dbusname, 0, 1024); + sprintf(dbusname, "%s.method.server", workername); + memset((uint8_t *) objname, 0, 1024); + sprintf(objname, "/%s/method/Object", workername); + memset((uint8_t *) interfacename, 0, 1024); + sprintf(interfacename, "%s.method.Type", workername); + msg = + dbus_message_new_method_call( + // "test.method.server", // target for the method call + dbusname, + // "/test/method/Object", // object to call on + objname, + // "test.method.Type", // interface to call on + interfacename, + "Destroy" // method name + ); + if (NULL == msg) + { + fprintf(stderr, "Message Null\n"); + dbus_connection_flush(conn); + return; + } + + // append arguments + dbus_message_iter_init_append(msg, &args); + + charp = name; + if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &charp)) + { + fprintf(stderr, "Out Of Memory!\n"); + return; + } + + /* + // send message and get a handle for a reply + if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) + { // -1 is default timeout + fprintf(stderr, "Out Of Memory!\n"); + return; + } + if (NULL == pending) + { + fprintf(stderr, "Pending Call Null\n"); + return; + } + dbus_connection_flush(conn); + + printf("\n"); + printf("Method Call Destroy Threadpool Sent. \n"); + + // free message + dbus_message_unref(msg); + + // block until we recieve a reply + dbus_pending_call_block(pending); + + // get the reply message + msg = dbus_pending_call_steal_reply(pending); + if (NULL == msg) + { + fprintf(stderr, "Reply Null\n"); + return; + } + // free the pending message handle + dbus_pending_call_unref(pending); + */ + + // printf("\n"); + printf("libdbuscgpw method call destroygpw sent. \n"); + + DBusMessage *reply; + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err); + if (dbus_error_is_set(&err)) + { + fprintf(stderr, "libdbuscgpw: destroygpw send_with_reply_and_block error, %s \n", err.message); + dbus_error_free(&err); + + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return; + } + if (reply == NULL) + { + fprintf(stderr, "libdbuscgpw: destroygpw dbus reply error \n"); + dbus_message_unref(msg); + dbus_connection_flush(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + return; + } + + dbus_message_unref(msg); + dbus_connection_flush(conn); + msg = reply; + + // read the parameters + bResult = + dbus_message_iter_init( + msg, + &args + ); + if (!bResult) + { + fprintf(stderr, "Message has no arguments!\n"); + return; + } + + iType = + dbus_message_iter_get_arg_type( + &args + ); + if ( + iType != DBUS_TYPE_UINT32 + ) + { + fprintf(stderr, "Argument is not UINT32.\n"); + return; + } + dbus_message_iter_get_basic( + &args, + &retcode + ); + + printf("libdbusgpw got reply of method call destroygpw: \n"); + printf(" retcode = 0x%8x \n", retcode); + + // free reply + dbus_message_unref(msg); + + dbus_connection_close(conn); + dbus_connection_unref(conn); +} diff --git a/teeproxy/libdbuscgpw/dbusc_gpw.h b/teeproxy/libdbuscgpw/dbusc_gpw.h new file mode 100644 index 0000000..714c08c --- /dev/null +++ b/teeproxy/libdbuscgpw/dbusc_gpw.h @@ -0,0 +1,406 @@ +#ifndef _DBUSC_GPW_H_ +#define _DBUSC_GPW_H_ + +#include +#include + + +void +receive_signal(void); + +void +send_signal( + char *sigvalue +); + +int32_t +method_call_teec_inicont( + const char *workername, + + const uint8_t *name, size_t name_size, + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t *teecresult, + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint64_t *context_addr, + uint32_t *context_tapath_outsize +); + +int32_t +method_call_teec_fincont( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint64_t in_context_addr, + + int32_t *context_fd, + uint8_t *context_tapath, size_t context_tapath_insize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + uint32_t *context_tapath_outsize +); + +int32_t +method_call_teec_opensession( + const char *workername, + + int32_t in_context_fd, + const uint8_t *in_context_tapath, + size_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + + uint32_t in_destination_timelow, + uint32_t in_destination_timemid, + uint32_t in_destination_timehiandver, + uint32_t *in_destination_clockseqandnode, + int32_t in_destination_clockseqandnode_size, + uint32_t in_connectionmethod, + uint64_t in_connectiondata, + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint64_t in_context_addr, + + + uint32_t *teecresult, + + int32_t *context_fd, + uint8_t *context_tapath, + size_t context_tapath_size, + uint32_t *context_tapath_outsize, + uint64_t *context_sessionlist_next, + uint64_t *context_sessionlist_prev, + uint64_t *context_shrdmemlist_next, + uint64_t *context_shrdmemlist_prev, + uint64_t *context_sharebuffer_buffer, + int64_t *context_sharebuffer_bufferbarrier, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin +); + +int32_t +method_call_teec_closesession( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + int32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context +); + +int32_t +method_call_teec_invokecommand( + const char *workername, + + uint32_t in_session_seesionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint32_t *in_session_serviceid_clockseqandnode, + uint32_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + + uint32_t commandid, + + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_parent_flag, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_parent_flag, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_parent_flag, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_parent_flag, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + + uint32_t in_returnorigin, + + uint32_t *in_buffer1, + uint32_t in_buffer1_size, + uint32_t *in_buffer2, + uint32_t in_buffer2_size, + uint32_t *in_buffer3, + uint32_t in_buffer3_size, + uint32_t *in_buffer4, + uint32_t in_buffer4_size, + + + uint32_t *teecresult, + + uint32_t *session_seesionid, + uint32_t *session_serviceid_timelow, + uint32_t *session_serviceid_timemid, + uint32_t *session_serviceid_timehiandver, + uint32_t *session_serviceid_clockseqandnode, + int32_t session_serviceid_clockseqandnode_size, + uint32_t *session_serviceid_clockseqandnode_outsize, + uint32_t *session_opscnt, + uint64_t *session_head_next, + uint64_t *session_head_prev, + uint64_t *session_context, + + uint32_t *operation_started, + uint32_t *operation_paramtypes, + + uint64_t *operation_param1_tmpref_buffer, + uint32_t *operation_param1_tmpref_size, + uint64_t *operation_param1_memref_parent, + uint32_t *operation_param1_memref_parent_flag, + uint32_t *operation_param1_memref_size, + uint32_t *operation_param1_memref_offset, + uint32_t *operation_param1_value_a, + uint32_t *operation_param1_value_b, + int32_t *operation_param1_ionref_ionsharefd, + uint32_t *operation_param1_ionref_ionsize, + + uint64_t *operation_param2_tmpref_buffer, + uint32_t *operation_param2_tmpref_size, + uint64_t *operation_param2_memref_parent, + uint32_t *operation_param2_memref_parent_flag, + uint32_t *operation_param2_memref_size, + uint32_t *operation_param2_memref_offset, + uint32_t *operation_param2_value_a, + uint32_t *operation_param2_value_b, + int32_t *operation_param2_ionref_ionsharefd, + uint32_t *operation_param2_ionref_ionsize, + + uint64_t *operation_param3_tmpref_buffer, + uint32_t *operation_param3_tmpref_size, + uint64_t *operation_param3_memref_parent, + uint32_t *operation_param3_memref_parent_flag, + uint32_t *operation_param3_memref_size, + uint32_t *operation_param3_memref_offset, + uint32_t *operation_param3_value_a, + uint32_t *operation_param3_value_b, + int32_t *operation_param3_ionref_ionsharefd, + uint32_t *operation_param3_ionref_ionsize, + + uint64_t *operation_param4_tmpref_buffer, + uint32_t *operation_param4_tmpref_size, + uint64_t *operation_param4_memref_parent, + uint32_t *operation_param4_memref_parent_flag, + uint32_t *operation_param4_memref_size, + uint32_t *operation_param4_memref_offset, + uint32_t *operation_param4_value_a, + uint32_t *operation_param4_value_b, + int32_t *operation_param4_ionref_ionsharefd, + uint32_t *operation_param4_ionref_ionsize, + + uint64_t *operation_session, + int32_t *operation_cancelflag, + + uint32_t *returnorigin, + + uint32_t *buffer1, + uint32_t buffer1_size, + uint32_t *buffer1_outsize, + uint32_t *buffer2, + uint32_t buffer2_size, + uint32_t *buffer2_outsize, + uint32_t *buffer3, + uint32_t buffer3_size, + uint32_t *buffer3_outsize, + uint32_t *buffer4, + uint32_t buffer4_size, + uint32_t *buffer4_outsize +); + +void +method_call_destroy_threadpool( + const char *workername +); + +#endif /* _DBUSC_GPW_H_ */ diff --git a/teeproxy/libteecc/CMakeLists.txt b/teeproxy/libteecc/CMakeLists.txt new file mode 100644 index 0000000..d27d391 --- /dev/null +++ b/teeproxy/libteecc/CMakeLists.txt @@ -0,0 +1,119 @@ +# +# + +cmake_minimum_required(VERSION 3.5.1) + +project(teecc C CXX) + +include(common.cmake) + +# Proto file +get_filename_component(gt_proto "./protos/gt.proto" ABSOLUTE) +get_filename_component(gt_proto_path "${gt_proto}" PATH) +# [[get_filename_component(proto "../protos/${proto_name}.proto" ABSOLUTE) +# get_filename_component(proto_dir "${proto}" DIRECTORY)]] + +# Generated sources +set(gt_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/gt.pb.cc") +set(gt_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gt.pb.h") +set(gt_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/gt.grpc.pb.cc") +set(gt_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/gt.grpc.pb.h") + +add_custom_command( + OUTPUT "${gt_proto_srcs}" "${gt_proto_hdrs}" "${gt_grpc_srcs}" "${gt_grpc_hdrs}" + COMMAND ${_PROTOBUF_PROTOC} + ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" + --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" + -I "${gt_proto_path}" + --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" + "${gt_proto}" + DEPENDS "${gt_proto}" +) + +# Include generated *.pb.h files +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +include_directories(/usr/include/dbus-1.0/) +include_directories(/usr/lib64/dbus-1.0/include/) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../include) + +# Introduce variables: +# - CMAKE_INSTALL_LIBDIR +# - CMAKE_INSTALL_BINDIR +# - CMAKE_INSTALL_INCLUDEDIR +include(GNUInstallDirs) + + +set(TEECC_NAME "teecc") +set(LIB_TEECC + ${PROJECT_SOURCE_DIR}/teecc.cc + ${gt_grpc_srcs} + ${gt_proto_srcs} +) +# Install Headers: +set(HEADERS_TEECC + ${PROJECT_SOURCE_DIR}/include/teecc/teec_client_api.h + ${PROJECT_SOURCE_DIR}/include/teecc/tee_client_constants.h + ${PROJECT_SOURCE_DIR}/include/teecc/tee_client_list.h + ${PROJECT_SOURCE_DIR}/include/teecc/tee_client_log.h + ${PROJECT_SOURCE_DIR}/include/teecc/tee_client_type.h +) +install( + FILES ${HEADERS_TEECC} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${TEECC_NAME}/${TARGET_NAME}" +) + + +# gt_grpc_proto +add_library(gt_grpc_proto + ${gt_grpc_srcs} + ${gt_grpc_hdrs} + ${gt_proto_srcs} + ${gt_proto_hdrs} +) +target_link_libraries(gt_grpc_proto + ${_REFLECTION} + ${_GRPC_GRPCPP} + ${_PROTOBUF_LIBPROTOBUF} +) + + + +add_library(teecc SHARED + ${LIB_TEECC} +) +target_link_libraries(teecc + gt_grpc_proto + ${_REFLECTION} + ${_GRPC_GRPCPP} + ${_PROTOBUF_LIBPROTOBUF} + yaml-cpp.a +) + +# Install lib +install( + TARGETS "teecc" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +) +# Install config file +set(teecc_config_dir "$ENV{HOME}/.teecc") +# install( +# DIRECTORY +# DESTINATION ${gpp_config_dir}) +install( + FILES "conf/teecc_config.yaml" + DESTINATION ${teecc_config_dir} +) +# Install certs +set(teecc_certs_dir "$ENV{HOME}/.teecc/certs") +install( + FILES + "certs/ca_crt.pem" + "certs/client_key.pem" + "certs/client_crt.pem" + "certs/gen_client_keycsr.sh" + "certs/msg.txt" + "certs/check_ca_crt.sh" + "certs/check_client_key.sh" + "certs/check_client_crt.sh" + DESTINATION ${teecc_certs_dir} +) diff --git a/teeproxy/libteecc/build/cmake.sh b/teeproxy/libteecc/build/cmake.sh new file mode 100644 index 0000000..4511f00 --- /dev/null +++ b/teeproxy/libteecc/build/cmake.sh @@ -0,0 +1,3 @@ +# cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=$MY_INSTALL_DIR .. +cmake -DCMAKE_BUILD_TYPE=Debug .. + diff --git a/teeproxy/libteecc/certs/ca_crt.pem b/teeproxy/libteecc/certs/ca_crt.pem new file mode 100644 index 0000000..c1f851a --- /dev/null +++ b/teeproxy/libteecc/certs/ca_crt.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDozCCAougAwIBAgIUZoRrQX6TrtP0Reyf9DbHVJRNDoQwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUh1YmVpMQ4wDAYDVQQHDAVXdWhh +bjESMBAGA1UECgwJVHJ1c3RDdXRlMQ0wCwYDVQQLDARnUlBDMQ8wDQYDVQQDDAZj +YS5vcmcwHhcNMjIwODIwMDQ1OTUyWhcNMzIwODE3MDQ1OTUyWjBhMQswCQYDVQQG +EwJDTjEOMAwGA1UECAwFSHViZWkxDjAMBgNVBAcMBVd1aGFuMRIwEAYDVQQKDAlU +cnVzdEN1dGUxDTALBgNVBAsMBGdSUEMxDzANBgNVBAMMBmNhLm9yZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMYdYD9GChLzSOWmaIcHMqx8itp/7Zvx +7y2qgb23EWCWIz01kPQaCXpuSOi38dFipXFBWo5o3GaezIoSCp66eN3kHGpcluu2 +0nbyh7zdUVCSXhNWbEiwlhC53DDs2SBYWr2KGTRDEcJEXli110v8sEGZQvkj3XGF +B6IbTczMbhpVfJ82RMqGqNYSJ5jCvqw3XOX6xoN4CP3PuAKC6MtEkLLkXQOS72oL +TSE9XoZNqlyhmymAVwQwCV1zT28W/hwKbCN4tVoO+1bwc3togNYO0W7x1GgOoNoZ +va1UNDX1sfW6B041TgSTGQ0OhGzgKWadKHm2UpG2d5NLkaiBUPpvuokCAwEAAaNT +MFEwHQYDVR0OBBYEFKrFU5qoBe2AkvvTiOfwY24T36zTMB8GA1UdIwQYMBaAFKrF +U5qoBe2AkvvTiOfwY24T36zTMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACjfqOa6G596NbFfAAhBFFS+RIueRWdDkBxR7kk+eQ3Z5j4hIBmrA0OS +R6KCrvmvnXxqSBRmuwRfs0e7G76jkUAFFHkslTPLwgklWCarsGXeAkrdgQU7WL4n +NYBNnjUNK11JREUdAXgvzyuLOhjf4l5UvhujWivhviChFB8xpTQfq2d1oE9jsotv +r2opic4ynu69LXd8HZiShabXgQ60/BNOX8D+wb1YzoZlUCKzSH15QRuuEbkj4/Hy +R2+qxUODbuwfqI4fkOvQIIrD2NO89nHpWFtui4ByQEQaeTesus8M8corCekrxr08 +VkxuOGg2U3zWUlLuSZMD2G7KWuDXU78= +-----END CERTIFICATE----- diff --git a/teeproxy/libteecc/certs/check_ca_crt.sh b/teeproxy/libteecc/certs/check_ca_crt.sh new file mode 100644 index 0000000..83cffa1 --- /dev/null +++ b/teeproxy/libteecc/certs/check_ca_crt.sh @@ -0,0 +1,42 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the cert expiry date in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# CACRTPEM=$HOME/.gpp/certs/ca_crt.pem +# REGENCRTSCRIPT=${HOME}/gen_ca_crt.sh +CUR_DIR=$( dirname -- "$0"; ) +CACRTPEM=$CUR_DIR/ca_crt.pem +REGENCRTSCRIPT=${CUR_DIR}/gen_ca_crt.sh + +# 7 days in seconds +DAYS="604800" + +# Email settings +_sub=$CACRTPEM" will expire within $DAYS seconds (7 days)" +# _sub="${CACRTPEM} will expire within $DAYS seconds (7 days)" +_from="system-account@your-dommain" +_to="sysadmin@your-domain" + +echo -e '\n'get date of $CACRTPEM: +openssl x509 -in $CACRTPEM -noout -dates + +echo -e '\n'check expiry of $CACRTPEM: +$_openssl x509 -enddate -noout -in "$CACRTPEM" -checkend "$DAYS" +$_openssl x509 -enddate -noout -in "$CACRTPEM" -checkend "$DAYS" | grep -q 'Certificate will expire' +# If will expire, regenerate key and certifcate +# // , and send email +if [ $? -eq 0 ] +then + echo "${_sub}" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${REGENCRTSCRIPT} +fi diff --git a/teeproxy/libteecc/certs/check_client_crt.sh b/teeproxy/libteecc/certs/check_client_crt.sh new file mode 100644 index 0000000..769041a --- /dev/null +++ b/teeproxy/libteecc/certs/check_client_crt.sh @@ -0,0 +1,43 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the cert expiry date in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# CRTPEM=$HOME/.gpp/certs/client_crt.pem +# REGENCRTSCRIPT=${HOME}/gen_client_crt.sh +CUR_DIR=$( dirname -- "$0"; ) +CRTPEM=$CUR_DIR/client_crt.pem +REGENCRTSCRIPT=${CUR_DIR}/gen_client_crt.sh + +# 7 days in seconds +DAYS="604800" + +# Email settings +_sub=$CRTPEM" will expire within $DAYS seconds (7 days)" +# _sub="${CRTPEM} will expire within $DAYS seconds (7 days)" +_from="system-account@your-dommain" +_to="sysadmin@your-domain" + + +echo -e '\n'get date of $CRTPEM: +openssl x509 -in $CRTPEM -noout -dates + +echo -e '\n'check expiry of $CRTPEM: +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" +$_openssl x509 -enddate -noout -in "$CRTPEM" -checkend "$DAYS" | grep -q 'Certificate will expire' +# If will expire, regenerate key and certifcate +# // , and send email +if [ $? -eq 0 ] +then + echo "${_sub}" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${REGENCRTSCRIPT} +fi diff --git a/teeproxy/libteecc/certs/check_client_key.sh b/teeproxy/libteecc/certs/check_client_key.sh new file mode 100644 index 0000000..c62d32c --- /dev/null +++ b/teeproxy/libteecc/certs/check_client_key.sh @@ -0,0 +1,62 @@ +#! /bin/sh +# Purpose: Alert sysadmin/developer about the interity of key in advance +# Author: under license +# ------------------------------------------------------------------------------- + + +_openssl="openssl" + + +# KEYPEM=$HOME/.gpp/certs/client_key.pem +# PUBPEM=$HOME/.gpp/certs/client_pubkey.pem +# CRTPEM=$HOME/.gpp/certs/client_crt.pem +# MSGTXT=$HOME/.gpp/certs/msg.txt +# MSGSIG=$HOME/.gpp/certs/msg.sig +# GENKEYCRTSCRIPT=${HOME}/.gpp/certs/gen_client_keycrt.sh +CUR_DIR=$( dirname -- "$0"; ) +KEYPEM=$CUR_DIR/client_key.pem +PUBPEM=$CUR_DIR/client_pubkey.pem +CRTPEM=$CUR_DIR/client_crt.pem +MSGTXT=${CUR_DIR}/msg.txt +MSGSIG=${CUR_DIR}/msg.sig +GENKEYCRTSCRIPT=${CUR_DIR}/gen_client_keycrt.sh + +echo -e '\n'check integrity of ${KEYPEM}: +# ${_openssl} rsa -in ${KEYPEM} -passin pass:111111 -check -noout +# ${_openssl} rsa -in ${KEYPEM} -check -noout +${_openssl} rsa -in ${KEYPEM} -check -noout | grep -q 'RSA key ok' +if [ $? -ne 0 ] +then + echo "the integrity of "${KEYPEM}" is broken" + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +else + echo -e "RSA key ok" +fi + +echo -e '\n'use private ${KEYPEM} to sign ${MSGTXT}: +# ${_openssl} dgst -sha256 -sign ${KEYPEM} -passin pass:111111 -out msg.sig msg.txt +${_openssl} dgst -sha256 -sign ${KEYPEM} -out ${MSGSIG} ${MSGTXT} + +echo -e '\n'get public key from ${CRTPEM}: +${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + +echo -e '\n'use public key in ${CRTPEM} to verify signature of ${MSGTXT}: +# ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} +${_openssl} dgst -sha256 -verify ${PUBPEM} -signature ${MSGSIG} ${MSGTXT} | grep -q 'Verified OK' +if [ $? -ne 0 ] +then + echo ${KEYPEM}" is not matched with "${CRTPEM} + # mail -s "$_sub" -r "$_from" "$_to" <<< "Warning: The certificate ($CACRTPEM) will expire soon on $HOSTNAME [$(date)]" + # See https://www.cyberciti.biz/mobile-devices/android/how-to-push-send-message-to-ios-and-android-from-linux-cli/ # + # source ~/bin/cli_app.sh + # push_to_mobile "$0" "$_sub. See $_to email for detailed log. -- $HOSTNAME " >/dev/null + + # bash ${GENKEYCRTSCRIPT} +fi +rm -f ${PUBPEM} diff --git a/teeproxy/libteecc/certs/client_crt.pem b/teeproxy/libteecc/certs/client_crt.pem new file mode 100644 index 0000000..4056b74 --- /dev/null +++ b/teeproxy/libteecc/certs/client_crt.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTzCCAjcCFD3UsYh/aU1yUsNsej6x2MjHaxBOMA0GCSqGSIb3DQEBCwUAMGEx +CzAJBgNVBAYTAkNOMQ4wDAYDVQQIDAVIdWJlaTEOMAwGA1UEBwwFV3VoYW4xEjAQ +BgNVBAoMCVRydXN0Q3V0ZTENMAsGA1UECwwEZ1JQQzEPMA0GA1UEAwwGY2Eub3Jn +MB4XDTIyMDgyMDA1MDYzNVoXDTMyMDgxNzA1MDYzNVowZzELMAkGA1UEBhMCQ04x +DjAMBgNVBAgMBUh1YmVpMQ4wDAYDVQQHDAVXdWhhbjESMBAGA1UECgwJVHJ1c3RD +dXRlMQ0wCwYDVQQLDARnUlBDMRUwEwYDVQQDDAxncGNsaWVudC5vcmcwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi8gFUTU1Fd5quFIUvmO/ViRrN416n +EaDyzt1qFfMU7CMyp6vmw5+xb7+z0bsSlucdCtWTHNFBt7ovZuAuUqRHAUm6Of7B +JNCpLY9aaWnhhwfCBO20wQs82djcMhVpWLfWAwUTrdkPubVpC+5pKUM1e7qWkF5Y +72edrtYjBkmhteq5mc3sZyHz4W0BjdO7vnYJ1PSqNvZt+z5krV1KNJ9D+HPC6CjH +syugS7hYSBVSMvGRk/B6VhhjcEV4QABZV7tCt1z9pfV28N7ODFw3kPbZo1rgAd+O +Os0XaUJx/exoVj9Ky93SPyIVh/pNdNtUFaoSx9VGg8osBFawPDEagPD3AgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAIigZPrS0XsUQ38SSCSjMmqRx4bJcAdjkFnmwCAf +NiEjfdreKF67ID/DuXwNUSp0imNnlpb8Zvim4TiSU+YoT6zPr1o9+KTiE0FHK+lE ++FTyNlKthbIC+x0hShFSQFoxjQzPZXQNcSWWHiGbapzjW5VTa807YUp7rmXopvrP +f3gTw6gzuZKUN+FSTv284kEqrPYA4KsuLJgsZz78uaH1RgHnRwqCRmwNdBLI2Mr8 ++G/mVOL/3gmi87mhqXdxWjCnoPQN+3stop8ZaZOPKtkR9e1vbdPfNZhuUTCG45zf +AyhVFCa2ykfFTE7rP10iGLH8Ek7AYOueImH3esVB5KpJSzM= +-----END CERTIFICATE----- diff --git a/teeproxy/libteecc/certs/client_key.pem b/teeproxy/libteecc/certs/client_key.pem new file mode 100644 index 0000000..d0a2b54 --- /dev/null +++ b/teeproxy/libteecc/certs/client_key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-192-CBC,4C084D8A0A073B8F63DD51AEE7F3EF9F + +mQNTKrxaKmWUhzJxNTW9Q74HZ+e9q+oJ1NqlkM5+qQTdoXo/JAblgSDuAWWRby1Y +RgmoFerqp+MDu8SpOHpWr0msvUgGSZ8tDrcjw4762qEnu/aT+q1FAq7tHM1waOtK +Euse0FFXrN4a0vesjQi3u/N4lrv53cl9fXDfg/eVhn+MncrR6sQo+XzhDPskKKhU +ecMn2cEtfb9ozXkSU3VfmOukM6FeA6zIcEr8QjLIP1n258TJmoxilUdebacZZZoO +N2t1gzTLxXmvUKYBt7CIJOeJhY8edQHByUQGCjzt2ZV3hv1AX+eNGYN5Sod/76aT +VbJhKgSXI4necPSc5l8UWV304gQEqcVk+aCyZJiXBF3Z46Fqw8LOQV0llsAsjiPs +llLbKQay8/NeF9XWRKclMeuDfQnU5qGuBblfM5YjWZqmxkC9MFVYgPrMrIxqXZnV +/ZTiApFvE25HJBlbiBo2JIv1jTWRduedq2XchtyUVUCcJ+U0xutpQ3A862Kygaa3 +IBA61BgpmJyrE7V2obgH+W6dY2D5N8W1PVFGONiCdU2ejXXuzuRT+0+TYfkvZHaR +dIvQwF35hzm4GlpHU73q/ZO5axqkPpyaLb6Y8I2+8JZi7Ns2eWjGRNjvs9kbOd0N +WI5JkjYdTPXDAjxA6pOntD2yx0Da9hgPbRf3HBazHUQg8RUQGRg9+mkJOfK720l0 +8DEUq29CUvYfAcWT+bIcZL+DDoHmLmNRi//+tmC0kRs9goRmm8FmgXSl8mQfAm4K +IYBFOd2KEmKItPklCuGWhzneri4qVAzhI8fODGzyLNaEXJkn2CFavgQRo2LIL26V +hGMiafuvtoQOj3HJg9yf5rinodo8agtxlnN0ZI5Li377b9vHJqLBvNdotpscXZk5 +qTlBeWhznFbK+p/VOESk1Lav2oFO7nxph6pV3gOhgRON2BMRp3LlqBsbLaxiNcp2 +RuQSp8QjBOypldmHn1SmTMXqlTxYI7/nzJrLOzlVGOkPJjDeZ3Kf9mvnXsolxjlS +GrhrBcdypG0bsQZO7PcqXr4p9NSlZZHHZXu78hvWZszoWWNHSUdpqnwnxHAn4AsK +X2Ge1n/XBzYCtXbofhjB7uaUqIdoR3O0CaWxl/MKw89v+64tU90fTzbSqKScmBgZ +oM7MEgdRQ/MmJ1kGb9GLVbJuhLdfwocjzRAFyrMI1jScSKP61qqwBNbxDe1n/zC/ +6OPQYh4g35kLBYR/Aht/9KlZ6Yfu5/bX4VZZ+ZgM3skryJsidafdNLttjVz8Nm5l +aqrJepxmCBuUz1r274gtTewEyjLHGkaoUSJ/Z+Q8P99dJ0mnp3yXghx3FNQCdKzU +gqjLk6tauCith9OEskzoZcOPNiigIaqY5J9JWr0VRscOkKaPHFo4rYK9GFBc+WlP +oaUbpBqxG1aGwida62l5gXJ3s9L7GHdea/7J/QJHu4bqWrBJ+PCwqkjaJdvnpIiI +EdcQXy3wbQJPkP2HdusF/FnC/9aSk4PR+X6gX+owDD/qAKNurss7XP0yHm4PRKI9 +kLa/+8sfFNCsny9KJTRYRV8lWz0sag52c3qUlZSRD/63ghKEI2mZdcouTMabCS4F +-----END RSA PRIVATE KEY----- diff --git a/teeproxy/libteecc/certs/gen_client_keycsr.sh b/teeproxy/libteecc/certs/gen_client_keycsr.sh new file mode 100644 index 0000000..cbf8077 --- /dev/null +++ b/teeproxy/libteecc/certs/gen_client_keycsr.sh @@ -0,0 +1,22 @@ +#! /bin/sh + +_openssl="openssl" + +CUR_DIR=$( dirname -- "$0"; ) + + +# KEYPEM=$HOME/.teecc/certs/client_key.pem +# CSRPEM=$HOME/.teecc/certs/client_csr.pem +KEYPEM=$CUR_DIR/client_key.pem +CSRPEM=$CUR_DIR/client_csr.pem +RSAKEYLEN=2048 +SUBSTR="/C=CN/ST=Hubei/L=Wuhan/O=TrustCute/OU=gRPC/CN=gpclient.org" + +echo -e '\n'generate $KEYPEM: +# $_openssl genrsa -passout pass:111111 -aes192 -out $KEYPEM ${RSAKEYLEN} +$_openssl genrsa -aes192 -out $KEYPEM ${RSAKEYLEN} + +echo -e '\n'generate certgen request $CSRPEM: +# $_openssl req -passin pass:111111 -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} +$_openssl req -new -key $KEYPEM -out $CSRPEM -subj ${SUBSTR} + diff --git a/teeproxy/libteecc/certs/msg.txt b/teeproxy/libteecc/certs/msg.txt new file mode 100644 index 0000000..93388ad --- /dev/null +++ b/teeproxy/libteecc/certs/msg.txt @@ -0,0 +1 @@ +verify the integrity of a certificate and private key pair diff --git a/teeproxy/libteecc/changelog.md b/teeproxy/libteecc/changelog.md new file mode 100644 index 0000000..f66c4e1 --- /dev/null +++ b/teeproxy/libteecc/changelog.md @@ -0,0 +1,7 @@ +# 更新日志 + +## [1.0.0] - 2022-10-11 + +### 新增 + +* 项目初始化,上传第一版 diff --git a/teeproxy/libteecc/common.cmake b/teeproxy/libteecc/common.cmake new file mode 100644 index 0000000..62099c5 --- /dev/null +++ b/teeproxy/libteecc/common.cmake @@ -0,0 +1,129 @@ +# Copyright 2018 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# cmake build file for C++ route_guide example. +# Assumes protobuf and gRPC have been installed using cmake. +# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build +# that automatically builds all the dependencies before building route_guide. + +cmake_minimum_required(VERSION 3.5.1) + +# set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD 14) + +set (GRPC_FETCHCONTENT 1) + + +if(MSVC) + add_definitions(-D_WIN32_WINNT=0x600) +endif() + +find_package(Threads REQUIRED) + +if(GRPC_AS_SUBMODULE) + # One way to build a projects that uses gRPC is to just include the + # entire gRPC project tree via "add_subdirectory". + # This approach is very simple to use, but the are some potential + # disadvantages: + # * it includes gRPC's CMakeLists.txt directly into your build script + # without and that can make gRPC's internal setting interfere with your + # own build. + # * depending on what's installed on your system, the contents of submodules + # in gRPC's third_party/* might need to be available (and there might be + # additional prerequisites required to build them). Consider using + # the gRPC_*_PROVIDER options to fine-tune the expected behavior. + # + # A more robust approach to add dependency on gRPC is using + # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt). + + # Include the gRPC's cmake build (normally grpc source code would live + # in a git submodule called "third_party/grpc", but this example lives in + # the same repository as gRPC sources, so we just look a few directories up) + add_subdirectory(../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) + message(STATUS "Using gRPC via add_subdirectory.") + + # After using add_subdirectory, we can now use the grpc targets directly from + # this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $) + endif() + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +elseif(GRPC_FETCHCONTENT) + # Another way is to use CMake's FetchContent module to clone gRPC at + # configure time. This makes gRPC's source code available to your project, + # similar to a git submodule. + message(STATUS "Using gRPC via add_subdirectory (FetchContent).") + include(FetchContent) + FetchContent_Declare( + grpc + GIT_REPOSITORY https://github.com/grpc/grpc.git + # when using gRPC, you will actually set this to an existing tag, such as + # v1.25.0, v1.26.0 etc.. + # For the purpose of testing, we override the tag used to the commit + # that's currently under test. + # GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE + GIT_TAG v1.48.0 + ) + FetchContent_MakeAvailable(grpc) + + # Since FetchContent uses add_subdirectory under the hood, we can use + # the grpc targets directly from this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + set(_PROTOBUF_PROTOC $) + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +else() + # This branch assumes that gRPC and all its dependencies are already installed + # on this system, so they can be located by find_package(). + + # Find Protobuf installation + # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation. + set(protobuf_MODULE_COMPATIBLE TRUE) + find_package(Protobuf CONFIG REQUIRED) + message(STATUS "Using protobuf ${Protobuf_VERSION}") + + set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) + set(_REFLECTION gRPC::grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $) + endif() + + # Find gRPC installation + # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. + find_package(gRPC CONFIG REQUIRED) + message(STATUS "Using gRPC ${gRPC_VERSION}") + + set(_GRPC_GRPCPP gRPC::grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $) + endif() +endif() diff --git a/teeproxy/libteecc/conf/teecc_config.yaml b/teeproxy/libteecc/conf/teecc_config.yaml new file mode 100644 index 0000000..a9cfe64 --- /dev/null +++ b/teeproxy/libteecc/conf/teecc_config.yaml @@ -0,0 +1,10 @@ +GPPROXY_ADDRESS: "gpserver.org:50051" + +NAME_SERVERCA_CERT: "ca_crt.pem" +NAME_CLIENT_KEY: "client_key.pem" +NAME_CLIENT_CERT: "client_crt.pem" + +# 0, no tls +# 1, only server certificate +# 2, server and client certificates +GRPC_TLS: 1 diff --git a/teeproxy/libteecc/include/teecc/tee_client_api.h b/teeproxy/libteecc/include/teecc/tee_client_api.h new file mode 100644 index 0000000..2cdc80a --- /dev/null +++ b/teeproxy/libteecc/include/teecc/tee_client_api.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2020. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: TEE client API definitions + */ + +#ifndef _TEE_CLIENT_API_H_ +#define _TEE_CLIENT_API_H_ + +#ifndef LOG_TAG +#define LOG_TAG NULL +#endif + +#ifdef LOG_NDEBUG +#undef LOG_NDEBUG +#endif +#define LOG_NDEBUG 0 + +#include +#include "tee_client_type.h" +#include "tee_client_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define S_VAR_NOT_USED(variable) do { (void)(variable); } while (0) + +#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \ + ((param3Type) << 12 | (param2Type) << 8 | (param1Type) << 4 | (param0Type)) + +#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ + (((paramTypes) >> (4*(index))) & 0x0F) + +#define TEEC_VALUE_UNDEF 0xFFFFFFFF + +/* + * initializes a new TEE Context, forming a connection between this Client Application and the TEE + * + * @param name [IN] TEE name (unused) + * @param context [IN/OUT] pointer to TEEC_Context to be initialized + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter + * @return TEEC_ERROR_GENERIC system error unhandled + */ +TEEC_Result TEEC_InitializeContext( + const char *name, + TEEC_Context *context); + +/* + * finalizes an initialized TEE Context, closing the connection between the Client Application and the TEE + * + * @param context [IN/OUT] pointer to TEEC_Context initialized by TEEC_InitializeContext + * + * @return void + */ +void TEEC_FinalizeContext( + TEEC_Context *context); + +/* + * opens a new Session between the Client Application and the specified Trusted Application + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param session [OUT] a pointer to a Session structure to be opened + * @param destination [IN] a pointer to a structure containing the UUID of the destination Trusted Application + * @param connectionMethod [IN] the method of connection to use + * @param connectionData [IN] any necessary data required to support the connection method + * @param operation [IN/OUT] a pointer to an Operation containing a set of Parameters to exchange with the + * Trusted Application + * @param returnOrigin [IN/OUT] a pointer to a variable which will contain the return origin, This field may be NULL + * if the return origin is not needed + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parametercontext or session or destination is NULL + * @return TEEC_ERROR_ACCESS_DENIED client Application's connection request is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return TEEC_ERROR_TRUSTED_APP_LOAD_ERROR load Trusted Application failed + * @return others refer TEEC_ReturnCode + */ +TEEC_Result TEEC_OpenSession( + TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connectionMethod, + const void *connectionData, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/* + * closes a Session which has been opened with a Trusted Application + * + * @param session [IN/OUT] pointer to a session to be closed + * + * @return void + */ +void TEEC_CloseSession( + TEEC_Session *session); + +/* + * invokes a Command within the specified Session + * + * @param session [IN/OUT] the open Session in which the command will be invoked + * @param commandID [IN] the identifier of the Command within the Trusted Application to invoke + * @param operation [IN/OUT] a pointer to a Client Application initialized TEEC_Operation structure + * @param returnOrigin [IN/OUT] a pointer to a variable which will contain the return origin + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parametersession is NULL or operation data invalid + * @return TEEC_ERROR_ACCESS_DENIED invoke command operation is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return others refer TEEC_ReturnCode + */ +TEEC_Result TEEC_InvokeCommand( + TEEC_Session *session, + uint32_t commandID, + TEEC_Operation *operation, + uint32_t *returnOrigin); + +/* + * registers a block of existing Client Application memory as a block of Shared Memory within + * the scope of the specified TEE Context, in accordance with the parameters which have been set by the + * Client Application inside the sharedMem structure (don't support 0 size data) + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to register + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + */ +TEEC_Result TEEC_RegisterSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/* + * allocates a new block of memory as a block of Shared Memory within the scope of the specified TEE Context + * size of sharedMem should not be 0 + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to allocate + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + */ +TEEC_Result TEEC_AllocateSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + +/* + * deregisters or deallocates a previously initialized block of Shared Memory + * if memory is allocated by TEEC_AllocateSharedMemory, system will free this memory + * if memory is registered by TEEC_RegisterSharedMemory, system will not free this memory + * + * @param sharedMem [IN/OUT] a pointer to a valid Shared Memory structure + * + * @return void + */ +void TEEC_ReleaseSharedMemory( + TEEC_SharedMemory *sharedMem); + +/* + * requests the cancellation of a pending open Session operation or a Command invocation operation + * this operation is not supported currently + * + * @param operation [IN/OUT] a pointer to a Client Application instantiated Operation structure + * + * @return void + */ +void TEEC_RequestCancellation( + TEEC_Operation *operation); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/teeproxy/libteecc/include/teecc/tee_client_constants.h b/teeproxy/libteecc/include/teecc/tee_client_constants.h new file mode 100644 index 0000000..eb31c89 --- /dev/null +++ b/teeproxy/libteecc/include/teecc/tee_client_constants.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2020. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: static definitions of client API + */ + +#ifndef _TEE_CLIENT_CONSTANTS_H_ +#define _TEE_CLIENT_CONSTANTS_H_ + +enum TEEC_ReturnCode { + TEEC_SUCCESS = 0x0, /* success */ + TEEC_ERROR_INVALID_CMD, /* invalid command */ + TEEC_ERROR_SERVICE_NOT_EXIST, /* target service is not exist */ + TEEC_ERROR_SESSION_NOT_EXIST, /* session between client and service is not exist */ + TEEC_ERROR_SESSION_MAXIMUM, /* exceed max num of sessions */ + TEEC_ERROR_REGISTER_EXIST_SERVICE, /* cannot register the service which already exist */ + TEEC_ERROR_TAGET_DEAD_FATAL, /* system error occurs in TEE */ + TEEC_ERROR_READ_DATA, /* failed to read data in file */ + TEEC_ERROR_WRITE_DATA, /* failed to write data to file */ + TEEC_ERROR_TRUNCATE_OBJECT, /* data is truncated */ + TEEC_ERROR_SEEK_DATA, /* failed to seek data in file */ + TEEC_ERROR_FSYNC_DATA, /* failed to sync data in file */ + TEEC_ERROR_RENAME_OBJECT, /* failed to rename file */ + TEEC_ERROR_TRUSTED_APP_LOAD_ERROR, /* failed to load Trusted Application */ + TEEC_ERROR_GENERIC = 0xFFFF0000, /* generic error occurs */ + TEEC_ERROR_ACCESS_DENIED = 0xFFFF0001, /* permission check failed, in initilize context or + open session or invoke commnad */ + TEEC_ERROR_CANCEL = 0xFFFF0002, /* operation is already canceled */ + TEEC_ERROR_ACCESS_CONFLICT = 0xFFFF0003, /* confilct occurs in concurrent access to data, + error occurs in file operaions generally */ + TEEC_ERROR_EXCESS_DATA = 0xFFFF0004, /* exceed max data to be handled by system */ + TEEC_ERROR_BAD_FORMAT = 0xFFFF0005, /* data format is invalid, Trusted Application cannot + handle it */ + TEEC_ERROR_BAD_PARAMETERS = 0xFFFF0006, /* invalid parameters */ + TEEC_ERROR_BAD_STATE = 0xFFFF0007, /* operation failed in current state, when try to access + storage without initilize storage service */ + TEEC_ERROR_ITEM_NOT_FOUND = 0xFFFF0008, /* cannot find target item */ + TEEC_ERROR_NOT_IMPLEMENTED = 0xFFFF0009, /* request operation is not implemented */ + TEEC_ERROR_NOT_SUPPORTED = 0xFFFF000A, /* request operation is not supported */ + TEEC_ERROR_NO_DATA = 0xFFFF000B, /* no data present for current operation */ + TEEC_ERROR_OUT_OF_MEMORY = 0xFFFF000C, /* system resource if out of use */ + TEEC_ERROR_BUSY = 0xFFFF000D, /* system is too busy to handle current operation */ + TEEC_ERROR_COMMUNICATION = 0xFFFF000E, /* error occurs when client try to communicate + with Trusted Application */ + TEEC_ERROR_SECURITY = 0xFFFF000F, /* security error occurs */ + TEEC_ERROR_SHORT_BUFFER = 0xFFFF0010, /* out buffer is not enough for current request */ + TEEC_ERROR_MAC_INVALID = 0xFFFF3071, /* MAC value check failed */ + TEEC_ERROR_TARGET_DEAD = 0xFFFF3024, /* Trusted Application is crashed */ + TEEC_FAIL = 0xFFFF5002, /* common error */ + TEEC_ERROR_EXTERNAL_CANCEL = 0xFFFF0011, /* used by adapt only, event caused User Interface operation aborted */ + TEEC_ERROR_OVERFLOW = 0xFFFF300F, /* used by adapt only */ + TEEC_ERROR_STORAGE_NO_SPACE = 0xFFFF3041, /* used by adapt only */ + TEEC_ERROR_SIGNATURE_INVALID = 0xFFFF3072, /* used by adapt only */ + TEEC_ERROR_TIME_NOT_SET = 0xFFFF5000, /* used by adapt only */ + TEEC_ERROR_TIME_NEEDS_RESET = 0xFFFF5001, /* used by adapt only */ + + TEEC_ERROR_CONTEXT_NULL = 0xAAAA0001, /* null context */ + TEEC_ERROR_CONTEXT_TAPATH_NULL = 0xAAAA0002, /* null context ta path */ + TEEC_ERROR_PARAM0_TEMPMEM_NULL = 0xAAAA0003, /* null param0 tempmem buf */ + TEEC_ERROR_PARAM0_TEMPMEM_LESS = 0xAAAA0004, /* param0 tempmem buf is less */ + TEEC_ERROR_PARAM1_TEMPMEM_NULL = 0xAAAA0005, /* null param1 tempmem buf */ + TEEC_ERROR_PARAM1_TEMPMEM_LESS = 0xAAAA0006, /* param1 tempmem buf is less */ + TEEC_ERROR_PARAM2_TEMPMEM_NULL = 0xAAAA0007, /* null param2 tempmem buf */ + TEEC_ERROR_PARAM2_TEMPMEM_LESS = 0xAAAA0008, /* param2 tempmem buf is less */ + TEEC_ERROR_PARAM3_TEMPMEM_NULL = 0xAAAA0009, /* null param3 tempmem buf */ + TEEC_ERROR_PARAM3_TEMPMEM_LESS = 0xAAAA000A, /* param3 tempmem buf is less */ + TEEC_ERROR_CONTEXT_LIST_NULL = 0xAAAA000B, /* null context list in woker */ + TEEC_ERROR_NO_CONTEXT_MATCH = 0xAAAA000C, /* no context match in woker */ + TEEC_ERROR_SESSION_LIST_NULL = 0xAAAA000D, /* null session list in woker */ + TEEC_ERROR_NO_SESSION_MATCH = 0xAAAA000E, /* no session match in woker */ + TEEC_ERROR_PARAM0_MEMREF_NULL = 0xAAAA000F, /* null param0 memref buf */ + TEEC_ERROR_PARAM0_MEMREF_LESS = 0xAAAA0010, /* param0 memref buf is less */ + TEEC_ERROR_PARAM1_MEMREF_NULL = 0xAAAA0011, /* null param1 memref buf */ + TEEC_ERROR_PARAM1_MEMREF_LESS = 0xAAAA0012, /* param1 memref buf is less */ + TEEC_ERROR_PARAM2_MEMREF_NULL = 0xAAAA0013, /* null param2 memref buf */ + TEEC_ERROR_PARAM2_MEMREF_LESS = 0xAAAA0014, /* param2 memref buf is less */ + TEEC_ERROR_PARAM3_MEMREF_NULL = 0xAAAA0015, /* null param3 memref buf */ + TEEC_ERROR_PARAM3_MEMREF_LESS = 0xAAAA0016, /* param3 memref buf is less */ + TEEC_ERROR_NO_WORKER_MATCHED = 0xAAAA0017, /* No woker mateched with the context or/and session */ + TEEC_ERROR_SESSION_NULL = 0xAAAA0018, /* null session */ + TEEC_ERROR_NO_SHAREMEMFLAG = 0xAAAA0019, /* no share memmory flag */ + + TEEC_ERROR_JWTVALIDATE_FAIL = 0xAAAA0020, /* jwt validate fail */ + TEEC_ERROR_GRPC_ERROR = 0xAAAA0021, /* grpc transmission error */ + TEEC_ERROR_DBUS_CONN_NULL = 0xAAAA0022, /* dbus connection null */ + TEEC_ERROR_DBUS_NAME_ERROR = 0xAAAA0023, /* dbus name set is error */ + TEEC_ERROR_DBUS_MSG_NULL = 0xAAAA0024, /* dbus message is null */ + TEEC_ERROR_DBUS_APPEND_ERROR = 0xAAAA0025, /* dbus append argument error */ + TEEC_ERROR_DBUS_REPLY_ERROR = 0xAAAA0026, /* dbus send with reply error */ + TEEC_ERROR_DBUS_ARG_NULL = 0xAAAA0027, /* dbus argument is null */ + TEEC_ERROR_DBUS_ARG_TYPE_ERROR = 0xAAAA0028, /* dbus argument type error */ + TEEC_ERROR_TOKEN_NULL = 0xAAAA0029, /* fetch token is null */ + TEEC_ERROR_TOKEN_SIZE_ERROR = 0xAAAA0030, /* token size is error */ + TEEC_ERROR_FETCHJWT_ERROR = 0xAAAA0031, /* fetch jwt error */ + TEEC_INFILE_PATH_NULL = 0xAAAA0032, /* deployta infile path is null*/ + TEEC_INFILE_NOT_FOUND = 0xAAAA0033 /* deployta infile is not found*/ +}; + +enum TEEC_ReturnCodeOrigin { + TEEC_ORIGIN_API = 0x1, /* error occurs in handling client API */ + TEEC_ORIGIN_COMMS = 0x2, /* error occurs in communicating between REE and TEE */ + TEEC_ORIGIN_TEE = 0x3, /* error occurs in TEE */ + TEEC_ORIGIN_TRUSTED_APP = 0x4, /* error occurs in Trusted Application */ +}; + +enum TEEC_SharedMemCtl { + TEEC_MEM_INPUT = 0x1, /* input type of memroy */ + TEEC_MEM_OUTPUT = 0x2, /* output type of memory */ + TEEC_MEM_INOUT = 0x3, /* memory is used as both input and output */ +}; + +enum TEEC_ParamType { + TEEC_NONE = 0x0, /* unused parameter */ + TEEC_VALUE_INPUT = 0x01, /* input type of value, refer TEEC_Value */ + TEEC_VALUE_OUTPUT = 0x02, /* output type of value, refer TEEC_Value */ + TEEC_VALUE_INOUT = 0x03, /* value is used as both input and output, refer TEEC_Value */ + TEEC_MEMREF_TEMP_INPUT = 0x05, /* input type of temp memory reference, refer TEEC_TempMemoryReference */ + TEEC_MEMREF_TEMP_OUTPUT = 0x06, /* output type of temp memory reference, refer TEEC_TempMemoryReference */ + TEEC_MEMREF_TEMP_INOUT = 0x07, /* temp memory reference used as both input and output, + refer TEEC_TempMemoryReference */ + TEEC_ION_INPUT = 0x08, /* input type of icon memory reference, refer TEEC_IonReference */ + TEEC_ION_SGLIST_INPUT = 0x09, /* input type of ion memory block reference, refer TEEC_IonSglistReference */ + TEEC_MEMREF_WHOLE = 0xc, /* use whole memory block, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_INPUT = 0xd, /* input type of memory reference, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, /* output type of memory reference, refer TEEC_RegisteredMemoryReference */ + TEEC_MEMREF_PARTIAL_INOUT = 0xf /* memory reference used as both input and output, + refer TEEC_RegisteredMemoryReference */ +}; + +/**************************************************** + * Session Login Methods + ****************************************************/ +enum TEEC_LoginMethod { + TEEC_LOGIN_PUBLIC = 0x0, /* no Login data is provided */ + TEEC_LOGIN_USER, /* Login data about the user running the + Client Application process is provided */ + TEEC_LOGIN_GROUP, /* Login data about the group running + the Client Application process is provided */ + TEEC_LOGIN_APPLICATION = 0x4, /* Login data about the running Client + Application itself is provided */ + TEEC_LOGIN_USER_APPLICATION = 0x5, /* Login data about the user running the + Client Application and about the + Client Application itself is provided */ + TEEC_LOGIN_GROUP_APPLICATION = 0x6, /* Login data about the group running + the Client Application and about the + Client Application itself is provided */ + TEEC_LOGIN_IDENTIFY = 0x7, /* Login data is provided by REE system */ +}; +enum TST_CMD_ID { + TST_CMD_ID_01 = 1, + TST_CMD_ID_02, + TST_CMD_ID_03, + TST_CMD_ID_04, + TST_CMD_ID_05 +}; + +#define TEEC_PARAM_NUM 4 /* teec param max number */ +#endif diff --git a/teeproxy/libteecc/include/teecc/tee_client_list.h b/teeproxy/libteecc/include/teecc/tee_client_list.h new file mode 100644 index 0000000..03e295f --- /dev/null +++ b/teeproxy/libteecc/include/teecc/tee_client_list.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2020. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: linked list data types and basic operations + */ + +#ifndef TEE_CLIENT_LIST_H +#define TEE_CLIENT_LIST_H + +struct ListNode { + struct ListNode *next; /* point to next node */ + struct ListNode *prev; /* point to prev node */ +}; + +#define OFFSET_OF(type, member) (unsigned long)(&(((type *)0)->member)) +#define CONTAINER_OF(pos, type, member) (type *)(((char *)(pos)) - OFFSET_OF(type, member)) + +#define LIST_DECLARE(name) \ + struct ListNode name = { \ + .next = &name, \ + .prev = &name, \ + } + +static inline void ListInit(struct ListNode *list) +{ + list->next = list; + list->prev = list; +} + +#define LIST_HEAD(list) ((list)->next) +#define LIST_TAIL(list) ((list)->prev) +#define LIST_EMPTY(list) ((list) == (list)->next) + +static inline void ListInsertHead(struct ListNode *list, struct ListNode *entry) +{ + list->next->prev = entry; + entry->next = list->next; + entry->prev = list; + list->next = entry; +} + +static inline void ListInsertTail(struct ListNode *list, struct ListNode *entry) +{ + entry->next = list; + entry->prev = list->prev; + list->prev->next = entry; + list->prev = entry; +} + +static inline void ListRemoveEntry(struct ListNode *entry) +{ + entry->prev->next = entry->next; + entry->next->prev = entry->prev; +} + +static inline struct ListNode *ListRemoveHead(struct ListNode *list) +{ + struct ListNode *entry = NULL; + if (!LIST_EMPTY(list)) { + entry = list->next; + ListRemoveEntry(entry); + } + return entry; +} + +static inline struct ListNode *ListRemoveTail(struct ListNode *list) +{ + struct ListNode *entry = NULL; + if (!LIST_EMPTY(list)) { + entry = list->prev; + ListRemoveEntry(entry); + } + return entry; +} + +#define LIST_ENTRY(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +#define LIST_FOR_EACH(pos, list) \ + for (pos = (list)->next; pos != (list); pos = pos->next) + +#define LIST_FOR_EACH_SAFE(pos, n, list) \ + for ((pos) = (list)->next, (n) = (pos)->next; (pos) != (list); (pos) = (n), (n) = (pos)->next) + +#define LIST_FOR_EACH_ENTRY(pos, list, member) \ + for (pos = LIST_ENTRY((list)->next, typeof(*pos), member); &pos->member != (list); \ + pos = LIST_ENTRY(pos->member.next, typeof(*pos), member)) + +#define LIST_FOR_EACH_ENTRY_SAFE(pos, n, list, member) \ + for (pos = LIST_ENTRY((list)->next, typeof(*pos), member), n = LIST_ENTRY(pos->member.next, typeof(*pos), \ + member); &pos->member != (list); pos = n, n = LIST_ENTRY(n->member.next, typeof(*n), member)) + +#endif diff --git a/teeproxy/libteecc/include/teecc/tee_client_log.h b/teeproxy/libteecc/include/teecc/tee_client_log.h new file mode 100644 index 0000000..9ba1fda --- /dev/null +++ b/teeproxy/libteecc/include/teecc/tee_client_log.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: TEE client log api + */ + +#ifndef TEE_CLIENT_LOG_H +#define TEE_CLIENT_LOG_H + +#include + +// #define TEEC_DEBUG + +#ifdef TEEC_DEBUG +#define TEEC_Debug(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__); +#else +#define TEEC_Debug(...) +#endif + +#define TEEC_Error(...) syslog(LOG_USER | LOG_INFO, __VA_ARGS__); + +#endif diff --git a/teeproxy/libteecc/include/teecc/tee_client_type.h b/teeproxy/libteecc/include/teecc/tee_client_type.h new file mode 100644 index 0000000..f590615 --- /dev/null +++ b/teeproxy/libteecc/include/teecc/tee_client_type.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2020. All rights reserved. + * iTrustee licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Description: data type and structure definition according to GP + */ + +#ifndef _TEE_CLIENT_TYPE_H_ +#define _TEE_CLIENT_TYPE_H_ + +#include +#include +#include +#include +#include "tee_client_list.h" +#include "tee_client_constants.h" + +#ifndef __cplusplus +#ifndef bool +#define bool uint8_t +#endif +#endif + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +typedef enum TEEC_ReturnCode TEEC_Result; + +typedef struct { + uint32_t timeLow; + uint16_t timeMid; + uint16_t timeHiAndVersion; + uint8_t clockSeqAndNode[8]; +} TEEC_UUID; + +typedef struct { + int32_t fd; + uint8_t *ta_path; + struct ListNode session_list; + struct ListNode shrd_mem_list; + union { + struct { + void *buffer; + sem_t buffer_barrier; + } share_buffer; + uint64_t imp; /* for adapt */ + }; +} TEEC_Context; + +typedef struct { + uint32_t session_id; + TEEC_UUID service_id; + uint32_t ops_cnt; + union { + struct ListNode head; + uint64_t imp; /* for adapt */ + }; + TEEC_Context *context; +} TEEC_Session; + +typedef struct { + void *buffer; + uint32_t size; + uint32_t flags; /* reference to TEEC_SharedMemCtl */ + uint32_t ops_cnt; + bool is_allocated; /* identify whether the memory is registered or allocated */ + union { + struct ListNode head; + void* imp; /* for adapt, imp is not used by system CA, only for vendor CA */ + }; + TEEC_Context *context; +} TEEC_SharedMemory; + +/* + * the corresponding param types are + * TEEC_MEMREF_TEMP_INPUT/TEEC_MEMREF_TEMP_OUTPUT/TEEC_MEMREF_TEMP_INOUT + */ +typedef struct { + void *buffer; + uint32_t size; +} TEEC_TempMemoryReference; + +/* + * the corresponding param types are + * TEEC_MEMREF_WHOLE/TEEC_MEMREF_PARTIAL_INPUT + * TEEC_MEMREF_PARTIAL_OUTPUT/TEEC_MEMREF_PARTIAL_INOUT + */ +typedef struct { + TEEC_SharedMemory *parent; + uint32_t size; + uint32_t offset; +} TEEC_RegisteredMemoryReference; + +/* + * the corresponding param types are + * TEEC_VALUE_INPUT/TEEC_VALUE_OUTPUT/TEEC_VALUE_INOUT + */ +typedef struct { + uint32_t a; + uint32_t b; +} TEEC_Value; + +typedef struct { + int ion_share_fd; + uint32_t ion_size; +} TEEC_IonReference; + +typedef union { + TEEC_TempMemoryReference tmpref; + TEEC_RegisteredMemoryReference memref; + TEEC_Value value; + TEEC_IonReference ionref; +} TEEC_Parameter; + +typedef struct { + uint32_t event_type; /* Tui event type */ + uint32_t value; /* return value, is keycode if tui event is getKeycode */ + uint32_t notch; /* notch size of the screen for tui */ + uint32_t width; /* width of foldable screen */ + uint32_t height; /* height of foldable screen */ + uint32_t fold_state; /* state of foldable screen */ + uint32_t display_state; /* one state of folded state */ + uint32_t phy_width; /* real width of the mobile */ + uint32_t phy_height; /* real height of the mobile */ +} TEEC_TUI_Parameter; + +typedef struct { + uint32_t started; /* 0 means cancel this operation, others mean to perform this operation */ + uint32_t paramTypes; /* use TEEC_PARAM_TYPES to construct this value */ + TEEC_Parameter params[TEEC_PARAM_NUM]; + TEEC_Session *session; + bool cancel_flag; +} TEEC_Operation; + +#endif diff --git a/teeproxy/libteecc/include/teecc/teec_client_api.h b/teeproxy/libteecc/include/teecc/teec_client_api.h new file mode 100644 index 0000000..996b5e7 --- /dev/null +++ b/teeproxy/libteecc/include/teecc/teec_client_api.h @@ -0,0 +1,192 @@ +#ifndef teec_client_api_h__ +#define teec_client_api_h__ + +#include "tee_client_type.h" +#include "tee_client_log.h" + + +#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \ + ((param3Type) << 12 | (param2Type) << 8 | (param1Type) << 4 | (param0Type)) + +#define TEEC_PARAM_TYPE_GET(paramTypes, index) \ + (((paramTypes) >> (4*(index))) & 0x0F) + +#ifdef __cplusplus +extern "C"{ +#endif + +/* + * initializes a new TEE Context, forming a connection between this Client Application and the TEE + * + * @param name [IN] TEE name (unused) + * @param context [IN/OUT] pointer to TEEC_Context to be initialized + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter + * @return TEEC_ERROR_GENERIC system error unhandled + */ +extern TEEC_Result +TEEC_InitializeContext( + const char *name, + TEEC_Context *context); + + +/* + * finalizes an initialized TEE Context, closing the connection between the Client Application and the TEE + * + * @param context [IN/OUT] pointer to TEEC_Context initialized by TEEC_InitializeContext + * @param context_addr [IN] the context address in gp woker process + * + * @return void + */ +extern void +TEEC_FinalizeContext( + TEEC_Context *context); + + +/* + * opens a new Session between the Client Application and the specified Trusted Application + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param context_addr [IN] the context address in gp woker process + * @param session [OUT] a pointer to a Session structure to be opened + * @param destination [IN] a pointer to a structure containing the UUID of the destination Trusted Application + * @param connectionMethod [IN] the method of connection to use + * @param connectionData [IN] any necessary data required to support the connection method + * @param operation [IN/OUT] a pointer to an Operation containing a set of Parameters to exchange with the + * Trusted Application + * @param returnOrigin [IN/OUT] a pointer to a variable which will contain the return origin, This field may be NULL + * if the return origin is not needed + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter£¬context or session or destination is NULL + * @return TEEC_ERROR_ACCESS_DENIED client Application's connection request is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return TEEC_ERROR_TRUSTED_APP_LOAD_ERROR load Trusted Application failed + * @return others refer TEEC_ReturnCode + */ +extern TEEC_Result +TEEC_OpenSession( + TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connectionMethod, + const void *connectionData, + TEEC_Operation *operation, + uint32_t *returnOrigin); + + +/* + * closes a Session which has been opened with a Trusted Application + * + * @param session [IN/OUT] pointer to a session to be closed + * + * @return void + */ +extern void +TEEC_CloseSession( + TEEC_Session *session); + + +/* + * invokes a Command within the specified Session + * + * @param session [IN/OUT] the open Session in which the command will be invoked + * @param commandID [IN] the identifier of the Command within the Trusted Application to invoke + * @param operation [IN/OUT] a pointer to a Client Application initialized TEEC_Operation structure + * @param returnOrigin [IN/OUT] a pointer to a variable which will contain the return origin + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter£¬session is NULL or operation data invalid + * @return TEEC_ERROR_ACCESS_DENIED invoke command operation is denied + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + * @return others refer TEEC_ReturnCode + */ +extern TEEC_Result +TEEC_InvokeCommand( + TEEC_Session *session, + uint32_t commandID, + TEEC_Operation *operation, + uint32_t *returnOrigin); + + +/* + * allocates a new block of memory as a block of Shared Memory within the scope of the specified TEE Context + * size of sharedMem should not be 0 + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to allocate + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + * @return TEEC_ERROR_OUT_OF_MEMORY system resource is out of use + */ +TEEC_Result TEEC_AllocateSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + + +/* + * registers a block of existing Client Application memory as a block of Shared Memory within + * the scope of the specified TEE Context, in accordance with the parameters which have been set by the + * Client Application inside the sharedMem structure (don't support 0 size data) + * + * @param context [IN/OUT] a pointer to an initialized TEE Context + * @param sharedMem [IN/OUT] a pointer to a Shared Memory structure to register + * + * @return TEEC_SUCCESS operation success + * @return TEEC_ERROR_BAD_PARAMETERS invalid parameter, context or sharedMem is NULL + */ +TEEC_Result TEEC_RegisterSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem); + + +/* + * deregisters or deallocates a previously initialized block of Shared Memory + * if memory is allocated by TEEC_AllocateSharedMemory, system will free this memory + * if memory is registered by TEEC_RegisterSharedMemory, system will not free this memory + * + * @param sharedMem [IN/OUT] a pointer to a valid Shared Memory structure + * + * @return void + */ +extern +void TEEC_ReleaseSharedMemory( + TEEC_SharedMemory *sharedMem); + + +/* + */ +extern +TEEC_Result +TEEC_DeployTa( + char * infile_path, + char * subdir, + char * outfile_name +); + + +/* + */ +extern +TEEC_Result +TEEC_SetJwt( + char * token +); + + +/* + */ +extern +TEEC_Result +TEEC_UnsetJwt( +); + + + +#ifdef __cplusplus +} +#endif + +#endif // teec_client_api_h__ diff --git a/teeproxy/libteecc/protos/gt.proto b/teeproxy/libteecc/protos/gt.proto new file mode 100644 index 0000000..3eeff06 --- /dev/null +++ b/teeproxy/libteecc/protos/gt.proto @@ -0,0 +1,392 @@ +// + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.gt"; +option java_outer_classname = "gtProto"; +option objc_class_prefix = "HLW"; + +package gt; + +// The gpp service definition. +service gpp { + rpc TEECC_InitializeContext (Inicont_Request) returns (Inicont_Reply) {} + rpc TEECC_FinalizeContext (Fincont_Request) returns (Fincont_Reply) {} + rpc TEECC_OpenSession (Opes_Request) returns (Opes_Reply) {} + rpc TEECC_InvokeCommand (Invo_Request) returns (Invo_Reply) {} + rpc TEECC_CloseSession (Close_Request) returns (Close_Reply) {} + rpc TEECC_TA(TA_Chunk) returns (TA_Reply) {} + rpc TEECC_SetJwt(Setjwt_Request) returns (Setjwt_Reply) {} +} + + +message Inicont_Request { + uint64 name_size = 1; + string name = 2; + string token = 3; + string taname = 4; +} + +message Inicont_Reply { + uint32 teecresult = 1; + int32 context_fd = 2; + uint64 context_tapath_outsize = 3; + bytes context_tapath = 4; + uint64 context_sessionlist_next = 5; + uint64 context_sessionlist_prev = 6; + uint64 context_shrdmemlist_next = 7; + uint64 context_shrdmemlist_prev = 8; + uint64 context_sharebuffer_buffer = 9; + int64 context_sharebuffer_bufferbarrier = 10; + uint64 context_addr = 11; + int32 flag = 12; +} + +message Fincont_Request { + int32 in_context_fd = 1; + uint64 in_context_tapath_size= 2; + bytes in_context_tapath = 3; + uint64 in_context_sessionlist_next = 4; + uint64 in_context_sessionlist_prev = 5; + uint64 in_context_shrdmemlist_next = 6; + uint64 in_context_shrdmemlist_prev = 7; + uint64 in_context_sharebuffer_buffer = 8; + int64 in_context_sharebuffer_bufferbarrier = 9; + uint64 in_context_addr = 10; + string token = 11; + string taname = 12; +} + +message Fincont_Reply { + int32 context_fd = 1; + uint64 context_tapath_outsize = 2; + bytes context_tapath = 3; + uint64 context_sessionlist_next = 4; + uint64 context_sessionlist_prev = 5; + uint64 context_shrdmemlist_next = 6; + uint64 context_shrdmemlist_prev = 7; + uint64 context_sharebuffer_buffer = 8; + int64 context_sharebuffer_bufferbarrier = 9; + uint64 context_addr = 10; + int32 flag = 11; +} + +message Opes_Request { + int32 in_context_fd = 1; + uint64 in_context_tapath_size= 2; + bytes in_context_tapath = 3; + uint64 in_context_sessionlist_next = 4; + uint64 in_context_sessionlist_prev = 5; + uint64 in_context_shrdmemlist_next = 6; + uint64 in_context_shrdmemlist_prev = 7; + uint64 in_context_sharebuffer_buffer = 8; + int64 in_context_sharebuffer_bufferbarrier = 9; + uint32 in_destination_timelow = 10; + uint32 in_destination_timemid = 11; + uint32 in_destination_timehiandver = 12; + uint64 in_destination_cad_size = 13; + repeated uint32 in_destination_clockseqandnode = 14; + uint32 in_connectionmethod = 15; + uint64 in_connectiondata = 16; + uint32 in_operation_started = 17; + uint32 in_operation_paramtypes = 18; + uint64 in_operation_param1_tmpref_buffer = 19; + uint32 in_operation_param1_tmpref_size = 20; + uint64 in_operation_param1_memref_parent = 21; + uint32 in_operation_param1_memref_size = 22; + uint32 in_operation_param1_memref_offset = 23; + uint32 in_operation_param1_value_a = 24; + uint32 in_operation_param1_value_b = 25; + int32 in_operation_param1_ionref_ionsharefd = 26; + uint32 in_operation_param1_ionref_ionsize = 27; + uint64 in_operation_param2_tmpref_buffer = 28; + uint32 in_operation_param2_tmpref_size = 29; + uint64 in_operation_param2_memref_parent = 30; + uint32 in_operation_param2_memref_size = 31; + uint32 in_operation_param2_memref_offset = 32; + uint32 in_operation_param2_value_a = 33; + uint32 in_operation_param2_value_b = 34; + int32 in_operation_param2_ionref_ionsharefd = 35; + uint32 in_operation_param2_ionref_ionsize = 36; + uint64 in_operation_param3_tmpref_buffer = 37; + uint32 in_operation_param3_tmpref_size = 38; + uint64 in_operation_param3_memref_parent = 39; + uint32 in_operation_param3_memref_size = 40; + uint32 in_operation_param3_memref_offset = 41; + uint32 in_operation_param3_value_a = 42; + uint32 in_operation_param3_value_b = 43; + int32 in_operation_param3_ionref_ionsharefd = 44; + uint32 in_operation_param3_ionref_ionsize = 45; + uint64 in_operation_param4_tmpref_buffer = 46; + uint32 in_operation_param4_tmpref_size = 47; + uint64 in_operation_param4_memref_parent = 48; + uint32 in_operation_param4_memref_size = 49; + uint32 in_operation_param4_memref_offset = 50; + uint32 in_operation_param4_value_a = 51; + uint32 in_operation_param4_value_b = 52; + int32 in_operation_param4_ionref_ionsharefd = 53; + uint32 in_operation_param4_ionref_ionsize = 54; + uint64 in_operation_session = 55; + int32 in_operation_cancelflag = 56; + uint32 in_returnorigin = 57; + uint64 in_context_addr = 58; + string token = 59; + string taname = 60; +} + +message Opes_Reply { + uint32 teecresult = 1; + int32 context_fd = 2; + bytes context_tapath = 3 ; + uint64 context_tapath_outsize = 4; + uint64 context_sessionlist_next = 5; + uint64 context_sessionlist_prev = 6; + uint64 context_shrdmemlist_next = 7; + uint64 context_shrdmemlist_prev = 8; + uint64 context_sharebuffer_buffer = 9; + int64 context_sharebuffer_bufferbarrier = 10; + uint32 session_sessionid = 11; + uint32 session_serviceid_timelow = 12; + uint32 session_serviceid_timemid = 13; + uint32 session_serviceid_timehiandver = 14; + uint64 session_serviceid_clockseqandnode_outsize = 15; + repeated uint32 session_serviceid_clockseqandnode = 16; + uint32 session_opscnt = 17; + uint64 session_head_next = 18; + uint64 session_head_prev = 19; + uint64 session_context = 20; + uint32 operation_started = 21; + uint32 operation_paramtypes = 22; + uint64 operation_param1_tmpref_buffer = 23; + uint32 operation_param1_tmpref_size = 24; + uint64 operation_param1_memref_parent = 25; + uint32 operation_param1_memref_size = 26; + uint32 operation_param1_memref_offset = 27; + uint32 operation_param1_value_a = 28; + uint32 operation_param1_value_b = 29; + int32 operation_param1_ionref_ionsharefd = 30; + uint32 operation_param1_ionref_ionsize = 31; + uint64 operation_param2_tmpref_buffer = 32; + uint32 operation_param2_tmpref_size = 33; + uint64 operation_param2_memref_parent = 34; + uint32 operation_param2_memref_size = 35; + uint32 operation_param2_memref_offset = 36; + uint32 operation_param2_value_a = 37; + uint32 operation_param2_value_b = 38; + int32 operation_param2_ionref_ionsharefd = 39; + uint32 operation_param2_ionref_ionsize = 40; + uint64 operation_param3_tmpref_buffer = 41; + uint32 operation_param3_tmpref_size = 42; + uint64 operation_param3_memref_parent = 43; + uint32 operation_param3_memref_size = 44; + uint32 operation_param3_memref_offset = 45; + uint32 operation_param3_value_a = 46; + uint32 operation_param3_value_b = 47; + int32 operation_param3_ionref_ionsharefd = 48; + uint32 operation_param3_ionref_ionsize = 49; + uint64 operation_param4_tmpref_buffer = 50; + uint32 operation_param4_tmpref_size = 51; + uint64 operation_param4_memref_parent = 52; + uint32 operation_param4_memref_size = 53; + uint32 operation_param4_memref_offset = 54; + uint32 operation_param4_value_a = 55; + uint32 operation_param4_value_b = 56; + int32 operation_param4_ionref_ionsharefd = 57; + uint32 operation_param4_ionref_ionsize = 58; + uint64 operation_session = 59; + int32 operation_cancelflag = 60; + uint32 returnorigin = 61; + int32 flag = 62; +} + +message Invo_Request { + uint32 in_session_sessionid = 1; + uint32 in_session_serviceid_timelow = 2; + uint32 in_session_serviceid_timemid = 3; + uint32 in_session_serviceid_timehiandver = 4; + uint64 in_session_serviceid_cad_size = 5; + repeated uint32 in_session_serviceid_clockseqandnode = 6; + uint32 in_session_opscnt = 7; + uint64 in_session_head_next = 8; + uint64 in_session_head_prev = 9; + uint64 in_session_context = 10; + uint32 in_commandid = 11; + uint32 in_operation_started = 12; + uint32 in_operation_paramtypes = 13; + uint64 in_operation_param1_tmpref_buffer = 14; + uint32 in_operation_param1_tmpref_size = 15; + uint64 in_operation_param1_memref_parent = 16; + uint32 in_operation_param1_memref_parent_flag = 17; + uint32 in_operation_param1_memref_size = 18; + uint32 in_operation_param1_memref_offset = 19; + uint32 in_operation_param1_value_a = 20; + uint32 in_operation_param1_value_b = 21; + int32 in_operation_param1_ionref_ionsharefd = 22; + uint32 in_operation_param1_ionref_ionsize = 23; + uint64 in_operation_param2_tmpref_buffer = 24; + uint32 in_operation_param2_tmpref_size = 25; + uint64 in_operation_param2_memref_parent = 26; + uint32 in_operation_param2_memref_parent_flag = 27; + uint32 in_operation_param2_memref_size = 28; + uint32 in_operation_param2_memref_offset = 29; + uint32 in_operation_param2_value_a = 30; + uint32 in_operation_param2_value_b = 31; + int32 in_operation_param2_ionref_ionsharefd = 32; + uint32 in_operation_param2_ionref_ionsize = 33; + uint64 in_operation_param3_tmpref_buffer = 34; + uint32 in_operation_param3_tmpref_size = 35; + uint64 in_operation_param3_memref_parent = 36; + uint32 in_operation_param3_memref_parent_flag = 37; + uint32 in_operation_param3_memref_size = 38; + uint32 in_operation_param3_memref_offset = 39; + uint32 in_operation_param3_value_a = 40; + uint32 in_operation_param3_value_b = 41; + int32 in_operation_param3_ionref_ionsharefd = 42; + uint32 in_operation_param3_ionref_ionsize = 43; + uint64 in_operation_param4_tmpref_buffer = 44; + uint32 in_operation_param4_tmpref_size = 45; + uint64 in_operation_param4_memref_parent = 46; + uint32 in_operation_param4_memref_parent_flag = 47; + uint32 in_operation_param4_memref_size = 48; + uint32 in_operation_param4_memref_offset = 49; + uint32 in_operation_param4_value_a = 50; + uint32 in_operation_param4_value_b = 51; + int32 in_operation_param4_ionref_ionsharefd = 52; + uint32 in_operation_param4_ionref_ionsize = 53; + uint64 in_operation_session = 54; + int32 in_operation_cancelflag = 55; + uint32 in_returnorigin = 56; + uint64 in_bufer1_size = 57; + repeated uint32 in_buffer1 = 58; + uint64 in_bufer2_size = 59; + repeated uint32 in_buffer2 = 60; + uint64 in_bufer3_size = 61; + repeated uint32 in_buffer3 = 62; + uint64 in_bufer4_size = 63; + repeated uint32 in_buffer4 = 64; + string token = 65; + string taname = 66; +} + +message Invo_Reply { + uint32 teecresult = 1; + uint32 session_sessionid = 2; + uint32 session_serviceid_timelow = 3; + uint32 session_serviceid_timemid = 4; + uint32 session_serviceid_timehiandver = 5; + uint64 session_serviceid_clockseqandnode_outsize = 6; + repeated uint32 session_serviceid_clockseqandnode = 7; + uint32 session_opscnt = 8; + uint64 session_head_next = 9; + uint64 session_head_prev = 10; + uint64 session_context = 11; + uint32 operation_started = 12; + uint32 operation_paramtypes = 13; + uint64 operation_param1_tmpref_buffer = 14; + uint32 operation_param1_tmpref_size = 15; + uint64 operation_param1_memref_parent = 16; + uint32 operation_param1_memref_parent_flag = 17; + uint32 operation_param1_memref_size = 18; + uint32 operation_param1_memref_offset = 19; + uint32 operation_param1_value_a = 20; + uint32 operation_param1_value_b = 21; + int32 operation_param1_ionref_ionsharefd = 22; + uint32 operation_param1_ionref_ionsize = 23; + uint64 operation_param2_tmpref_buffer = 24; + uint32 operation_param2_tmpref_size = 25; + uint64 operation_param2_memref_parent = 26; + uint32 operation_param2_memref_parent_flag = 27; + uint32 operation_param2_memref_size = 28; + uint32 operation_param2_memref_offset = 29; + uint32 operation_param2_value_a = 30; + uint32 operation_param2_value_b = 31; + int32 operation_param2_ionref_ionsharefd = 32; + uint32 operation_param2_ionref_ionsize = 33; + uint64 operation_param3_tmpref_buffer = 34; + uint32 operation_param3_tmpref_size = 35; + uint64 operation_param3_memref_parent = 36; + uint32 operation_param3_memref_parent_flag = 37; + uint32 operation_param3_memref_size = 38; + uint32 operation_param3_memref_offset = 39; + uint32 operation_param3_value_a = 40; + uint32 operation_param3_value_b = 41; + int32 operation_param3_ionref_ionsharefd = 42; + uint32 operation_param3_ionref_ionsize = 43; + uint64 operation_param4_tmpref_buffer = 44; + uint32 operation_param4_tmpref_size = 45; + uint64 operation_param4_memref_parent = 46; + uint32 operation_param4_memref_parent_flag = 47; + uint32 operation_param4_memref_size = 48; + uint32 operation_param4_memref_offset = 49; + uint32 operation_param4_value_a = 50; + uint32 operation_param4_value_b = 51; + int32 operation_param4_ionref_ionsharefd = 52; + uint32 operation_param4_ionref_ionsize = 53; + uint64 operation_session = 54; + int32 operation_cancelflag = 55; + uint32 returnorigin = 56; + + uint64 buffer1_outsize = 57; + uint64 buffer2_outsize = 58; + uint64 buffer3_outsize = 59; + uint64 buffer4_outsize = 60; + + repeated uint32 buffer1 = 61; + repeated uint32 buffer2 = 62; + repeated uint32 buffer3 = 63; + repeated uint32 buffer4 = 64; + int32 flag = 65; +} + +message Close_Request { + uint32 in_session_sessionid = 1; + uint32 in_session_serviceid_timelow = 2; + uint32 in_session_serviceid_timemid = 3; + uint32 in_session_serviceid_timehiandver = 4; + uint64 in_session_serviceid_cad_size = 5; + repeated uint32 in_session_serviceid_clockseqandnode = 6; + uint32 in_session_opscnt = 7; + uint64 in_session_head_next = 8; + uint64 in_session_head_prev = 9; + uint64 in_session_context = 10; + string token = 11; + string taname = 12; +} + +message Close_Reply { + uint32 session_sessionid = 1; + uint32 session_serviceid_timelow = 2; + uint32 session_serviceid_timemid = 3; + uint32 session_serviceid_timehiandver = 4; + uint64 session_serviceid_cad_outsize = 5; + repeated uint32 session_serviceid_clockseqandnode = 6; + uint32 session_opscnt = 7; + uint64 session_head_next = 8; + uint64 session_head_prev = 9; + uint64 session_context = 10; + int32 flag = 11; +} + +message TA_Chunk{ + string name = 1; + bytes buffer = 2; + string token = 3; + string taname = 4; + bytes sha256 = 5; + string subdir = 6; +} + +message TA_Reply{ + int32 code = 1; + int32 flag = 2; +} + +message Setjwt_Request{ + string taname = 1; + string token = 2; +} + +message Setjwt_Reply{ + int32 retcode = 1; +} diff --git a/teeproxy/libteecc/teecc.cc b/teeproxy/libteecc/teecc.cc new file mode 100644 index 0000000..c4a6617 --- /dev/null +++ b/teeproxy/libteecc/teecc.cc @@ -0,0 +1,4148 @@ +/* + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "gt.grpc.pb.h" + +#include "teecc.h" +#include "teecc/teec_client_api.h" +#include "yaml-cpp/yaml.h" + +#ifdef __cplusplus +extern "C" { +#endif + +using grpc::Channel; +using grpc::ChannelArguments; +using grpc::experimental::AltsCredentials; +using grpc::experimental::AltsCredentialsOptions; +using grpc::ClientContext; +using grpc::Status; +using grpc::ClientWriter; +using gt::gpp; +using gt::Inicont_Reply; +using gt::Inicont_Request; +using gt::Fincont_Reply; +using gt::Fincont_Request; +using gt::Opes_Reply; +using gt::Opes_Request; +using gt::Invo_Reply; +using gt::Invo_Request; +using gt::Close_Reply; +using gt::Close_Request; +using gt::TA_Chunk; +using gt::TA_Reply; + + +char glo_token[1024] = "noToken"; + + +bool utf8_check_is_valid(std::string &string) +{ + int c, i, ix, n, j; + for (i = 0, ix = string.length(); i < ix; i++) + { + c = (unsigned char) string[i]; + //if (c==0x09 || c==0x0a || c==0x0d || (0x20 <= c && c <= 0x7e) ) n = 0; // is_printable_ascii + if (0x00 <= c && c <= 0x7f) n = 0; // 0bbbbbbb + else if ((c & 0xE0) == 0xC0) n = 1; // 110bbbbb + else if (c == 0xed && i < (ix - 1) && ((unsigned char) string[i + 1] & 0xa0) == 0xa0) + return false; //U+d800 to U+dfff + else if ((c & 0xF0) == 0xE0) n = 2; // 1110bbbb + else if ((c & 0xF8) == 0xF0) n = 3; // 11110bbb + //else if (($c & 0xFC) == 0xF8) n=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8 + //else if (($c & 0xFE) == 0xFC) n=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8 + else return false; + for (j = 0; j < n && i < ix; j++) + { // n bytes matching 10bbbbbb follow ? + if ((++i == ix) || (((unsigned char) string[i] & 0xC0) != 0x80)) + return false; + } + } + return true; +} + +#define MAX_DATA_LEN 50*1024 +#define SHA256_LENTH 32 + +int get_file_sha256(char *file_path, char *val) +{ + SHA256_CTX sha256_ctx; + FILE *fp = NULL; + char *strFilePath = file_path; + unsigned char SHA256result[SHA256_LENTH]; + char DataBuff[MAX_DATA_LEN]; + int len; + int t = 0; + int i; + std::string sha256; + + + fp = fopen(strFilePath, "rb"); + + SHA256_Init(&sha256_ctx); + + while (!feof(fp)) + { + memset(DataBuff, 0x00, sizeof(DataBuff)); + + len = fread(DataBuff, 1, MAX_DATA_LEN, fp); + if (len) + { + t += len; + SHA256_Update(&sha256_ctx, DataBuff, len); + } + } + + fclose(fp); + SHA256_Final(SHA256result, &sha256_ctx); + + + if (val == NULL || sizeof(val) * 4 < SHA256_LENTH) + { + return -1; + } else + { + memset(val, 0, sizeof(val)); + for (int itemp = 0; itemp < SHA256_LENTH; itemp++) + { + val[itemp] = SHA256result[itemp]; + } + + } + + return 0; +} + + +class GppClient +{ +public: + GppClient(std::shared_ptr channel) + : stub_(gpp::NewStub(channel)) + {} + + // Assembles the client's payload, + // sends it and presents the response back from the server. + retstru_teec_inicont externc_teec_initializecontext( + std::uint8_t *name, + std::size_t name_size + ) + { + // Data we are sending to the server. + Inicont_Request request; + request.set_name_size(name_size); + if (name_size > 0) + { + std::string name_temp((char *) name); + request.set_name(name_temp); + } + request.set_token(glo_token); + + // Container for the data we expect from the server. + Inicont_Reply reply; + + ClientContext context; + retstru_teec_inicont rreply; + + // The actual RPC. + Status status = stub_->TEECC_InitializeContext(&context, request, &reply); + retstru_teec_inicont error; + + rreply.teecresult = reply.teecresult(); + rreply.context_fd = reply.context_fd(); + rreply.context_tapath_outsize = reply.context_tapath_outsize(); + if (rreply.context_tapath_outsize > 0) + { + rreply.context_tapath = (uint8_t *) malloc((rreply.context_tapath_outsize + 1) * sizeof(uint8_t));; + reply.context_tapath().copy((char *) rreply.context_tapath, rreply.context_tapath_outsize, 0); + } + rreply.context_sessionlist_next = reply.context_sessionlist_next(); + rreply.context_sessionlist_prev = reply.context_sessionlist_prev(); + rreply.context_shrdmemlist_prev = reply.context_shrdmemlist_prev(); + rreply.context_shrdmemlist_next = reply.context_shrdmemlist_next(); + rreply.context_sharebuffer_buffer = reply.context_sharebuffer_buffer(); + rreply.context_sharebuffer_bufferbarrier = reply.context_sharebuffer_bufferbarrier(); + rreply.context_addr = reply.context_addr(); + rreply.flag = reply.flag(); + // Act upon its status. + if (status.ok()) + { + return rreply; + } else + { + std::cout << "libteecc initcontext grpc error: " << status.error_code() << ", " << status.error_message() + << std::endl; + return error; + } + } + + retstru_teec_fincont externc_teec_finalizecontext( + std::int32_t in_context_fd, + std::uint8_t *in_context_tapath, + std::int32_t in_context_tapath_size, + std::uint64_t in_context_sessionlist_next, + std::uint64_t in_context_sessionlist_prev, + std::uint64_t in_context_shrdmemlist_next, + std::uint64_t in_context_shrdmemlist_prev, + std::uint64_t in_context_sharebuffer_buffer, + std::int64_t in_context_sharebuffer_bufferbarrier, + std::uint64_t in_context_addr + ) + { + // Data we are sending to the server. + Fincont_Request request; + + request.set_in_context_fd(in_context_fd); + request.set_in_context_tapath_size(in_context_tapath_size); + if (in_context_tapath_size > 0) + { + std::string in_context_tapath_temp((char *) in_context_tapath); + request.set_in_context_tapath(in_context_tapath_temp); + } + request.set_in_context_sessionlist_next(in_context_sessionlist_next); + request.set_in_context_sessionlist_prev(in_context_sessionlist_prev); + request.set_in_context_shrdmemlist_prev(in_context_shrdmemlist_prev); + request.set_in_context_shrdmemlist_next(in_context_shrdmemlist_next); + request.set_in_context_sharebuffer_buffer(in_context_sharebuffer_buffer); + request.set_in_context_sharebuffer_bufferbarrier(in_context_sharebuffer_bufferbarrier); + request.set_in_context_addr(in_context_addr); + request.set_token(glo_token); + + //questntainer for the data we expect from the server. + Fincont_Reply reply; + ClientContext context; + retstru_teec_fincont rreply; + + // The actual RPC. + Status status = stub_->TEECC_FinalizeContext(&context, request, &reply); + retstru_teec_fincont error; + + rreply.context_fd = reply.context_fd(); + rreply.context_tapath_outsize = reply.context_tapath_outsize(); + if (rreply.context_tapath_outsize > 0) + { + rreply.context_tapath = (uint8_t *) malloc((rreply.context_tapath_outsize + 1) * sizeof(uint8_t));; + reply.context_tapath().copy((char *) rreply.context_tapath, rreply.context_tapath_outsize, 0); + } + rreply.context_sessionlist_next = reply.context_sessionlist_next(); + rreply.context_sessionlist_prev = reply.context_sessionlist_prev(); + rreply.context_shrdmemlist_prev = reply.context_shrdmemlist_prev(); + rreply.context_shrdmemlist_next = reply.context_shrdmemlist_next(); + rreply.context_sharebuffer_buffer = reply.context_sharebuffer_buffer(); + rreply.context_sharebuffer_bufferbarrier = reply.context_sharebuffer_bufferbarrier(); + rreply.flag = reply.flag(); + // Act upon its status. + if (status.ok()) + { + return rreply; + } else + { + std::cout << "libteecc finalizecontext grpc error: " << status.error_code() << ", " << status.error_message() + << std::endl; + return error; + } + } + + retstru_teec_opensession externc_teec_opensession( + std::int32_t in_context_fd, + std::uint8_t *in_context_tapath, + std::int32_t in_context_tapath_size, + std::uint64_t in_context_sessionlist_next, + std::uint64_t in_context_sessionlist_prev, + std::uint64_t in_context_shrdmemlist_next, + std::uint64_t in_context_shrdmemlist_prev, + std::uint64_t in_context_sharebuffer_buffer, + std::int64_t in_context_sharebuffer_bufferbarrier, + std::uint32_t in_destination_timelow, + std::uint32_t in_destination_timemid, + std::uint32_t in_destination_timehiandver, + std::uint8_t *in_destination_clockseqandnode, + std::int32_t in_destination_clockseqandnode_size, + std::uint32_t in_connectionmethod, + std::uint64_t in_connectiondata, + std::uint32_t in_operation_started, + std::uint32_t in_operation_paramtypes, + std::uint64_t in_operation_param1_tmpref_buffer, + std::uint32_t in_operation_param1_tmpref_size, + std::uint64_t in_operation_param1_memref_parent, + std::uint32_t in_operation_param1_memref_size, + std::uint32_t in_operation_param1_memref_offset, + std::uint32_t in_operation_param1_value_a, + std::uint32_t in_operation_param1_value_b, + std::int32_t in_operation_param1_ionref_ionsharefd, + std::uint32_t in_operation_param1_ionref_ionsize, + std::uint64_t in_operation_param2_tmpref_buffer, + std::uint32_t in_operation_param2_tmpref_size, + std::uint64_t in_operation_param2_memref_parent, + std::uint32_t in_operation_param2_memref_size, + std::uint32_t in_operation_param2_memref_offset, + std::uint32_t in_operation_param2_value_a, + std::uint32_t in_operation_param2_value_b, + std::int32_t in_operation_param2_ionref_ionsharefd, + std::uint32_t in_operation_param2_ionref_ionsize, + std::uint64_t in_operation_param3_tmpref_buffer, + std::uint32_t in_operation_param3_tmpref_size, + std::uint64_t in_operation_param3_memref_parent, + std::uint32_t in_operation_param3_memref_size, + std::uint32_t in_operation_param3_memref_offset, + std::uint32_t in_operation_param3_value_a, + std::uint32_t in_operation_param3_value_b, + std::int32_t in_operation_param3_ionref_ionsharefd, + std::uint32_t in_operation_param3_ionref_ionsize, + std::uint64_t in_operation_param4_tmpref_buffer, + std::uint32_t in_operation_param4_tmpref_size, + std::uint64_t in_operation_param4_memref_parent, + std::uint32_t in_operation_param4_memref_size, + std::uint32_t in_operation_param4_memref_offset, + std::uint32_t in_operation_param4_value_a, + std::uint32_t in_operation_param4_value_b, + std::int32_t in_operation_param4_ionref_ionsharefd, + std::uint32_t in_operation_param4_ionref_ionsize, + std::uint64_t in_operation_session, + std::int32_t in_operation_cancelflag, + std::uint32_t in_returnorigin, + std::uint64_t in_context_addr + ) + { + // Data we are sending to the server. + Opes_Request request; + request.set_in_context_fd(in_context_fd); + request.set_in_context_tapath_size(in_context_tapath_size); + if (in_context_tapath_size > 0) + { + std::string in_context_tapath_temp((char *) in_context_tapath); + request.set_in_context_tapath(in_context_tapath_temp); + } + request.set_in_context_sessionlist_next(in_context_sessionlist_next); + request.set_in_context_sessionlist_prev(in_context_sessionlist_prev); + request.set_in_context_shrdmemlist_prev(in_context_shrdmemlist_prev); + request.set_in_context_shrdmemlist_next(in_context_shrdmemlist_next); + request.set_in_context_sharebuffer_buffer(in_context_sharebuffer_buffer); + request.set_in_context_sharebuffer_bufferbarrier(in_context_sharebuffer_bufferbarrier); + request.set_in_destination_timelow(in_destination_timelow); + request.set_in_destination_timemid(in_destination_timemid); + request.set_in_destination_timehiandver(in_destination_timehiandver); + request.set_in_destination_cad_size(in_destination_clockseqandnode_size); + if (in_destination_clockseqandnode_size > 0) + { + for (int i = 0; i < in_destination_clockseqandnode_size; i++) + { + request.add_in_destination_clockseqandnode(in_destination_clockseqandnode[i]); + } + + } + request.set_in_connectionmethod(in_connectionmethod); + request.set_in_connectiondata(in_connectiondata); + request.set_in_operation_started(in_operation_started); + request.set_in_operation_paramtypes(in_operation_paramtypes); + request.set_in_operation_param1_tmpref_buffer(in_operation_param1_tmpref_buffer); + request.set_in_operation_param1_tmpref_size(in_operation_param1_tmpref_size); + request.set_in_operation_param1_memref_parent(in_operation_param1_memref_parent); + request.set_in_operation_param1_memref_size(in_operation_param1_memref_size); + request.set_in_operation_param1_memref_offset(in_operation_param1_memref_offset); + request.set_in_operation_param1_value_a(in_operation_param1_value_a); + request.set_in_operation_param1_value_b(in_operation_param1_value_b); + request.set_in_operation_param1_ionref_ionsharefd(in_operation_param1_ionref_ionsharefd); + request.set_in_operation_param1_ionref_ionsize(in_operation_param1_ionref_ionsize); + request.set_in_operation_param2_tmpref_buffer(in_operation_param2_tmpref_buffer); + request.set_in_operation_param2_tmpref_size(in_operation_param2_tmpref_size); + request.set_in_operation_param2_memref_parent(in_operation_param2_memref_parent); + request.set_in_operation_param2_memref_size(in_operation_param2_memref_size); + request.set_in_operation_param2_memref_offset(in_operation_param2_memref_offset); + request.set_in_operation_param2_value_a(in_operation_param2_value_a); + request.set_in_operation_param2_value_b(in_operation_param2_value_b); + request.set_in_operation_param2_ionref_ionsharefd(in_operation_param2_ionref_ionsharefd); + request.set_in_operation_param2_ionref_ionsize(in_operation_param2_ionref_ionsize); + request.set_in_operation_param3_tmpref_buffer(in_operation_param3_tmpref_buffer); + request.set_in_operation_param3_tmpref_size(in_operation_param3_tmpref_size); + request.set_in_operation_param3_memref_parent(in_operation_param3_memref_parent); + request.set_in_operation_param3_memref_size(in_operation_param3_memref_size); + request.set_in_operation_param3_memref_offset(in_operation_param3_memref_offset); + request.set_in_operation_param3_value_a(in_operation_param3_value_a); + request.set_in_operation_param3_value_b(in_operation_param3_value_b); + request.set_in_operation_param3_ionref_ionsharefd(in_operation_param3_ionref_ionsharefd); + request.set_in_operation_param3_ionref_ionsize(in_operation_param3_ionref_ionsize); + request.set_in_operation_param4_tmpref_buffer(in_operation_param4_tmpref_buffer); + request.set_in_operation_param4_tmpref_size(in_operation_param4_tmpref_size); + request.set_in_operation_param4_memref_parent(in_operation_param4_memref_parent); + request.set_in_operation_param4_memref_size(in_operation_param4_memref_size); + request.set_in_operation_param4_memref_offset(in_operation_param4_memref_offset); + request.set_in_operation_param4_value_a(in_operation_param4_value_a); + request.set_in_operation_param4_value_b(in_operation_param4_value_b); + request.set_in_operation_param4_ionref_ionsharefd(in_operation_param4_ionref_ionsharefd); + request.set_in_operation_param4_ionref_ionsize(in_operation_param4_ionref_ionsize); + request.set_in_operation_session(in_operation_session); + request.set_in_operation_cancelflag(in_operation_cancelflag); + request.set_in_returnorigin(in_returnorigin); + request.set_in_context_addr(in_context_addr); + + request.set_token(glo_token); + //questntainer for the data we expect from the server. + Opes_Reply reply; + ClientContext context; + retstru_teec_opensession rreply; + + // The actual RPC. + Status status = stub_->TEECC_OpenSession(&context, request, &reply); + retstru_teec_opensession error; + + rreply.teecresult = reply.teecresult(); + rreply.context_fd = reply.context_fd(); + rreply.context_tapath_outsize = reply.context_tapath_outsize(); + if (rreply.context_tapath_outsize > 0) + { + rreply.context_tapath = (uint8_t *) malloc((rreply.context_tapath_outsize + 1) * sizeof(uint8_t));; + reply.context_tapath().copy((char *) rreply.context_tapath, rreply.context_tapath_outsize, 0); + } + rreply.context_sessionlist_next = reply.context_sessionlist_next(); + rreply.context_sessionlist_prev = reply.context_sessionlist_prev(); + rreply.context_shrdmemlist_prev = reply.context_shrdmemlist_prev(); + rreply.context_shrdmemlist_next = reply.context_shrdmemlist_next(); + rreply.context_sharebuffer_buffer = reply.context_sharebuffer_buffer(); + rreply.session_sessionid = reply.session_sessionid(); + rreply.session_serviceid_timelow = reply.session_serviceid_timelow(); + rreply.session_serviceid_timemid = reply.session_serviceid_timemid(); + rreply.session_serviceid_timehiandver = reply.session_serviceid_timehiandver(); + rreply.session_serviceid_clockseqandnode_outsize = reply.session_serviceid_clockseqandnode_outsize(); + if (rreply.session_serviceid_clockseqandnode_outsize > 0) + { + rreply.session_serviceid_clockseqandnode = new uint8_t[rreply.session_serviceid_clockseqandnode_outsize]; + for (int i = 0; i < rreply.session_serviceid_clockseqandnode_outsize; i++) + { + rreply.session_serviceid_clockseqandnode[i] = reply.session_serviceid_clockseqandnode(i); + } + } + rreply.session_opscnt = reply.session_opscnt(); + rreply.session_head_next = reply.session_head_next(); + rreply.session_head_prev = reply.session_head_prev(); + rreply.session_context = reply.session_context(); + rreply.operation_started = reply.operation_started(); + rreply.operation_paramtypes = reply.operation_paramtypes(); + rreply.operation_param1_tmpref_buffer = reply.operation_param1_tmpref_buffer(); + rreply.operation_param1_tmpref_size = reply.operation_param1_tmpref_size(); + rreply.operation_param1_memref_parent = reply.operation_param1_memref_parent(); + rreply.operation_param1_memref_size = reply.operation_param1_memref_size(); + rreply.operation_param1_memref_offset = reply.operation_param1_memref_offset(); + rreply.operation_param1_value_a = reply.operation_param1_value_a(); + rreply.operation_param1_value_b = reply.operation_param1_value_b(); + rreply.operation_param1_ionref_ionsharefd = reply.operation_param1_ionref_ionsharefd(); + rreply.operation_param1_ionref_ionsize = reply.operation_param1_ionref_ionsize(); + rreply.operation_param2_tmpref_buffer = reply.operation_param2_tmpref_buffer(); + rreply.operation_param2_tmpref_size = reply.operation_param2_tmpref_size(); + rreply.operation_param2_memref_parent = reply.operation_param2_memref_parent(); + rreply.operation_param2_memref_size = reply.operation_param2_memref_size(); + rreply.operation_param2_memref_offset = reply.operation_param2_memref_offset(); + rreply.operation_param2_value_a = reply.operation_param2_value_a(); + rreply.operation_param2_value_b = reply.operation_param2_value_b(); + rreply.operation_param2_ionref_ionsharefd = reply.operation_param2_ionref_ionsharefd(); + rreply.operation_param2_ionref_ionsize = reply.operation_param2_ionref_ionsize(); + rreply.operation_param3_tmpref_buffer = reply.operation_param3_tmpref_buffer(); + rreply.operation_param3_tmpref_size = reply.operation_param3_tmpref_size(); + rreply.operation_param3_memref_parent = reply.operation_param3_memref_parent(); + rreply.operation_param3_memref_size = reply.operation_param3_memref_size(); + rreply.operation_param3_memref_offset = reply.operation_param3_memref_offset(); + rreply.operation_param3_value_a = reply.operation_param3_value_a(); + rreply.operation_param3_value_b = reply.operation_param3_value_b(); + rreply.operation_param3_ionref_ionsharefd = reply.operation_param3_ionref_ionsharefd(); + rreply.operation_param3_ionref_ionsize = reply.operation_param3_ionref_ionsize(); + rreply.operation_param4_tmpref_buffer = reply.operation_param4_tmpref_buffer(); + rreply.operation_param4_tmpref_size = reply.operation_param4_tmpref_size(); + rreply.operation_param4_memref_parent = reply.operation_param4_memref_parent(); + rreply.operation_param4_memref_size = reply.operation_param4_memref_size(); + rreply.operation_param4_memref_offset = reply.operation_param4_memref_offset(); + rreply.operation_param4_value_a = reply.operation_param4_value_a(); + rreply.operation_param4_value_b = reply.operation_param4_value_b(); + rreply.operation_param4_ionref_ionsharefd = reply.operation_param4_ionref_ionsharefd(); + rreply.operation_param4_ionref_ionsize = reply.operation_param4_ionref_ionsize(); + rreply.operation_session = reply.operation_session(); + rreply.operation_cancelflag = reply.operation_cancelflag(); + rreply.returnorigin = reply.returnorigin(); + rreply.flag = reply.flag(); + + // Act upon its status. + if (status.ok()) + { + return rreply; + } else + { + std::cout << "libteecc opensession grpc error: " << status.error_code() << ", " << status.error_message() + << std::endl; + return error; + } + } + + retstru_teec_invokecommand externc_teec_invokecommand( + std::uint32_t in_session_sessionid, + std::uint32_t in_session_serviceid_timelow, + std::uint32_t in_session_serviceid_timemid, + std::uint32_t in_session_serviceid_timehiandver, + std::uint8_t *in_session_serviceid_clockseqandnode, + std::uintptr_t in_session_serviceid_clockseqandnode_size, + std::uint32_t in_session_opscnt, + std::uint64_t in_session_head_next, + std::uint64_t in_session_head_prev, + std::uint64_t in_session_context, + std::uint32_t in_commandid, + std::uint32_t in_operation_started, + std::uint32_t in_operation_paramtypes, + std::uint64_t in_operation_param1_tmpref_buffer, + std::uint32_t in_operation_param1_tmpref_size, + std::uint64_t in_operation_param1_memref_parent, + std::uint32_t in_operation_param1_memref_parent_flag, + std::uint32_t in_operation_param1_memref_size, + std::uint32_t in_operation_param1_memref_offset, + std::uint32_t in_operation_param1_value_a, + std::uint32_t in_operation_param1_value_b, + std::int32_t in_operation_param1_ionref_ionsharefd, + std::uint32_t in_operation_param1_ionref_ionsize, + std::uint64_t in_operation_param2_tmpref_buffer, + std::uint32_t in_operation_param2_tmpref_size, + std::uint64_t in_operation_param2_memref_parent, + std::uint32_t in_operation_param2_memref_parent_flag, + std::uint32_t in_operation_param2_memref_size, + std::uint32_t in_operation_param2_memref_offset, + std::uint32_t in_operation_param2_value_a, + std::uint32_t in_operation_param2_value_b, + std::int32_t in_operation_param2_ionref_ionsharefd, + std::uint32_t in_operation_param2_ionref_ionsize, + std::uint64_t in_operation_param3_tmpref_buffer, + std::uint32_t in_operation_param3_tmpref_size, + std::uint64_t in_operation_param3_memref_parent, + std::uint32_t in_operation_param3_memref_parent_flag, + std::uint32_t in_operation_param3_memref_size, + std::uint32_t in_operation_param3_memref_offset, + std::uint32_t in_operation_param3_value_a, + std::uint32_t in_operation_param3_value_b, + std::int32_t in_operation_param3_ionref_ionsharefd, + std::uint32_t in_operation_param3_ionref_ionsize, + std::uint64_t in_operation_param4_tmpref_buffer, + std::uint32_t in_operation_param4_tmpref_size, + std::uint64_t in_operation_param4_memref_parent, + std::uint32_t in_operation_param4_memref_parent_flag, + std::uint32_t in_operation_param4_memref_size, + std::uint32_t in_operation_param4_memref_offset, + std::uint32_t in_operation_param4_value_a, + std::uint32_t in_operation_param4_value_b, + std::int32_t in_operation_param4_ionref_ionsharefd, + std::uint32_t in_operation_param4_ionref_ionsize, + std::uint64_t in_operation_session, + std::int32_t in_operation_cancelflag, + std::uint32_t in_returnorigin, + std::uint8_t *in_buffer1, + std::uintptr_t in_buffer1_size, + std::uint8_t *in_buffer2, + std::uintptr_t in_buffer2_size, + std::uint8_t *in_buffer3, + std::uintptr_t in_buffer3_size, + std::uint8_t *in_buffer4, + std::uintptr_t in_buffer4_size + ) + { + // Data we are sending to the server. + Invo_Request request; + request.set_in_session_sessionid(in_session_sessionid); + + request.set_in_session_serviceid_timelow(in_session_serviceid_timelow); + request.set_in_session_serviceid_timemid(in_session_serviceid_timemid); + request.set_in_session_serviceid_timehiandver(in_session_serviceid_timehiandver); + request.set_in_session_serviceid_cad_size(in_session_serviceid_clockseqandnode_size); + if (in_session_serviceid_clockseqandnode_size > 0) + { + for (int i = 0; i < in_session_serviceid_clockseqandnode_size; i++) + { + request.add_in_session_serviceid_clockseqandnode(in_session_serviceid_clockseqandnode[i]); + } + + } + request.set_in_session_opscnt(in_session_opscnt); + request.set_in_session_head_next(in_session_head_next); + request.set_in_session_head_prev(in_session_head_prev); + request.set_in_session_context(in_session_context); + request.set_in_commandid(in_commandid); + request.set_in_operation_started(in_operation_started); + request.set_in_operation_paramtypes(in_operation_paramtypes); + request.set_in_operation_param1_tmpref_buffer(in_operation_param1_tmpref_buffer); + request.set_in_operation_param1_tmpref_size(in_operation_param1_tmpref_size); + request.set_in_operation_param1_memref_parent(in_operation_param1_memref_parent); + request.set_in_operation_param1_memref_parent_flag(in_operation_param1_memref_parent_flag); + request.set_in_operation_param1_memref_size(in_operation_param1_memref_size); + request.set_in_operation_param1_memref_offset(in_operation_param1_memref_offset); + request.set_in_operation_param1_value_a(in_operation_param1_value_a); + request.set_in_operation_param1_value_b(in_operation_param1_value_b); + request.set_in_operation_param1_ionref_ionsharefd(in_operation_param1_ionref_ionsharefd); + request.set_in_operation_param1_ionref_ionsize(in_operation_param1_ionref_ionsize); + request.set_in_operation_param2_tmpref_buffer(in_operation_param2_tmpref_buffer); + request.set_in_operation_param2_tmpref_size(in_operation_param2_tmpref_size); + request.set_in_operation_param2_memref_parent(in_operation_param2_memref_parent); + request.set_in_operation_param2_memref_parent_flag(in_operation_param2_memref_parent_flag); + request.set_in_operation_param2_memref_size(in_operation_param2_memref_size); + request.set_in_operation_param2_memref_offset(in_operation_param2_memref_offset); + request.set_in_operation_param2_value_a(in_operation_param2_value_a); + request.set_in_operation_param2_value_b(in_operation_param2_value_b); + request.set_in_operation_param2_ionref_ionsharefd(in_operation_param2_ionref_ionsharefd); + request.set_in_operation_param2_ionref_ionsize(in_operation_param2_ionref_ionsize); + request.set_in_operation_param3_tmpref_buffer(in_operation_param3_tmpref_buffer); + request.set_in_operation_param3_tmpref_size(in_operation_param3_tmpref_size); + request.set_in_operation_param3_memref_parent(in_operation_param3_memref_parent); + request.set_in_operation_param3_memref_parent_flag(in_operation_param3_memref_parent_flag); + request.set_in_operation_param3_memref_size(in_operation_param3_memref_size); + request.set_in_operation_param3_memref_offset(in_operation_param3_memref_offset); + request.set_in_operation_param3_value_a(in_operation_param3_value_a); + request.set_in_operation_param3_value_b(in_operation_param3_value_b); + request.set_in_operation_param3_ionref_ionsharefd(in_operation_param3_ionref_ionsharefd); + request.set_in_operation_param3_ionref_ionsize(in_operation_param3_ionref_ionsize); + request.set_in_operation_param4_tmpref_buffer(in_operation_param4_tmpref_buffer); + request.set_in_operation_param4_tmpref_size(in_operation_param4_tmpref_size); + request.set_in_operation_param4_memref_parent(in_operation_param4_memref_parent); + request.set_in_operation_param4_memref_parent_flag(in_operation_param4_memref_parent_flag); + request.set_in_operation_param4_memref_size(in_operation_param4_memref_size); + request.set_in_operation_param4_memref_offset(in_operation_param4_memref_offset); + request.set_in_operation_param4_value_a(in_operation_param4_value_a); + request.set_in_operation_param4_value_b(in_operation_param4_value_b); + request.set_in_operation_param4_ionref_ionsharefd(in_operation_param4_ionref_ionsharefd); + request.set_in_operation_param4_ionref_ionsize(in_operation_param4_ionref_ionsize); + request.set_in_operation_session(in_operation_session); + request.set_in_operation_cancelflag(in_operation_cancelflag); + request.set_in_returnorigin(in_returnorigin); + request.set_in_bufer1_size(in_buffer1_size); + if (in_buffer1_size > 0) + { + for (int i = 0; i < in_buffer1_size; i++) + { + request.add_in_buffer1(in_buffer1[i]); + } + } + request.set_in_bufer2_size(in_buffer2_size); + if (in_buffer2_size > 0) + { + for (int i = 0; i < in_buffer2_size; i++) + { + request.add_in_buffer2(in_buffer2[i]); + } + } + request.set_in_bufer3_size(in_buffer3_size); + if (in_buffer3_size > 0) + { + for (int i = 0; i < in_buffer3_size; i++) + { + request.add_in_buffer3(in_buffer3[i]); + } + } + request.set_in_bufer4_size(in_buffer4_size); + if (in_buffer4_size > 0) + { + for (int i = 0; i < in_buffer4_size; i++) + { + request.add_in_buffer4(in_buffer4[i]); + } + } + request.set_token(glo_token); + //questntainer for the data we expect from the server. + Invo_Reply reply; + ClientContext context; + retstru_teec_invokecommand rreply; + + // The actual RPC. + Status status = stub_->TEECC_InvokeCommand(&context, request, &reply); + retstru_teec_invokecommand error; + + rreply.teecresult = reply.teecresult(); + rreply.session_sessionid = reply.session_sessionid(); + rreply.session_serviceid_timelow = reply.session_serviceid_timelow(); + rreply.session_serviceid_timemid = reply.session_serviceid_timemid(); + rreply.session_serviceid_timehiandver = reply.session_serviceid_timehiandver(); + rreply.session_serviceid_clockseqandnode_outsize = reply.session_serviceid_clockseqandnode_outsize(); + if (rreply.session_serviceid_clockseqandnode_outsize > 0) + { + rreply.session_serviceid_clockseqandnode = new uint8_t[rreply.session_serviceid_clockseqandnode_outsize]; + for (int i = 0; i < rreply.session_serviceid_clockseqandnode_outsize; i++) + { + rreply.session_serviceid_clockseqandnode[i] = reply.session_serviceid_clockseqandnode(i); + } + } + rreply.session_opscnt = reply.session_opscnt(); + rreply.session_head_next = reply.session_head_next(); + rreply.session_head_prev = reply.session_head_prev(); + rreply.session_context = reply.session_context(); + rreply.operation_started = reply.operation_started(); + rreply.operation_paramtypes = reply.operation_paramtypes(); + rreply.operation_param1_tmpref_buffer = reply.operation_param1_tmpref_buffer(); + rreply.operation_param1_tmpref_size = reply.operation_param1_tmpref_size(); + rreply.operation_param1_memref_parent = reply.operation_param1_memref_parent(); + rreply.operation_param1_memref_parent_flag = reply.operation_param1_memref_parent_flag(); + rreply.operation_param1_memref_size = reply.operation_param1_memref_size(); + rreply.operation_param1_memref_offset = reply.operation_param1_memref_offset(); + rreply.operation_param1_value_a = reply.operation_param1_value_a(); + rreply.operation_param1_value_b = reply.operation_param1_value_b(); + rreply.operation_param1_ionref_ionsharefd = reply.operation_param1_ionref_ionsharefd(); + rreply.operation_param1_ionref_ionsize = reply.operation_param1_ionref_ionsize(); + + rreply.operation_param2_tmpref_buffer = reply.operation_param2_tmpref_buffer(); + rreply.operation_param2_tmpref_size = reply.operation_param2_tmpref_size(); + rreply.operation_param2_memref_parent = reply.operation_param2_memref_parent(); + rreply.operation_param2_memref_parent_flag = reply.operation_param2_memref_parent_flag(); + rreply.operation_param2_memref_size = reply.operation_param2_memref_size(); + rreply.operation_param2_memref_offset = reply.operation_param2_memref_offset(); + rreply.operation_param2_value_a = reply.operation_param2_value_a(); + rreply.operation_param2_value_b = reply.operation_param2_value_b(); + rreply.operation_param2_ionref_ionsharefd = reply.operation_param2_ionref_ionsharefd(); + rreply.operation_param2_ionref_ionsize = reply.operation_param2_ionref_ionsize(); + + rreply.operation_param3_tmpref_buffer = reply.operation_param3_tmpref_buffer(); + rreply.operation_param3_tmpref_size = reply.operation_param3_tmpref_size(); + rreply.operation_param3_memref_parent = reply.operation_param3_memref_parent(); + rreply.operation_param3_memref_parent_flag = reply.operation_param3_memref_parent_flag(); + rreply.operation_param3_memref_size = reply.operation_param3_memref_size(); + rreply.operation_param3_memref_offset = reply.operation_param3_memref_offset(); + rreply.operation_param3_value_a = reply.operation_param3_value_a(); + rreply.operation_param3_value_b = reply.operation_param3_value_b(); + rreply.operation_param3_ionref_ionsharefd = reply.operation_param3_ionref_ionsharefd(); + rreply.operation_param3_ionref_ionsize = reply.operation_param3_ionref_ionsize(); + + rreply.operation_param4_tmpref_buffer = reply.operation_param4_tmpref_buffer(); + rreply.operation_param4_tmpref_size = reply.operation_param4_tmpref_size(); + rreply.operation_param4_memref_parent = reply.operation_param4_memref_parent(); + rreply.operation_param4_memref_parent_flag = reply.operation_param4_memref_parent_flag(); + rreply.operation_param4_memref_size = reply.operation_param4_memref_size(); + rreply.operation_param4_memref_offset = reply.operation_param4_memref_offset(); + rreply.operation_param4_value_a = reply.operation_param4_value_a(); + rreply.operation_param4_value_b = reply.operation_param4_value_b(); + rreply.operation_param4_ionref_ionsharefd = reply.operation_param4_ionref_ionsharefd(); + rreply.operation_param4_ionref_ionsize = reply.operation_param4_ionref_ionsize(); + + rreply.operation_session = reply.operation_session(); + rreply.operation_cancelflag = reply.operation_cancelflag(); + rreply.returnorigin = reply.returnorigin(); + rreply.buffer1_outsize = reply.buffer1_outsize(); + if (rreply.buffer1_outsize > 0) + { + rreply.buffer1 = new uint8_t[rreply.buffer1_outsize]; + for (int i = 0; i < rreply.buffer1_outsize; i++) + { + rreply.buffer1[i] = reply.buffer1(i); + } + } + rreply.buffer2_outsize = reply.buffer2_outsize(); + if (rreply.buffer2_outsize > 0) + { + rreply.buffer2 = new uint8_t[rreply.buffer2_outsize]; + for (int i = 0; i < rreply.buffer2_outsize; i++) + { + rreply.buffer2[i] = reply.buffer2(i); + } + } + rreply.buffer3_outsize = reply.buffer3_outsize(); + if (rreply.buffer3_outsize > 0) + { + rreply.buffer3 = new uint8_t[rreply.buffer3_outsize]; + for (int i = 0; i < rreply.buffer3_outsize; i++) + { + rreply.buffer3[i] = reply.buffer3(i); + } + } + rreply.buffer4_outsize = reply.buffer4_outsize(); + if (rreply.buffer4_outsize > 0) + { + rreply.buffer4 = new uint8_t[rreply.buffer4_outsize]; + for (int i = 0; i < rreply.buffer4_outsize; i++) + { + rreply.buffer4[i] = reply.buffer4(i); + } + } + rreply.flag = reply.flag(); + + // Act upon its status. + if (status.ok()) + { + return rreply; + } else + { + std::cout << "libteec invokecommand grpc error: " << status.error_code() << ", " << status.error_message() + << std::endl; + return error; + } + } + + retstru_teec_closesession externc_teec_closesession( + std::uint32_t in_session_sessionid, + std::uint32_t in_session_serviceid_timelow, + std::uint32_t in_session_serviceid_timemid, + std::uint32_t in_session_serviceid_timehiandver, + std::uint8_t *in_session_serviceid_clockseqandnode, + std::uintptr_t in_session_serviceid_clockseqandnode_size, + std::uint32_t in_session_opscnt, + std::uint64_t in_session_head_next, + std::uint64_t in_session_head_prev, + std::uint64_t in_session_context + ) + { + Close_Request request; + + request.set_in_session_sessionid(in_session_sessionid); + request.set_in_session_serviceid_timelow(in_session_serviceid_timelow); + request.set_in_session_serviceid_timemid(in_session_serviceid_timemid); + request.set_in_session_serviceid_timehiandver(in_session_serviceid_timehiandver); + request.set_in_session_serviceid_cad_size(in_session_serviceid_clockseqandnode_size); + if (in_session_serviceid_clockseqandnode_size > 0) + { + for (int i = 0; i < in_session_serviceid_clockseqandnode_size; i++) + { + request.add_in_session_serviceid_clockseqandnode(in_session_serviceid_clockseqandnode[i]); + } + } + request.set_in_session_opscnt(in_session_opscnt); + request.set_in_session_head_next(in_session_head_next); + request.set_in_session_head_prev(in_session_head_prev); + request.set_in_session_context(in_session_context); + request.set_token(glo_token); + + Close_Reply reply; + ClientContext context; + retstru_teec_closesession rreply; + // The actual RPC. + Status status = stub_->TEECC_CloseSession(&context, request, &reply); + retstru_teec_closesession error; + + rreply.session_sessionid = reply.session_sessionid(); + rreply.session_serviceid_timelow = reply.session_serviceid_timelow(); + rreply.session_serviceid_timemid = reply.session_serviceid_timemid(); + rreply.session_serviceid_timehiandver = reply.session_serviceid_timehiandver(); + rreply.session_serviceid_clockseqandnode_outsize = reply.session_serviceid_cad_outsize(); + + if (rreply.session_serviceid_clockseqandnode_outsize > 0) + { + rreply.session_serviceid_clockseqandnode = new uint8_t[rreply.session_serviceid_clockseqandnode_outsize]; + for (int i = 0; i < rreply.session_serviceid_clockseqandnode_outsize; i++) + { + rreply.session_serviceid_clockseqandnode[i] = reply.session_serviceid_clockseqandnode(i); + } + } + + rreply.session_opscnt = reply.session_opscnt(); + rreply.session_head_next = reply.session_head_next(); + rreply.session_head_prev = reply.session_head_prev(); + rreply.session_context = reply.session_context(); + rreply.flag = reply.flag(); + + // Act upon its status. + if (status.ok()) + { + return rreply; + } else + { + std::cout << "libteec closesession grpc error: " << status.error_code() << ", " << status.error_message() + << std::endl; + return error; + } + } + + + int + Upload( + std::string infile_path, + std::string subdir, + std::string outfile_name + ) + { + TA_Chunk chunk; + TA_Reply stats; + ClientContext context; + const char *filename = infile_path.data(); + std::ifstream infile; + int retcode = 0; + + struct timeval start, end; + gettimeofday(&start, NULL); + + infile.open(filename, std::ifstream::in | std::ifstream::binary); + if (!infile) + { + return TEEC_INFILE_NOT_FOUND; + } + + long beginoffset, endoffset; + beginoffset = infile.tellg(); + infile.seekg(0, std::ios::end); + endoffset = infile.tellg(); + long filesize = endoffset - beginoffset; + infile.seekg(0, std::ios::beg); + char *data = new char[filesize]; + infile.read(data, filesize); + + chunk.set_buffer(data, infile.gcount()); + + delete[]data; + infile.close(); + + if (subdir.empty()) + { + std::string strsubdirdefault("default"); + chunk.set_subdir(strsubdirdefault); + } else + { + bool bResult; + bResult = utf8_check_is_valid(subdir); + if (bResult == false) + { + return TEEC_FAIL; + } + + chunk.set_subdir(subdir); + } + + std::string stroutname; + std::string infile_path_temp = infile_path; + if (outfile_name.empty()) + { + char *filenametemp = const_cast(infile_path_temp.data()); + const char slash[] = "/"; + char *nametemp = strtok(filenametemp, slash); + while (nametemp != NULL) + { + stroutname = std::string(nametemp); + nametemp = strtok(NULL, slash); + } + chunk.set_name(stroutname); + } else + { + chunk.set_name(outfile_name); + } + + chunk.set_token(glo_token); + + char sha256[SHA256_LENTH]; + int iRet; + iRet = get_file_sha256((char *) filename, sha256); + if (iRet != 0) + { + return TEEC_FAIL; + } + + chunk.set_sha256(sha256, SHA256_LENTH); + + Status status = stub_->TEECC_TA(&context, chunk, &stats); + + + if (status.ok()) + { + retcode = stats.code(); + + if (stats.code() == 0) + { + retcode = 0; + } else if (stats.code() == -1) + { + std::cout << "libteeccc: deployta jwt validate error" << std::endl; + retcode = TEEC_ERROR_JWTVALIDATE_FAIL; + } else + { + retcode = TEEC_FAIL; + } + } else + { + std::cout << "libteec deployta grpc error: " << status.error_code() << ", " + << status.error_message() << std::endl; + retcode = TEEC_FAIL; + } + + return retcode; + } + + // Out of the passed in Channel comes the stub, stored here, our view of the + // server's exposed services. + std::unique_ptr stub_; +}; + + +static GppClient *client = NULL; +std::shared_ptr gpp_channel = NULL; + + +std::string global_strcfgfiletemp = getenv("HOME"); +std::string global_strcfgfile = global_strcfgfiletemp + "/.teecc/teecc_config.yaml"; +YAML::Node glo_config = YAML::LoadFile(global_strcfgfile); +std::string global_target_str = glo_config["GPPROXY_ADDRESS"].as(); +std::string global_servercacert_path = global_strcfgfiletemp + "/.teecc/certs/" + glo_config["NAME_SERVERCA_CERT"].as(); +std::string global_clientkey_path = global_strcfgfiletemp + "/.teecc/certs/" + glo_config["NAME_CLIENT_KEY"].as(); +std::string global_clientcert_path = global_strcfgfiletemp + "/.teecc/certs/" + glo_config["NAME_CLIENT_CERT"].as(); +int grpc_tls = glo_config["GRPC_TLS"].as(); + + +int64_t glob_scontaddr; + +bool isFileExists_ifstream(std::string &name) +{ + std::ifstream f(name.c_str()); + return f.good(); +} + +static std::string get_file_contents(std::string fpath) +{ + std::ifstream finstream(fpath); + std::string contents; + contents.assign((std::istreambuf_iterator(finstream)), + std::istreambuf_iterator()); + finstream.close(); + return contents; +} + + +TEEC_Result +TEEC_InitializeContext(const char *name, TEEC_Context *context) +{ + if (gpp_channel == NULL) + { + int igrpctls = grpc_tls; + + if (grpc_tls != 0 && grpc_tls != 1 && grpc_tls != 2) + { + std::cout << global_strcfgfile << " grpc_tls should be 0 or 1 or 2 " << std::endl; + return TEEC_FAIL; + } + + switch (igrpctls) + { + case 0: + { + gpp_channel = grpc::CreateChannel(global_target_str, grpc::InsecureChannelCredentials()); + + break; + } + + case 1: + { + if (!isFileExists_ifstream(global_servercacert_path)) + { + std::cout << "error file : " << global_servercacert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + + std::string strcmd; + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercacert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "gpp '" << global_servercacert_path << "' will expire in 7 days, please reget it" << std::endl; + return TEEC_FAIL; + } + + auto servercacert = get_file_contents(global_servercacert_path); + grpc::SslCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = servercacert; + std::shared_ptr creds = grpc::SslCredentials(ssl_opts); + gpp_channel = grpc::CreateChannel(global_target_str, creds); + + break; + } + + case 2: + { + if (!isFileExists_ifstream(global_servercacert_path)) + { + std::cout << "error file : " << global_servercacert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + if (!isFileExists_ifstream(global_clientkey_path)) + { + std::cout << "error file : " << global_clientkey_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + if (!isFileExists_ifstream(global_clientcert_path)) + { + std::cout << "error file : " << global_clientcert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + + std::string strcmd; + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercacert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "libteecc '" << global_servercacert_path << "' will expire in 7 days, please reget it" + << std::endl; + return TEEC_FAIL; + } + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_clientcert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "libteecc '" << global_clientcert_path << "' will expire in 7 days, please reget it" << std::endl; + return TEEC_FAIL; + } + + strcmd = "openssl rsa -in " + global_clientkey_path + " -out " + + global_clientkey_path + ".nopass"; + std::string nopass_clientkey_path = global_clientkey_path + ".nopass"; + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + + strcmd = "openssl rsa -in " + nopass_clientkey_path + " -check -noout"; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string keyok("RSA key ok\n"); + if (result.compare(keyok) != 0) + { + std::cout << "libteecc '" + global_clientkey_path + "' integrity is broken" << std::endl; + return TEEC_FAIL; + } + + std::string sigfile_path = global_strcfgfiletemp + "/.teecc/certs/msg.sig"; + std::string msgfile_path = global_strcfgfiletemp + "/.teecc/certs/msg.txt"; + strcmd = + "openssl dgst -sha256 -sign " + nopass_clientkey_path + " -out " + sigfile_path + " " + msgfile_path; + system(strcmd.c_str()); + // ${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + std::string pubkeyfile_path = global_strcfgfiletemp + "/.teecc/certs/client_pubkey.pem"; + strcmd = "openssl x509 -in " + global_clientcert_path + " -pubkey -out " + pubkeyfile_path; + system(strcmd.c_str()); + + // ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt + strcmd = "openssl dgst -sha256 -verify " + pubkeyfile_path + " -signature " + sigfile_path + " " + + msgfile_path; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + // std::cout << "gpp popen " << strcmd << " succed, result: " << result < creds = grpc::SslCredentials(ssl_opts); + gpp_channel = grpc::CreateChannel(global_target_str, creds); + + break; + } + + default: + { + gpp_channel = grpc::CreateChannel(global_target_str, grpc::InsecureChannelCredentials()); + } + } + + client = new GppClient( + gpp_channel + ); + } + + std::uint8_t *name_temp = NULL; + std::uint32_t name_size; + struct retstru_teec_inicont rs_inicont_ins; + + if (name != NULL) + { + name_temp = (uint8_t *) name; + name_size = strlen(name); + } else + { + name_size = 0; + } + + if (context == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + rs_inicont_ins = client->externc_teec_initializecontext(name_temp, + name_size + ); + if (rs_inicont_ins.flag == 1) + { + std::cout << "libteecc: inicont token null" << std::endl; + + return TEEC_ERROR_BAD_PARAMETERS; + } + if (rs_inicont_ins.flag == 2) + { + std::cout << "libteecc: inicont jwt validate error" << std::endl; + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (rs_inicont_ins.teecresult == TEEC_SUCCESS) + { + context->fd = rs_inicont_ins.context_fd; + + if ( + rs_inicont_ins.context_tapath_outsize > 0 && + rs_inicont_ins.context_tapath != NULL + ) + { + if (context->ta_path == NULL) + { + return TEEC_ERROR_CONTEXT_TAPATH_NULL; + } else + { + memcpy( + context->ta_path, + rs_inicont_ins.context_tapath, + rs_inicont_ins.context_tapath_outsize + ); + *(context->ta_path + rs_inicont_ins.context_tapath_outsize) = 0; + } + } else + { + context->ta_path = NULL; + } + context->session_list.next = (struct ListNode *) rs_inicont_ins.context_sessionlist_next; + context->session_list.prev = (struct ListNode *) rs_inicont_ins.context_sessionlist_prev; + context->shrd_mem_list.next = (struct ListNode *) rs_inicont_ins.context_shrdmemlist_next; + context->shrd_mem_list.prev = (struct ListNode *) rs_inicont_ins.context_shrdmemlist_prev; + context->share_buffer.buffer = (void *) rs_inicont_ins.context_sharebuffer_buffer; + context->share_buffer.buffer_barrier.__align = rs_inicont_ins.context_sharebuffer_bufferbarrier; + glob_scontaddr = rs_inicont_ins.context_addr; + } + return static_cast(rs_inicont_ins.teecresult); +} + +void +TEEC_FinalizeContext(TEEC_Context *context) +{ + std::int32_t in_context_fd; + std::uint8_t *in_context_tapath; + std::int32_t in_context_tapath_size; + std::uint64_t in_context_sessionlist_next; + std::uint64_t in_context_sessionlist_prev; + std::uint64_t in_context_shrdmemlist_next; + std::uint64_t in_context_shrdmemlist_prev; + std::uint64_t in_context_sharebuffer_buffer; + std::int64_t in_context_sharebuffer_bufferbarrier; + struct retstru_teec_fincont rs_fincont_ins; + + + if (gpp_channel == NULL) + { + std::cout << "libteecc: the grpc client or channel is null, when executing TEEC_FinalizeContext." << std::endl; + return; + } + + if (context == NULL) + { + return; + } + + in_context_fd = context->fd; + in_context_tapath = context->ta_path; + if (in_context_tapath == NULL) + { + in_context_tapath_size = 0; + } else + { + std::string strtmp((char *) in_context_tapath); + bool bResult; + bResult = utf8_check_is_valid(strtmp); + if (bResult == true) + { + in_context_tapath_size = strtmp.length(); + } else + { + in_context_tapath_size = 0; + } + } + in_context_sessionlist_next = (uint64_t) context->session_list.next; + in_context_sessionlist_prev = (uint64_t) context->session_list.prev; + in_context_shrdmemlist_next = (uint64_t) context->shrd_mem_list.next; + in_context_shrdmemlist_prev = (uint64_t) context->shrd_mem_list.prev; + in_context_sharebuffer_buffer = (uint64_t) context->share_buffer.buffer; + in_context_sharebuffer_bufferbarrier = context->share_buffer.buffer_barrier.__align; + + rs_fincont_ins = client->externc_teec_finalizecontext(in_context_fd, + in_context_tapath, + in_context_tapath_size, + in_context_sessionlist_next, + in_context_sessionlist_prev, + in_context_shrdmemlist_next, + in_context_shrdmemlist_prev, + in_context_sharebuffer_buffer, + in_context_sharebuffer_bufferbarrier, + glob_scontaddr); + if (rs_fincont_ins.flag == 1) + { + std::cout << "libteecc: fincont token null" << std::endl; + return; + } + if (rs_fincont_ins.flag == 2) + { + std::cout << "libteecc: fincont jwt validate error" << std::endl; + return; + } +#if 0 + std::cout << "externc_teec_finalizecontext: " << std::endl; + std::cout << "gpp reply context_fd: " << rs_fincont_ins.context_fd < 0){ + std::cout << "gpp reply context_tapath: " << rs_fincont_ins.context_tapath <fd = rs_fincont_ins.context_fd; + if ( + rs_fincont_ins.context_tapath_outsize > 0 && + rs_fincont_ins.context_tapath != NULL + ) + { + if (context->ta_path == NULL) + { + return; + } + } + context->session_list.next = (struct ListNode *) rs_fincont_ins.context_sessionlist_next; + context->session_list.prev = (struct ListNode *) rs_fincont_ins.context_sessionlist_prev; + context->shrd_mem_list.next = (struct ListNode *) rs_fincont_ins.context_shrdmemlist_next; + context->shrd_mem_list.prev = (struct ListNode *) rs_fincont_ins.context_shrdmemlist_prev; + context->share_buffer.buffer = (void *) rs_fincont_ins.context_sharebuffer_buffer; + context->share_buffer.buffer_barrier.__align = rs_fincont_ins.context_sharebuffer_bufferbarrier; + + gpp_channel.reset(); + delete gpp_channel.get(); + delete client; +} + +TEEC_Result +TEEC_OpenSession(TEEC_Context *context, + TEEC_Session *session, + const TEEC_UUID *destination, + uint32_t connectionMethod, + const void *connectionData, + TEEC_Operation *operation, + uint32_t *returnOrigin +) +{ + + std::int32_t in_context_fd; + std::uint8_t *in_context_tapath; + std::int32_t in_context_tapath_size; + std::uint64_t in_context_sessionlist_next; + std::uint64_t in_context_sessionlist_prev; + std::uint64_t in_context_shrdmemlist_next; + std::uint64_t in_context_shrdmemlist_prev; + std::uint64_t in_context_sharebuffer_buffer; + std::int64_t in_context_sharebuffer_bufferbarrier; + + if (gpp_channel == NULL) + { + std::cout << "libteecc: the grpc client or channel is null, when executing TEEC_OpenSession." << std::endl; + return TEEC_ERROR_GRPC_ERROR; + } + + if (context == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (session == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (destination == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + in_context_fd = context->fd; + in_context_tapath = context->ta_path; + + if (in_context_tapath == NULL) + { + in_context_tapath_size = 0; + } else + { + in_context_tapath_size = strlen((const char *) in_context_tapath); + } + in_context_sessionlist_next = (uint64_t) context->session_list.next; + in_context_sessionlist_prev = (uint64_t) context->session_list.prev; + in_context_shrdmemlist_next = (uint64_t) context->shrd_mem_list.next; + in_context_shrdmemlist_prev = (uint64_t) context->shrd_mem_list.prev; + in_context_sharebuffer_buffer = (uint64_t) context->share_buffer.buffer; + in_context_sharebuffer_bufferbarrier = context->share_buffer.buffer_barrier.__align; + + uint32_t in_destination_timelow; + uint32_t in_destination_timemid; + uint32_t in_destination_timehiandver; + uint8_t in_destination_clockseqandnode[8]; + int32_t in_destination_clockseqandnode_size; + + uint32_t in_connectionmethod; + uint64_t in_connectiondata; + + uint32_t in_operation_started; + uint32_t in_operation_paramtypes; + + uint64_t in_operation_param1_tmpref_buffer; + uint32_t in_operation_param1_tmpref_size; + uint64_t in_operation_param1_memref_parent; + uint32_t in_operation_param1_memref_size; + uint32_t in_operation_param1_memref_offset; + uint32_t in_operation_param1_value_a; + uint32_t in_operation_param1_value_b; + int32_t in_operation_param1_ionref_ionsharefd; + uint32_t in_operation_param1_ionref_ionsize; + + uint64_t in_operation_param2_tmpref_buffer; + uint32_t in_operation_param2_tmpref_size; + uint64_t in_operation_param2_memref_parent; + uint32_t in_operation_param2_memref_size; + uint32_t in_operation_param2_memref_offset; + uint32_t in_operation_param2_value_a; + uint32_t in_operation_param2_value_b; + int32_t in_operation_param2_ionref_ionsharefd; + uint32_t in_operation_param2_ionref_ionsize; + + uint64_t in_operation_param3_tmpref_buffer; + uint32_t in_operation_param3_tmpref_size; + uint64_t in_operation_param3_memref_parent; + uint32_t in_operation_param3_memref_size; + uint32_t in_operation_param3_memref_offset; + uint32_t in_operation_param3_value_a; + uint32_t in_operation_param3_value_b; + int32_t in_operation_param3_ionref_ionsharefd; + uint32_t in_operation_param3_ionref_ionsize; + + uint64_t in_operation_param4_tmpref_buffer; + uint32_t in_operation_param4_tmpref_size; + uint64_t in_operation_param4_memref_parent; + uint32_t in_operation_param4_memref_size; + uint32_t in_operation_param4_memref_offset; + uint32_t in_operation_param4_value_a; + uint32_t in_operation_param4_value_b; + int32_t in_operation_param4_ionref_ionsharefd; + uint32_t in_operation_param4_ionref_ionsize; + + uint64_t in_operation_session; + int32_t in_operation_cancelflag; + + uint32_t in_returnorigin; + + struct retstru_teec_opensession rs_opensession_ins; + + + in_destination_timelow = destination->timeLow; + in_destination_timemid = destination->timeMid; + in_destination_timehiandver = destination->timeHiAndVersion; + for (int i = 0; i < 8; i++) + { + in_destination_clockseqandnode[i] = destination->clockSeqAndNode[i]; + } + in_destination_clockseqandnode_size = 8; + + in_connectionmethod = connectionMethod; + in_connectiondata = (uint64_t) connectionData; + + in_operation_started = operation->started; + in_operation_paramtypes = operation->paramTypes; + + in_operation_param1_tmpref_buffer = (uint64_t) operation->params[0].tmpref.buffer; + in_operation_param1_tmpref_size = operation->params[0].tmpref.size; + in_operation_param1_memref_parent = (uint64_t) operation->params[0].memref.parent; + in_operation_param1_memref_size = operation->params[0].memref.size; + in_operation_param1_memref_offset = operation->params[0].memref.offset; + in_operation_param1_value_a = operation->params[0].value.a; + in_operation_param1_value_b = operation->params[0].value.b; + in_operation_param1_ionref_ionsharefd = operation->params[0].ionref.ion_share_fd; + in_operation_param1_ionref_ionsize = operation->params[0].ionref.ion_size; + + in_operation_param2_tmpref_buffer = (uint64_t) operation->params[1].tmpref.buffer; + in_operation_param2_tmpref_size = operation->params[1].tmpref.size; + in_operation_param2_memref_parent = (uint64_t) operation->params[1].memref.parent; + in_operation_param2_memref_size = operation->params[1].memref.size; + in_operation_param2_memref_offset = operation->params[1].memref.offset; + in_operation_param2_value_a = operation->params[1].value.a; + in_operation_param2_value_b = operation->params[1].value.b; + in_operation_param2_ionref_ionsharefd = operation->params[1].ionref.ion_share_fd; + in_operation_param2_ionref_ionsize = operation->params[1].ionref.ion_size; + + in_operation_param3_tmpref_buffer = (uint64_t) operation->params[2].tmpref.buffer; + in_operation_param3_tmpref_size = operation->params[2].tmpref.size; + in_operation_param3_memref_parent = (uint64_t) operation->params[2].memref.parent; + in_operation_param3_memref_size = operation->params[2].memref.size; + in_operation_param3_memref_offset = operation->params[2].memref.offset; + in_operation_param3_value_a = operation->params[2].value.a; + in_operation_param3_value_b = operation->params[2].value.b; + in_operation_param3_ionref_ionsharefd = operation->params[2].ionref.ion_share_fd; + in_operation_param3_ionref_ionsize = operation->params[2].ionref.ion_size; + + in_operation_param4_tmpref_buffer = (uint64_t) operation->params[3].tmpref.buffer; + in_operation_param4_tmpref_size = operation->params[3].tmpref.size; + in_operation_param4_memref_parent = (uint64_t) operation->params[3].memref.parent; + in_operation_param4_memref_size = operation->params[3].memref.size; + in_operation_param4_memref_offset = operation->params[3].memref.offset; + in_operation_param4_value_a = operation->params[3].value.a; + in_operation_param4_value_b = operation->params[3].value.b; + in_operation_param4_ionref_ionsharefd = operation->params[3].ionref.ion_share_fd; + in_operation_param4_ionref_ionsize = operation->params[3].ionref.ion_size; + + in_operation_session = (uint64_t) operation->session; + in_operation_cancelflag = operation->cancel_flag; + + in_returnorigin = *returnOrigin; + + rs_opensession_ins = + client->externc_teec_opensession( + in_context_fd, + in_context_tapath, + in_context_tapath_size, + in_context_sessionlist_next, + in_context_sessionlist_prev, + in_context_shrdmemlist_next, + in_context_shrdmemlist_prev, + in_context_sharebuffer_buffer, + in_context_sharebuffer_bufferbarrier, + + in_destination_timelow, + in_destination_timemid, + in_destination_timehiandver, + in_destination_clockseqandnode, + in_destination_clockseqandnode_size, + + in_connectionmethod, + in_connectiondata, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + in_returnorigin, + glob_scontaddr + ); + if (rs_opensession_ins.flag == 1) + { + std::cout << "libteecc: opensession token null" << std::endl; + return TEEC_ERROR_BAD_PARAMETERS; + } + if (rs_opensession_ins.flag == 2) + { + std::cout << "libteecc: opensession jwt validate error" << std::endl; + return TEEC_ERROR_BAD_PARAMETERS; + } + +#if 0 + std::cout << "externc_teec_opensession:" << std::endl; + std::cout << "gpp request in_context_fd: 0x " << std::hex << std::setfill('0') << std::setw(8) << in_context_fd + << std::endl; + std::cout << "gpp request in_context_addr: 0x" << std::hex << std::setfill('0') << std::setw(8) + << (unsigned long) glob_scontaddr << std::endl; + std::cout << "gpp reply teecresult: " << std::hex << std::setfill('0') << std::setw(8) + << rs_opensession_ins.teecresult << std::endl; + std::cout << "gpp reply context_fd: " << std::hex << std::setfill('0') << std::setw(8) + << rs_opensession_ins.context_fd << std::endl; + + if ( + rs_opensession_ins.context_tapath_outsize > 0 + && + rs_opensession_ins.context_tapath != NULL + ) + { + std::cout << "gpp reply context_tapath: " << rs_opensession_ins.context_tapath << std::endl; + } + printf("gpp reply context_tapath outsize = %ld\n", + rs_opensession_ins.context_tapath_outsize); +#endif + +#if 0 + printf("ret context_sessionlist_next = 0x %16.16lx\n", + rs_opensession_ins.context_sessionlist_next); + printf("ret context_sessionlist_prev = 0x %16.16lx\n", + rs_opensession_ins.context_sessionlist_prev); + printf("ret context_shrdmemlist_next = 0x %16.16lx\n", + rs_opensession_ins.context_shrdmemlist_next); + printf("ret context_shrdmemlist_prev = 0x %16.16lx\n", + rs_opensession_ins.context_shrdmemlist_prev); + printf("ret context_sharebuffer_buffer = 0x %16.16lx\n", + rs_opensession_ins.context_sharebuffer_buffer); + printf("ret context_sharebuffer_bufferbarrier = 0x %16.16lx\n", + (long unsigned int) rs_opensession_ins.context_sharebuffer_bufferbarrier); +#endif + +#if 0 + std::cout << "gpp reply session_sessionid: 0x " << std::hex << std::setfill('0') << std::setw(8) + << rs_opensession_ins.session_sessionid << std::endl; +#endif + +#if 0 + printf("ret session_serviceid_timelow = 0x %8.8x\n", + rs_opensession_ins.session_serviceid_timelow); + printf("ret session_serviceid_timemid = 0x %8.8x\n", + rs_opensession_ins.session_serviceid_timemid); + printf("ret session_serviceid_timehiandver = 0x %8.8x\n", + rs_opensession_ins.session_serviceid_timehiandver); + if ( + rs_opensession_ins.session_serviceid_clockseqandnode_outsize > 0 + && + rs_opensession_ins.session_serviceid_clockseqandnode != NULL + ) { + printf("ret session_serviceid_clockseqandnode = \n"); + for (uintptr_t uisize = 0; + uisize < rs_opensession_ins.session_serviceid_clockseqandnode_outsize; + uisize++) { + printf(" %2.2x", *(rs_opensession_ins.session_serviceid_clockseqandnode + uisize)); + } + printf("\n"); + } else { + printf("ret clockseqandnode addr = 0x %16.16lx\n", + (unsigned long) rs_opensession_ins.session_serviceid_clockseqandnode); + } + printf("ret clockseqandnode_outsize = %ld\n", + rs_opensession_ins.session_serviceid_clockseqandnode_outsize); + printf("ret session_opscnt = 0x %8.8x\n", + rs_opensession_ins.session_opscnt); + printf("ret session_head_next = 0x %16.16lx\n", + rs_opensession_ins.session_head_next); + printf("ret session_head_prev = 0x %16.16lx\n", + rs_opensession_ins.session_head_prev); +#endif + +#if 0 + std::cout << "gpp reply session_context: 0x " << std::hex << std::setfill('0') << std::setw(16) + << rs_opensession_ins.session_context << std::endl; +#endif + if (rs_opensession_ins.teecresult == TEEC_SUCCESS) + { + context->fd = rs_opensession_ins.context_fd; + + if ( + rs_opensession_ins.context_tapath_outsize > 0 && + rs_opensession_ins.context_tapath != NULL + ) + { + if (context->ta_path == NULL) + { + return TEEC_ERROR_CONTEXT_TAPATH_NULL; + } + } + context->session_list.next = (struct ListNode *) rs_opensession_ins.context_sessionlist_next; + context->session_list.prev = (struct ListNode *) rs_opensession_ins.context_sessionlist_prev; + context->shrd_mem_list.next = (struct ListNode *) rs_opensession_ins.context_shrdmemlist_next; + context->shrd_mem_list.prev = (struct ListNode *) rs_opensession_ins.context_shrdmemlist_prev; + context->share_buffer.buffer = (void *) rs_opensession_ins.context_sharebuffer_buffer; + context->share_buffer.buffer_barrier.__align = rs_opensession_ins.context_sharebuffer_bufferbarrier; + + session->session_id = rs_opensession_ins.session_sessionid; + session->service_id.timeLow = rs_opensession_ins.session_serviceid_timelow; + session->service_id.timeMid = rs_opensession_ins.session_serviceid_timemid; + session->service_id.timeHiAndVersion = rs_opensession_ins.session_serviceid_timehiandver; + + if (rs_opensession_ins.session_serviceid_clockseqandnode_outsize <= 8 && + rs_opensession_ins.session_serviceid_clockseqandnode_outsize > 0 && + rs_opensession_ins.session_serviceid_clockseqandnode != NULL && + session->service_id.clockSeqAndNode != NULL + ) + { + for (int i = 0; i < rs_opensession_ins.session_serviceid_clockseqandnode_outsize; i++) + { + session->service_id.clockSeqAndNode[i] = + (uint8_t)(rs_opensession_ins.session_serviceid_clockseqandnode[i] & 0x000000ff); + } + } else + { + for (int i = 0; i < 8; i++) + { + session->service_id.clockSeqAndNode[i] = 0; + } + } + session->ops_cnt = rs_opensession_ins.session_opscnt; + session->head.next = (struct ListNode *) rs_opensession_ins.session_head_next; + session->head.prev = (struct ListNode *) rs_opensession_ins.session_head_prev; + session->context = (TEEC_Context *) rs_opensession_ins.session_context; + + + operation->started = rs_opensession_ins.operation_started; + operation->paramTypes = rs_opensession_ins.operation_paramtypes; + +#if 0 + uint32_t * buffer1_temp = NULL; + if ( + (rs_opensession_ins.operation_paramtypes & 0x000000ff) == TEEC_MEMREF_TEMP_OUTPUT || + (rs_opensession_ins.operation_paramtypes & 0x000000ff) == TEEC_MEMREF_TEMP_INOUT + ) + { + if (operation->params[0].tmpref.buffer == NULL) + { + externc_retstru_teec_opensession_free(rs_opensession_ins); + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + } +#endif + + operation->params[0].tmpref.buffer = (void *) rs_opensession_ins.operation_param1_tmpref_buffer; + operation->params[0].tmpref.size = rs_opensession_ins.operation_param1_tmpref_size; + operation->params[0].memref.parent = + (TEEC_SharedMemory *) rs_opensession_ins.operation_param1_memref_parent; + operation->params[0].memref.size = rs_opensession_ins.operation_param1_memref_size; + operation->params[0].memref.offset = rs_opensession_ins.operation_param1_memref_offset; + operation->params[0].value.a = rs_opensession_ins.operation_param1_value_a; + operation->params[0].value.b = rs_opensession_ins.operation_param1_value_b; + operation->params[0].ionref.ion_share_fd = rs_opensession_ins.operation_param1_ionref_ionsharefd; + operation->params[0].ionref.ion_size = rs_opensession_ins.operation_param1_ionref_ionsize; + + operation->params[1].tmpref.buffer = (void *) rs_opensession_ins.operation_param2_tmpref_buffer; + operation->params[1].tmpref.size = rs_opensession_ins.operation_param2_tmpref_size; + operation->params[1].memref.parent = + (TEEC_SharedMemory *) rs_opensession_ins.operation_param2_memref_parent; + operation->params[1].memref.size = rs_opensession_ins.operation_param2_memref_size; + operation->params[1].memref.offset = rs_opensession_ins.operation_param2_memref_offset; + operation->params[1].value.a = rs_opensession_ins.operation_param2_value_a; + operation->params[1].value.b = rs_opensession_ins.operation_param2_value_b; + operation->params[1].ionref.ion_share_fd = rs_opensession_ins.operation_param2_ionref_ionsharefd; + operation->params[1].ionref.ion_size = rs_opensession_ins.operation_param2_ionref_ionsize; + + operation->params[2].tmpref.buffer = (void *) rs_opensession_ins.operation_param3_tmpref_buffer; + operation->params[2].tmpref.size = rs_opensession_ins.operation_param3_tmpref_size; + operation->params[2].memref.parent = + (TEEC_SharedMemory *) rs_opensession_ins.operation_param3_memref_parent; + operation->params[2].memref.size = rs_opensession_ins.operation_param3_memref_size; + operation->params[2].memref.offset = rs_opensession_ins.operation_param3_memref_offset; + operation->params[2].value.a = rs_opensession_ins.operation_param3_value_a; + operation->params[2].value.b = rs_opensession_ins.operation_param3_value_b; + operation->params[2].ionref.ion_share_fd = rs_opensession_ins.operation_param3_ionref_ionsharefd; + operation->params[2].ionref.ion_size = rs_opensession_ins.operation_param3_ionref_ionsize; + + operation->params[3].tmpref.buffer = (void *) rs_opensession_ins.operation_param4_tmpref_buffer; + operation->params[3].tmpref.size = rs_opensession_ins.operation_param4_tmpref_size; + operation->params[3].memref.parent = + (TEEC_SharedMemory *) rs_opensession_ins.operation_param4_memref_parent; + operation->params[3].memref.size = rs_opensession_ins.operation_param4_memref_size; + operation->params[3].memref.offset = rs_opensession_ins.operation_param4_memref_offset; + operation->params[3].value.a = rs_opensession_ins.operation_param4_value_a; + operation->params[3].value.b = rs_opensession_ins.operation_param4_value_b; + operation->params[3].ionref.ion_share_fd = rs_opensession_ins.operation_param4_ionref_ionsharefd; + operation->params[3].ionref.ion_size = rs_opensession_ins.operation_param4_ionref_ionsize; + + operation->session = (TEEC_Session *) rs_opensession_ins.operation_session; + operation->cancel_flag = rs_opensession_ins.operation_cancelflag; + + *returnOrigin = in_returnorigin; + } + return static_cast(rs_opensession_ins.teecresult); +} + +extern +TEEC_Result +TEEC_InvokeCommand(TEEC_Session *session, + uint32_t commandID, + TEEC_Operation *operation, + uint32_t *returnOrigin +) +{ + uint32_t in_session_sessionid; + uint32_t in_session_serviceid_timelow; + uint32_t in_session_serviceid_timemid; + uint32_t in_session_serviceid_timehiandver; + uint8_t in_session_serviceid_clockseqandnode[8]; + uintptr_t in_session_serviceid_clockseqandnode_size; + uint32_t in_session_opscnt; + uint64_t in_session_head_next; + int64_t in_session_head_prev; + uint64_t in_session_context; + + uint32_t in_commandid; + + uint32_t in_operation_started; + uint32_t in_operation_paramtypes; + + uint64_t in_operation_param1_tmpref_buffer; + uint32_t in_operation_param1_tmpref_size; + uint64_t in_operation_param1_memref_parent; + uint32_t in_operation_param1_memref_parent_flag; + uint32_t in_operation_param1_memref_size; + uint32_t in_operation_param1_memref_offset; + uint32_t in_operation_param1_value_a; + uint32_t in_operation_param1_value_b; + int32_t in_operation_param1_ionref_ionsharefd; + uint32_t in_operation_param1_ionref_ionsize; + + uint64_t in_operation_param2_tmpref_buffer; + uint32_t in_operation_param2_tmpref_size; + uint64_t in_operation_param2_memref_parent; + uint32_t in_operation_param2_memref_parent_flag; + uint32_t in_operation_param2_memref_size; + uint32_t in_operation_param2_memref_offset; + uint32_t in_operation_param2_value_a; + uint32_t in_operation_param2_value_b; + int32_t in_operation_param2_ionref_ionsharefd; + uint32_t in_operation_param2_ionref_ionsize; + + uint64_t in_operation_param3_tmpref_buffer; + uint32_t in_operation_param3_tmpref_size; + uint64_t in_operation_param3_memref_parent; + uint32_t in_operation_param3_memref_parent_flag; + uint32_t in_operation_param3_memref_size; + uint32_t in_operation_param3_memref_offset; + uint32_t in_operation_param3_value_a; + uint32_t in_operation_param3_value_b; + int32_t in_operation_param3_ionref_ionsharefd; + uint32_t in_operation_param3_ionref_ionsize; + + uint64_t in_operation_param4_tmpref_buffer; + uint32_t in_operation_param4_tmpref_size; + uint64_t in_operation_param4_memref_parent; + uint32_t in_operation_param4_memref_parent_flag; + uint32_t in_operation_param4_memref_size; + uint32_t in_operation_param4_memref_offset; + uint32_t in_operation_param4_value_a; + uint32_t in_operation_param4_value_b; + int32_t in_operation_param4_ionref_ionsharefd; + uint32_t in_operation_param4_ionref_ionsize; + + uint64_t in_operation_session; + int32_t in_operation_cancelflag; + + uint32_t in_returnorigin; + struct retstru_teec_invokecommand rs_invokecommand_ins; + + if (gpp_channel == NULL) + { + std::cout << "libteecc: the grpc client or channel is null, when executing TEEC_InvokeCommand." << std::endl; + return TEEC_ERROR_GRPC_ERROR; + } + + if (session == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (operation == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + in_session_sessionid = session->session_id; + in_session_serviceid_timelow = session->service_id.timeLow; + in_session_serviceid_timemid = session->service_id.timeMid; + in_session_serviceid_timehiandver = session->service_id.timeHiAndVersion; + if ( + session->service_id.clockSeqAndNode != NULL + ) + { + for (int i = 0; i < 8; i++) + { + in_session_serviceid_clockseqandnode[i] = + session->service_id.clockSeqAndNode[i]; + } + } else + { + for (int i = 0; i < 8; i++) + { + in_session_serviceid_clockseqandnode[i] = 0; + } + } + in_session_serviceid_clockseqandnode_size = 8; + in_session_opscnt = session->ops_cnt; + in_session_head_next = (uint64_t) session->head.next; + in_session_head_prev = (uint64_t) session->head.prev; + in_session_context = glob_scontaddr; + + in_commandid = commandID; + + in_operation_started = operation->started; + in_operation_paramtypes = operation->paramTypes; + + in_operation_param1_ionref_ionsharefd = operation->params[0].ionref.ion_share_fd; + in_operation_param1_ionref_ionsize = operation->params[0].ionref.ion_size; + + in_operation_param2_ionref_ionsharefd = operation->params[1].ionref.ion_share_fd; + in_operation_param2_ionref_ionsize = operation->params[1].ionref.ion_size; + + in_operation_param3_ionref_ionsharefd = operation->params[2].ionref.ion_share_fd; + in_operation_param3_ionref_ionsize = operation->params[2].ionref.ion_size; + + in_operation_param4_ionref_ionsharefd = operation->params[3].ionref.ion_share_fd; + in_operation_param4_ionref_ionsize = operation->params[3].ionref.ion_size; + + uint8_t *in_buffer1 = NULL; + uintptr_t in_buffer1_size = 0; + + switch ( + TEEC_PARAM_TYPE_GET(operation->paramTypes, 0) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + in_operation_param1_value_a = operation->params[0].value.a; + in_operation_param1_value_b = operation->params[0].value.b; + + break; + } + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + operation->params[0].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + if ( + operation->params[0].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + in_operation_param1_tmpref_buffer = (uint64_t) operation->params[0].tmpref.buffer; + in_operation_param1_tmpref_size = operation->params[0].tmpref.size; + + in_buffer1_size = operation->params[0].tmpref.size; + in_buffer1 = (uint8_t *) malloc(in_buffer1_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + in_buffer1[isize] = (uint8_t) * ((uint8_t * )(operation->params[0].tmpref.buffer) + isize); + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + operation->params[0].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + if ( + operation->params[0].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + in_operation_param1_tmpref_buffer = (uint64_t) operation->params[0].tmpref.buffer; + in_operation_param1_tmpref_size = operation->params[0].tmpref.size; + + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operation->params[0].memref.parent->flags) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[0].memref.parent->buffer == NULL || + operation->params[0].memref.parent->ops_cnt != 0xfffe + ) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if ( + operation->params[0].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param1_memref_parent = + (uint64_t) operation->params[0].memref.parent->buffer; + in_operation_param1_memref_parent_flag = + (uint32_t) operation->params[0].memref.parent->flags; + in_operation_param1_memref_size = operation->params[0].memref.size; + + in_buffer1_size = operation->params[0].memref.parent->size; + in_buffer1 = (uint8_t *) malloc(in_buffer1_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + in_buffer1[isize] = + (uint8_t) * ((uint8_t * )( + operation->params[0].memref.parent->buffer + ) + + isize + ); + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + operation->params[0].memref.parent->buffer == NULL || + operation->params[0].memref.parent->ops_cnt != 0xfffe + ) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if ( + operation->params[0].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param1_memref_parent = + (uint64_t) operation->params[0].memref.parent->buffer; + in_operation_param1_memref_parent_flag = + (uint32_t) operation->params[0].memref.parent->flags; + in_operation_param1_memref_size = operation->params[0].memref.size; + + break; + } + + default: + { + return TEEC_ERROR_NO_SHAREMEMFLAG; + break; + } + + } // end of switch(operation->params[0].memref.parent->flags) + + break; + } + // end of case TEEC_MEMREF_WHOLE + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[0].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[0].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param1_memref_parent = + (uint64_t) operation->params[0].memref.parent->buffer; + in_operation_param1_memref_parent_flag = + (uint32_t) operation->params[0].memref.parent->flags; + in_operation_param1_memref_offset = operation->params[0].memref.offset; + in_operation_param1_memref_size = operation->params[0].memref.size; + + in_buffer1_size = operation->params[0].memref.parent->size; + in_buffer1 = (uint8_t *) malloc(in_buffer1_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + in_buffer1[isize] = + (uint8_t) * ((uint8_t * )(operation->params[0].memref.parent->buffer) + isize); + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_INPUT INOUT + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (operation->params[0].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[0].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param1_memref_parent = + (uint64_t) operation->params[0].memref.parent->buffer; + in_operation_param1_memref_parent_flag = + (uint32_t) operation->params[0].memref.parent->flags; + in_operation_param1_memref_offset = operation->params[0].memref.offset; + in_operation_param1_memref_size = operation->params[0].memref.size; + + in_buffer1_size = operation->params[0].memref.parent->size; + in_buffer1 = (uint8_t *) malloc(in_buffer1_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer1_size; isize++) + { + in_buffer1[isize] = 0x0; + } + + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT + + + default: + break; + } + + + uint8_t *in_buffer2 = NULL; + uintptr_t in_buffer2_size = 0; + switch ( + TEEC_PARAM_TYPE_GET(operation->paramTypes, 1) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + in_operation_param2_value_a = operation->params[1].value.a; + in_operation_param2_value_b = operation->params[1].value.b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + operation->params[1].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM1_TEMPMEM_NULL; + } + if ( + operation->params[1].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM1_TEMPMEM_LESS; + } + + in_operation_param2_tmpref_buffer = (uint64_t) operation->params[1].tmpref.buffer; + in_operation_param2_tmpref_size = operation->params[1].tmpref.size; + + in_buffer2_size = operation->params[1].tmpref.size; + in_buffer2 = (uint8_t *) malloc(in_buffer2_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + in_buffer2[isize] = (uint8_t) * ((uint8_t * )(operation->params[1].tmpref.buffer) + isize); + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + operation->params[1].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM1_TEMPMEM_NULL; + } + if ( + operation->params[1].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM1_TEMPMEM_LESS; + } + + in_operation_param2_tmpref_buffer = (uint64_t) operation->params[1].tmpref.buffer; + in_operation_param2_tmpref_size = operation->params[1].tmpref.size; + + break; + } + + case TEEC_MEMREF_WHOLE: + { + switch (operation->params[1].memref.parent->flags) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[1].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM1_MEMREF_NULL; + } + if ( + operation->params[1].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM1_MEMREF_LESS; + } + + in_operation_param2_memref_parent = + (uint64_t) operation->params[1].memref.parent->buffer; + in_operation_param2_memref_parent_flag = + (uint32_t) operation->params[1].memref.parent->flags; + in_operation_param2_memref_size = operation->params[1].memref.size; + + in_buffer2_size = operation->params[1].memref.parent->size; + in_buffer2 = (uint8_t *) malloc(in_buffer2_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + in_buffer2[isize] = + (uint8_t) * ((uint8_t * )( + operation->params[1].memref.parent->buffer + ) + + isize + ); + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + operation->params[1].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM1_MEMREF_NULL; + } + if ( + operation->params[1].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM1_MEMREF_LESS; + } + + in_operation_param2_memref_parent = + (uint64_t) operation->params[1].memref.parent->buffer; + in_operation_param2_memref_parent_flag = + (uint32_t) operation->params[1].memref.parent->flags; + in_operation_param2_memref_size = operation->params[1].memref.size; + + break; + } + + default: + { + return TEEC_ERROR_NO_SHAREMEMFLAG; + break; + } + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[1].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[1].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param2_memref_parent = + (uint64_t) operation->params[1].memref.parent->buffer; + in_operation_param2_memref_parent_flag = + (uint32_t) operation->params[1].memref.parent->flags; + in_operation_param2_memref_offset = operation->params[1].memref.offset; + in_operation_param2_memref_size = operation->params[1].memref.size; + + in_buffer2_size = operation->params[1].memref.parent->size; + in_buffer2 = (uint8_t *) malloc(in_buffer2_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + in_buffer2[isize] = + (uint8_t) * ((uint8_t * )(operation->params[1].memref.parent->buffer) + isize); + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_INPUT INOUT + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (operation->params[1].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM1_MEMREF_NULL; + } + if (operation->params[1].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM1_MEMREF_LESS; + } + + in_operation_param2_memref_parent = + (uint64_t) operation->params[1].memref.parent->buffer; + in_operation_param2_memref_parent_flag = + (uint32_t) operation->params[1].memref.parent->flags; + in_operation_param2_memref_offset = operation->params[1].memref.offset; + in_operation_param2_memref_size = operation->params[1].memref.size; + + in_buffer2_size = operation->params[1].memref.parent->size; + in_buffer2 = (uint8_t *) malloc(in_buffer2_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer2_size; isize++) + { + in_buffer2[isize] = 0x0; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT + + + default: + break; + } + + uint8_t *in_buffer3 = NULL; + uintptr_t in_buffer3_size = 0; + switch ( + TEEC_PARAM_TYPE_GET(operation->paramTypes, 2) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + in_operation_param3_value_a = operation->params[2].value.a; + in_operation_param3_value_b = operation->params[2].value.b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + operation->params[2].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM2_TEMPMEM_NULL; + } + if ( + operation->params[2].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM2_TEMPMEM_LESS; + } + + in_operation_param3_tmpref_buffer = (uint64_t) operation->params[2].tmpref.buffer; + in_operation_param3_tmpref_size = operation->params[2].tmpref.size; + + in_buffer3_size = operation->params[2].tmpref.size; + in_buffer3 = (uint8_t *) malloc(in_buffer3_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + in_buffer3[isize] = (uint8_t) * ((uint8_t * )(operation->params[2].tmpref.buffer) + isize); + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + operation->params[2].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM2_TEMPMEM_NULL; + } + if ( + operation->params[2].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM2_TEMPMEM_LESS; + } + + in_operation_param3_tmpref_buffer = (uint64_t) operation->params[2].tmpref.buffer; + in_operation_param3_tmpref_size = operation->params[2].tmpref.size; + + break; + } + + case TEEC_MEMREF_WHOLE: + { + switch (operation->params[2].memref.parent->flags) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[2].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM2_MEMREF_NULL; + } + if ( + operation->params[2].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM2_MEMREF_LESS; + } + + in_operation_param3_memref_parent = + (uint64_t) operation->params[2].memref.parent->buffer; + in_operation_param3_memref_parent_flag = + (uint32_t) operation->params[2].memref.parent->flags; + in_operation_param3_memref_size = operation->params[2].memref.size; + + in_buffer3_size = operation->params[2].memref.parent->size; + in_buffer3 = (uint8_t *) malloc(in_buffer3_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + in_buffer3[isize] = + (uint8_t) * ((uint8_t * )( + operation->params[2].memref.parent->buffer + ) + + isize + ); + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + operation->params[2].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM2_MEMREF_NULL; + } + if ( + operation->params[2].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM2_MEMREF_LESS; + } + + in_operation_param3_memref_parent = + (uint64_t) operation->params[2].memref.parent->buffer; + in_operation_param3_memref_parent_flag = + (uint32_t) operation->params[2].memref.parent->flags; + in_operation_param3_memref_size = operation->params[2].memref.size; + + break; + } + + default: + { + return TEEC_ERROR_NO_SHAREMEMFLAG; + break; + } + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[2].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM2_MEMREF_NULL; + } + if (operation->params[2].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM2_MEMREF_LESS; + } + + in_operation_param3_memref_parent = + (uint64_t) operation->params[2].memref.parent->buffer; + in_operation_param3_memref_parent_flag = + (uint32_t) operation->params[2].memref.parent->flags; + in_operation_param3_memref_offset = operation->params[2].memref.offset; + in_operation_param3_memref_size = operation->params[2].memref.size; + + in_buffer3_size = operation->params[2].memref.parent->size; + in_buffer3 = (uint8_t *) malloc(in_buffer3_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + in_buffer3[isize] = + (uint8_t) * ((uint8_t * )(operation->params[2].memref.parent->buffer) + isize); + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_INPUT INOUT + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (operation->params[2].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[2].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param3_memref_parent = + (uint64_t) operation->params[2].memref.parent->buffer; + in_operation_param3_memref_parent_flag = + (uint32_t) operation->params[2].memref.parent->flags; + in_operation_param3_memref_offset = operation->params[2].memref.offset; + in_operation_param3_memref_size = operation->params[2].memref.size; + + in_buffer3_size = operation->params[2].memref.parent->size; + in_buffer3 = (uint8_t *) malloc(in_buffer3_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer3_size; isize++) + { + in_buffer3[isize] = 0x0; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT + + default: + break; + } + + + uint8_t *in_buffer4 = NULL; + uintptr_t in_buffer4_size = 0; + switch ( + TEEC_PARAM_TYPE_GET(operation->paramTypes, 3) + ) + { + case TEEC_VALUE_INPUT: + case TEEC_VALUE_INOUT: + { + in_operation_param4_value_a = operation->params[3].value.a; + in_operation_param4_value_b = operation->params[3].value.b; + + break; + } + + case TEEC_MEMREF_TEMP_INPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if ( + operation->params[3].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM3_TEMPMEM_NULL; + } + if ( + operation->params[3].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM3_TEMPMEM_LESS; + } + + in_operation_param4_tmpref_buffer = (uint64_t) operation->params[3].tmpref.buffer; + in_operation_param4_tmpref_size = operation->params[3].tmpref.size; + + in_buffer4_size = operation->params[3].tmpref.size; + in_buffer4 = (uint8_t *) malloc(in_buffer4_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + in_buffer4[isize] = (uint8_t) * ((uint8_t * )(operation->params[3].tmpref.buffer) + isize); + } + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + { + if ( + operation->params[3].tmpref.buffer == NULL + ) + { + return TEEC_ERROR_PARAM3_TEMPMEM_NULL; + } + if ( + operation->params[3].tmpref.size <= 0 + ) + { + return TEEC_ERROR_PARAM3_TEMPMEM_LESS; + } + + in_operation_param4_tmpref_buffer = (uint64_t) operation->params[3].tmpref.buffer; + in_operation_param4_tmpref_size = operation->params[3].tmpref.size; + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + switch (operation->params[3].memref.parent->flags) + { + case TEEC_MEM_INPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[3].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM3_MEMREF_NULL; + } + if ( + operation->params[3].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM3_MEMREF_LESS; + } + + in_operation_param4_memref_parent = + (uint64_t) operation->params[3].memref.parent->buffer; + in_operation_param4_memref_parent_flag = + (uint32_t) operation->params[3].memref.parent->flags; + in_operation_param4_memref_size = operation->params[3].memref.size; + + in_buffer4_size = operation->params[3].memref.parent->size; + in_buffer4 = (uint8_t *) malloc(in_buffer4_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + in_buffer4[isize] = + (uint8_t) * ((uint8_t * )( + operation->params[3].memref.parent->buffer + ) + + isize + ); + } + + break; + } + + case TEEC_MEM_OUTPUT: + { + if ( + operation->params[3].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM3_MEMREF_NULL; + } + if ( + operation->params[3].memref.parent->size <= 0 + ) + { + return TEEC_ERROR_PARAM3_MEMREF_LESS; + } + + in_operation_param4_memref_parent = + (uint64_t) operation->params[3].memref.parent->buffer; + in_operation_param4_memref_parent_flag = + (uint32_t) operation->params[3].memref.parent->flags; + in_operation_param4_memref_size = operation->params[3].memref.size; + + break; + } + + default: + { + return TEEC_ERROR_NO_SHAREMEMFLAG; + break; + } + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_INPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[3].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM3_MEMREF_NULL; + } + if (operation->params[3].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM3_MEMREF_LESS; + } + + in_operation_param4_memref_parent = + (uint64_t) operation->params[3].memref.parent->buffer; + in_operation_param4_memref_parent_flag = + (uint32_t) operation->params[3].memref.parent->flags; + in_operation_param4_memref_offset = operation->params[3].memref.offset; + in_operation_param4_memref_size = operation->params[3].memref.size; + + in_buffer4_size = operation->params[3].memref.parent->size; + in_buffer4 = (uint8_t *) malloc(in_buffer4_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + in_buffer4[isize] = + (uint8_t) * ((uint8_t * )(operation->params[3].memref.parent->buffer) + isize); + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_INPUT INOUT + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + { + if (operation->params[3].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[3].memref.parent->size <= 0) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + in_operation_param4_memref_parent = + (uint64_t) operation->params[3].memref.parent->buffer; + in_operation_param4_memref_parent_flag = + (uint32_t) operation->params[3].memref.parent->flags; + in_operation_param4_memref_offset = operation->params[3].memref.offset; + in_operation_param4_memref_size = operation->params[3].memref.size; + + in_buffer4_size = operation->params[3].memref.parent->size; + in_buffer4 = (uint8_t *) malloc(in_buffer4_size * sizeof(uint8_t)); + for (int isize = 0; isize < in_buffer4_size; isize++) + { + in_buffer4[isize] = 0x0; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT + + + default: + break; + } + + + in_operation_session = (uint64_t) operation->session; + in_operation_cancelflag = operation->cancel_flag; + + if (returnOrigin == NULL) + { + in_returnorigin = 0; + } else + { + in_returnorigin = *returnOrigin; + } + + rs_invokecommand_ins = + client->externc_teec_invokecommand( + in_session_sessionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context, + + in_commandid, + + in_operation_started, + in_operation_paramtypes, + + in_operation_param1_tmpref_buffer, + in_operation_param1_tmpref_size, + in_operation_param1_memref_parent, + in_operation_param1_memref_parent_flag, + in_operation_param1_memref_size, + in_operation_param1_memref_offset, + in_operation_param1_value_a, + in_operation_param1_value_b, + in_operation_param1_ionref_ionsharefd, + in_operation_param1_ionref_ionsize, + + in_operation_param2_tmpref_buffer, + in_operation_param2_tmpref_size, + in_operation_param2_memref_parent, + in_operation_param2_memref_parent_flag, + in_operation_param2_memref_size, + in_operation_param2_memref_offset, + in_operation_param2_value_a, + in_operation_param2_value_b, + in_operation_param2_ionref_ionsharefd, + in_operation_param2_ionref_ionsize, + + in_operation_param3_tmpref_buffer, + in_operation_param3_tmpref_size, + in_operation_param3_memref_parent, + in_operation_param3_memref_parent_flag, + in_operation_param3_memref_size, + in_operation_param3_memref_offset, + in_operation_param3_value_a, + in_operation_param3_value_b, + in_operation_param3_ionref_ionsharefd, + in_operation_param3_ionref_ionsize, + + in_operation_param4_tmpref_buffer, + in_operation_param4_tmpref_size, + in_operation_param4_memref_parent, + in_operation_param4_memref_parent_flag, + in_operation_param4_memref_size, + in_operation_param4_memref_offset, + in_operation_param4_value_a, + in_operation_param4_value_b, + in_operation_param4_ionref_ionsharefd, + in_operation_param4_ionref_ionsize, + + in_operation_session, + in_operation_cancelflag, + + in_returnorigin, + + in_buffer1, + in_buffer1_size, + in_buffer2, + in_buffer2_size, + in_buffer3, + in_buffer3_size, + in_buffer4, + in_buffer4_size + ); + if (rs_invokecommand_ins.flag == 1) + { + std::cout << "libteecc: invoke token null" << std::endl; + return TEEC_ERROR_TOKEN_NULL; + } + if (rs_invokecommand_ins.flag == 2) + { + std::cout << "libteecc: invoke jwt validate error" << std::endl; + return TEEC_ERROR_JWTVALIDATE_FAIL; + } + if (rs_invokecommand_ins.teecresult == TEEC_SUCCESS) + { + session->session_id = rs_invokecommand_ins.session_sessionid; + session->service_id.timeLow = rs_invokecommand_ins.session_serviceid_timelow; + session->service_id.timeMid = rs_invokecommand_ins.session_serviceid_timemid; + session->service_id.timeHiAndVersion = rs_invokecommand_ins.session_serviceid_timehiandver; + if (rs_invokecommand_ins.session_serviceid_clockseqandnode_outsize <= 8 && + rs_invokecommand_ins.session_serviceid_clockseqandnode_outsize > 0 && + rs_invokecommand_ins.session_serviceid_clockseqandnode != NULL && + session->service_id.clockSeqAndNode != NULL + ) + { + for (int i = 0; i < rs_invokecommand_ins.session_serviceid_clockseqandnode_outsize; i++) + { + session->service_id.clockSeqAndNode[i] = + (uint8_t)(rs_invokecommand_ins.session_serviceid_clockseqandnode[i] & 0x000000ff); + } + } else + { + for (int i = 0; i < 8; i++) + { + session->service_id.clockSeqAndNode[i] = 0; + } + } + session->ops_cnt = rs_invokecommand_ins.session_opscnt; + session->head.next = (struct ListNode *) rs_invokecommand_ins.session_head_next; + session->head.prev = (struct ListNode *) rs_invokecommand_ins.session_head_prev; + session->context = (TEEC_Context *) rs_invokecommand_ins.session_context; + + operation->started = rs_invokecommand_ins.operation_started; + operation->paramTypes = rs_invokecommand_ins.operation_paramtypes; + + switch ( + TEEC_PARAM_TYPE_GET(rs_invokecommand_ins.operation_paramtypes, 0) + ) + { + case TEEC_VALUE_OUTPUT: + case TEEC_VALUE_INOUT: + { + operation->params[0].value.a = rs_invokecommand_ins.operation_param1_value_a; + operation->params[0].value.b = rs_invokecommand_ins.operation_param1_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if (operation->params[0].tmpref.buffer == NULL) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + + if (operation->params[0].tmpref.size < + rs_invokecommand_ins.buffer1_outsize + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + if (rs_invokecommand_ins.buffer1 != NULL && + rs_invokecommand_ins.buffer1_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer1_outsize; iind++) + { + *((uint8_t * )(operation->params[0].tmpref.buffer) + iind) = + *(rs_invokecommand_ins.buffer1 + iind); + } + operation->params[0].tmpref.size = rs_invokecommand_ins.buffer1_outsize; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + operation->params[0].memref.parent->flags = + rs_invokecommand_ins.operation_param1_memref_parent_flag; + switch (operation->params[0].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[0].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if ( + operation->params[0].memref.parent->size < + rs_invokecommand_ins.buffer1_outsize + ) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer1 != NULL && + rs_invokecommand_ins.buffer1_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer1_outsize; iind++) + { + *((uint8_t * )(operation->params[0].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer1 + iind); + } + operation->params[0].memref.size = rs_invokecommand_ins.buffer1_outsize; + operation->params[0].memref.parent->size = rs_invokecommand_ins.buffer1_outsize; + } + + break; + } + + default: + break; + } + + break; + + } + // end of case TEEC_MEMREF_WHOLE: + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[0].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM0_MEMREF_NULL; + } + if (operation->params[0].memref.parent->size < + rs_invokecommand_ins.buffer1_outsize + ) + { + return TEEC_ERROR_PARAM0_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer1 != NULL && + rs_invokecommand_ins.buffer1_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer1_outsize; iind++) + { + *((uint8_t * )(operation->params[0].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer1 + iind); + } + operation->params[0].memref.parent->size = rs_invokecommand_ins.buffer1_outsize; + + operation->params[0].memref.offset = rs_invokecommand_ins.operation_param1_memref_offset; + operation->params[0].memref.size = rs_invokecommand_ins.operation_param1_memref_size; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT, INOUT + + + default: + break; + } + + operation->params[0].ionref.ion_share_fd = rs_invokecommand_ins.operation_param1_ionref_ionsharefd; + operation->params[0].ionref.ion_size = rs_invokecommand_ins.operation_param1_ionref_ionsize; + + + switch ( + TEEC_PARAM_TYPE_GET(rs_invokecommand_ins.operation_paramtypes, 1) + ) + { + case TEEC_VALUE_OUTPUT: + case TEEC_VALUE_INOUT: + { + operation->params[1].value.a = rs_invokecommand_ins.operation_param2_value_a; + operation->params[1].value.b = rs_invokecommand_ins.operation_param2_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if (operation->params[1].tmpref.buffer == NULL) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + + if (operation->params[1].tmpref.size < + rs_invokecommand_ins.buffer2_outsize + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + if (rs_invokecommand_ins.buffer2 != NULL && + rs_invokecommand_ins.buffer2_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer2_outsize; iind++) + { + *((uint8_t * )(operation->params[1].tmpref.buffer) + iind) = + *(rs_invokecommand_ins.buffer2 + iind); + } + operation->params[1].tmpref.size = rs_invokecommand_ins.buffer2_outsize; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + operation->params[1].memref.parent->flags = + rs_invokecommand_ins.operation_param2_memref_parent_flag; + switch (operation->params[1].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[1].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM1_MEMREF_NULL; + } + if ( + operation->params[1].memref.parent->size < + rs_invokecommand_ins.buffer2_outsize + ) + { + return TEEC_ERROR_PARAM1_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer2 != NULL && + rs_invokecommand_ins.buffer2_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer2_outsize; iind++) + { + *((uint8_t * )(operation->params[1].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer2 + iind); + } + operation->params[1].memref.size = rs_invokecommand_ins.buffer2_outsize; + operation->params[1].memref.parent->size = rs_invokecommand_ins.buffer2_outsize; + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[1].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM1_MEMREF_NULL; + } + if (operation->params[1].memref.parent->size < + rs_invokecommand_ins.buffer2_outsize + ) + { + return TEEC_ERROR_PARAM1_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer2 != NULL && + rs_invokecommand_ins.buffer2_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer2_outsize; iind++) + { + *((uint8_t * )(operation->params[1].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer2 + iind); + } + operation->params[1].memref.parent->size = rs_invokecommand_ins.buffer2_outsize; + + operation->params[1].memref.offset = rs_invokecommand_ins.operation_param2_memref_offset; + operation->params[1].memref.size = rs_invokecommand_ins.operation_param2_memref_size; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT, INOUT + + + default: + break; + } + + operation->params[1].ionref.ion_share_fd = rs_invokecommand_ins.operation_param2_ionref_ionsharefd; + operation->params[1].ionref.ion_size = rs_invokecommand_ins.operation_param2_ionref_ionsize; + + + switch ( + TEEC_PARAM_TYPE_GET(rs_invokecommand_ins.operation_paramtypes, 2) + ) + { + case TEEC_VALUE_OUTPUT: + case TEEC_VALUE_INOUT: + { + operation->params[2].value.a = rs_invokecommand_ins.operation_param3_value_a; + operation->params[2].value.b = rs_invokecommand_ins.operation_param3_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if (operation->params[2].tmpref.buffer == NULL) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + + if (operation->params[2].tmpref.size < + rs_invokecommand_ins.buffer3_outsize + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + if (rs_invokecommand_ins.buffer3 != NULL && + rs_invokecommand_ins.buffer3_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer3_outsize; iind++) + { + *((uint8_t * )(operation->params[2].tmpref.buffer) + iind) = + *(rs_invokecommand_ins.buffer3 + iind); + } + operation->params[2].tmpref.size = rs_invokecommand_ins.buffer3_outsize; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + operation->params[2].memref.parent->flags = + rs_invokecommand_ins.operation_param3_memref_parent_flag; + switch (operation->params[2].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[2].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM2_MEMREF_NULL; + } + if ( + operation->params[2].memref.parent->size < + rs_invokecommand_ins.buffer3_outsize + ) + { + return TEEC_ERROR_PARAM2_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer3 != NULL && + rs_invokecommand_ins.buffer3_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer3_outsize; iind++) + { + *((uint8_t * )(operation->params[2].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer3 + iind); + } + operation->params[2].memref.size = rs_invokecommand_ins.buffer3_outsize; + operation->params[2].memref.parent->size = rs_invokecommand_ins.buffer3_outsize; + } + + break; + } + + default: + break; + } + + break; + + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[2].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM2_MEMREF_NULL; + } + if (operation->params[2].memref.parent->size < + rs_invokecommand_ins.buffer3_outsize + ) + { + return TEEC_ERROR_PARAM2_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer3 != NULL && + rs_invokecommand_ins.buffer3_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer3_outsize; iind++) + { + *((uint8_t * )(operation->params[2].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer3 + iind); + } + operation->params[2].memref.parent->size = rs_invokecommand_ins.buffer3_outsize; + + operation->params[2].memref.offset = rs_invokecommand_ins.operation_param3_memref_offset; + operation->params[2].memref.size = rs_invokecommand_ins.operation_param3_memref_size; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT, INOUT + + + default: + break; + } + + operation->params[2].ionref.ion_share_fd = rs_invokecommand_ins.operation_param3_ionref_ionsharefd; + operation->params[2].ionref.ion_size = rs_invokecommand_ins.operation_param3_ionref_ionsize; + + + switch ( + TEEC_PARAM_TYPE_GET(rs_invokecommand_ins.operation_paramtypes, 3) + ) + { + case TEEC_VALUE_OUTPUT: + case TEEC_VALUE_INOUT: + { + operation->params[3].value.a = rs_invokecommand_ins.operation_param4_value_a; + operation->params[3].value.b = rs_invokecommand_ins.operation_param4_value_b; + + break; + } + + case TEEC_MEMREF_TEMP_OUTPUT: + case TEEC_MEMREF_TEMP_INOUT: + { + if (operation->params[3].tmpref.buffer == NULL) + { + return TEEC_ERROR_PARAM0_TEMPMEM_NULL; + } + + if (operation->params[3].tmpref.size < + rs_invokecommand_ins.buffer4_outsize + ) + { + return TEEC_ERROR_PARAM0_TEMPMEM_LESS; + } + + if (rs_invokecommand_ins.buffer4 != NULL && + rs_invokecommand_ins.buffer4_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer4_outsize; iind++) + { + *((uint8_t * )(operation->params[3].tmpref.buffer) + iind) = + *(rs_invokecommand_ins.buffer4 + iind); + } + operation->params[3].tmpref.size = rs_invokecommand_ins.buffer4_outsize; + } + + break; + } + + + case TEEC_MEMREF_WHOLE: + { + operation->params[3].memref.parent->flags = + rs_invokecommand_ins.operation_param4_memref_parent_flag; + switch (operation->params[3].memref.parent->flags) + { + case TEEC_MEM_OUTPUT: + case TEEC_MEM_INOUT: + { + if ( + operation->params[3].memref.parent->buffer == NULL + ) + { + return TEEC_ERROR_PARAM3_MEMREF_NULL; + } + if ( + operation->params[3].memref.parent->size < + rs_invokecommand_ins.buffer4_outsize + ) + { + return TEEC_ERROR_PARAM3_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer4 != NULL && + rs_invokecommand_ins.buffer4_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer4_outsize; iind++) + { + *((uint8_t * )(operation->params[3].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer4 + iind); + } + operation->params[3].memref.size = rs_invokecommand_ins.buffer3_outsize; + operation->params[3].memref.parent->size = rs_invokecommand_ins.buffer3_outsize; + } + + break; + } + + default: + break; + } + + break; + } + + + case TEEC_MEMREF_PARTIAL_OUTPUT: + case TEEC_MEMREF_PARTIAL_INOUT: + { + if (operation->params[3].memref.parent->buffer == NULL) + { + return TEEC_ERROR_PARAM3_MEMREF_NULL; + } + if (operation->params[3].memref.parent->size < + rs_invokecommand_ins.buffer4_outsize + ) + { + return TEEC_ERROR_PARAM3_MEMREF_LESS; + } + + if (rs_invokecommand_ins.buffer4 != NULL && + rs_invokecommand_ins.buffer4_outsize > 0) + { + for (int iind = 0; iind < rs_invokecommand_ins.buffer4_outsize; iind++) + { + *((uint8_t * )(operation->params[3].memref.parent->buffer) + iind) = + *(rs_invokecommand_ins.buffer4 + iind); + } + operation->params[3].memref.parent->size = rs_invokecommand_ins.buffer4_outsize; + + operation->params[3].memref.offset = rs_invokecommand_ins.operation_param4_memref_offset; + operation->params[3].memref.size = rs_invokecommand_ins.operation_param4_memref_size; + } + + break; + } + // end of case TEEC_MEMREF_PARTIAL_OUTPUT, INOUT + + + default: + break; + } + + operation->params[3].ionref.ion_share_fd = rs_invokecommand_ins.operation_param4_ionref_ionsharefd; + operation->params[3].ionref.ion_size = rs_invokecommand_ins.operation_param4_ionref_ionsize; + + + operation->session = (TEEC_Session *) rs_invokecommand_ins.operation_session; + operation->cancel_flag = rs_invokecommand_ins.operation_cancelflag; + + if (returnOrigin != NULL) + { + *returnOrigin = in_returnorigin; + } + } + return static_cast(rs_invokecommand_ins.teecresult); + +} + +void +TEEC_CloseSession(TEEC_Session *session) +{ + if (gpp_channel == NULL) + { + printf("libteec: the grpc client or channel is null, when executing TEEC_CloseSession. \n"); + return; + } + + uint32_t in_session_sessionid; + uint32_t in_session_serviceid_timelow; + uint32_t in_session_serviceid_timemid; + uint32_t in_session_serviceid_timehiandver; + uint8_t in_session_serviceid_clockseqandnode[8]; + uintptr_t in_session_serviceid_clockseqandnode_size; + uint32_t in_session_opscnt; + uint64_t in_session_head_next; + int64_t in_session_head_prev; + uint64_t in_session_context; + + if (session == NULL) + { + return; + } + struct retstru_teec_closesession rs_closesession_ins; + + in_session_sessionid = session->session_id; + in_session_serviceid_timelow = session->service_id.timeLow; + in_session_serviceid_timemid = session->service_id.timeMid; + in_session_serviceid_timehiandver = session->service_id.timeHiAndVersion; + if ( + session->service_id.clockSeqAndNode != NULL + ) + { + for (int i = 0; i < 8; i++) + { + in_session_serviceid_clockseqandnode[i] = + session->service_id.clockSeqAndNode[i]; + } + } else + { + for (int i = 0; i < 8; i++) + { + in_session_serviceid_clockseqandnode[i] = 0; + } + } + in_session_serviceid_clockseqandnode_size = 8; + in_session_opscnt = session->ops_cnt; + in_session_head_next = (uint64_t) session->head.next; + in_session_head_prev = (uint64_t) session->head.prev; + in_session_context = glob_scontaddr; + + rs_closesession_ins = + client->externc_teec_closesession( + in_session_sessionid, + in_session_serviceid_timelow, + in_session_serviceid_timemid, + in_session_serviceid_timehiandver, + in_session_serviceid_clockseqandnode, + in_session_serviceid_clockseqandnode_size, + in_session_opscnt, + in_session_head_next, + in_session_head_prev, + in_session_context + ); + + if (rs_closesession_ins.flag == 1) + { + std::cout << "libteecc: closesession token null" << std::endl; + return; + } + if (rs_closesession_ins.flag == 2) + { + std::cout << "libteecc: closesession jwt validate error" << std::endl; + return; + } +#if 0 + std::cout << "externc_teec_closesession: " << std::endl; + std::cout << "gpp request sessionid: " << in_session_sessionid < 0 + && + rs_closesession_ins.session_serviceid_clockseqandnode != NULL + ) + { + printf("ret session_serviceid_clockseqandnode = \n"); + for (uintptr_t uisize = 0; + uisize < rs_closesession_ins.session_serviceid_clockseqandnode_outsize; + uisize ++) + { + printf(" %2.2x", *(rs_closesession_ins.session_serviceid_clockseqandnode + uisize)); + } + printf("\n"); + } + else + { + printf("ret clockseqandnode addr = 0x %16.16lx\n", + (unsigned long)rs_closesession_ins.session_serviceid_clockseqandnode); + } + printf("ret clockseqandnode_outsize = %ld\n", + rs_closesession_ins.session_serviceid_clockseqandnode_outsize); + printf("ret session_opscnt = 0x %8.8x\n", + rs_closesession_ins.session_opscnt); + printf("ret session_head_next = 0x %16.16lx\n", + rs_closesession_ins.session_head_next); + printf("ret session_head_prev = 0x %16.16lx\n", + rs_closesession_ins.session_head_prev); +#endif + session->session_id = rs_closesession_ins.session_sessionid; + session->service_id.timeLow = rs_closesession_ins.session_serviceid_timelow; + session->service_id.timeMid = rs_closesession_ins.session_serviceid_timemid; + session->service_id.timeHiAndVersion = rs_closesession_ins.session_serviceid_timehiandver; + if (rs_closesession_ins.session_serviceid_clockseqandnode_outsize <= 8 && + rs_closesession_ins.session_serviceid_clockseqandnode_outsize > 0 && + rs_closesession_ins.session_serviceid_clockseqandnode != NULL && + session->service_id.clockSeqAndNode != NULL + ) + { + for (int i = 0; i < rs_closesession_ins.session_serviceid_clockseqandnode_outsize; i++) + { + session->service_id.clockSeqAndNode[i] = + (uint8_t)(rs_closesession_ins.session_serviceid_clockseqandnode[i] & 0x000000ff); + } + } else + { + for (int i = 0; i < 8; i++) + { + session->service_id.clockSeqAndNode[i] = 0; + } + } + session->ops_cnt = rs_closesession_ins.session_opscnt; + session->head.next = (struct ListNode *) rs_closesession_ins.session_head_next; + session->head.prev = (struct ListNode *) rs_closesession_ins.session_head_prev; + session->context = (TEEC_Context *) rs_closesession_ins.session_context; + return; +} + +TEEC_Result +TEEC_AllocateSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem) +{ + if (context == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + if (sharedMem == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + if (sharedMem->size <= 0) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + sharedMem->buffer = (uint8_t *) malloc(sharedMem->size); + if (sharedMem->buffer == NULL) + { + return TEEC_ERROR_OUT_OF_MEMORY; + } + + sharedMem->is_allocated = true; + sharedMem->context = context; + sharedMem->ops_cnt = 0xfffe; + + return TEEC_SUCCESS; +} + +TEEC_Result +TEEC_RegisterSharedMemory( + TEEC_Context *context, + TEEC_SharedMemory *sharedMem) +{ + if (context == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + if (sharedMem == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + if (sharedMem->size <= 0) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + if (sharedMem->buffer == NULL) + { + return TEEC_ERROR_BAD_PARAMETERS; + } + + sharedMem->is_allocated = false; + sharedMem->context = context; + sharedMem->ops_cnt = 0xfffe; + + return TEEC_SUCCESS; +} + +void +TEEC_ReleaseSharedMemory( + TEEC_SharedMemory *sharedMem) +{ + if (sharedMem == NULL) + { + return; + } + if (sharedMem->buffer == NULL) + { + return; + } + + sharedMem->ops_cnt = 0x0; + if (sharedMem->is_allocated == true) + { + free(sharedMem->buffer); + } +} + + +TEEC_Result +TEEC_DeployTa( + char *infile_path, + char *subdir, + char *outfile_name +) +{ + + if (infile_path == NULL) + { + return TEEC_INFILE_PATH_NULL; + } + + std::string str_infile_path(infile_path); + std::string str_subdir; + std::string str_outfile_name; + + if (subdir != NULL) + { + str_subdir = std::string(subdir); + } + + if (outfile_name != NULL) + { + str_outfile_name = std::string(outfile_name); + } + + int iret; + + if (gpp_channel == NULL) + { + int igrpctls = grpc_tls; + + if (grpc_tls != 0 && grpc_tls != 1 && grpc_tls != 2) + { + std::cout << global_strcfgfile << " grpc_tls should be 0 or 1 or 2 " << std::endl; + return TEEC_FAIL; + } + + switch (igrpctls) + { + case 0: + { + gpp_channel = grpc::CreateChannel(global_target_str, grpc::InsecureChannelCredentials()); + + break; + } + + case 1: + { + if (!isFileExists_ifstream(global_servercacert_path)) + { + std::cout << "error file : " << global_servercacert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + + std::string strcmd; + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercacert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "gpp '" << global_servercacert_path << "' will expire in 7 days, please reget it" << std::endl; + return TEEC_FAIL; + } + + auto servercacert = get_file_contents(global_servercacert_path); + grpc::SslCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = servercacert; + std::shared_ptr creds = grpc::SslCredentials(ssl_opts); + gpp_channel = grpc::CreateChannel(global_target_str, creds); + + break; + } + + case 2: + { + if (!isFileExists_ifstream(global_servercacert_path)) + { + std::cout << "error file : " << global_servercacert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + if (!isFileExists_ifstream(global_clientkey_path)) + { + std::cout << "error file : " << global_clientkey_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + if (!isFileExists_ifstream(global_clientcert_path)) + { + std::cout << "error file : " << global_clientcert_path << " is not exist " << std::endl; + return TEEC_FAIL; + } + + std::string strcmd; + FILE *pipe; + char buffer[128]; + std::string result; + + std::string strdayseconds; + char *resulttemp; + const char slash[] = "\n"; + char *parresult; + std::string strparresult; + std::string willexpire("Certificate will expire"); + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_servercacert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "libteecc '" << global_servercacert_path << "' will expire in 7 days, please reget it" + << std::endl; + return TEEC_FAIL; + } + + // 7 days in seconds + strdayseconds = "604800"; + strcmd = "openssl x509 -enddate -noout -in " + global_clientcert_path + " -checkend " + strdayseconds; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + resulttemp = const_cast(result.data()); + parresult = strtok(resulttemp, slash); + while (parresult != NULL) + { + strparresult = std::string(parresult); + parresult = strtok(NULL, slash); + } + if (strparresult.compare(willexpire) == 0) + { + std::cout << "libteecc '" << global_clientcert_path << "' will expire in 7 days, please reget it" << std::endl; + return TEEC_FAIL; + } + strcmd = "openssl rsa -in " + global_clientkey_path + " -out " + + global_clientkey_path + ".nopass"; + std::string nopass_clientkey_path = global_clientkey_path + ".nopass"; + + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + + strcmd = "openssl rsa -in " + nopass_clientkey_path + " -check -noout"; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string keyok("RSA key ok\n"); + if (result.compare(keyok) != 0) + { + std::cout << "libteecc '" + global_clientkey_path + "' integrity is broken" << std::endl; + return TEEC_FAIL; + } + + std::string sigfile_path = global_strcfgfiletemp + "/.teecc/certs/msg.sig"; + std::string msgfile_path = global_strcfgfiletemp + "/.teecc/certs/msg.txt"; + strcmd = + "openssl dgst -sha256 -sign " + nopass_clientkey_path + " -out " + sigfile_path + " " + msgfile_path; + system(strcmd.c_str()); + // ${_openssl} x509 -in ${CRTPEM} -pubkey -out ${PUBPEM} + std::string pubkeyfile_path = global_strcfgfiletemp + "/.teecc/certs/client_pubkey.pem"; + strcmd = "openssl x509 -in " + global_clientcert_path + " -pubkey -out " + pubkeyfile_path; + system(strcmd.c_str()); + + // ${_openssl} dgst -sha256 -verify ${PUBPEM} -signature msg.sig msg.txt + strcmd = "openssl dgst -sha256 -verify " + pubkeyfile_path + " -signature " + sigfile_path + " " + + msgfile_path; + // system(strcmd.c_str()); + pipe = popen(strcmd.c_str(), "r"); + if (!pipe) + { + std::cout << "libteecc popen '" << strcmd << "' failed" << std::endl; + return TEEC_FAIL; + } + result = ""; + // read till end of process: + while (!feof(pipe)) + { + // use buffer to read and add to result + if (fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + std::string verifyok("Verified OK\n"); + if (result.compare(verifyok) != 0) + { + std::cout << "libteecc '" + global_clientkey_path + "' is not matched with '" + global_clientcert_path + "'" + << std::endl; + return TEEC_FAIL; + } + + auto clientkey = get_file_contents(nopass_clientkey_path); + strcmd = "rm -f " + global_clientkey_path + ".nopass"; + system(strcmd.c_str()); + strcmd = "rm -f " + pubkeyfile_path; + system(strcmd.c_str()); + strcmd = "rm -f " + sigfile_path; + system(strcmd.c_str()); + + auto servercacert = get_file_contents(global_servercacert_path); + auto clientcert = get_file_contents(global_clientcert_path); + grpc::SslCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = servercacert; + ssl_opts.pem_private_key = clientkey; + ssl_opts.pem_cert_chain = clientcert; + std::shared_ptr creds = grpc::SslCredentials(ssl_opts); + gpp_channel = grpc::CreateChannel(global_target_str, creds); + + break; + } + + default: + { + gpp_channel = grpc::CreateChannel(global_target_str, grpc::InsecureChannelCredentials()); + } + } + + client = new GppClient( + gpp_channel + ); + } + + iret = client->Upload(str_infile_path, str_subdir, str_outfile_name); + + return (TEEC_Result) iret; +} + + +TEEC_Result +TEEC_SetJwt( + char *token +) +{ + if (token == NULL || sizeof(token) > 1024) + { + return TEEC_FAIL; + } + + memset(glo_token, '\0', sizeof(glo_token)); + strcpy(glo_token, token); + + return TEEC_SUCCESS; +} + + +TEEC_Result +TEEC_UnsetJwt( +) +{ + memset(glo_token, '\0', sizeof(glo_token)); + strcpy(glo_token, "noToken"); + + return TEEC_SUCCESS; +} + + +#ifdef __cplusplus +}; +#endif diff --git a/teeproxy/libteecc/teecc.h b/teeproxy/libteecc/teecc.h new file mode 100644 index 0000000..47abd0f --- /dev/null +++ b/teeproxy/libteecc/teecc.h @@ -0,0 +1,351 @@ +#ifndef _TEECC_H +#define _TEECC_H + +#include + +struct retstru_teec_inicont { + uint32_t teecresult; + int32_t context_fd; + uint8_t *context_tapath; + uintptr_t context_tapath_outsize; + uint64_t context_sessionlist_next; + uint64_t context_sessionlist_prev; + uint64_t context_shrdmemlist_next; + uint64_t context_shrdmemlist_prev; + uint64_t context_sharebuffer_buffer; + int64_t context_sharebuffer_bufferbarrier; + uint64_t context_addr; + int32_t flag; +}; + +struct retstru_teec_fincont { + int32_t context_fd; + uint8_t *context_tapath; + uintptr_t context_tapath_outsize; + uint64_t context_sessionlist_next; + uint64_t context_sessionlist_prev; + uint64_t context_shrdmemlist_next; + uint64_t context_shrdmemlist_prev; + uint64_t context_sharebuffer_buffer; + int64_t context_sharebuffer_bufferbarrier; + int32_t flag; +}; + +struct retstru_teec_opensession { + uint32_t teecresult; + int32_t context_fd; + uint8_t *context_tapath; + uintptr_t context_tapath_outsize; + uint64_t context_sessionlist_next; + uint64_t context_sessionlist_prev; + uint64_t context_shrdmemlist_next; + uint64_t context_shrdmemlist_prev; + uint64_t context_sharebuffer_buffer; + int64_t context_sharebuffer_bufferbarrier; + uint32_t session_sessionid; + uint32_t session_serviceid_timelow; + uint32_t session_serviceid_timemid; + uint32_t session_serviceid_timehiandver; + uint8_t *session_serviceid_clockseqandnode; + uintptr_t session_serviceid_clockseqandnode_outsize; + uint32_t session_opscnt; + uint64_t session_head_next; + uint64_t session_head_prev; + uint64_t session_context; + uint32_t operation_started; + uint32_t operation_paramtypes; + uint64_t operation_param1_tmpref_buffer; + uint32_t operation_param1_tmpref_size; + uint64_t operation_param1_memref_parent; + uint32_t operation_param1_memref_size; + uint32_t operation_param1_memref_offset; + uint32_t operation_param1_value_a; + uint32_t operation_param1_value_b; + int32_t operation_param1_ionref_ionsharefd; + uint32_t operation_param1_ionref_ionsize; + uint64_t operation_param2_tmpref_buffer; + uint32_t operation_param2_tmpref_size; + uint64_t operation_param2_memref_parent; + uint32_t operation_param2_memref_size; + uint32_t operation_param2_memref_offset; + uint32_t operation_param2_value_a; + uint32_t operation_param2_value_b; + int32_t operation_param2_ionref_ionsharefd; + uint32_t operation_param2_ionref_ionsize; + uint64_t operation_param3_tmpref_buffer; + uint32_t operation_param3_tmpref_size; + uint64_t operation_param3_memref_parent; + uint32_t operation_param3_memref_size; + uint32_t operation_param3_memref_offset; + uint32_t operation_param3_value_a; + uint32_t operation_param3_value_b; + int32_t operation_param3_ionref_ionsharefd; + uint32_t operation_param3_ionref_ionsize; + uint64_t operation_param4_tmpref_buffer; + uint32_t operation_param4_tmpref_size; + uint64_t operation_param4_memref_parent; + uint32_t operation_param4_memref_size; + uint32_t operation_param4_memref_offset; + uint32_t operation_param4_value_a; + uint32_t operation_param4_value_b; + int32_t operation_param4_ionref_ionsharefd; + uint32_t operation_param4_ionref_ionsize; + uint64_t operation_session; + int32_t operation_cancelflag; + uint32_t returnorigin; + int32_t flag; + +}; + +struct retstru_teec_closesession { + uint32_t session_sessionid; + uint32_t session_serviceid_timelow; + uint32_t session_serviceid_timemid; + uint32_t session_serviceid_timehiandver; + uint8_t *session_serviceid_clockseqandnode; + uintptr_t session_serviceid_clockseqandnode_outsize; + uint32_t session_opscnt; + uint64_t session_head_next; + uint64_t session_head_prev; + uint64_t session_context; + int32_t flag; + +}; + +struct retstru_teec_invokecommand { + uint32_t teecresult; + uint32_t session_sessionid; + uint32_t session_serviceid_timelow; + uint32_t session_serviceid_timemid; + uint32_t session_serviceid_timehiandver; + uint8_t *session_serviceid_clockseqandnode; + uintptr_t session_serviceid_clockseqandnode_outsize; + uint32_t session_opscnt; + uint64_t session_head_next; + uint64_t session_head_prev; + uint64_t session_context; + uint32_t operation_started; + uint32_t operation_paramtypes; + uint64_t operation_param1_tmpref_buffer; + uint32_t operation_param1_tmpref_size; + uint64_t operation_param1_memref_parent; + uint32_t operation_param1_memref_parent_flag; + uint32_t operation_param1_memref_size; + uint32_t operation_param1_memref_offset; + uint32_t operation_param1_value_a; + uint32_t operation_param1_value_b; + int32_t operation_param1_ionref_ionsharefd; + uint32_t operation_param1_ionref_ionsize; + uint64_t operation_param2_tmpref_buffer; + uint32_t operation_param2_tmpref_size; + uint64_t operation_param2_memref_parent; + uint32_t operation_param2_memref_parent_flag; + uint32_t operation_param2_memref_size; + uint32_t operation_param2_memref_offset; + uint32_t operation_param2_value_a; + uint32_t operation_param2_value_b; + int32_t operation_param2_ionref_ionsharefd; + uint32_t operation_param2_ionref_ionsize; + uint64_t operation_param3_tmpref_buffer; + uint32_t operation_param3_tmpref_size; + uint64_t operation_param3_memref_parent; + uint32_t operation_param3_memref_parent_flag; + uint32_t operation_param3_memref_size; + uint32_t operation_param3_memref_offset; + uint32_t operation_param3_value_a; + uint32_t operation_param3_value_b; + int32_t operation_param3_ionref_ionsharefd; + uint32_t operation_param3_ionref_ionsize; + uint64_t operation_param4_tmpref_buffer; + uint32_t operation_param4_tmpref_size; + uint64_t operation_param4_memref_parent; + uint32_t operation_param4_memref_parent_flag; + uint32_t operation_param4_memref_size; + uint32_t operation_param4_memref_offset; + uint32_t operation_param4_value_a; + uint32_t operation_param4_value_b; + int32_t operation_param4_ionref_ionsharefd; + uint32_t operation_param4_ionref_ionsize; + uint64_t operation_session; + int32_t operation_cancelflag; + uint32_t returnorigin; + uint8_t *buffer1; + uintptr_t buffer1_outsize; + uint8_t *buffer2; + uintptr_t buffer2_outsize; + uint8_t *buffer3; + uintptr_t buffer3_outsize; + uint8_t *buffer4; + uintptr_t buffer4_outsize; + int32_t flag; +}; + + +struct retstru_teec_inicont externc_teec_initializecontext(uint8_t *name, + uint32_t name_size, + int32_t in_context_fd, + uint8_t *in_context_tapath, + int32_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier); + +void externc_retstru_teec_inicont_free(struct retstru_teec_inicont rs_ins); + +struct retstru_teec_fincont externc_teec_finalizecontext(int32_t in_context_fd, + uint8_t *in_context_tapath, + int32_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint64_t in_context_addr); + +void externc_retstru_teec_fincont_free(struct retstru_teec_fincont rs_ins); + +struct retstru_teec_opensession externc_teec_opensession(int32_t in_context_fd, + uint8_t *in_context_tapath, + int32_t in_context_tapath_size, + uint64_t in_context_sessionlist_next, + uint64_t in_context_sessionlist_prev, + uint64_t in_context_shrdmemlist_next, + uint64_t in_context_shrdmemlist_prev, + uint64_t in_context_sharebuffer_buffer, + int64_t in_context_sharebuffer_bufferbarrier, + uint32_t in_destination_timelow, + uint32_t in_destination_timemid, + uint32_t in_destination_timehiandver, + uint8_t *in_destination_clockseqandnode, + int32_t in_destination_clockseqandnode_size, + uint32_t in_connectionmethod, + uint64_t in_connectiondata, + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + uint32_t in_returnorigin, + uint64_t in_context_addr); + +void externc_retstru_teec_opensession_free(struct retstru_teec_opensession rs_ins); + +struct retstru_teec_closesession externc_teec_closesession(uint32_t in_session_sessionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint8_t *in_session_serviceid_clockseqandnode, + uintptr_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context); + +void externc_retstru_teec_closesession_free(struct retstru_teec_closesession rs_ins); + +struct retstru_teec_invokecommand externc_teec_invokecommand(uint32_t in_session_sessionid, + uint32_t in_session_serviceid_timelow, + uint32_t in_session_serviceid_timemid, + uint32_t in_session_serviceid_timehiandver, + uint8_t *in_session_serviceid_clockseqandnode, + uintptr_t in_session_serviceid_clockseqandnode_size, + uint32_t in_session_opscnt, + uint64_t in_session_head_next, + uint64_t in_session_head_prev, + uint64_t in_session_context, + uint32_t in_commandid, + uint32_t in_operation_started, + uint32_t in_operation_paramtypes, + uint64_t in_operation_param1_tmpref_buffer, + uint32_t in_operation_param1_tmpref_size, + uint64_t in_operation_param1_memref_parent, + uint32_t in_operation_param1_memref_parent_flag, + uint32_t in_operation_param1_memref_size, + uint32_t in_operation_param1_memref_offset, + uint32_t in_operation_param1_value_a, + uint32_t in_operation_param1_value_b, + int32_t in_operation_param1_ionref_ionsharefd, + uint32_t in_operation_param1_ionref_ionsize, + uint64_t in_operation_param2_tmpref_buffer, + uint32_t in_operation_param2_tmpref_size, + uint64_t in_operation_param2_memref_parent, + uint32_t in_operation_param2_memref_parent_flag, + uint32_t in_operation_param2_memref_size, + uint32_t in_operation_param2_memref_offset, + uint32_t in_operation_param2_value_a, + uint32_t in_operation_param2_value_b, + int32_t in_operation_param2_ionref_ionsharefd, + uint32_t in_operation_param2_ionref_ionsize, + uint64_t in_operation_param3_tmpref_buffer, + uint32_t in_operation_param3_tmpref_size, + uint64_t in_operation_param3_memref_parent, + uint32_t in_operation_param3_memref_parent_flag, + uint32_t in_operation_param3_memref_size, + uint32_t in_operation_param3_memref_offset, + uint32_t in_operation_param3_value_a, + uint32_t in_operation_param3_value_b, + int32_t in_operation_param3_ionref_ionsharefd, + uint32_t in_operation_param3_ionref_ionsize, + uint64_t in_operation_param4_tmpref_buffer, + uint32_t in_operation_param4_tmpref_size, + uint64_t in_operation_param4_memref_parent, + uint32_t in_operation_param4_memref_parent_flag, + uint32_t in_operation_param4_memref_size, + uint32_t in_operation_param4_memref_offset, + uint32_t in_operation_param4_value_a, + uint32_t in_operation_param4_value_b, + int32_t in_operation_param4_ionref_ionsharefd, + uint32_t in_operation_param4_ionref_ionsize, + uint64_t in_operation_session, + int32_t in_operation_cancelflag, + uint32_t in_returnorigin, + uint8_t *in_buffer1, + uintptr_t in_buffer1_size, + uint8_t *in_buffer2, + uintptr_t in_buffer2_size, + uint8_t *in_buffer3, + uintptr_t in_buffer3_size, + uint8_t *in_buffer4, + uintptr_t in_buffer4_size); + +void externc_retstru_teec_invokecommand_free(struct retstru_teec_invokecommand rs_ins); +#endif // _TEECC_H \ No newline at end of file -- Gitee

  • |%{RhN$@0=;@WF?L93o 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