From: Youngjae Shin Date: Fri, 26 Jun 2015 06:26:23 +0000 (+0900) Subject: Imported Upstream version 0.9.1 X-Git-Tag: upstream/0.9.1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=935fdb9b67b6c10d007e652e9e2e028fd6ccfe09;p=contrib%2Fiotivity.git Imported Upstream version 0.9.1 --- diff --git a/.gitignore b/.gitignore index 04161af..d0fbb21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,23 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + # Ignore output dirs /release resource/release @@ -22,6 +42,9 @@ resource/oc_logger/lib/ resource/oc_logger/samples/linux/release/ resource/oc_logger/samples/linux/debug +resource/unittests/release/ +resource/unittests/debug/ + service/things-manager/build/linux/release service/things-manager/build/linux/debug service/things-manager/sdk/build/linux/ @@ -32,9 +55,9 @@ service/things-manager/sdk/build/linux/ # Ignore Eclipse workspace files *.settings/ -*.cproject -*.project +# Ignore CTags default data +tags # Ignore dependencies folder, which should be generated dependencies/ @@ -53,8 +76,24 @@ out/ platform # Ignore downloaded dependencies -extlibs/gtest* +extlibs/gtest/gtest-* +extlibs/hippomocks-master/ +extlibs/master.zip +extlibs/cereal/cereal +extlibs/expat/expat* extlibs/cereal +extlibs/android/gradle/gradle-2.2.1 +extlibs/android/ndk/android-ndk-r10d +extlibs/android/sdk/android-sdk_r24.2 +extlibs/boost/boost_1_58_0 +*.tgz +*.zip +extlibs/arduino/arduino-1.5.8 +build_common/arduino/extlibs/arduino/arduino-1.5.8 +# Ignore editor (e.g. Emacs) backup and autosave files *~ -cscope.out +*#*# + +# Ignore byte-compiled Python scripts +*.pyc diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e9e1f02 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,195 @@ +Copyright (c) 2014, 2015 IoTivity + + +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 + + + +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. + +``` +------------------------------------------------------------------------- + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS +``` diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..6d243f8 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,59 @@ +IoTivity +Copyright (c) 2014, 2015 IoTivity + +This product includes software developed as part of +the IoTivity (http://www.iotivity.org/) project. + +Tools and Utilities +=================== + +Software construction is provided by SCons a python-based software +constrution tools which is open source software with copyright +by The SCons Foundation with an MIT license. The original software +is available from + http://scons.org/download.php + +Android binaries are created using the Android SDK and NDK provided +by Google. The original software can be found at + https://developer.android.com/sdk + +Libraries +========= + +The CoAP protocol is provided by the libcoap package, +which is open source software, written and copyright by Olaf Bergmann +with a BSD and GPLv2 license. The original software is available from + http://sourceforge.net/projects/libcoap/ + +The DTLS protocol is provided by the tinyDTLS package, +which is open source software, written and copyright by Olaf Bergmann +with an MIT license. The tinyDTLS library relies on algorithms whose +source is under a BSD license. The additional licenses can be viewed at + http://tinydtls.sourceforge.net/ +The original software is available from + http://sourceforge.net/projects/tinydtls/ + +This project relies on utilities in the Boost C++library which is open +source software with a Boost Software License v1.0. The details of the +license can be found at + http://www.boost.org/users/license.html +The original software is available from + http://sourceforge.net/projects/boost/files/boost + +JSON serialization is provided by the cereal package, +which is open source software, written by Philip Hazel, and copyright +by the University of Cambridge, England. The original software is +available from + ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ + +JSON serialization is provided by the cjson package, +which is open source software, written and copyright by Dave Gamble +with an MIT license. The original software is available from + http://sourceforge.net/projects/cjson/ + +JSON serialization is provided by the rapidjson package, +which is open source software, written and copyright by Milo Yip +with an MIT license. The original software is available from + http://code.google.com/p/rapidjson/ + + diff --git a/Readme.scons.txt b/Readme.scons.txt index 2129efe..d433b3b 100644 --- a/Readme.scons.txt +++ b/Readme.scons.txt @@ -1,3 +1,33 @@ +== Quick guide: build and run IoTivity projects on Ubuntu == + +1. Build + Go to the top directory of 'iotivity' project(Note: should always run 'scons' +command in this directory) + + Install external libraries: + $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev libboost-thread-dev uuid-dev + + Build release binaries: + $ scons +(Note: C++ sdk requires cereal. Please follow the instruction in the build +message to install cereal) + + Build debug binaries: + $scons RELEASE=false + + Help: + $ scons -h + + Clear: + $ scons -c + +2. Run the samples + $ export LD_LIBRARY_PATH=/out/linux/x86_64/release + Run the c++ samples in /out/linux/x86_64/release/resource/examples + Run the c samples in /out/linux/x86_64/release/resource/csdk/stack/samples/linux/SimpleClientServer +('' is the path to 'iotivity' project. If your device is x86, arm, +or arm64, please change 'x86_64' to the proper arch) + == How to build IoTivity projects == IoTivity includes a series of projects. You can find all these projects here: @@ -8,7 +38,7 @@ Linux, Tizen, Android, Arduino, Windows, MAC OSX, IOS ...). The output of the build is in: /out//// e.g. - oic-resource/out/android/armeabi-v7a/release/. + iotivity/out/android/armeabi-v7a/release/. This document takes 'iotivity' project as example, the way to build other projects is almost the same. @@ -26,7 +56,16 @@ information(include build options). To see the help information: $ scons [options] -h Note: If no value is specified for an option, the default value will be used. -The change of options value may impact the output. +The change of options value may impact the help information and the behavior +of the building. + +Generally, it's required to specify the target OS and target ARCH, that's to say +tell Scons which OS and which ARCH you'd like build this project for. By default, +the target OS and ARCH is the same as the host. + +Some more options may be required, please care the 'error' notification when build. +For help about how to set an option, please run: + $ scons TARGET_OS=xxx TARGET_ARCH=yyy [XXX=zzz ...] -h === Prerequites === @@ -46,7 +85,7 @@ To build for Android, Andorid NDK and SDK are required. Android NDK: http://developer.android.com/tools/sdk/ndk/index.html Android SDK: http://developer.android.com/sdk/index.html (Note: as in some IoTivity projects, C++11 features are used, recommend Android - NDK >= r10, according to our test result r10c is the best one currently) + NDK >= r10) Arduino: To build for Arduino, Arduino IDE is required. @@ -76,33 +115,32 @@ Java codes, this isn't required) so you don't need to add it in command line each time. The build script will guide you to do that.) -* 3. External libraries -For Android and IOS build, most of the external libraries are provided as -binary in oic-utilities project (https://oic-review.01.org/gerrit/oic-utilities). -Please download it in the same directory as other IoTivity projects. If it's -in different directory, an additional option (OIC_UITLS) will be required. The -build command should be: - $ scons OIC_UITLS= [other options] [target] +Tizen: +To build for tizen platform cereal library is needed. +Please download cereal if it is not present in extlibs/cereal folder +and apply the patch as following: + $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal + $ cd extlibs/cereal/cereal + $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 + $ git apply ../../../resource/patches/cereal_gcc46.patch -(Note: for convenience, you can also add it in environment variable. So you -don't need to add this option in command line each time.) - e.g.: - $ export OIC_UITLS= +* 3. External libraries +IoTivity project depends on some external libraries, such as boost, expat ... +During building, the existence of external library will be checked, if it doesn't +exist, the build script will try to download, unpack and build the library or +notify user to install it. -=== Build IoTivity project on Linux(Ubuntu) === +Downloading and unpacking may fail due to network problem or required unpacking +tool isn't installed. An message will be displayed, please follow the message +to skip it. -Generally, it's required to specify the target OS and target ARCH, that's to say -tell Scons which OS and which ARCH you'd like build this project for. By default, -the target OS and ARCH is the same as the host. -Some more options may be required, please care the 'error' notification when build. -For help about how to set an option, please run: - $ scons TARGET_OS=xxx TARGET_ARCH=yyy [XXX=zzz ...] -h +=== Build IoTivity project on Linux(Ubuntu) === 1. Build IoTivity project for Linux $ cd - $ sudo apt-get install libboost-dev libboost-program-options-dev libexpat1-dev + $ sudo apt-get install libboost-dev libexpat1-dev libboost-thread-dev $ scons 2. Build IoTivity project for Android @@ -111,10 +149,6 @@ For help about how to set an option, please run: (xxx can be x86, armeabi, armeabi-v7a, armeabi-v7a-hard. To see all of its allowed value, please execute command 'scons TARGET_OS=android -Q -h') -Note: Currently as x86_64/arm64_v8a external library binaries aren't provided, -you may meet link problem if build executable binary which depends on external -library for x86_64/arm64_v8a. - 3. Build IoTivity project for Arduino $ cd $ scons TARGET_OS=arduino TARGET_ARCH=xxx BOARD=yyy @@ -127,13 +161,13 @@ it's unnecessary to specify it) 4. Build Iotivity project for Tizen $ cd - $ gbs build -A xxx --packaging-dir tools/tizen/ -(xxx can be i586 or armv7l, we provide the spec file required by gbs tool at -toools/tizen directory. gbs is default build tool for Tizen platfrom, we can -refer the following wiki to setup Tizen development environment: + $ sh gbsbuild.sh +(we provide the spec file required by gbs tool at toools/tizen directory. +gbs is default build tool for Tizen platfrom, we can refer the following +wiki to setup Tizen development environment: https://source.tizen.org/documentation/developer-guide/getting-started-guide) -=== Build IoTivity project on Windows === +=== Build IoTivity project on Android === 1. Build IoTivity project for Android(It's the same as on Ubuntu) $ cd @@ -183,7 +217,7 @@ Note: at once. Following is the usage: To build: - $ auto_build.sh + $ auto_build.sh To clean: $ auto_build.sh -c diff --git a/SConstruct b/SConstruct index 92eac38..bbe03d1 100644 --- a/SConstruct +++ b/SConstruct @@ -1,18 +1,47 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ## # The main build script # ## +import os # Load common build config SConscript('build_common/SConscript') +Import('env') + +if os.environ.get('TERM') != None: + env['ENV']['TERM'] = os.environ['TERM'] + # Load extra options SConscript('extra_options.scons') -Import('env') target_os = env.get('TARGET_OS') if target_os == 'arduino': SConscript('arduino.scons') + +if target_os == 'android': + SConscript('android/android_api/SConscript') + # By default, src_dir is current dir, the build_dir is: # ./out//// # @@ -27,6 +56,9 @@ build_dir = env.get('BUILD_DIR') # Build 'resource' sub-project SConscript(build_dir + 'resource/SConscript') +if target_os not in ['arduino','darwin','ios', 'android']: + SConscript(build_dir + 'examples/OICMiddle/SConscript') + # Build 'service' sub-project SConscript(build_dir + 'service/SConscript') @@ -37,3 +69,4 @@ env.PrintTargets() # Print bin upload command line (arduino only) if target_os == 'arduino': env.UploadHelp() + diff --git a/android/Base/app/build.gradle b/android/Base/app/build.gradle deleted file mode 100644 index 31d66bb..0000000 --- a/android/Base/app/build.gradle +++ /dev/null @@ -1,60 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 19 - buildToolsVersion "19.1.0" - - defaultConfig { - applicationId "org.iotivity.base" - minSdkVersion 19 - targetSdkVersion 19 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} - - -////////////// -// NDK Support -////////////// -// If using this, Android studio will fail run the following to set the environment variable for android studio: -// launchctl setenv ANDROID_NDK_HOME /Users/boos_patrick/Development/Android/android-ndk-r8e -// otherwise remove the dependsOn part and run ./gradlew buildNative from the command line -task copyNativeLibs(type: Copy, dependsOn: 'buildNative') { - dependsOn 'buildNative' - from(new File('libs')) { include '**/*.so' } - into new File(buildDir, 'native-libs') -} - -tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs } - -clean.dependsOn 'cleanCopyNativeLibs' - -tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> - pkgTask.jniFolders = new HashSet() - pkgTask.jniFolders.add(new File(buildDir, 'native-libs')) -} - -task buildNative(type: Exec) { - if (System.env.ANDROID_NDK_HOME != null) { - def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build') - commandLine ndkBuild - } else { - doLast { - println '##################' - println 'Skipping NDK build' - println 'Reason: ANDROID_NDK_HOME not set.' - println '##################' - } - } -} diff --git a/android/Base/app/jni/Android.mk b/android/Base/app/jni/Android.mk deleted file mode 100644 index 58e9a36..0000000 --- a/android/Base/app/jni/Android.mk +++ /dev/null @@ -1,57 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release -LOCAL_MODULE := libandroid-oc_logger -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc_logger.a -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release -LOCAL_MODULE := libandroid-octbstack -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboctbstack.a -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release -LOCAL_MODULE := libandroid-oc -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc.a -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release -LOCAL_MODULE := libandroid-coap -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libcoap.a -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -OIC_LIB_PATH := ../../../../out/android/$(TARGET_ARCH_ABI)/release -LOCAL_MODULE := libandroid-compatibility -LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libcompatibility.a -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -OIC_SRC_PATH := ../../../resource -OIC_OUT_PATH := ../../../out -LOCAL_MODULE := ocstack-jni -LOCAL_SRC_FILES := ocstack-jni.cpp \ - ocheaderoption-jni.cpp \ - ocrepresentation-jni.cpp \ - ocresource-jni.cpp \ - ocplatform-jni.cpp \ - platformcfg-jni.cpp -LOCAL_LDLIBS := -llog -LOCAL_STATIC_LIBRARIES := android-oc -LOCAL_STATIC_LIBRARIES += android-octbstack -LOCAL_STATIC_LIBRARIES += android-coap -LOCAL_STATIC_LIBRARIES += android-oc_logger -LOCAL_STATIC_LIBRARIES += libandroid-compatibility -LOCAL_CPPFLAGS += -std=c++0x -frtti -fexceptions -LOCAL_C_INCLUDES := $(OIC_SRC_PATH)/include -LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/stack/include -LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/ocsocket/include -LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/oc_logger/include -LOCAL_C_INCLUDES += $(OIC_OUT_PATH)/android/include -LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/dependencies/cereal/include -include $(BUILD_SHARED_LIBRARY) - diff --git a/android/Base/app/jni/Application.mk b/android/Base/app/jni/Application.mk deleted file mode 100644 index 4450fdf..0000000 --- a/android/Base/app/jni/Application.mk +++ /dev/null @@ -1,2 +0,0 @@ -NDK_TOOLCHAIN_VERSION := 4.9 -APP_STL := gnustl_static diff --git a/android/Base/app/jni/ocheaderoption-jni.cpp b/android/Base/app/jni/ocheaderoption-jni.cpp deleted file mode 100644 index 7dcd320..0000000 --- a/android/Base/app/jni/ocheaderoption-jni.cpp +++ /dev/null @@ -1,44 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -static const char* TAG = "OCHEADEROPTION-JNI"; - -JNIEXPORT jint JNICALL getOptionID(JNIEnv *env, jobject jobj) -{ - OC::HeaderOption::OCHeaderOption *option = getHandle(env, jobj); - return option->getOptionID(); -} - -JNIEXPORT jstring JNICALL getOptionData(JNIEnv *env, jobject jobj) -{ - OC::HeaderOption::OCHeaderOption *option = getHandle(env, jobj); - std::string data = option->getOptionData(); - return env->NewStringUTF(data.c_str()); -} - -JNIEXPORT jlong JNICALL OCHeaderOptionConstructor(JNIEnv *env, jobject jobj, jint joption, jstring jdata) -{ - OC::HeaderOption::OCHeaderOption *option = new OC::HeaderOption::OCHeaderOption(joption, env->GetStringUTFChars(jdata, 0)); - jlong instptr = reinterpret_cast(option); - return instptr; -} - diff --git a/android/Base/app/jni/ocplatform-jni.cpp b/android/Base/app/jni/ocplatform-jni.cpp deleted file mode 100644 index a69ac2d..0000000 --- a/android/Base/app/jni/ocplatform-jni.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -static const char* TAG = "OCPLATFORM-JNI"; - -JNIEXPORT void JNICALL configure(JNIEnv *env, jobject obj, jobject jcfg) -{ - OC::PlatformConfig *cfg = getHandle(env, jcfg); - - __android_log_print(ANDROID_LOG_INFO, TAG, "service : %d\n", (int) cfg->serviceType); - __android_log_print(ANDROID_LOG_INFO, TAG, "mode : %d\n", (int) cfg->mode); - __android_log_print(ANDROID_LOG_INFO, TAG, "IP : %s\n", (cfg->ipAddress).c_str()); - __android_log_print(ANDROID_LOG_INFO, TAG, "port : %d\n", cfg->port); - __android_log_print(ANDROID_LOG_INFO, TAG, "QOS : %d\n", (int) cfg->QoS); - - OC::OCPlatform::Configure(*cfg); -} - - -JNIEXPORT jint JNICALL findResource(JNIEnv* env, jobject obj, jstring jhost, jstring juri, jobject found) -{ - string host = env->GetStringUTFChars(jhost,0); - string uri = env->GetStringUTFChars(juri,0); - - JNICallBackContext *callbackContext; - string key = uri + "/FIND"; - std:map::iterator iter = gJNICallBackContextList.find(key); - if(iter == gJNICallBackContextList.end()) { - gJNICallBackContextList[key] = new JNICallBackContext(env->NewGlobalRef(found)); - callbackContext = gJNICallBackContextList[key]; - __android_log_print(ANDROID_LOG_INFO, TAG, "Adding %s to gJNICallBackContextList", key.c_str()); - } - else - callbackContext = iter->second; - - __android_log_print(ANDROID_LOG_ERROR, TAG, "Calling oic base findresource()\n"); - try { - OC::OCPlatform::findResource(host, uri, - [callbackContext](std::shared_ptr resource) - { - JNIEnv * env; - - // Attach to JavaVM - // double check it's all ok - int getEnvStat = g_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: not attached"); - if (g_JavaVM->AttachCurrentThread(&env, NULL) != 0) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to attach"); - } - else - __android_log_print(ANDROID_LOG_INFO, TAG, "Attached OK"); - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: version not supported"); - } - - // save the C++ resource ptr now - jmethodID resource_constructor = env->GetMethodID(g_ocresource_clazz, "", "(J)V"); - - callbackContext->m_resource = resource; - jobject jresource = env->NewObject(g_ocresource_clazz, resource_constructor, \ - (jlong) reinterpret_cast(&callbackContext->m_resource)); - - if(jresource == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "cannot create OCResource class"); - return; - } - - jclass clazz = env->GetObjectClass(callbackContext->m_callBackFunction); - if (clazz == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to find class"); - } - - // Find Callback function - jmethodID mid = env->GetMethodID(clazz, "Callback", \ - "(Lorg/iotivity/base/OCResource;)V"); - if(mid == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "FoundResource.Callback() is not defined in JAVA"); - return; - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "calling JAVA FindCallback"); - try { - env->CallVoidMethod(callbackContext->m_callBackFunction, mid, jresource); - } catch(OC::OCException& e) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "callbackContext() exception : %s", e.reason(e).c_str()); - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "fineResourceCB detach"); - env->DeleteLocalRef(jresource); - g_JavaVM->DetachCurrentThread(); - - } - ); - } - catch(OC::OCException& e) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "FindCB() exception : %s", e.reason(e).c_str()); - } - __android_log_print(ANDROID_LOG_ERROR, TAG, "Called oic base findresource()\n"); - - return 0; -} - diff --git a/android/Base/app/jni/ocrepresentation-jni.cpp b/android/Base/app/jni/ocrepresentation-jni.cpp deleted file mode 100644 index d7c894d..0000000 --- a/android/Base/app/jni/ocrepresentation-jni.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -static const char* TAG = "OCREPRESENTATION-JNI"; - -JNIEXPORT jlong JNICALL OCRepresentationConstructor(JNIEnv *env, jobject jobj) -{ - OC::OCRepresentation *rep = new OC::OCRepresentation(); - jlong instptr = reinterpret_cast(rep); - return instptr; -} - -JNIEXPORT jstring JNICALL getUri(JNIEnv *env, jobject jobj) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string uri = rep->getUri(); - __android_log_print(ANDROID_LOG_INFO, TAG, "getUri() URI : %s", uri.c_str()); - return env->NewStringUTF(uri.c_str()); -} - -JNIEXPORT jint JNICALL getValueInt(JNIEnv *env, jobject jobj, jstring jstr) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - int val; - rep->getValue(str, val); - __android_log_print(ANDROID_LOG_INFO, TAG, "getValueInt() : %d", val); - return((jint) val); -} - - -JNIEXPORT jboolean JNICALL getValueBool(JNIEnv *env, jobject jobj, jstring jstr) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - bool val; - rep->getValue(str, val); - __android_log_print(ANDROID_LOG_INFO, TAG, "getValueBool() : %d", val); - return((jboolean) val); -} - -JNIEXPORT jstring JNICALL getValueString(JNIEnv *env, jobject jobj, jstring jstr) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - string get_val; - rep->getValue(str, get_val); - - __android_log_print(ANDROID_LOG_INFO, TAG, "getValueString() : %s", get_val.c_str()); - return env->NewStringUTF(get_val.c_str()); -} - -JNIEXPORT void JNICALL setValueInt(JNIEnv *env, jobject jobj, jstring jstr, jint jval) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - rep->setValue(str, jval); -} - -JNIEXPORT void JNICALL setValueBool(JNIEnv *env, jobject jobj, jstring jstr, jboolean jval) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - rep->setValue(str, (bool) jval); -} - -JNIEXPORT void JNICALL setValueString(JNIEnv *env, jobject jobj, jstring jstr, jstring jval) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - string val = env->GetStringUTFChars(jval,0); - - rep->setValue(str, val); -} - -JNIEXPORT jboolean JNICALL hasAttribute(JNIEnv *env, jobject jobj, jstring jstr) -{ - OC::OCRepresentation *rep = getHandle(env, jobj); - string str = env->GetStringUTFChars(jstr,0); - - return rep->hasAttribute(str); -} diff --git a/android/Base/app/jni/ocresource-jni.cpp b/android/Base/app/jni/ocresource-jni.cpp deleted file mode 100644 index 95c2c39..0000000 --- a/android/Base/app/jni/ocresource-jni.cpp +++ /dev/null @@ -1,445 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -static const char* TAG = "OCRESOURCE-JNI"; - -JNIEXPORT jobject JNICALL jniOicGet(JNIEnv *env, jobject jobj, jobject jattributeHandler) -{ - - std::shared_ptr *resource = getHandle>(env, jobj); - __android_log_print(ANDROID_LOG_ERROR, TAG, "get() resource = %p\n", resource); - - JNICallBackContext *callbackContext; - string key = (*resource)->uri() + "/GET"; - std:map::iterator iter = gJNICallBackContextList.find(key); - if(iter == gJNICallBackContextList.end()) { - gJNICallBackContextList[key] = new JNICallBackContext(*resource, env->NewGlobalRef(jattributeHandler)); - callbackContext = gJNICallBackContextList[key]; - __android_log_print(ANDROID_LOG_INFO, TAG, "Adding %s to gJNICallBackContextList", key.c_str()); - } - else { - iter->second->m_callBackFunction = env->NewGlobalRef(jattributeHandler); - callbackContext = iter->second; - } - - OC::QueryParamsMap test; - __android_log_print(ANDROID_LOG_ERROR, TAG, "calling oic base get()\n"); - - (*resource)->get(test, - [callbackContext](const OC::HeaderOptions& headerOptions, const OC::OCRepresentation& rep, const int eCode) - { - JNIEnv * env; - - // Attach to JavaVM - // double check it's all ok - int getEnvStat = g_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: not attached"); - if (g_JavaVM->AttachCurrentThread(&env, NULL) != 0) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to attach"); - } - else - __android_log_print(ANDROID_LOG_INFO, TAG, "Attached OK"); - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: version not supported"); - } - - // save C++ ocheaderoption ptr now - jmethodID option_constructor = env->GetMethodID(g_ocheaderoption_clazz, "", "(J)V"); - int size = headerOptions.size(); - jobjectArray joptions = env->NewObjectArray(size, g_ocheaderoption_clazz, 0); - for (int n=0; nNewObject(g_ocheaderoption_clazz, option_constructor, \ - (jlong) reinterpret_cast(&headerOptions[n])); - - __android_log_print(ANDROID_LOG_ERROR, TAG, "jelem : %llu", (jlong) reinterpret_cast(&headerOptions[n])); - - env->SetObjectArrayElement(joptions, n, jelem); - env->DeleteLocalRef(jelem); - } - - // save C++ ocrepresentation ptr now - jmethodID representation_constructor = env->GetMethodID(g_ocrepresentation_clazz, "", "(J)V"); - jobject jrepresentation = env->NewObject(g_ocrepresentation_clazz, representation_constructor, \ - (jlong) reinterpret_cast(&rep)); - if(jrepresentation == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "cannot create OCRepresentation class"); - return; - } - - jclass cb_clazz = env->GetObjectClass(callbackContext->m_callBackFunction); - if (cb_clazz == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to find class"); - } - - // Find Callback function - jmethodID cb_mid = env->GetMethodID(cb_clazz, "Callback", \ - "([Lorg/iotivity/base/OCHeaderOption;Lorg/iotivity/base/OCRepresentation;I)V"); - if(cb_mid == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "onGet.Callback() is not defined in JAVA"); - return; - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "calling JAVA GetCallback"); - env->CallVoidMethod(callbackContext->m_callBackFunction, cb_mid, joptions, jrepresentation, eCode); - - __android_log_print(ANDROID_LOG_INFO, TAG, "getCB detach"); - g_JavaVM->DetachCurrentThread(); - - } - ); - return NULL; - -} - -JNIEXPORT jobject JNICALL jniOicPut(JNIEnv *env, jobject jobj, jobject jocrepresentation, jobject jattributeHandler) -{ - std::shared_ptr *resource = getHandle>(env, jobj); - __android_log_print(ANDROID_LOG_ERROR, TAG, "put1() resource = %p\n", resource); - - JNICallBackContext *callbackContext; - string key = (*resource)->uri() + "/PUT"; - std:map::iterator iter = gJNICallBackContextList.find(key); - if(iter == gJNICallBackContextList.end()) { - gJNICallBackContextList[key] = new JNICallBackContext(*resource, env->NewGlobalRef(jattributeHandler)); - callbackContext = gJNICallBackContextList[key]; - __android_log_print(ANDROID_LOG_INFO, TAG, "Adding %s to gJNICallBackContextList", key.c_str()); - } - else { - iter->second->m_callBackFunction = env->NewGlobalRef(jattributeHandler); - callbackContext = iter->second; - } - - OC::OCRepresentation *rep = getHandle(env, jocrepresentation); - OC::QueryParamsMap test; - __android_log_print(ANDROID_LOG_ERROR, TAG, "calling oic base put()\n"); - - (*resource)->put(*rep, test, - [callbackContext](const OC::HeaderOptions& headerOptions, const OC::OCRepresentation& rep, const int eCode) - { - JNIEnv * env; - - // Attach to JavaVM - // double check it's all ok - int getEnvStat = g_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: not attached"); - if (g_JavaVM->AttachCurrentThread(&env, NULL) != 0) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to attach"); - } - else - __android_log_print(ANDROID_LOG_INFO, TAG, "Attached OK"); - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: version not supported"); - } - - // save C++ ocheaderoption ptr now - jmethodID option_constructor = env->GetMethodID(g_ocheaderoption_clazz, "", "(J)V"); - int size = headerOptions.size(); - jobjectArray joptions = env->NewObjectArray(size, g_ocheaderoption_clazz, 0); - for (int n=0; nNewObject(g_ocheaderoption_clazz, option_constructor, \ - (jlong) reinterpret_cast(&headerOptions[n])); - - __android_log_print(ANDROID_LOG_ERROR, TAG, "jelem : %llu", (jlong) reinterpret_cast(&headerOptions[n])); - - env->SetObjectArrayElement(joptions, n, jelem); - env->DeleteLocalRef(jelem); - } - - // save C++ ocrepresentation ptr now - jmethodID representation_constructor = env->GetMethodID(g_ocrepresentation_clazz, "", "(J)V"); - jobject jrepresentation = env->NewObject(g_ocrepresentation_clazz, representation_constructor, \ - (jlong) reinterpret_cast(&rep)); - if(jrepresentation == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "cannot create OCRepresentation class"); - return; - } - - jclass cb_clazz = env->GetObjectClass(callbackContext->m_callBackFunction); - if (cb_clazz == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to find class"); - } - - // Find Callback function - jmethodID cb_mid = env->GetMethodID(cb_clazz, "Callback", \ - "([Lorg/iotivity/base/OCHeaderOption;Lorg/iotivity/base/OCRepresentation;I)V"); - if(cb_mid == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "onPut.Callback() is not defined in JAVA"); - return; - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "calling JAVA PutCallback"); - env->CallVoidMethod(callbackContext->m_callBackFunction, cb_mid, joptions, jrepresentation, eCode); - - __android_log_print(ANDROID_LOG_INFO, TAG, "putCB detach"); - g_JavaVM->DetachCurrentThread(); - } - ); - return NULL; -} - -JNIEXPORT jobject JNICALL jniOicPost(JNIEnv *env, jobject jobj, jobject jocrepresentation, jobject jattributeHandler) -{ - std::shared_ptr *resource = getHandle>(env, jobj); - __android_log_print(ANDROID_LOG_ERROR, TAG, "post1() resource = %p\n", resource); - - JNICallBackContext *callbackContext; - string key = (*resource)->uri() + "/POST"; - std:map::iterator iter = gJNICallBackContextList.find(key); - if(iter == gJNICallBackContextList.end()) { - gJNICallBackContextList[key] = new JNICallBackContext(*resource, env->NewGlobalRef(jattributeHandler)); - callbackContext = gJNICallBackContextList[key]; - __android_log_print(ANDROID_LOG_INFO, TAG, "Adding %s to gJNICallBackContextList", key.c_str()); - } - else { - iter->second->m_callBackFunction = env->NewGlobalRef(jattributeHandler); - callbackContext = iter->second; - } - - OC::OCRepresentation *rep = getHandle(env, jocrepresentation); - OC::QueryParamsMap test; - __android_log_print(ANDROID_LOG_ERROR, TAG, "calling oic base post()\n"); - - (*resource)->post(*rep, test, - [callbackContext](const OC::HeaderOptions& headerOptions, const OC::OCRepresentation& rep, const int eCode) - { - JNIEnv * env; - - // Attach to JavaVM - // double check it's all ok - int getEnvStat = g_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: not attached"); - if (g_JavaVM->AttachCurrentThread(&env, NULL) != 0) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to attach"); - } - else - __android_log_print(ANDROID_LOG_INFO, TAG, "Attached OK"); - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: version not supported"); - } - - // save C++ ocheaderoption ptr now - jmethodID option_constructor = env->GetMethodID(g_ocheaderoption_clazz, "", "(J)V"); - int size = headerOptions.size(); - jobjectArray joptions = env->NewObjectArray(size, g_ocheaderoption_clazz, 0); - for (int n=0; nNewObject(g_ocheaderoption_clazz, option_constructor, \ - (jlong) reinterpret_cast(&headerOptions[n])); - - __android_log_print(ANDROID_LOG_ERROR, TAG, "jelem : %llu", (jlong) reinterpret_cast(&headerOptions[n])); - - env->SetObjectArrayElement(joptions, n, jelem); - env->DeleteLocalRef(jelem); - } - - // save C++ ocrepresentation ptr now - jmethodID representation_constructor = env->GetMethodID(g_ocrepresentation_clazz, "", "(J)V"); - jobject jrepresentation = env->NewObject(g_ocrepresentation_clazz, representation_constructor, \ - (jlong) reinterpret_cast(&rep)); - if(jrepresentation == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "cannot create OCRepresentation class"); - return; - } - - jclass cb_clazz = env->GetObjectClass(callbackContext->m_callBackFunction); - if (cb_clazz == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to find class"); - } - - // Find Callback function - jmethodID cb_mid = env->GetMethodID(cb_clazz, "Callback", \ - "([Lorg/iotivity/base/OCHeaderOption;Lorg/iotivity/base/OCRepresentation;I)V"); - if(cb_mid == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "onPost.Callback() is not defined in JAVA"); - return; - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "calling JAVA PostCallback"); - env->CallVoidMethod(callbackContext->m_callBackFunction, cb_mid, joptions, jrepresentation, eCode); - - __android_log_print(ANDROID_LOG_INFO, TAG, "postCB detach"); - g_JavaVM->DetachCurrentThread(); - - } - ); - return NULL; -} - -JNIEXPORT jobject JNICALL jniOicObserve(JNIEnv *env, jobject jobj, jint jobservetype, jobject jattributeHandler) -{ - std::shared_ptr *resource = getHandle>(env, jobj); - __android_log_print(ANDROID_LOG_ERROR, TAG, "observe1() resource = %p\n", resource); - - JNICallBackContext *callbackContext; - string key = (*resource)->uri() + "/OBSERVE"; - std:map::iterator iter = gJNICallBackContextList.find(key); - if(iter == gJNICallBackContextList.end()) { - gJNICallBackContextList[key] = new JNICallBackContext(*resource, env->NewGlobalRef(jattributeHandler)); - callbackContext = gJNICallBackContextList[key]; - __android_log_print(ANDROID_LOG_INFO, TAG, "Adding %s to gJNICallBackContextList", key.c_str()); - } - else { - iter->second->m_callBackFunction = env->NewGlobalRef(jattributeHandler); - callbackContext = iter->second; - } - - OC::QueryParamsMap test; - __android_log_print(ANDROID_LOG_ERROR, TAG, "calling oic base observe()\n"); - - (*resource)->observe((OC::ObserveType) jobservetype, test, - [callbackContext](const OC::HeaderOptions& headerOptions, const OC::OCRepresentation& rep, const int eCode, const int seqNum) - { - JNIEnv * env; - - // Attach to JavaVM - // double check it's all ok - int getEnvStat = g_JavaVM->GetEnv((void **)&env, JNI_VERSION_1_6); - if (getEnvStat == JNI_EDETACHED) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: not attached"); - if (g_JavaVM->AttachCurrentThread(&env, NULL) != 0) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to attach"); - } - else - __android_log_print(ANDROID_LOG_INFO, TAG, "Attached OK"); - } else if (getEnvStat == JNI_OK) { - // - } else if (getEnvStat == JNI_EVERSION) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv: version not supported"); - } - - // save C++ ocheaderoption ptr now - jmethodID option_constructor = env->GetMethodID(g_ocheaderoption_clazz, "", "(J)V"); - int size = headerOptions.size(); - jobjectArray joptions = env->NewObjectArray(size, g_ocheaderoption_clazz, 0); - for (int n=0; nNewObject(g_ocheaderoption_clazz, option_constructor, \ - (jlong) reinterpret_cast(&headerOptions[n])); - - __android_log_print(ANDROID_LOG_ERROR, TAG, "jelem : %llu", (jlong) reinterpret_cast(&headerOptions[n])); - - env->SetObjectArrayElement(joptions, n, jelem); - env->DeleteLocalRef(jelem); - } - - // save C++ ocrepresentation ptr now - jmethodID representation_constructor = env->GetMethodID(g_ocrepresentation_clazz, "", "(J)V"); - jobject jrepresentation = env->NewObject(g_ocrepresentation_clazz, representation_constructor, \ - (jlong) reinterpret_cast(&rep)); - if(jrepresentation == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "cannot create OCRepresentation class"); - return; - } - - jclass cb_clazz = env->GetObjectClass(callbackContext->m_callBackFunction); - if (cb_clazz == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to find class"); - } - - // Find Callback function - jmethodID cb_mid = env->GetMethodID(cb_clazz, "Callback", \ - "([Lorg/iotivity/base/OCHeaderOption;Lorg/iotivity/base/OCRepresentation;II)V"); - if(cb_mid == NULL) { - __android_log_print(ANDROID_LOG_ERROR, TAG, "onObserve.Callback() is not defined in JAVA"); - return; - } - - __android_log_print(ANDROID_LOG_INFO, TAG, "calling JAVA ObserveCallback"); - env->CallVoidMethod(callbackContext->m_callBackFunction, cb_mid, joptions, jrepresentation, eCode, seqNum); - - __android_log_print(ANDROID_LOG_INFO, TAG, "observeCB detach"); - g_JavaVM->DetachCurrentThread(); - - } - ); - return NULL; -} - -JNIEXPORT jobject JNICALL jniOicCancelObserve(JNIEnv *env, jobject jobj) -{ - std::shared_ptr *resource = getHandle>(env, jobj); - __android_log_print(ANDROID_LOG_ERROR, TAG, "cancelObserve1() resource = %p\n", resource); - __android_log_print(ANDROID_LOG_ERROR, TAG, "calling oic base cancelObserve()\n"); - - (*resource)->cancelObserve(); - return NULL; -} - -JNIEXPORT jstring JNICALL uri(JNIEnv *env, jobject jobj) -{ - __android_log_print(ANDROID_LOG_ERROR, TAG, "uri()"); - std::shared_ptr *resource = getHandle>(env, jobj); - return env->NewStringUTF((*resource)->uri().c_str()); -} - -JNIEXPORT jstring JNICALL host(JNIEnv *env, jobject jobj) -{ - __android_log_print(ANDROID_LOG_ERROR, TAG, "host()"); - std::shared_ptr *resource = getHandle>(env, jobj); - return env->NewStringUTF((*resource)->host().c_str()); -} - -JNIEXPORT jobjectArray JNICALL getResourceTypes(JNIEnv *env, jobject jobj) -{ - __android_log_print(ANDROID_LOG_ERROR, TAG, "getResourceTypes()"); - std::shared_ptr *resource = getHandle>(env, jobj); - - std::vector resourceTypes = (*resource)->getResourceTypes(); - - int size = resourceTypes.size(); - jclass clazz = env->FindClass("java/lang/String"); - jobjectArray jresourceTypes = env->NewObjectArray(size, clazz, 0); - - for (int n=0; nNewStringUTF(resourceTypes[n].c_str()); - env->SetObjectArrayElement(jresourceTypes, n, jstr); - } - - return jresourceTypes; -} - -JNIEXPORT jobjectArray JNICALL getResourceInterfaces(JNIEnv *env, jobject jobj) -{ - __android_log_print(ANDROID_LOG_ERROR, TAG, "getResourceInterfaces()"); - std::shared_ptr *resource = getHandle>(env, jobj); - - std::vector resourceInterfaces = (*resource)->getResourceInterfaces(); - - int size = resourceInterfaces.size(); - jclass clazz = env->FindClass("java/lang/String"); - jobjectArray jresourceInterfaces = env->NewObjectArray(size, clazz, 0); - - for (int n=0; nNewStringUTF(resourceInterfaces[n].c_str()); - env->SetObjectArrayElement(jresourceInterfaces, n, jstr); - } - - return jresourceInterfaces; -} - diff --git a/android/Base/app/jni/ocstack-jni.cpp b/android/Base/app/jni/ocstack-jni.cpp deleted file mode 100644 index d9ae850..0000000 --- a/android/Base/app/jni/ocstack-jni.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -// Global map to maintain callback functions and ocresource -// with key = URL + callback operation -// e.g. key = /a/light/GET -std::map gJNICallBackContextList; - -JavaVM* g_JavaVM = NULL; - -jclass g_ocplatform_clazz; -jclass g_ocresource_clazz; -jclass g_ocheaderoption_clazz; -jclass g_ocrepresentation_clazz; -jclass g_platformcfg_clazz; - -static const char* TAG = "OCSTACK-JNI"; - -static JNINativeMethod ocplatform_method_table[] = { - { "configure", "(Lorg/iotivity/base/PlatformConfig;)V", (void *) configure}, - { "findResource", "(Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/AbstractFindCallback;)I", (void *) findResource } -}; - -static int ocplatform_method_table_size = sizeof(ocplatform_method_table) / sizeof(ocplatform_method_table[0]); - -static JNINativeMethod platformconfig_method_table[] = { - { "createNativeInstance", "(IILjava/lang/String;II)J", (void *) createNativeInstance }, -}; - -static int platformconfig_method_table_size = sizeof(platformconfig_method_table) / sizeof(platformconfig_method_table[0]); - -static JNINativeMethod ocresource_method_table[] = { - { "get", "(Lorg/iotivity/base/AbstractGetCallback;)Lorg/iotivity/base/OCStackResult;", (void *) jniOicGet}, - - { "put", "(Lorg/iotivity/base/OCRepresentation;Lorg/iotivity/base/AbstractPutCallback;)Lorg/iotivity/base/OCStackResult;", (void *) jniOicPut}, - { "post", "(Lorg/iotivity/base/OCRepresentation;Lorg/iotivity/base/AbstractPostCallback;)Lorg/iotivity/base/OCStackResult;", (void *) jniOicPost}, - { "observe", "(ILorg/iotivity/base/AbstractObserveCallback;)Lorg/iotivity/base/OCStackResult;", (void *) jniOicObserve}, - { "cancelObserve", "()Lorg/iotivity/base/OCStackResult;", (void *) jniOicCancelObserve}, - { "uri", "()Ljava/lang/String;", (void *) uri}, - { "host", "()Ljava/lang/String;", (void *) host}, - { "getResourceTypes", "()[Ljava/lang/String;", (void *) getResourceTypes}, - { "getResourceInterfaces", "()[Ljava/lang/String;", (void *) getResourceInterfaces}, -}; - -static int ocresource_method_table_size = sizeof(ocresource_method_table) / sizeof(ocresource_method_table[0]); - -static JNINativeMethod ocheaderoption_method_table[] = { - { "getOptionID", "()I", (void *) getOptionID}, - { "getOptionData", "()Ljava/lang/String;", (void *) getOptionData}, - { "OCHeaderOptionConstructor", "(ILjava/lang/String;)J", (void *) OCHeaderOptionConstructor}, -}; - -static int ocheaderoption_method_table_size = sizeof(ocheaderoption_method_table) / sizeof(ocheaderoption_method_table[0]); - -static JNINativeMethod ocrepresentation_method_table[] = { - { "OCRepresentationConstructor", "()J", (void *) OCRepresentationConstructor}, - { "getUri", "()Ljava/lang/String;", (void *) getUri}, - { "getValueInt", "(Ljava/lang/String;)I", (void *) getValueInt}, - { "getValueBool", "(Ljava/lang/String;)Z", (void *) getValueBool}, - { "getValueString", "(Ljava/lang/String;)Ljava/lang/String;", (void *) getValueString}, - { "setValueInt", "(Ljava/lang/String;I)V", (void *) setValueInt}, - { "setValueBool", "(Ljava/lang/String;Z)V", (void *) setValueBool}, - { "setValueString", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) setValueString}, - { "hasAttribute", "(Ljava/lang/String;)Z", (void *) hasAttribute}, -}; - -static int ocrepresentation_method_table_size = sizeof(ocrepresentation_method_table) / sizeof(ocrepresentation_method_table[0]); - -// JNI OnLoad -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) -{ - JNIEnv* env; - - g_JavaVM = vm; - __android_log_print(ANDROID_LOG_ERROR, TAG, "g_JavaVM = %p\n", g_JavaVM); - - if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) { - return JNI_ERR; - } else { - jint ret; - jclass clazz; - - clazz = env->FindClass("org/iotivity/base/OCPlatform"); - g_ocplatform_clazz = (jclass) env->NewGlobalRef(clazz); - env->DeleteLocalRef(clazz); - ret = env->RegisterNatives(g_ocplatform_clazz, ocplatform_method_table, ocplatform_method_table_size); - __android_log_print(ANDROID_LOG_ERROR, TAG, "load ocplatform = %d\n", ret); - - clazz = env->FindClass("org/iotivity/base/OCResource"); - g_ocresource_clazz = (jclass) env->NewGlobalRef(clazz); - env->DeleteLocalRef(clazz); - ret = env->RegisterNatives(g_ocresource_clazz, ocresource_method_table, ocresource_method_table_size); - __android_log_print(ANDROID_LOG_ERROR, TAG, "load ocresource = %d\n", ret); - - clazz = env->FindClass("org/iotivity/base/PlatformConfig"); - g_platformcfg_clazz = (jclass) env->NewGlobalRef(clazz); - env->DeleteLocalRef(clazz); - ret = env->RegisterNatives(g_platformcfg_clazz, platformconfig_method_table, platformconfig_method_table_size); - __android_log_print(ANDROID_LOG_ERROR, TAG, "load platformconfig = %d\n", ret); - - clazz = env->FindClass("org/iotivity/base/OCHeaderOption"); - g_ocheaderoption_clazz = (jclass) env->NewGlobalRef(clazz); - env->DeleteLocalRef(clazz); - ret = env->RegisterNatives(g_ocheaderoption_clazz, ocheaderoption_method_table, ocheaderoption_method_table_size); - __android_log_print(ANDROID_LOG_ERROR, TAG, "load ocheaderoption = %d\n", ret); - - clazz = env->FindClass("org/iotivity/base/OCRepresentation"); - g_ocrepresentation_clazz = (jclass) env->NewGlobalRef(clazz); - env->DeleteLocalRef(clazz); - ret = env->RegisterNatives(g_ocrepresentation_clazz, ocrepresentation_method_table, ocrepresentation_method_table_size); - __android_log_print(ANDROID_LOG_ERROR, TAG, "load ocrepresentation = %d\n", ret); - - return JNI_VERSION_1_6; - } -} diff --git a/android/Base/app/jni/ocstack-jni.h b/android/Base/app/jni/ocstack-jni.h deleted file mode 100644 index dd55aa4..0000000 --- a/android/Base/app/jni/ocstack-jni.h +++ /dev/null @@ -1,101 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#ifndef _Included_org_iotivity_base_ocstack -#define _Included_org_iotivity_base_ocstack - -#include -#include -#include "OCApi.h" -#include "OCPlatform.h" - -class JNICallBackContext { - public: - - std::shared_ptr m_resource; - jobject m_callBackFunction; - - JNICallBackContext(jobject callback) { - m_resource = NULL; - m_callBackFunction = callback; - } - - JNICallBackContext(std::shared_ptr rsrc, - jobject callback) { - m_resource = rsrc; - m_callBackFunction = callback; - } -}; - -extern std::map gJNICallBackContextList; - -extern JavaVM* g_JavaVM; - -extern jclass g_ocplatform_clazz; -extern jclass g_ocresource_clazz; -extern jclass g_ocheaderoption_clazz; -extern jclass g_ocrepresentation_clazz; -extern jclass g_platformcfg_clazz; - -template -T *getHandle(JNIEnv *env, jobject obj) -{ - jclass cls = env->GetObjectClass(obj); - jfieldID fid = env->GetFieldID(cls, "nativeHandle", "J"); - jlong handle = env->GetLongField(obj, fid); - return reinterpret_cast(handle); -} - -// ocplatform-jni -extern JNIEXPORT void JNICALL configure(JNIEnv *env, jobject obj, jobject jcfg); -extern JNIEXPORT jint JNICALL findResource(JNIEnv* env, jobject obj, jstring jhost, jstring juri, jobject found); - -// platformcfg-jni -extern JNIEXPORT jlong JNICALL createNativeInstance - (JNIEnv *env, jobject obj, jint jServiceType, jint jModeType, jstring jIpAddress, jint port, jint jQOS); - -// ocheaderoption-jni -extern JNIEXPORT jint JNICALL getOptionID(JNIEnv *env, jobject jobj); -extern JNIEXPORT jstring JNICALL getOptionData(JNIEnv *env, jobject jobj); -extern JNIEXPORT jlong JNICALL OCHeaderOptionConstructor(JNIEnv *env, jobject jobj, jint joption, jstring jdata); - -// ocrepresentation-jni -extern JNIEXPORT jlong JNICALL OCRepresentationConstructor(JNIEnv *env, jobject jobj); -extern JNIEXPORT jstring JNICALL getUri(JNIEnv *env, jobject jobj); -extern JNIEXPORT jint JNICALL getValueInt(JNIEnv *env, jobject jobj, jstring jstr); -extern JNIEXPORT jboolean JNICALL getValueBool(JNIEnv *env, jobject jobj, jstring jstr); -extern JNIEXPORT jstring JNICALL getValueString(JNIEnv *env, jobject jobj, jstring jstr); -extern JNIEXPORT void JNICALL setValueInt(JNIEnv *env, jobject jobj, jstring jstr, jint jval); -extern JNIEXPORT void JNICALL setValueBool(JNIEnv *env, jobject jobj, jstring jstr, jboolean jval); -extern JNIEXPORT void JNICALL setValueString(JNIEnv *env, jobject jobj, jstring jstr, jstring jval); -extern JNIEXPORT jboolean JNICALL hasAttribute(JNIEnv *env, jobject jobj, jstring jstr); - -// ocresource-jni -extern JNIEXPORT jobject JNICALL jniOicGet(JNIEnv *env, jobject jobj, jobject jattributeHandler); -extern JNIEXPORT jobject JNICALL jniOicPut(JNIEnv *env, jobject jobj, jobject jocrepresentation, jobject jattributeHandler); -extern JNIEXPORT jobject JNICALL jniOicPost(JNIEnv *env, jobject jobj, jobject jocrepresentation, jobject jattributeHandler); -extern JNIEXPORT jobject JNICALL jniOicObserve(JNIEnv *env, jobject jobj, jint jobservetype, jobject jattributeHandler); -extern JNIEXPORT jobject JNICALL jniOicCancelObserve(JNIEnv *env, jobject jobj); -extern JNIEXPORT jstring JNICALL uri(JNIEnv *env, jobject jobj); -extern JNIEXPORT jstring JNICALL host(JNIEnv *env, jobject jobj); -extern JNIEXPORT jobjectArray JNICALL getResourceTypes(JNIEnv *env, jobject jobj); -extern JNIEXPORT jobjectArray JNICALL getResourceInterfaces(JNIEnv *env, jobject jobj); - -#endif diff --git a/android/Base/app/jni/platformcfg-jni.cpp b/android/Base/app/jni/platformcfg-jni.cpp deleted file mode 100644 index 73d40f9..0000000 --- a/android/Base/app/jni/platformcfg-jni.cpp +++ /dev/null @@ -1,80 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -#include "ocstack-jni.h" - -static const char* TAG = "PLATFORMCFG-JNI"; - -OC::ServiceType getServiceType(int type) -{ - switch (type) { - case 0: - return OC::ServiceType::InProc; - case 1: - default: - return OC::ServiceType::OutOfProc; - }; -} - -OC::ModeType getModeType(int type) -{ - switch (type) { - case 0: - return OC::ModeType::Server; - case 1: - return OC::ModeType::Client; - case 2: - default: - return OC::ModeType::Both; - }; -} - -OC::QualityOfService getQOS(int type) -{ - switch (type) { - case 0: - return OC::QualityOfService::LowQos; - case 1: - return OC::QualityOfService::MidQos; - case 2: - return OC::QualityOfService::HighQos; - case 3: - default: - return OC::QualityOfService::NaQos; - }; -} - -OC::PlatformConfig *g_cfg; - -JNIEXPORT jlong JNICALL createNativeInstance - (JNIEnv *env, jobject obj, jint jServiceType, jint jModeType, jstring jIpAddress, jint port, jint jQOS) -{ - - g_cfg = new OC::PlatformConfig{getServiceType(jServiceType), - getModeType(jModeType), - env->GetStringUTFChars(jIpAddress, 0), - (uint16_t) port, - getQOS(jQOS) - }; - - - jlong instptr = reinterpret_cast(g_cfg); - return instptr; -} diff --git a/android/Base/app/proguard-rules.pro b/android/Base/app/proguard-rules.pro deleted file mode 100644 index 0e559b0..0000000 --- a/android/Base/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/vchen/ubuntu_sw/adt-bundle-linux-x86_64/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android/Base/app/src/androidTest/java/org/iotivity/base/ApplicationTest.java b/android/Base/app/src/androidTest/java/org/iotivity/base/ApplicationTest.java deleted file mode 100644 index ac4bdc3..0000000 --- a/android/Base/app/src/androidTest/java/org/iotivity/base/ApplicationTest.java +++ /dev/null @@ -1,33 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} diff --git a/android/Base/app/src/main/AndroidManifest.xml b/android/Base/app/src/main/AndroidManifest.xml deleted file mode 100644 index 32cf1c1..0000000 --- a/android/Base/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractDeleteCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractDeleteCallback.java deleted file mode 100644 index d1c26b4..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractDeleteCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractDeleteCallback { - public abstract void Callback(OCHeaderOption options, int a); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractFindCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractFindCallback.java deleted file mode 100644 index 132b1a8..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractFindCallback.java +++ /dev/null @@ -1,26 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractFindCallback { - public abstract void Callback(OCResource resource); -// public OCResource ocresource = new OCResource(); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractGetCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractGetCallback.java deleted file mode 100644 index 6ba339b..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractGetCallback.java +++ /dev/null @@ -1,27 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractGetCallback { - public abstract void Callback(OCHeaderOption[] options, OCRepresentation rep, int a); -// public OCHeaderOption[] ocoptions; -// public OCRepresentation ocrep = new OCRepresentation(); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractObserveCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractObserveCallback.java deleted file mode 100644 index 6c90561..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractObserveCallback.java +++ /dev/null @@ -1,27 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractObserveCallback { - public abstract void Callback(OCHeaderOption[] options, OCRepresentation rep, int a, int b); -// public OCHeaderOption[] ocoptions; -// public OCRepresentation ocrep = new OCRepresentation(); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractPostCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractPostCallback.java deleted file mode 100644 index 20acbea..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractPostCallback.java +++ /dev/null @@ -1,27 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractPostCallback { - public abstract void Callback(OCHeaderOption[] options, OCRepresentation rep, int a); -// public OCHeaderOption[] ocoptions; -// public OCRepresentation ocrep = new OCRepresentation(); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractPutCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractPutCallback.java deleted file mode 100644 index 46f2a19..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractPutCallback.java +++ /dev/null @@ -1,7 +0,0 @@ -package org.iotivity.base; - -public abstract class AbstractPutCallback { - public abstract void Callback(OCHeaderOption[] options, OCRepresentation rep, int a); -// public OCHeaderOption[] ocoptions; -// public OCRepresentation ocrep = new OCRepresentation(); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/AbstractSubscriberCallback.java b/android/Base/app/src/main/java/org/iotivity/base/AbstractSubscriberCallback.java deleted file mode 100644 index 1f996cb..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/AbstractSubscriberCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class AbstractSubscriberCallback { - public abstract void Callback(OCStackResult result, int a); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/EntityHandler.java b/android/Base/app/src/main/java/org/iotivity/base/EntityHandler.java deleted file mode 100644 index 779543c..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/EntityHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public interface EntityHandler { - public abstract void Callback(OCResourceRequest request, OCResourceResponse response); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/NativeInstance.java b/android/Base/app/src/main/java/org/iotivity/base/NativeInstance.java deleted file mode 100644 index f6d02bb..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/NativeInstance.java +++ /dev/null @@ -1,33 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public abstract class NativeInstance -{ - protected long nativeHandle = 0; - - public NativeInstance() - { - } - - public long getHandle() { return nativeHandle;} - -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCHeaderOption.java b/android/Base/app/src/main/java/org/iotivity/base/OCHeaderOption.java deleted file mode 100644 index c169870..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCHeaderOption.java +++ /dev/null @@ -1,36 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCHeaderOption extends NativeInstance { - final private static String TAG = "OCHeaderOption"; - static { - System.loadLibrary("ocstack-jni"); - } - - public OCHeaderOption(long instPtr) { - super.nativeHandle = instPtr; - } - - public native int getOptionID(); - public native String getOptionData(); - public native long OCHeaderOptionConstructor(int optionID, String optionData); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCPlatform.java b/android/Base/app/src/main/java/org/iotivity/base/OCPlatform.java deleted file mode 100644 index e4424a6..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCPlatform.java +++ /dev/null @@ -1,32 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCPlatform { - final private static String TAG = "OCPlatform"; - static { - System.loadLibrary("ocstack-jni"); - } - - public static native void configure(PlatformConfig cfg); - public static native int findResource(String host, String Uri, AbstractFindCallback found); - -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCRepresentation.java b/android/Base/app/src/main/java/org/iotivity/base/OCRepresentation.java deleted file mode 100644 index 06a2156..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCRepresentation.java +++ /dev/null @@ -1,49 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCRepresentation extends NativeInstance { - final private static String TAG = "OCRepresentation"; - static { - System.loadLibrary("ocstack-jni"); - } - - public OCRepresentation(long instPtr) { - super.nativeHandle = instPtr; - } - public OCRepresentation() { - super.nativeHandle = OCRepresentationConstructor(); - } - - public native long OCRepresentationConstructor(); - - public native int getValueInt(String str); - public native boolean getValueBool(String str); - public native String getValueString(String str); - - public native void setValueInt (String str, int val); - public native void setValueBool (String str, boolean val); - public native void setValueString (String str, String val); - - public native String getUri(); - - public native boolean hasAttribute(String str); -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCResource.java b/android/Base/app/src/main/java/org/iotivity/base/OCResource.java deleted file mode 100644 index 7a7f6c8..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCResource.java +++ /dev/null @@ -1,60 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCResource extends NativeInstance { - final private static String TAG = "OCResource"; - static { - System.loadLibrary("ocstack-jni"); - } - - public native OCStackResult get(AbstractGetCallback attributeHandler); -// public native OCStackResult get(AbstractGetCallback attributeHandler, PlatformConfig.QualityOfService QoS); - - public native OCStackResult get(String resourceType, String resourceInterface, AbstractGetCallback attributeHandler); -// public native OCStackResult get(String resourceType, String resourceInterface, AbstractGetCallback attributeHandler, PlatformConfig.QualityOfService QoS); - - public native OCStackResult put(OCRepresentation rep, AbstractPutCallback attributeHandler); -// public native OCStackResult put(OCRepresentation rep, AbstractPutCallback attributeHandler, PlatformConfig.QualityOfService QoS); -// public native OCStackResult put(String resourceType, String resourceInterface, OCRepresentation rep, AbstractPutCallback attributeHandler); -// public native OCStackResult put(String resourceType, String resourceInterface, OCRepresentation rep, AbstractPutCallback attributeHandler, PlatformConfig.QualityOfService QoS); - - public native OCStackResult post(OCRepresentation rep, AbstractPostCallback attributeHandler); -// public native OCStackResult post(OCRepresentation rep, AbstractPostCallback attributeHandler, PlatformConfig.QualityOfService QoS); -// public native OCStackResult post(String resourceType, String resourceInterface, OCRepresentation rep, AbstractPostCallback attributeHandler); -// public native OCStackResult post(String resourceType, String resourceInterface, OCRepresentation rep, AbstractPostCallback attributeHandler, PlatformConfig.QualityOfService QoS); - - public native OCStackResult observe(int observeType, AbstractObserveCallback observerHandler); -// public native OCStackResult observe(int observeType, AbstractObserveCallback observerHandler, PlatformConfig.QualityOfService QoS); - - public native OCStackResult cancelObserve(); -// public native OCStackResult cancelObserve(PlatformConfig.QualityOfService QoS); - - public native String uri(); - public native String host(); - - public native String[] getResourceInterfaces(); - public native String[] getResourceTypes(); - - public OCResource(long instPtr) { - super.nativeHandle = instPtr; - } -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCResourceRequest.java b/android/Base/app/src/main/java/org/iotivity/base/OCResourceRequest.java deleted file mode 100644 index 87c406e..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCResourceRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCResourceRequest { -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCResourceResponse.java b/android/Base/app/src/main/java/org/iotivity/base/OCResourceResponse.java deleted file mode 100644 index 283d8de..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCResourceResponse.java +++ /dev/null @@ -1,24 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCResourceResponse { -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/OCStackResult.java b/android/Base/app/src/main/java/org/iotivity/base/OCStackResult.java deleted file mode 100644 index 10440b6..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/OCStackResult.java +++ /dev/null @@ -1,54 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class OCStackResult { - /* Success status code - START HERE */ - static final public int OC_STACK_OK = 0; - static final public int OC_STACK_RESOURCE_CREATED = 1; - static final public int OC_STACK_RESOURCE_DELETED = 2; - /* Success status code - END HERE */ - /* Error status code - START HERE */ - static final public int OC_STACK_INVALID_URI = 3; - static final public int OC_STACK_INVALID_QUERY = 4; - static final public int OC_STACK_INVALID_IP = 5; - static final public int OC_STACK_INVALID_PORT = 6; - static final public int OC_STACK_INVALID_CALLBACK = 7; - static final public int OC_STACK_INVALID_METHOD = 8; - static final public int OC_STACK_INVALID_PARAM = 9; - static final public int OC_STACK_INVALID_OBSERVE_PARAM = 10; - static final public int OC_STACK_NO_MEMORY = 11; - static final public int OC_STACK_COMM_ERROR = 12; - static final public int OC_STACK_NOTIMPL = 13; - static final public int OC_STACK_NO_RESOURCE = 14; /* resource not found */ - static final public int OC_STACK_RESOURCE_ERROR = 15; /* ex: not supported method or interface */ - static final public int OC_STACK_SLOW_RESOURCE = 16; - static final public int OC_STACK_NO_OBSERVERS = 17; /* resource has no registered observers */ - static final public int OC_STACK_OBSERVER_NOT_FOUND = 18; - static final public int OC_STACK_OBSERVER_NOT_ADDED = 19; - static final public int OC_STACK_OBSERVER_NOT_REMOVED = 20; - static final public int OC_STACK_PRESENCE_STOPPED = 21; - static final public int OC_STACK_PRESENCE_DO_NOT_HANDLE = 22; - static final public int OC_STACK_INVALID_OPTION = 23; - static final public int OC_STACK_MALFORMED_RESPONSE = 24; /* the remote reply contained malformed data */ - static final public int OC_STACK_ERROR = 25; - /* Error status code - END HERE */ -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/ObserveType.java b/android/Base/app/src/main/java/org/iotivity/base/ObserveType.java deleted file mode 100644 index f61c5d8..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/ObserveType.java +++ /dev/null @@ -1,26 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class ObserveType { - static final public int Observe = 0; - static final public int ObserveAll = 1; -} diff --git a/android/Base/app/src/main/java/org/iotivity/base/PlatformConfig.java b/android/Base/app/src/main/java/org/iotivity/base/PlatformConfig.java deleted file mode 100755 index 301cdde..0000000 --- a/android/Base/app/src/main/java/org/iotivity/base/PlatformConfig.java +++ /dev/null @@ -1,68 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.base; - -public class PlatformConfig extends NativeInstance -{ - final private static String TAG = "PlatformConfig"; - static { - System.loadLibrary("ocstack-jni"); - } - - // ENUM definition. Need to match with OCApi.h - public class ServiceType - { - static final public int INPROC = 0; - static final public int OUTPROC = 1; - }; - - public class ModeType - { - static final public int SERVER = 0; - static final public int CLIENT = 1; - static final public int BOTH = 2; - - }; - - public class QualityOfService - { - static final public int LO_QOS = 0; - static final public int ME_QOS = 1; - static final public int HI_QOS = 2; - static final public int NA_QOS = 3; - } - - public PlatformConfig(int serviceType, - int mode, - String ipAddress, - int port, - int QoS) - { - super.nativeHandle = createNativeInstance(serviceType, mode, ipAddress, port, QoS); - } - - - protected native long createNativeInstance(int serviceType, - int mode, - String ipAddress, - int port, - int QoS); -} diff --git a/android/Base/app/src/main/res/values/strings.xml b/android/Base/app/src/main/res/values/strings.xml deleted file mode 100644 index 73ef225..0000000 --- a/android/Base/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Base - diff --git a/android/Base/app/src/main/res/values/styles.xml b/android/Base/app/src/main/res/values/styles.xml deleted file mode 100644 index ff6c9d2..0000000 --- a/android/Base/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/android/Base/build.gradle b/android/Base/build.gradle deleted file mode 100644 index 9b8abe4..0000000 --- a/android/Base/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.12.2' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - } -} diff --git a/android/Base/gradle.properties b/android/Base/gradle.properties deleted file mode 100644 index 5d08ba7..0000000 --- a/android/Base/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Settings specified in this file will override any Gradle settings -# configured through the IDE. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/android/Base/gradlew b/android/Base/gradlew deleted file mode 100755 index 91a7e26..0000000 --- a/android/Base/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/Base/settings.gradle b/android/Base/settings.gradle deleted file mode 100644 index e7b4def..0000000 --- a/android/Base/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/android/BuildInstructionsForAndroidAPI.txt b/android/BuildInstructionsForAndroidAPI.txt new file mode 100644 index 0000000..8dda6db --- /dev/null +++ b/android/BuildInstructionsForAndroidAPI.txt @@ -0,0 +1,45 @@ +Build Instructions for Android-API: + +1.Verify that you have the latest JDK (you might need to set the JDK_HOME variable) +2.Clone the latest iotivity codebase. +3.set environment variables: + a.platform=android + b.If running in windows, change the following line in the build.gradle file (/android/android_api/base/build.gradle): + def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build') + to + def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd') + +4.Build scons for android and your targeted architecture (This will also build Android API): + a.scons TARGET_OS=android TARGET_ARCH= TARGET_TRANSPORT=IP RELEASE=1 + where can be armeabi, armeabi-v7a, x86. + Note: To build in debug mode, use RELEASE=0. + Note: The minimum SDK version supported is 21. + Note: Only TARGET_TRANSPORT currently supported is IP + b.If the project is setup correctly, you should see a BUILD SUCCESSFUL message on the terminal + c.You should see the .aar files generated inside of '/android/android_api/base/build/outputs/aar' directory. The .aar files contain jni directory and also a .jar file + + +TO RUN UNIT TESTS IN ANDROID-API + +5.The '/android/android_api/base/src/androidTest/...' directory contains tests which can be used to get an idea about the Android API usage. + + +TO USE THE .AAR FILE IN /android/examples project + +6. Verify that 9 different *.so files exist inside /android/android-api/base/libs/ directory. (They should already be present in the *.aar file.) +7. Import Project 'Examples' into android-studio. +8.To add an .aar file to the 'Examples' project, + a.Right click on Examples->New->Module->Import .JAR or .AAR Package + b.Select the .aar file from the location in step 6e above + c.Right click on Examples->Open Module Settings + d.Select each sample app module under 'Modules'->Dependencies->Add->Module Dependency + e.The .aar file selected in step 10b above should be present. Select it. + f.Repeat steps d and e for each sample app module. + + +TO USE THE .AAR FILE IN A DIFFERENT PROJECT + +9. Verify that 9 different *.so files exist inside /android/android-api/base/libs/ directory. +10. Import the .aar file in your project to use it + + diff --git a/android/SimpleClient/app/build.gradle b/android/SimpleClient/app/build.gradle deleted file mode 100644 index bf753bf..0000000 --- a/android/SimpleClient/app/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 20 - buildToolsVersion "19.1.0" - - defaultConfig { - applicationId "org.iotivity.simpleclient" - minSdkVersion 19 - targetSdkVersion 20 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} - -repositories { - mavenCentral() - flatDir { - dirs 'libs' - } -} - - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile fileTree(dir: 'libs', include: ['*.so']) - compile fileTree(dir: 'libs', include: ['**/*.so']) -// compile(name: 'OicLib', ext:'aar') - compile 'org.iotivity.Base:app:1.0@aar' -} \ No newline at end of file diff --git a/android/SimpleClient/app/proguard-rules.pro b/android/SimpleClient/app/proguard-rules.pro deleted file mode 100644 index 0e559b0..0000000 --- a/android/SimpleClient/app/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/vchen/ubuntu_sw/adt-bundle-linux-x86_64/sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android/SimpleClient/app/src/androidTest/java/org/iotivity/simpleclient/ApplicationTest.java b/android/SimpleClient/app/src/androidTest/java/org/iotivity/simpleclient/ApplicationTest.java deleted file mode 100644 index a2b6778..0000000 --- a/android/SimpleClient/app/src/androidTest/java/org/iotivity/simpleclient/ApplicationTest.java +++ /dev/null @@ -1,33 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} diff --git a/android/SimpleClient/app/src/main/AndroidManifest.xml b/android/SimpleClient/app/src/main/AndroidManifest.xml deleted file mode 100644 index 08329da..0000000 --- a/android/SimpleClient/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/FoundResource.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/FoundResource.java deleted file mode 100644 index cd558f4..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/FoundResource.java +++ /dev/null @@ -1,72 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.util.Log; - -import org.iotivity.base.AbstractFindCallback; -import org.iotivity.base.OCResource; - -public class FoundResource extends AbstractFindCallback { - final private static String TAG = "FoundResource"; - - - public void Callback(OCResource resource) { - - if(SimpleClient.curResource != null) { - Log.e(TAG, "Found another resource, ignoring"); - } - - String resourceURI; - String hostAddress; - - if(resource != null) { - Log.i(TAG, "DISCOVERED Resource"); - - resourceURI = resource.uri(); - Log.i(TAG, "URI of the resource: " + resourceURI); - - hostAddress = resource.host(); - Log.i(TAG, "Host address of the resource: " + hostAddress); - - new SimpleToast().execute("URI of the resource: " + resourceURI + "\nHost address of the resource: " + hostAddress); - - String[] resourceTypes = resource.getResourceTypes(); - for(int i=0; i 5) { - Log.i(TAG, "Cancelling Observe ..."); - OCStackResult result = SimpleClient.curResource.cancelObserve(); - Log.i(TAG, "Cancel result : " + result); - try { - Thread.sleep(10000); // 10 sec - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Log.i(TAG, "DONE"); - new SimpleToast().execute( - "DONE" - ); - } - - } - } - else { - Log.e(TAG, "onPut Response error : " + eCode); - } - - } -} diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost.java deleted file mode 100644 index ca7e1ae..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost.java +++ /dev/null @@ -1,77 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.util.Log; - -import org.iotivity.base.AbstractPostCallback; -import org.iotivity.base.OCHeaderOption; -import org.iotivity.base.OCRepresentation; - -public class OnPost extends AbstractPostCallback { - - final private static String TAG = "OnPost"; - - public void Callback(OCHeaderOption[] options, OCRepresentation rep, int eCode) { -//FIXME : Need to check why ocstack is returning error code 28 to us after 12/6/14 rebase -// if(eCode == OCStackResult.OC_STACK_OK || eCode == OCStackResult.OC_STACK_RESOURCE_CREATED) { - if(true) { - Log.i(TAG, "POST request was successful"); - - if(rep.hasAttribute("createduri")) { - Log.i(TAG, "Uri of the created resource : " + rep.getValueString("createduri")); - } - else { - SimpleClient.mylight.m_state = rep.getValueBool("state"); - Log.i(TAG, "state : " + SimpleClient.mylight.m_state); - SimpleClient.mylight.m_power = rep.getValueInt("power"); - Log.i(TAG, "power : " + SimpleClient.mylight.m_power); - SimpleClient.mylight.m_name = rep.getValueString("name"); - Log.i(TAG, "name : " + SimpleClient.mylight.m_name); - - new SimpleToast().execute( - "state : " + SimpleClient.mylight.m_state + - "\npower : " + SimpleClient.mylight.m_power + - "\nname : " + SimpleClient.mylight.m_name - ); - } - - OCRepresentation rep2 = new OCRepresentation(); - - Log.e(TAG, "Posting Light Representation ..."); - - SimpleClient.mylight.m_state = true; - SimpleClient.mylight.m_power = 55; - - Log.i(TAG, "setValueBool : " + SimpleClient.mylight.m_state); - Log.i(TAG, "setValueInt : " + SimpleClient.mylight.m_power); - rep2.setValueBool("state", SimpleClient.mylight.m_state); - rep2.setValueInt("power", SimpleClient.mylight.m_power); - - OnPost2 onPost2 = new OnPost2(); - SimpleClient.curResource.post(rep2, onPost2); - } - else { - Log.e(TAG, "onPost Response error : " + eCode); - } - - } -} diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost2.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost2.java deleted file mode 100644 index cfc6ae6..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPost2.java +++ /dev/null @@ -1,75 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.util.Log; - -import org.iotivity.base.AbstractPostCallback; -import org.iotivity.base.OCHeaderOption; -import org.iotivity.base.OCRepresentation; -import org.iotivity.base.OCStackResult; -import org.iotivity.base.ObserveType; - -public class OnPost2 extends AbstractPostCallback { - - final private static String TAG = "OnPost2"; - - public void Callback(OCHeaderOption[] options, OCRepresentation rep, int eCode) { -//FIXME : Need to check why ocstack is returning error code 28 to us after 12/6/14 rebase -// if(eCode == OCStackResult.OC_STACK_OK || eCode == OCStackResult.OC_STACK_RESOURCE_CREATED) { - if(true) { - - Log.i(TAG, "POST2 request was successful"); - - if(rep.hasAttribute("createduri")) { - String createdUri = rep.getValueString("createduri"); - Log.i(TAG, "Uri of the created resource : " + createdUri); // FIXME - new SimpleToast().execute( - "Uri of the created resource : " + createdUri - ); - } - else { - SimpleClient.mylight.m_state = rep.getValueBool("state"); - Log.i(TAG, "state : " + SimpleClient.mylight.m_state); - SimpleClient.mylight.m_power = rep.getValueInt("power"); - Log.i(TAG, "power : " + SimpleClient.mylight.m_power); - SimpleClient.mylight.m_name = rep.getValueString("name"); - Log.i(TAG, "name : " + SimpleClient.mylight.m_name); - new SimpleToast().execute( - "state : " + SimpleClient.mylight.m_state + - "\npower : " + SimpleClient.mylight.m_power + - "\nname : " + SimpleClient.mylight.m_name - ); - } - - if(SimpleClient.OBSERVE_TYPE_TO_USE == ObserveType.Observe) - Log.i(TAG, "Observe is used"); - else if(SimpleClient.OBSERVE_TYPE_TO_USE == ObserveType.ObserveAll) - Log.i(TAG, "ObserveAll is used"); - - OnObserve onObserve = new OnObserve(); - SimpleClient.curResource.observe(SimpleClient.OBSERVE_TYPE_TO_USE, onObserve); - } - else { - Log.e(TAG, "onPost Response error : " + eCode); - } - } -} diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPut.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPut.java deleted file mode 100644 index fa8410c..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/OnPut.java +++ /dev/null @@ -1,59 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.util.Log; - -import org.iotivity.base.AbstractPutCallback; -import org.iotivity.base.OCHeaderOption; -import org.iotivity.base.OCRepresentation; -import org.iotivity.base.OCStackResult; - -public class OnPut extends AbstractPutCallback { - - final private static String TAG = "OnGet"; - - public void Callback(OCHeaderOption[] options, OCRepresentation rep, int eCode) { - if(eCode == OCStackResult.OC_STACK_OK) { - { - Log.i(TAG, "PUT request was successful"); - - SimpleClient.mylight.m_state = rep.getValueBool("state"); - Log.i(TAG, "state : " + SimpleClient.mylight.m_state); - SimpleClient.mylight.m_power = rep.getValueInt("power"); - Log.i(TAG, "power : " + SimpleClient.mylight.m_power); - SimpleClient.mylight.m_name = rep.getValueString("name"); - Log.i(TAG, "name : " + SimpleClient.mylight.m_name); - new SimpleToast().execute( - "state : " + SimpleClient.mylight.m_state + - "\npower : " + SimpleClient.mylight.m_power + - "\nname : " + SimpleClient.mylight.m_name - ); - - SimpleClient.postLightRepresentation(SimpleClient.curResource); - } - } - else { - Log.e(TAG, "onPut Response error : " + eCode); - } - - } -} diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleClient.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleClient.java deleted file mode 100644 index 7413ca2..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleClient.java +++ /dev/null @@ -1,151 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.app.Activity; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; - -import org.iotivity.base.OCPlatform; -import org.iotivity.base.OCRepresentation; -import org.iotivity.base.OCResource; -import org.iotivity.base.ObserveType; -import org.iotivity.base.PlatformConfig; - - -public class SimpleClient extends Activity { - final private static String TAG = "SimpleClient"; - - class Light { - public boolean m_state; - public int m_power; - public String m_name; - - public Light() { - m_state = false; - m_power = 0; - m_name = "vincent"; - } - } - - static int OBSERVE_TYPE_TO_USE = ObserveType.Observe; - - public static Light mylight; - public static OCResource curResource; - static int oc = 0; - static Activity mActivity; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mActivity = this; - - mylight = new Light(); - - PlatformConfig cfg = new PlatformConfig(PlatformConfig.ServiceType.INPROC, - PlatformConfig.ModeType.CLIENT, - "0.0.0.0", - 0, - PlatformConfig.QualityOfService.LO_QOS); - - OCPlatform.configure(cfg); - FoundResource foundResource = new FoundResource(); - OCPlatform.findResource("", "coap://224.0.1.187/oc/core?rt=core.light", foundResource); - - setContentView(R.layout.activity_simple_client); - } - - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.simple_client, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_settings) { - return true; - } - return super.onOptionsItemSelected(item); - } - - protected static void getLightRepresentation(OCResource resource) { - if(resource != null) { - Log.e(TAG, "Getting Light Representation ..."); - - OnGet onGet = new OnGet(); - resource.get(onGet); - } - } - - protected static void putLightRepresentation(OCResource resource) { - if(resource != null) { - - OCRepresentation rep = new OCRepresentation(); - - Log.e(TAG, "Putting Light Representation ..."); - - mylight.m_state = true; - mylight.m_power = 15; - - Log.i(TAG, "setValueBool : " + SimpleClient.mylight.m_state); - Log.i(TAG, "setValueInt : " + SimpleClient.mylight.m_power); - rep.setValueBool("state", mylight.m_state); - rep.setValueInt("power", mylight.m_power); - - OnPut onPut = new OnPut(); - resource.put(rep, onPut); - } - } - - protected static void postLightRepresentation(OCResource resource) { - if(resource != null) { - - OCRepresentation rep = new OCRepresentation(); - - Log.e(TAG, "Posting Light Representation ..."); - - mylight.m_state = false; - mylight.m_power = 105; - - Log.i(TAG, "setValueBool : " + SimpleClient.mylight.m_state); - Log.i(TAG, "setValueInt : " + SimpleClient.mylight.m_power); - rep.setValueBool("state", mylight.m_state); - rep.setValueInt("power", mylight.m_power); - - OnPost onPost = new OnPost(); - resource.post(rep, onPost); - } - } - - protected static int observe_count() { - return ++oc; - } - -} diff --git a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleToast.java b/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleToast.java deleted file mode 100644 index 8f7d672..0000000 --- a/android/SimpleClient/app/src/main/java/org/iotivity/simpleclient/SimpleToast.java +++ /dev/null @@ -1,44 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 MediaTek All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -package org.iotivity.simpleclient; - -import android.os.AsyncTask; -import android.widget.Toast; - -public class SimpleToast extends AsyncTask { - String toastMessage; - - @Override - protected String doInBackground(String... params) { - toastMessage = params[0]; - return toastMessage; - } - - protected void OnProgressUpdate(String... values) { - super.onProgressUpdate(values); - } - // This is executed in the context of the main GUI thread - protected void onPostExecute(String result){ - Toast toast = Toast.makeText(SimpleClient.mActivity, result, Toast.LENGTH_SHORT); - toast.show(); - } - -} diff --git a/android/SimpleClient/app/src/main/res/layout/activity_simple_client.xml b/android/SimpleClient/app/src/main/res/layout/activity_simple_client.xml deleted file mode 100644 index f347f6c..0000000 --- a/android/SimpleClient/app/src/main/res/layout/activity_simple_client.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - diff --git a/android/SimpleClient/app/src/main/res/menu/simple_client.xml b/android/SimpleClient/app/src/main/res/menu/simple_client.xml deleted file mode 100644 index 1a65997..0000000 --- a/android/SimpleClient/app/src/main/res/menu/simple_client.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/android/SimpleClient/app/src/main/res/values-w820dp/dimens.xml b/android/SimpleClient/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816..0000000 --- a/android/SimpleClient/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/android/SimpleClient/app/src/main/res/values/dimens.xml b/android/SimpleClient/app/src/main/res/values/dimens.xml deleted file mode 100644 index 47c8224..0000000 --- a/android/SimpleClient/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/android/SimpleClient/app/src/main/res/values/strings.xml b/android/SimpleClient/app/src/main/res/values/strings.xml deleted file mode 100644 index 532e40d..0000000 --- a/android/SimpleClient/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - SimpleClient - Hello world! - Settings - - diff --git a/android/SimpleClient/app/src/main/res/values/styles.xml b/android/SimpleClient/app/src/main/res/values/styles.xml deleted file mode 100644 index ff6c9d2..0000000 --- a/android/SimpleClient/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/android/SimpleClient/build.gradle b/android/SimpleClient/build.gradle deleted file mode 100644 index 9b8abe4..0000000 --- a/android/SimpleClient/build.gradle +++ /dev/null @@ -1,19 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - jcenter() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.12.2' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - } -} diff --git a/android/SimpleClient/gradle.properties b/android/SimpleClient/gradle.properties deleted file mode 100644 index 5d08ba7..0000000 --- a/android/SimpleClient/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Settings specified in this file will override any Gradle settings -# configured through the IDE. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/android/SimpleClient/gradlew b/android/SimpleClient/gradlew deleted file mode 100755 index 91a7e26..0000000 --- a/android/SimpleClient/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/SimpleClient/settings.gradle b/android/SimpleClient/settings.gradle deleted file mode 100644 index e7b4def..0000000 --- a/android/SimpleClient/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/android/android_api/.gitignore b/android/android_api/.gitignore new file mode 100644 index 0000000..e86e67c --- /dev/null +++ b/android/android_api/.gitignore @@ -0,0 +1,10 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build/* +/base/build/* +/base/obj/* +/base/libs/* +/sample/* diff --git a/android/android_api/SConscript b/android/android_api/SConscript new file mode 100644 index 0000000..2575c97 --- /dev/null +++ b/android/android_api/SConscript @@ -0,0 +1,48 @@ +import os +import platform +Import('env') + +android_home = env.get('ANDROID_HOME') + +ANDROID_TARGET_ARCH = env.get('TARGET_ARCH') +if env.get('RELEASE'): + ANDROID_RELEASE="release" +else: + ANDROID_RELEASE="debug" + +os.environ['ANDROID_HOME'] = env.get('ANDROID_HOME') +os.environ['ANDROID_NDK_HOME'] = env.get('ANDROID_NDK') + +if not os.path.exists(android_home + '/platforms/android-21') or not os.path.exists(android_home + '/build-tools/20.0.0'): + print ''' +***************************************** Info ******************************** +* Either 'Android API 21' is not installed or 'Android SDK Build Tools * +* 20.0.0' is not installed. The Android SDK Manager will now open. Please * +* be sure to deselect all options, then select the following 2 packages: * +* 1. Under "Tools" select "Android SDK Build-tools" Revision 20. * +* 2. Under "Android 5.0.1 (API 21)" select "SDK Platform" * +* 3. Continue by selecting "Install 2 Packages" * +* * +* NOTE: If you have an http proxy, please press ctrl+c now and edit/create * +* the following file in your $HOME directory as follows: * +* * +* Edit/Create file: "$HOME/.android/androidtool.cfg" * +* * +* http.proxyPort= * +* sdkman.monitor.density=108 * +* http.proxyHost= * +* sdkman.show.update.only=true * +* sdkman.ask.adb.restart=false * +* sdkman.force.http=true * +* sdkman.show.updateonly=true * +* * +******************************************************************************* + +...Opening Android SDK Manager now. Once you are finished, the build will continue. +''' + os.system(android_home + '/tools/android') + +jdk_env = Environment(ENV=os.environ) +jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE)) +jdk_env.Gradle(target="base/objs", source="base/src/main/java/org/iotivity/base/OcResource.java") + diff --git a/android/android_api/android_api.iml b/android/android_api/android_api.iml new file mode 100755 index 0000000..8d49284 --- /dev/null +++ b/android/android_api/android_api.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/android/android_api/base/.gitignore b/android/android_api/base/.gitignore new file mode 100644 index 0000000..6e8872c --- /dev/null +++ b/android/android_api/base/.gitignore @@ -0,0 +1,5 @@ +.gradle/ +.idea/ +sample/ +base/build/ +base/obj/ diff --git a/android/android_api/base/base.iml b/android/android_api/base/base.iml new file mode 100755 index 0000000..36cf651 --- /dev/null +++ b/android/android_api/base/base.iml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/android_api/base/build.gradle b/android/android_api/base/build.gradle new file mode 100755 index 0000000..9cbdaf8 --- /dev/null +++ b/android/android_api/base/build.gradle @@ -0,0 +1,115 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 21 + buildToolsVersion "20.0.0" + archivesBaseName = "iotivity" + + libraryVariants.all { variant -> + variant.outputs.each { output -> + def outputFile = output.outputFile + if (outputFile != null && outputFile.name.endsWith('.aar')) { + def fileName = "${archivesBaseName}-${TARGET_ARCH}-${outputFile.name}" + output.outputFile = new File(outputFile.parent, fileName) + } + } + } + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "0.9" + } + buildTypes { + release { + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + lintOptions { + abortOnError false + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + jniLibs.srcDir 'libs' + jni.srcDirs = [] //disable automatic ndk-build call + } + } +} + + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} + +//////////////// +////NDK Support +//////////////// +//If using this, Android studio will fail run the following to set the environment variable for android studio: +//launchctl setenv ANDROID_NDK_HOME /Users/boos_patrick/Development/Android/android-ndk-r8e +//otherwise remove the dependsOn part and run ./gradlew buildNative from the command line + +task copyNativeLibs(type: Copy, dependsOn: 'buildNative') { + dependsOn 'buildNative' + from(new File('libs')) { include '**/*.so' } + into new File(buildDir, 'native-libs') +} + +tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyNativeLibs } + +clean.dependsOn 'cleanCopyNativeLibs' + +tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> + pkgTask.jniFolders = new HashSet() + pkgTask.jniFolders.add(new File(buildDir, 'native-libs')) +} + +task buildNative(type: Exec) { + if (System.env.ANDROID_NDK_HOME != null) { + //for windows use 'ndk-build.cmd' + //def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd') + def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build') + commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE" + } else { + println '##################' + println 'Skipping NDK build' + println 'Reason: ANDROID_NDK_HOME not set.' + println '##################' + } +} +// +//task (copyARR, type: Copy) { +// copy { +// from 'build/outputs/aar/' +// into '../../../out/android/' +// include '**/*.aar' +// } +//} +//build.finalizedBy(copyARR) + + diff --git a/android/android_api/base/jni/Android.mk b/android/android_api/base/jni/Android.mk new file mode 100644 index 0000000..aa2cbae --- /dev/null +++ b/android/android_api/base/jni/Android.mk @@ -0,0 +1,78 @@ +LOCAL_PATH := $(call my-dir) +TARGET_ARCH_ABI := $(APP_ABI) + +include $(CLEAR_VARS) +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM) +LOCAL_MODULE := libandroid-oc_logger +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc_logger.so +include $(PREBUILT_SHARED_LIBRARY) + +include $(CLEAR_VARS) +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM) +LOCAL_MODULE := libandroid-octbstack +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboctbstack.so +include $(PREBUILT_SHARED_LIBRARY) + +include $(CLEAR_VARS) +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM) +LOCAL_MODULE := libandroid-oc +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc.so +include $(PREBUILT_SHARED_LIBRARY) + +include $(CLEAR_VARS) +OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM) +LOCAL_MODULE := libandroid-ca +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so +include $(PREBUILT_SHARED_LIBRARY) + +include $(CLEAR_VARS) +OIC_SRC_PATH := ../../../resource +LOCAL_MODULE := libca-interface +LOCAL_SRC_FILES := JniCaInterface.c +LOCAL_STATIC_LIBRARIES := libandroid-ca +LOCAL_LDLIBS := -llog +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/connectivity/api +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +OIC_SRC_PATH := ../../../resource +OIC_OUT_PATH := ../../../out +LOCAL_MODULE := ocstack-jni +LOCAL_SRC_FILES := JniOcStack.cpp \ + JniUtils.cpp \ + JniEntityHandler.cpp \ + JniOnResourceFoundListener.cpp \ + JniOnDeviceInfoListener.cpp \ + JniOnPresenceListener.cpp \ + JniOnGetListener.cpp \ + JniOnPutListener.cpp \ + JniOnPostListener.cpp \ + JniOnDeleteListener.cpp \ + JniOnObserveListener.cpp \ + JniOcRepresentation.cpp \ + JniOcResourceHandle.cpp \ + JniOcPresenceHandle.cpp \ + JniOcRequestHandle.cpp \ + JniOcResourceRequest.cpp \ + JniOcResourceResponse.cpp \ + JniOcPlatform.cpp \ + JniOcResource.cpp \ + JniOcResourceIdentifier.cpp + +LOCAL_LDLIBS := -llog +LOCAL_STATIC_LIBRARIES := android-oc +LOCAL_STATIC_LIBRARIES += android-octbstack +LOCAL_STATIC_LIBRARIES += android-coap +LOCAL_STATIC_LIBRARIES += android-oc_logger +LOCAL_STATIC_LIBRARIES += android-ca +LOCAL_STATIC_LIBRARIES += android_cpp11_compat + +LOCAL_CPPFLAGS += -std=c++0x +LOCAL_CPP_FEATURES := rtti exceptions +LOCAL_C_INCLUDES := $(OIC_SRC_PATH)/include +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/stack/include +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/ocsocket/include +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/oc_logger/include +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/boost/boost_1_58_0 +LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../build_common/android/compatibility +include $(BUILD_SHARED_LIBRARY) diff --git a/android/android_api/base/jni/Application.mk b/android/android_api/base/jni/Application.mk new file mode 100644 index 0000000..089c9b3 --- /dev/null +++ b/android/android_api/base/jni/Application.mk @@ -0,0 +1,2 @@ +NDK_TOOLCHAIN_VERSION := 4.9 +APP_STL := gnustl_shared \ No newline at end of file diff --git a/android/android_api/base/jni/JniCaInterface.c b/android/android_api/base/jni/JniCaInterface.c new file mode 100644 index 0000000..eb1e07a --- /dev/null +++ b/android/android_api/base/jni/JniCaInterface.c @@ -0,0 +1,60 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include +#include +#include +#include "cainterface.h" +#include "JniCaInterface.h" + +#define LOG_TAG "JNI_CA_INTERFACE" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) + +JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved) +{ + LOGI("CaInterface_initialize"); + CANativeJNISetJavaVM(jvm); + + return JNI_VERSION_1_6; +} + +void JNI_OnUnload(JavaVM *jvm, void *reserved) +{ + return; +} + +JNIEXPORT void JNICALL +Java_org_iotivity_ca_CaInterface_initialize +(JNIEnv *env, jclass clazz, jobject context) +{ + LOGI("CaInterface_initialize"); + + CANativeJNISetContext(env, context); + + CAResult_t res = CAInitialize(); + + if (CA_STATUS_OK != res) + { + LOGE("Could not Initialize"); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniCaInterface.h b/android/android_api/base/jni/JniCaInterface.h new file mode 100644 index 0000000..ee77a97 --- /dev/null +++ b/android/android_api/base/jni/JniCaInterface.h @@ -0,0 +1,44 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include +// THIS FILE IS SUBJECT TO CHANGE DUE TO THE ONGOING DEVELOPMENT OF THE CA FOR ANDROID +// DO NOT REVIEW THIS FILE + +/* Header for class org_iotivity_ca_CaInterface */ + +#ifndef _Included_org_iotivity_ca_CaInterface +#define _Included_org_iotivity_ca_CaInterface +#ifdef __cplusplus +extern "C" { +#endif + /* + * Class: org_iotivity_ca_CaInterface_Initialize + * Method: Initialize + * Signature: (Landroid/content/Context;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_ca_CaInterface_initialize + (JNIEnv *, jclass, jobject); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniEntityHandler.cpp b/android/android_api/base/jni/JniEntityHandler.cpp new file mode 100644 index 0000000..860d52b --- /dev/null +++ b/android/android_api/base/jni/JniEntityHandler.cpp @@ -0,0 +1,111 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniEntityHandler.h" +#include "JniOcResourceRequest.h" +#include "JniOcResourceResponse.h" +#include "JniUtils.h" + +JniEntityHandler::JniEntityHandler(JNIEnv *env, jobject entityHandler) +{ + m_jListener = env->NewGlobalRef(entityHandler); +} + +JniEntityHandler::~JniEntityHandler() +{ + LOGD("~JniEntityHandler"); + if (m_jListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + env->DeleteGlobalRef(m_jListener); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +OCEntityHandlerResult JniEntityHandler::handleEntity(const std::shared_ptr request) +{ + LOGD("JniEntityHandler_handleEntity"); + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return OC_EH_ERROR; + + JniOcResourceRequest* jniResReq = new JniOcResourceRequest(request); + jlong reqHandle = reinterpret_cast(jniResReq); + jobject jResourceRequest = env->NewObject(g_cls_OcResourceRequest, g_mid_OcResourceRequest_N_ctor, + reqHandle); + if (!jResourceRequest) + { + LOGE("Failed to create OcResourceRequest"); + delete jniResReq; + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + + jclass clsL = env->GetObjectClass(m_jListener); + if (!clsL) + { + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + jmethodID midL = env->GetMethodID(clsL, "handleEntity", + "(Lorg/iotivity/base/OcResourceRequest;)Lorg/iotivity/base/EntityHandlerResult;"); + if (!midL) + { + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + jobject entityHandlerResult = env->CallObjectMethod(m_jListener, midL, jResourceRequest); + if (env->ExceptionCheck()) + { + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + if (!entityHandlerResult) + { + ThrowOcException(JNI_INVALID_VALUE, "EntityHandlerResult cannot be null"); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + jclass clsResult = env->GetObjectClass(entityHandlerResult); + if (!clsResult) + { + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + jmethodID getValue_ID = env->GetMethodID(clsResult, "getValue", "()I"); + if (!getValue_ID) + { + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + jint jResult = env->CallIntMethod(entityHandlerResult, getValue_ID); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return OC_EH_ERROR; + } + + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return JniUtils::getOCEntityHandlerResult(env, static_cast(jResult)); +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniEntityHandler.h b/android/android_api/base/jni/JniEntityHandler.h new file mode 100644 index 0000000..8cf3373 --- /dev/null +++ b/android/android_api/base/jni/JniEntityHandler.h @@ -0,0 +1,39 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_JniEntityHandler +#define _Included_org_iotivity_base_JniEntityHandler + +class JniEntityHandler +{ +public: + JniEntityHandler(JNIEnv *env, jobject listener); + ~JniEntityHandler(); + + OCEntityHandlerResult handleEntity(const std::shared_ptr request); + +private: + jobject m_jListener; +}; + +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniListenerManager.cpp b/android/android_api/base/jni/JniListenerManager.cpp new file mode 100644 index 0000000..c9ccaa3 --- /dev/null +++ b/android/android_api/base/jni/JniListenerManager.cpp @@ -0,0 +1,103 @@ +///* +//* //****************************************************************** +//* // +//* // Copyright 2015 Intel Corporation. +//* // +//* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +//* // +//* // 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. +//* // +//* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +//*/ +// +//#include "JniListenerManager.h" +// +//#include "JniOnGetListener.h" +// +//template +//T* JniListenerManager::addListener(JNIEnv* env, jobject jListener) +//{ +// T *onEventListener = NULL; +// +// m_mapMutex.lock(); +// +// for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it) +// { +// if (env->IsSameObject(jListener, it->first)) +// { +// auto refPair = it->second; +// onEventListener = refPair.first; +// refPair.second++; +// it->second = refPair; +// m_listenerMap.insert(*it); +// LOGD("OnEventListener: ref. count is incremented"); +// break; +// } +// } +// +// if (!onEventListener) +// { +// onEventListener = new T(env, jListener, this); +// jobject jgListener = env->NewGlobalRef(jListener); +// +// m_listenerMap.insert(std::pair>(jgListener, std::pair(onEventListener, 1))); +// LOGD("OnEventListener: new listener"); +// } +// +// m_mapMutex.unlock(); +// +// return onEventListener; +//} +// +//template +//void JniListenerManager::removeListener(JNIEnv* env, jobject jListener) +//{ +// m_mapMutex.lock(); +// +// bool isFound = false; +// +// for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it) +// { +// if (env->IsSameObject(jListener, it->first)) +// { +// auto refPair = it->second; +// if (refPair.second > 1) +// { +// refPair.second--; +// it->second = refPair; +// m_listenerMap.insert(*it); +// LOGI("OnEventListener: ref. count is decremented"); +// } +// else +// { +// env->DeleteGlobalRef(it->first); +// T* listener = refPair.first; +// delete listener; +// m_listenerMap.erase(it); +// +// LOGI("OnEventListener is removed"); +// } +// +// isFound = true; +// break; +// } +// } +// +// if (!isFound) +// { +// ThrowOcException(JNI_EXCEPTION, "OnEventListener isn't found"); +// } +// +// m_mapMutex.unlock(); +//} +// diff --git a/android/android_api/base/jni/JniListenerManager.h b/android/android_api/base/jni/JniListenerManager.h new file mode 100644 index 0000000..a43ea82 --- /dev/null +++ b/android/android_api/base/jni/JniListenerManager.h @@ -0,0 +1,125 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOcStack.h" +#include + +#ifndef _JniListenerManager +#define _JniListenerManager + +class JniOcResource; + +template +class JniListenerManager +{ +public: + T* addListener(JNIEnv* env, jobject jListener, JniOcResource* owner) + { + T *onEventListener = NULL; + + m_mapMutex.lock(); + + for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + onEventListener = refPair.first; + refPair.second++; + it->second = refPair; + m_listenerMap.insert(*it); + LOGD("OnEventListener: ref. count is incremented"); + break; + } + } + if (!onEventListener) + { + onEventListener = new T(env, jListener, owner); + jobject jgListener = env->NewGlobalRef(jListener); + + if (jgListener) + { + m_listenerMap.insert(std::pair>(jgListener, std::pair(onEventListener, 1))); + } + else + { + LOGD("OnEventListener: Failed to create global listener ref."); + delete onEventListener; + } + LOGD("OnEventListener: new listener"); + } + m_mapMutex.unlock(); + return onEventListener; + } + + void removeListener(JNIEnv* env, jobject jListener) + { + m_mapMutex.lock(); + for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + if (refPair.second > 1) + { + refPair.second--; + it->second = refPair; + m_listenerMap.insert(*it); + LOGI("OnEventListener: ref. count is decremented"); + } + else + { + env->DeleteGlobalRef(it->first); + T* listener = refPair.first; + delete listener; + m_listenerMap.erase(it); + + LOGI("OnEventListener is removed"); + } + break; + } + } + m_mapMutex.unlock(); + } + + void removeAllListeners(JNIEnv* env) + { + m_mapMutex.lock(); + + for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it) + { + env->DeleteGlobalRef(it->first); + auto refPair = it->second; + T* listener = refPair.first; + delete listener; + m_listenerMap.erase(it); + } + + m_mapMutex.unlock(); + } + +private: + std::map> m_listenerMap; + std::mutex m_mapMutex; +}; + +#endif diff --git a/android/android_api/base/jni/JniOcPlatform.cpp b/android/android_api/base/jni/JniOcPlatform.cpp new file mode 100644 index 0000000..0a50d8e --- /dev/null +++ b/android/android_api/base/jni/JniOcPlatform.cpp @@ -0,0 +1,1591 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcPlatform.h" +#include "OCPlatform.h" +#include "JniOcResource.h" +#include "JniOcResourceHandle.h" +#include "JniOcPresenceHandle.h" +#include "JniOcResourceResponse.h" +#include "JniUtils.h" + +using namespace OC; + +JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener) +{ + JniOnResourceFoundListener *onResourceFoundListener = NULL; + + resourceFoundMapLock.lock(); + + for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + onResourceFoundListener = refPair.first; + refPair.second++; + it->second = refPair; + onResourceFoundListenerMap.insert(*it); + LOGD("OnResourceFoundListener: ref. count incremented"); + break; + } + } + + if (!onResourceFoundListener) + { + onResourceFoundListener = new JniOnResourceFoundListener(env, jListener, RemoveOnResourceFoundListener); + jobject jgListener = env->NewGlobalRef(jListener); + + onResourceFoundListenerMap.insert(std::pair < jobject, std::pair < JniOnResourceFoundListener*, + int >> (jgListener, std::pair(onResourceFoundListener, 1))); + LOGD("OnResourceFoundListener: new listener"); + } + resourceFoundMapLock.unlock(); + return onResourceFoundListener; +} + +void RemoveOnResourceFoundListener(JNIEnv* env, jobject jListener) +{ + resourceFoundMapLock.lock(); + + for (auto it = onResourceFoundListenerMap.begin(); it != onResourceFoundListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + if (refPair.second > 1) + { + refPair.second--; + it->second = refPair; + onResourceFoundListenerMap.insert(*it); + LOGI("OnResourceFoundListener: ref. count decremented"); + } + else + { + env->DeleteGlobalRef(it->first); + JniOnResourceFoundListener* listener = refPair.first; + delete listener; + onResourceFoundListenerMap.erase(it); + LOGI("OnResourceFoundListener removed"); + } + break; + } + } + resourceFoundMapLock.unlock(); +} + +JniOnDeviceInfoListener* AddOnDeviceInfoListener(JNIEnv* env, jobject jListener) +{ + JniOnDeviceInfoListener *onDeviceInfoListener = NULL; + + deviceInfoMapLock.lock(); + + for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + onDeviceInfoListener = refPair.first; + refPair.second++; + it->second = refPair; + onDeviceInfoListenerMap.insert(*it); + LOGD("OnDeviceInfoListener: ref. count incremented"); + break; + } + } + + if (!onDeviceInfoListener) + { + onDeviceInfoListener = new JniOnDeviceInfoListener(env, jListener, RemoveOnDeviceInfoListener); + jobject jgListener = env->NewGlobalRef(jListener); + + onDeviceInfoListenerMap.insert(std::pair < jobject, std::pair < JniOnDeviceInfoListener*, + int >> (jgListener, std::pair(onDeviceInfoListener, 1))); + LOGI("OnDeviceInfoListener: new listener"); + } + + deviceInfoMapLock.unlock(); + return onDeviceInfoListener; +} + +void RemoveOnDeviceInfoListener(JNIEnv* env, jobject jListener) +{ + deviceInfoMapLock.lock(); + bool isFound = false; + for (auto it = onDeviceInfoListenerMap.begin(); it != onDeviceInfoListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + if (refPair.second > 1) + { + refPair.second--; + it->second = refPair; + onDeviceInfoListenerMap.insert(*it); + LOGI("OnDeviceInfoListener: ref. count decremented"); + } + else + { + env->DeleteGlobalRef(it->first); + JniOnDeviceInfoListener* listener = refPair.first; + delete listener; + onDeviceInfoListenerMap.erase(it); + + LOGI("OnDeviceInfoListener removed"); + } + + isFound = true; + break; + } + } + + if (!isFound) + { + ThrowOcException(JNI_EXCEPTION, "OnDeviceInfoListenet not found"); + } + deviceInfoMapLock.unlock(); +} + +JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener) +{ + JniOnPresenceListener *onPresenceListener = NULL; + + presenceMapLock.lock(); + + for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + onPresenceListener = refPair.first; + refPair.second++; + it->second = refPair; + onPresenceListenerMap.insert(*it); + LOGD("OnPresenceListener: ref. count incremented"); + break; + } + } + if (!onPresenceListener) + { + onPresenceListener = new JniOnPresenceListener(env, jListener, RemoveOnPresenceListener); + jobject jgListener = env->NewGlobalRef(jListener); + onPresenceListenerMap.insert(std::pair < jobject, std::pair < JniOnPresenceListener*, + int >> (jgListener, std::pair(onPresenceListener, 1))); + LOGI("OnPresenceListener: new listener"); + } + presenceMapLock.unlock(); + return onPresenceListener; +} + +void RemoveOnPresenceListener(JNIEnv* env, jobject jListener) +{ + presenceMapLock.lock(); + bool isFound = false; + for (auto it = onPresenceListenerMap.begin(); it != onPresenceListenerMap.end(); ++it) + { + if (env->IsSameObject(jListener, it->first)) + { + auto refPair = it->second; + if (refPair.second > 1) + { + refPair.second--; + it->second = refPair; + onPresenceListenerMap.insert(*it); + LOGI("OnPresenceListener: ref. count decremented"); + } + else + { + env->DeleteGlobalRef(it->first); + JniOnPresenceListener* listener = refPair.first; + delete listener; + onPresenceListenerMap.erase(it); + LOGI("OnPresenceListener is removed"); + } + isFound = true; + break; + } + } + if (!isFound) + { + ThrowOcException(JNI_EXCEPTION, "OnPresenceListener not found"); + } + presenceMapLock.unlock(); +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: configure +* Signature: (IILjava/lang/String;II)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure +(JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort, jint jQOS) +{ + LOGI("OcPlatform_configure"); + + std::string ipAddress; + if (jIpAddress) + { + ipAddress = env->GetStringUTFChars(jIpAddress, NULL); + } + uint16_t port; + if (jPort > 0) + { + port = static_cast(jPort); + } + PlatformConfig cfg{ + JniUtils::getServiceType(env, jServiceType), + JniUtils::getModeType(env, jModeType), + ipAddress, + port, + JniUtils::getQOS(env, static_cast(jQOS)) + }; + + OCPlatform::Configure(cfg); +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: notifyAllObservers0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers0 +(JNIEnv *env, jclass clazz, jobject jResourceHandle) +{ + LOGI("OcPlatform_notifyAllObservers"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCStackResult result = OCPlatform::notifyAllObservers(jniOcResourceHandle->getOCResourceHandle()); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to notify all observers"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: notifyAllObservers1 +* Signature: (Lorg/iotivity/base/OcResourceHandle;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers1 +(JNIEnv *env, jclass clazz, jobject jResourceHandle, jint jQoS) +{ + LOGI("OcPlatform_notifyAllObservers1"); + + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try{ + OCStackResult result = OCPlatform::notifyAllObservers( + jniOcResourceHandle->getOCResourceHandle(), + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to notify all observers"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: notifyListOfObservers2 +* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers2 +(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse) +{ + LOGD("OcPlatform_notifyListOfObservers2"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + if (!jObservationIdArr) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null"); + return; + } + if (!jResourceResponse) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr( + env, jResourceResponse); + if (!jniOcResourceResponse) return; + + int len = env->GetArrayLength(jObservationIdArr); + uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0); + + ObservationIds observationIds; + for (int i = 0; i < len; ++i) + { + observationIds.push_back(bArr[i]); + } + + env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0); + + try{ + OCStackResult result = OCPlatform::notifyListOfObservers( + jniOcResourceHandle->getOCResourceHandle(), + observationIds, + jniOcResourceResponse->getOCResourceResponse()); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to notify all observers"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: notifyListOfObservers3 +* Signature: (Lorg/iotivity/base/OcResourceHandle;[Ljava/lang/Byte;Lorg/iotivity/base/OcResourceResponse;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers3 +(JNIEnv *env, jclass clazz, jobject jResourceHandle, jbyteArray jObservationIdArr, jobject jResourceResponse, jint jQoS) +{ + LOGD("OcPlatform_notifyListOfObservers3"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + if (!jObservationIdArr) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "observationIdList cannot be null"); + return; + } + if (!jResourceResponse) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + JniOcResourceResponse* jniOcResourceResponse = JniOcResourceResponse::getJniOcResourceResponsePtr( + env, jResourceResponse); + if (!jniOcResourceResponse) return; + + int len = env->GetArrayLength(jObservationIdArr); + uint8_t* bArr = (uint8_t*)env->GetByteArrayElements(jObservationIdArr, 0); + + ObservationIds observationIds; + for (int i = 0; i < len; ++i) + { + observationIds.push_back(bArr[i]); + } + + env->ReleaseByteArrayElements(jObservationIdArr, (jbyte*)bArr, 0); + + try{ + OCStackResult result = OCPlatform::notifyListOfObservers( + jniOcResourceHandle->getOCResourceHandle(), + observationIds, + jniOcResourceResponse->getOCResourceResponse(), + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to notify all observers"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: findResource0 +* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource0 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener) +{ + LOGD("OcPlatform_findResource"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string resourceUri; + if (jResourceUri) + { + resourceUri = env->GetStringUTFChars(jResourceUri, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null"); + return; + } + + JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener); + + FindCallback findCallback = [onResFoundListener](std::shared_ptr resource) + { + onResFoundListener->foundResourceCallback(resource); + }; + + try + { + OCStackResult result = OCPlatform::findResource( + host, + resourceUri, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + findCallback); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Find resource has failed"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: findResource1 +* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource1 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS) +{ + LOGD("OcPlatform_findResource"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string resourceUri; + if (jResourceUri) + { + resourceUri = env->GetStringUTFChars(jResourceUri, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onResourceFoundListener cannot be null"); + return; + } + JniOnResourceFoundListener *onResFoundListener = AddOnResourceFoundListener(env, jListener); + + FindCallback findCallback = [onResFoundListener](std::shared_ptr resource) + { + onResFoundListener->foundResourceCallback(resource); + }; + + try + { + OCStackResult result = OCPlatform::findResource( + host, + resourceUri, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + findCallback, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Find resource has failed"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: getDeviceInfo0 +* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo0 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener) +{ + LOGD("OcPlatform_getDeviceInfo0"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string resourceUri; + if (jResourceUri) + { + resourceUri = env->GetStringUTFChars(jResourceUri, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null"); + return; + } + JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener); + + FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation) + { + onDeviceInfoListener->foundDeviceCallback(ocRepresentation); + }; + + try + { + OCStackResult result = OCPlatform::getDeviceInfo( + host, + resourceUri, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + findDeviceCallback); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Find device has failed"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: getDeviceInfo1 +* Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo1 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceUri, jint jConnectivityType, jobject jListener, jint jQoS) +{ + LOGD("OcPlatform_getDeviceInfo1"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string resourceUri; + if (jResourceUri) + { + resourceUri = env->GetStringUTFChars(jResourceUri, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onDeviceFoundListener cannot be null"); + return; + } + JniOnDeviceInfoListener *onDeviceInfoListener = AddOnDeviceInfoListener(env, jListener); + + FindDeviceCallback findDeviceCallback = [onDeviceInfoListener](const OCRepresentation& ocRepresentation) + { + onDeviceInfoListener->foundDeviceCallback(ocRepresentation); + }; + + try + { + OCStackResult result = OCPlatform::getDeviceInfo( + host, + resourceUri, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + findDeviceCallback, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Find device has failed"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: registerResource0 +* Signature: (Lorg/iotivity/base/OcResource;)Lorg/iotivity/base/OcResourceHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource0 +(JNIEnv *env, jclass clazz, jobject jResource) +{ + LOGD("OcPlatform_registerResource"); + if (!jResource) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "Resource cannot be null"); + return nullptr; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, jResource); + if (!resource) return nullptr; + + OCResourceHandle resourceHandle; + try + { + OCStackResult result = OCPlatform::registerResource( + resourceHandle, + resource->getOCResource()); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "register resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + return nullptr; + } + + JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle); + jlong handle = reinterpret_cast(jniHandle); + jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle); + if (!jResourceHandle) + { + LOGE("Failed to create OcResourceHandle"); + delete jniHandle; + } + return jResourceHandle; +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: registerResource1 +* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcPlatform/EntityHandler;I)Lorg/iotivity/base/OcResourceHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource1 +(JNIEnv *env, jclass clazz, jstring jResourceUri, jstring jResourceTypeName, jstring jResourceInterface, +jobject jListener, jint jResourceProperty) +{ + LOGI("OcPlatform_registerResource1"); + std::string resourceUri; + if (jResourceUri) + { + resourceUri = env->GetStringUTFChars(jResourceUri, NULL); + } + std::string resourceTypeName; + if (jResourceTypeName) + { + resourceTypeName = env->GetStringUTFChars(jResourceTypeName, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "entityHandler cannot be null"); + return nullptr; + } + JniEntityHandler* entityHandler = new JniEntityHandler(env, jListener); + EntityHandler handleEntityCallback = [entityHandler](const std::shared_ptr request) -> + OCEntityHandlerResult{ + return entityHandler->handleEntity(request); + }; + + OCResourceHandle resourceHandle; + try + { + OCStackResult result = OCPlatform::registerResource( + resourceHandle, + resourceUri, + resourceTypeName, + resourceInterface, + handleEntityCallback, + static_cast(jResourceProperty)); + + if (OC_STACK_OK != result) + { + delete entityHandler; + ThrowOcException(result, "register resource"); + return nullptr; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + delete entityHandler; + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + return nullptr; + } + + JniOcResourceHandle* jniHandle = new JniOcResourceHandle(resourceHandle); + jlong handle = reinterpret_cast(jniHandle); + jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle); + if (!jResourceHandle) + { + LOGE("Failed to create OcResourceHandle"); + delete jniHandle; + } + + return jResourceHandle; +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: registerDeviceInfo0 +* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0 +(JNIEnv *env, +jclass clazz, +jstring jDeviceName, +jstring jHostName, +jstring jDeviceUUID, +jstring jContentType, +jstring jVersion, +jstring jManufacturerName, +jstring jManufacturerUrl, +jstring jModelNumber, +jstring jDateOfManufacture, +jstring jPlatformVersion, +jstring jFirmwareVersion, +jstring jSupportUrl) +{ + LOGI("OcPlatform_registerDeviceInfo"); + + std::string deviceName; + if (jDeviceName) + { + deviceName = env->GetStringUTFChars(jDeviceName, NULL); + } + std::string hostName; + if (jHostName) + { + hostName = env->GetStringUTFChars(jHostName, NULL); + } + std::string deviceUUID; + if (jDeviceUUID) + { + deviceUUID = env->GetStringUTFChars(jDeviceUUID, NULL); + } + std::string contentType; + if (jContentType) + { + contentType = env->GetStringUTFChars(jContentType, NULL); + } + std::string version; + if (jVersion) + { + version = env->GetStringUTFChars(jVersion, NULL); + } + std::string manufacturerName; + if (jManufacturerName) + { + manufacturerName = env->GetStringUTFChars(jManufacturerName, NULL); + } + std::string manufacturerUrl; + if (jManufacturerUrl) + { + manufacturerUrl = env->GetStringUTFChars(jManufacturerUrl, NULL); + } + std::string modelNumber; + if (jModelNumber) + { + modelNumber = env->GetStringUTFChars(jModelNumber, NULL); + } + std::string dateOfManufacture; + if (jDateOfManufacture) + { + dateOfManufacture = env->GetStringUTFChars(jDateOfManufacture, NULL); + } + std::string platformVersion; + if (jPlatformVersion) + { + platformVersion = env->GetStringUTFChars(jPlatformVersion, NULL); + } + std::string firmwareVersion; + if (jFirmwareVersion) + { + firmwareVersion = env->GetStringUTFChars(jFirmwareVersion, NULL); + } + std::string supportUrl; + if (jSupportUrl) + { + supportUrl = env->GetStringUTFChars(jSupportUrl, NULL); + } + + OCDeviceInfo deviceInfo; + try + { + DuplicateString(&deviceInfo.contentType, contentType); + DuplicateString(&deviceInfo.dateOfManufacture, dateOfManufacture); + DuplicateString(&deviceInfo.deviceName, deviceName); + DuplicateString(&deviceInfo.deviceUUID, deviceUUID); + DuplicateString(&deviceInfo.firmwareVersion, firmwareVersion); + DuplicateString(&deviceInfo.hostName, hostName); + DuplicateString(&deviceInfo.manufacturerName, manufacturerName); + DuplicateString(&deviceInfo.manufacturerUrl, manufacturerUrl); + DuplicateString(&deviceInfo.modelNumber, modelNumber); + DuplicateString(&deviceInfo.platformVersion, platformVersion); + DuplicateString(&deviceInfo.supportUrl, supportUrl); + DuplicateString(&deviceInfo.version, version); + } + catch (std::exception &e) + { + ThrowOcException(JNI_EXCEPTION, "Failed to register device info"); + return; + } + + try + { + OCStackResult result = OCPlatform::registerDeviceInfo(deviceInfo); + + delete deviceInfo.contentType; + delete deviceInfo.dateOfManufacture; + delete deviceInfo.deviceName; + delete deviceInfo.deviceUUID; + delete deviceInfo.firmwareVersion; + delete deviceInfo.hostName; + delete deviceInfo.manufacturerName; + delete deviceInfo.manufacturerUrl; + delete deviceInfo.modelNumber; + delete deviceInfo.platformVersion; + delete deviceInfo.supportUrl; + delete deviceInfo.version; + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to register device info"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: unregisterResource0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unregisterResource0 +(JNIEnv *env, jclass clazz, jobject jResourceHandle) +{ + LOGI("OcPlatform_unregisterResource"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCResourceHandle resHandle = jniOcResourceHandle->getOCResourceHandle(); + OCStackResult result = OCPlatform::unregisterResource(resHandle); + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to unregister resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: bindResource0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResource0 +(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle) +{ + LOGI("OcPlatform_bindResource"); + if (!jResourceCollectionHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null"); + return; + } + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceCollectionHandle); + if (!jniOcResourceCollectionHandle) return; + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCStackResult result = OCPlatform::bindResource( + jniOcResourceCollectionHandle->getOCResourceHandle(), + jniOcResourceHandle->getOCResourceHandle() + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to bind resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: bindResources0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResources0 +(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray) +{ + LOGI("OcPlatform_bindResources"); + + if (!jResourceCollectionHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null"); + return; + } + if (!jResourceHandleArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceCollectionHandle); + if (!jniOcResourceCollectionHandle) return; + + std::vector resourceHandleList; + int len = env->GetArrayLength(jResourceHandleArray); + for (int i = 0; i < len; ++i) + { + jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i); + if (!jResourceHandle) + { + ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + resourceHandleList.push_back( + jniOcResourceHandle->getOCResourceHandle()); + } + + try + { + OCStackResult result = OCPlatform::bindResources( + jniOcResourceCollectionHandle->getOCResourceHandle(), + resourceHandleList + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to bind resources"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: unbindResource0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResource0 +(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobject jResourceHandle) +{ + LOGI("OcPlatform_unbindResource"); + if (!jResourceCollectionHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null"); + return; + } + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceCollectionHandle); + if (!jniOcResourceCollectionHandle) return; + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCStackResult result = OCPlatform::unbindResource( + jniOcResourceCollectionHandle->getOCResourceHandle(), + jniOcResourceHandle->getOCResourceHandle() + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to unbind resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: unbindResources0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResources0 +(JNIEnv *env, jclass clazz, jobject jResourceCollectionHandle, jobjectArray jResourceHandleArray) +{ + LOGI("OcPlatform_unbindResources"); + if (!jResourceCollectionHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceCollectionHandle cannot be null"); + return; + } + if (!jResourceHandleArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandleList cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceCollectionHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceCollectionHandle); + if (!jniOcResourceCollectionHandle) return; + + std::vector resourceHandleList; + int len = env->GetArrayLength(jResourceHandleArray); + for (int i = 0; i < len; ++i) + { + jobject jResourceHandle = env->GetObjectArrayElement(jResourceHandleArray, i); + if (!jResourceHandle) + { + ThrowOcException(JNI_EXCEPTION, "resource handle cannot be null"); + return; + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + resourceHandleList.push_back( + jniOcResourceHandle->getOCResourceHandle()); + } + + try + { + OCStackResult result = OCPlatform::unbindResources( + jniOcResourceCollectionHandle->getOCResourceHandle(), + resourceHandleList + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to unbind resources"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: bindTypeToResource0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindTypeToResource0 +(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceTypeName) +{ + LOGI("OcPlatform_bindTypeToResource"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + std::string typeName; + if (jResourceTypeName) + { + typeName = env->GetStringUTFChars(jResourceTypeName, NULL); + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCStackResult result = OCPlatform::bindTypeToResource( + jniOcResourceHandle->getOCResourceHandle(), + typeName + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to bind type to resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: bindInterfaceToResource0 +* Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindInterfaceToResource0 +(JNIEnv *env, jclass clazz, jobject jResourceHandle, jstring jResourceInterfaceName) +{ + LOGI("OcPlatform_bindInterfaceToResource"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + std::string interfaceName; + if (jResourceInterfaceName) + { + interfaceName = env->GetStringUTFChars(jResourceInterfaceName, NULL); + } + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr( + env, jResourceHandle); + if (!jniOcResourceHandle) return; + + try + { + OCStackResult result = OCPlatform::bindInterfaceToResource( + jniOcResourceHandle->getOCResourceHandle(), + interfaceName + ); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to bind interface to resource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: startPresence0 +* Signature: (I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_startPresence0 +(JNIEnv *env, jclass clazz, jint ttl) +{ + LOGI("OcPlatform_startPresence"); + + try + { + OCStackResult result = OCPlatform::startPresence((unsigned int)ttl); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to start presence"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: stopPresence0 +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stopPresence0 +(JNIEnv *env, jclass clazz) +{ + LOGI("OcPlatform_stopPresence"); + + try + { + OCStackResult result = OCPlatform::stopPresence(); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "Failed to stop presence"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: subscribePresence0 +* Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence0 +(JNIEnv *env, jclass clazz, jstring jHost, jint jConnectivityType, jobject jListener) +{ + LOGD("OcPlatform_subscribePresence"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null"); + return nullptr; + } + + JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener); + + SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result, const unsigned int nonce, + const std::string& hostAddress) + { + onPresenceListener->onPresenceCallback(result, nonce, hostAddress); + }; + + OCPlatform::OCPresenceHandle presenceHandle; + try + { + OCStackResult result = OCPlatform::subscribePresence( + presenceHandle, + host, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + subscribeCallback); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "subscribe presence has failed"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + return nullptr; + } + + JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle); + jlong jhandle = reinterpret_cast(jniPresenceHandle); + jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle); + if (!jPresenceHandle) + { + LOGE("Failed to create OcPresenceHandle"); + delete jniPresenceHandle; + } + + return jPresenceHandle; +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: subscribePresence1 +* Signature: (Ljava/lang/String;Ljava/lang/String;I +Lorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence1 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jResourceType, jint jConnectivityType, jobject jListener) +{ + LOGD("OcPlatform_subscribePresence1"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPresenceListener cannot be null"); + return nullptr; + } + + JniOnPresenceListener *onPresenceListener = AddOnPresenceListener(env, jListener); + + SubscribeCallback subscribeCallback = [onPresenceListener](OCStackResult result, + const unsigned int nonce, const std::string& hostAddress) + { + onPresenceListener->onPresenceCallback(result, nonce, hostAddress); + }; + + OCPlatform::OCPresenceHandle presenceHandle; + try + { + OCStackResult result = OCPlatform::subscribePresence( + presenceHandle, + host, + resourceType, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + subscribeCallback); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "subscribe presence has failed"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + return nullptr; + } + + JniOcPresenceHandle* jniPresenceHandle = new JniOcPresenceHandle(onPresenceListener, presenceHandle); + jlong jhandle = reinterpret_cast(jniPresenceHandle); + jobject jPresenceHandle = env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle); + if (!jPresenceHandle) + { + LOGE("Failed to create OcPresenceHandle"); + delete jniPresenceHandle; + } + return jPresenceHandle; +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: unsubscribePresence0 +* Signature: (Lorg/iotivity/base/OcPresenceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unsubscribePresence0 +(JNIEnv *env, jclass clazz, jobject jPresenceHandle) +{ + LOGD("OcPlatform_unsubscribePresence"); + if (!jPresenceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "presenceHandle cannot be null"); + return; + } + JniOcPresenceHandle* jniPresenceHandle = JniOcPresenceHandle::getJniOcPresenceHandlePtr(env, jPresenceHandle); + if (!jniPresenceHandle) return; + + OCPresenceHandle presenceHandle = jniPresenceHandle->getOCPresenceHandle(); + + try + { + OCStackResult result = OCPlatform::unsubscribePresence(presenceHandle); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "unsubscribe presence has failed"); + return; + } + jweak jwOnPresenceListener = jniPresenceHandle->getJniOnPresenceListener()->getJWListener(); + if (jwOnPresenceListener) + { + RemoveOnPresenceListener(env, jwOnPresenceListener); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: constructResourceObject0 +* Signature: (Ljava/lang/String;Ljava/lang/String;IZ[Ljava/lang/String;[Ljava/lang/String;) +Lorg/iotivity/base/OcResource; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_constructResourceObject0 +(JNIEnv *env, jclass clazz, jstring jHost, jstring jUri, jint jConnectivityType, +jboolean jIsObservable, jobjectArray jResourceTypeArray, jobjectArray jInterfaceArray) +{ + LOGD("OcPlatform_constructResourceObject"); + std::string host; + if (jHost) + { + host = env->GetStringUTFChars(jHost, NULL); + } + std::string uri; + if (jUri) + { + uri = env->GetStringUTFChars(jUri, NULL); + } + if (!jResourceTypeArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceTypeList cannot be null"); + return nullptr; + } + if (!jInterfaceArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "interfaceList cannot be null"); + return nullptr; + } + + std::vector resourceTypes; + JniUtils::convertJavaStrArrToStrVector(env, jResourceTypeArray, resourceTypes); + + std::vector interfaces; + JniUtils::convertJavaStrArrToStrVector(env, jInterfaceArray, interfaces); + + std::shared_ptr resource = OCPlatform::constructResourceObject( + host, + uri, + JniUtils::getConnectivityType(env, static_cast(jConnectivityType)), + static_cast(jIsObservable), + resourceTypes, + interfaces); + + if (!resource) + { + ThrowOcException(OC_STACK_ERROR, "Failed to create OCResource"); + return nullptr; + } + + JniOcResource *jniOcResource = new JniOcResource(resource); + jlong handle = reinterpret_cast(jniOcResource); + + jobject jResource = env->NewObject(g_cls_OcResource, g_mid_OcResource_ctor); + if (!jResource) + { + delete jniOcResource; + return nullptr; + } + SetHandle(env, jResource, jniOcResource); + if (env->ExceptionCheck()) + { + delete jniOcResource; + return nullptr; + } + return jResource; +} + +/* +* Class: org_iotivity_base_OcPlatform +* Method: sendResponse0 +* Signature: (Lorg/iotivity/base/OcResourceResponse;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0 +(JNIEnv *env, jclass clazz, jobject jResourceResponse) +{ + LOGD("OcPlatform_sendResponse"); + if (!jResourceResponse) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceResponse cannot be null"); + return; + } + + JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr( + env, jResourceResponse); + if (!jniResponse) return; + + try + { + OCStackResult result = OCPlatform::sendResponse(jniResponse->getOCResourceResponse()); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "failed to send response"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcPlatform.h b/android/android_api/base/jni/JniOcPlatform.h new file mode 100644 index 0000000..1019147 --- /dev/null +++ b/android/android_api/base/jni/JniOcPlatform.h @@ -0,0 +1,264 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "JniOnResourceFoundListener.h" +#include "JniOnDeviceInfoListener.h" +#include "JniOnPresenceListener.h" +#include + +#ifndef _Included_org_iotivity_base_OcPlatform +#define _Included_org_iotivity_base_OcPlatform + +using namespace OC; + +JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener); +void RemoveOnResourceFoundListener(JNIEnv* env, jobject jListener); + +JniOnDeviceInfoListener* AddOnDeviceInfoListener(JNIEnv* env, jobject jListener); +void RemoveOnDeviceInfoListener(JNIEnv* env, jobject jListener); + +JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener); +void RemoveOnPresenceListener(JNIEnv* env, jobject jListener); + +std::map> onResourceFoundListenerMap; +std::map> onDeviceInfoListenerMap; +std::map> onPresenceListenerMap; + +std::mutex resourceFoundMapLock; +std::mutex deviceInfoMapLock; +std::mutex presenceMapLock; + +#ifdef __cplusplus +extern "C" { +#endif + /* + * Class: org_iotivity_base_OcPlatform + * Method: configure + * Signature: (IILjava/lang/String;II)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure + (JNIEnv *, jclass, jint, jint, jstring, jint, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: notifyAllObservers0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers0 + (JNIEnv *, jclass, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: notifyAllObservers1 + * Signature: (Lorg/iotivity/base/OcResourceHandle;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyAllObservers1 + (JNIEnv *, jclass, jobject, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: notifyListOfObservers2 + * Signature: (Lorg/iotivity/base/OcResourceHandle;[BLorg/iotivity/base/OcResourceResponse;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers2 + (JNIEnv *, jclass, jobject, jbyteArray, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: notifyListOfObservers3 + * Signature: (Lorg/iotivity/base/OcResourceHandle;[BLorg/iotivity/base/OcResourceResponse;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_notifyListOfObservers3 + (JNIEnv *, jclass, jobject, jbyteArray, jobject, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: findResource0 + * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource0 + (JNIEnv *, jclass, jstring, jstring, jint, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: findResource1 + * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnResourceFoundListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findResource1 + (JNIEnv *, jclass, jstring, jstring, jint, jobject, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: getDeviceInfo0 + * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo0 + (JNIEnv *, jclass, jstring, jstring, jint, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: getDeviceInfo1 + * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnDeviceFoundListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_getDeviceInfo1 + (JNIEnv *, jclass, jstring, jstring, jint, jobject, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: registerResource0 + * Signature: (Lorg/iotivity/base/OcResource;)Lorg/iotivity/base/OcResourceHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource0 + (JNIEnv *, jclass, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: registerResource1 + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcPlatform/EntityHandler;I)Lorg/iotivity/base/OcResourceHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_registerResource1 + (JNIEnv *, jclass, jstring, jstring, jstring, jobject, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: registerDeviceInfo0 + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0 + (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring, jstring); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: unregisterResource0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unregisterResource0 + (JNIEnv *, jclass, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: bindResource0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResource0 + (JNIEnv *, jclass, jobject, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: bindResources0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindResources0 + (JNIEnv *, jclass, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: unbindResource0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResource0 + (JNIEnv *, jclass, jobject, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: unbindResources0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;[Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unbindResources0 + (JNIEnv *, jclass, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: bindTypeToResource0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindTypeToResource0 + (JNIEnv *, jclass, jobject, jstring); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: bindInterfaceToResource0 + * Signature: (Lorg/iotivity/base/OcResourceHandle;Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_bindInterfaceToResource0 + (JNIEnv *, jclass, jobject, jstring); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: startPresence0 + * Signature: (I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_startPresence0 + (JNIEnv *, jclass, jint); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: stopPresence0 + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stopPresence0 + (JNIEnv *, jclass); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: subscribePresence0 + * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence0 + (JNIEnv *, jclass, jstring, jint, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: subscribePresence1 + * Signature: (Ljava/lang/String;Ljava/lang/String;ILorg/iotivity/base/OcPlatform/OnPresenceListener;)Lorg/iotivity/base/OcPresenceHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribePresence1 + (JNIEnv *, jclass, jstring, jstring, jint, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: unsubscribePresence0 + * Signature: (Lorg/iotivity/base/OcPresenceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_unsubscribePresence0 + (JNIEnv *, jclass, jobject); + + /* + * Class: org_iotivity_base_OcPlatform + * Method: constructResourceObject0 + * Signature: (Ljava/lang/String;Ljava/lang/String;IZ[Ljava/lang/String;[Ljava/lang/String;)Lorg/iotivity/base/OcResource; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_constructResourceObject0 + (JNIEnv *, jclass, jstring, jstring, jint, jboolean, jobjectArray, jobjectArray); + + /* + * Class: org_iotivity_base_OcPlatform0 + * Method: sendResponse0 + * Signature: (Lorg/iotivity/base/OcResourceResponse;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0 + (JNIEnv *, jclass, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/android/android_api/base/jni/JniOcPresenceHandle.cpp b/android/android_api/base/jni/JniOcPresenceHandle.cpp new file mode 100644 index 0000000..83950bc --- /dev/null +++ b/android/android_api/base/jni/JniOcPresenceHandle.cpp @@ -0,0 +1,73 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcPresenceHandle.h" +#include "OCPlatform.h" + +JniOcPresenceHandle::JniOcPresenceHandle(JniOnPresenceListener* jniListener, OCPresenceHandle presenceHandle) + : m_jniListener(jniListener), m_presenceHandle(presenceHandle) +{} + +JniOcPresenceHandle::~JniOcPresenceHandle() +{ + LOGD("~JniOcPresenceHandle()"); + + //delete m_jniListener; + m_presenceHandle = nullptr; +} + +JniOcPresenceHandle* JniOcPresenceHandle::getJniOcPresenceHandlePtr +(JNIEnv *env, jobject thiz) +{ + JniOcPresenceHandle *handle = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcPresenceHandle"); + } + if (!handle) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return handle; +} + +OCPresenceHandle JniOcPresenceHandle::getOCPresenceHandle() +{ + return this->m_presenceHandle; +} + +JniOnPresenceListener* JniOcPresenceHandle::getJniOnPresenceListener() +{ + return this->m_jniListener; +} + +/* +* Class: org_iotivity_base_OcPresenceHandle +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcPresenceHandle_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcPresenceHandle_dispose"); + JniOcPresenceHandle *presenceHandle = JniOcPresenceHandle::getJniOcPresenceHandlePtr(env, thiz); + delete presenceHandle; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcPresenceHandle.h b/android/android_api/base/jni/JniOcPresenceHandle.h new file mode 100644 index 0000000..26f6a8d --- /dev/null +++ b/android/android_api/base/jni/JniOcPresenceHandle.h @@ -0,0 +1,65 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "JniOnPresenceListener.h" +#include "OCPlatform.h" + +#ifndef _Included_org_iotivity_base_OcPresenceHandle +#define _Included_org_iotivity_base_OcPresenceHandle + +using namespace OC::OCPlatform; + +class JniOcPresenceHandle +{ +public: + + JniOcPresenceHandle(JniOnPresenceListener* jniListener, OCPresenceHandle presenceHandle); + ~JniOcPresenceHandle(); + JniOcPresenceHandle(const JniOcPresenceHandle &) = delete; + void operator=(const JniOcPresenceHandle &) = delete; + + static JniOcPresenceHandle* getJniOcPresenceHandlePtr(JNIEnv *env, jobject thiz); + + OCPresenceHandle getOCPresenceHandle(); + JniOnPresenceListener* getJniOnPresenceListener(); + +private: + JniOnPresenceListener* m_jniListener; + OCPresenceHandle m_presenceHandle; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcPresenceHandle + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcPresenceHandle_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/android/android_api/base/jni/JniOcRepresentation.cpp b/android/android_api/base/jni/JniOcRepresentation.cpp new file mode 100644 index 0000000..e2c2cd0 --- /dev/null +++ b/android/android_api/base/jni/JniOcRepresentation.cpp @@ -0,0 +1,1040 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +using namespace OC; + +OCRepresentation* JniOcRepresentation::getOCRepresentationPtr(JNIEnv *env, jobject thiz) +{ + OCRepresentation *rep = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcRepresentation"); + } + if (!rep) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return rep; +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getValueN +* Signature: (Ljava/lang/String;)Ljava/lang/Object; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getValueN +(JNIEnv *env, jobject thiz, jstring jKey) +{ + LOGD("OcRepresentation_getValue"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "attributeKey cannot be null"); + return nullptr; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + std::string key = env->GetStringUTFChars(jKey, NULL); + + AttributeValue attrValue; + if (!rep->getAttributeValue(key.c_str(), attrValue)) + { + ThrowOcException(JNI_NO_SUCH_KEY, " attribute key does not exist"); + return nullptr; + } + return boost::apply_visitor(JObjectConverter(env), attrValue); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueInteger +* Signature: (Ljava/lang/String;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger +(JNIEnv *env, jobject thiz, jstring jKey, jint jValue) +{ + LOGD("OcRepresentation_setValueInteger"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string str = env->GetStringUTFChars(jKey, NULL); + rep->setValue(str, static_cast(jValue)); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueDouble +* Signature: (Ljava/lang/String;D)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble +(JNIEnv *env, jobject thiz, jstring jKey, jdouble jValue) +{ + LOGD("OcRepresentation_setValueDouble"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string str = env->GetStringUTFChars(jKey, NULL); + rep->setValue(str, static_cast(jValue)); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueBoolean +* Signature: (Ljava/lang/String;Z)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean +(JNIEnv *env, jobject thiz, jstring jKey, jboolean jValue) +{ + LOGD("OcRepresentation_setValueBoolean"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string str = env->GetStringUTFChars(jKey, NULL); + rep->setValue(str, static_cast(jValue)); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueStringN +* Signature: (Ljava/lang/String;Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueStringN +(JNIEnv *env, jobject thiz, jstring jKey, jstring jValue) +{ + LOGD("OcRepresentation_setValueString"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + std::string value = env->GetStringUTFChars(jValue, NULL); + + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueRepresentation +* Signature: (Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation +(JNIEnv *env, jobject thiz, jstring jKey, jobject jValue) +{ + LOGD("OcRepresentation_setValueRepresentation"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + OCRepresentation *value = JniOcRepresentation::getOCRepresentationPtr(env, jValue); + if (!value) return; + + rep->setValue(key, *value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueIntegerArray +* Signature: (Ljava/lang/String;[I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueIntegerArray +(JNIEnv *env, jobject thiz, jstring jKey, jintArray jValue) +{ + LOGD("OcRepresentation_setValueIntegerArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + + const jsize len = env->GetArrayLength(jValue); + jint* ints = env->GetIntArrayElements(jValue, NULL); + + std::vector value; + for (jsize i = 0; i < len; ++i) + { + value.push_back(static_cast(ints[i])); + } + env->ReleaseIntArrayElements(jValue, ints, JNI_ABORT); + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueInteger2DArray +* Signature: (Ljava/lang/String;[[I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger2DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation__setValueInteger2DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize j = 0; j < lenOuter; ++j) + { + jintArray jInnerArray = static_cast(env->GetObjectArrayElement(jValue, j)); + jint* ints = env->GetIntArrayElements(jInnerArray, NULL); + std::vector innerVector; + const jsize lenInner = env->GetArrayLength(jInnerArray); + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(ints[i])); + } + env->ReleaseIntArrayElements(jInnerArray, ints, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + value.push_back(innerVector); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueInteger3DArray +* Signature: (Ljava/lang/String;[[[I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger3DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueInteger3DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector>> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize k = 0; k < lenOuter; ++k) + { + jobjectArray jMiddleArray = static_cast(env->GetObjectArrayElement(jValue, k)); + const jsize lenMiddle = env->GetArrayLength(jMiddleArray); + std::vector> middleArray; + for (jsize j = 0; j < lenMiddle; ++j) + { + jintArray jInnerArray = static_cast(env->GetObjectArrayElement(jMiddleArray, j)); + jint* ints = env->GetIntArrayElements(jInnerArray, NULL); + std::vector innerVector; + const jsize lenInner = env->GetArrayLength(jInnerArray); + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(ints[i])); + } + env->ReleaseIntArrayElements(jInnerArray, ints, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + middleArray.push_back(innerVector); + } + env->DeleteLocalRef(jMiddleArray); + value.push_back(middleArray); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueDoubleArray +* Signature: (Ljava/lang/String;[D)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDoubleArray +(JNIEnv *env, jobject thiz, jstring jKey, jdoubleArray jValue) +{ + LOGD("OcRepresentation_setValueDoubleArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + + const jsize len = env->GetArrayLength(jValue); + jdouble* doubles = env->GetDoubleArrayElements(jValue, NULL); + + std::vector value; + for (jsize i = 0; i < len; ++i) + { + value.push_back(static_cast(doubles[i])); + } + env->ReleaseDoubleArrayElements(jValue, doubles, JNI_ABORT); + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueDouble2DArray +* Signature: (Ljava/lang/String;[[D)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble2DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueDouble2DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize j = 0; j < lenOuter; ++j) + { + jdoubleArray jInnerArray = static_cast(env->GetObjectArrayElement(jValue, j)); + jdouble* doubles = env->GetDoubleArrayElements(jInnerArray, NULL); + std::vector innerVector; + const jsize lenInner = env->GetArrayLength(jInnerArray); + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(doubles[i])); + } + env->ReleaseDoubleArrayElements(jInnerArray, doubles, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + value.push_back(innerVector); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueDouble3DArray +* Signature: (Ljava/lang/String;[[[D)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble3DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueDouble3DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector>> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize k = 0; k < lenOuter; ++k) + { + jobjectArray jMiddleArray = static_cast(env->GetObjectArrayElement(jValue, k)); + const jsize lenMiddle = env->GetArrayLength(jMiddleArray); + std::vector> middleArray; + for (jsize j = 0; j < lenMiddle; ++j) + { + jdoubleArray jInnerArray = static_cast(env->GetObjectArrayElement(jMiddleArray, j)); + jdouble* doubles = env->GetDoubleArrayElements(jInnerArray, NULL); + std::vector innerVector; + const jsize lenInner = env->GetArrayLength(jInnerArray); + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(doubles[i])); + } + env->ReleaseDoubleArrayElements(jInnerArray, doubles, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + middleArray.push_back(innerVector); + } + env->DeleteLocalRef(jMiddleArray); + value.push_back(middleArray); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueBooleanArray +* Signature: (Ljava/lang/String;[Z)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBooleanArray +(JNIEnv *env, jobject thiz, jstring jKey, jbooleanArray jValue) +{ + LOGD("OcRepresentation_setValueBooleanArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + + const jsize len = env->GetArrayLength(jValue); + jboolean* booleans = env->GetBooleanArrayElements(jValue, NULL); + + std::vector value; + for (jsize i = 0; i < len; ++i) + { + value.push_back(static_cast(booleans[i])); + } + env->ReleaseBooleanArrayElements(jValue, booleans, JNI_ABORT); + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueBoolean2DArray +* Signature: (Ljava/lang/String;[[Z)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean2DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueBoolean2DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize j = 0; j < lenOuter; ++j) + { + jbooleanArray jInnerArray = static_cast(env->GetObjectArrayElement(jValue, j)); + const jsize lenInner = env->GetArrayLength(jInnerArray); + jboolean* booleans = env->GetBooleanArrayElements(jInnerArray, NULL); + + std::vector innerVector; + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(booleans[i])); + } + env->ReleaseBooleanArrayElements(jInnerArray, booleans, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + value.push_back(innerVector); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueBoolean3DArray +* Signature: (Ljava/lang/String;[[[Z)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean3DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueBoolean3DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector>> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize k = 0; k < lenOuter; ++k) + { + jobjectArray jMiddleArray = static_cast(env->GetObjectArrayElement(jValue, k)); + const jsize lenMiddle = env->GetArrayLength(jMiddleArray); + std::vector> middleArray; + for (jsize j = 0; j < lenMiddle; ++j) + { + jbooleanArray jInnerArray = static_cast(env->GetObjectArrayElement(jMiddleArray, j)); + const jsize lenInner = env->GetArrayLength(jInnerArray); + jboolean* booleans = env->GetBooleanArrayElements(jInnerArray, NULL); + + std::vector innerVector; + for (jsize i = 0; i < lenInner; ++i) + { + innerVector.push_back(static_cast(booleans[i])); + } + env->ReleaseBooleanArrayElements(jInnerArray, booleans, JNI_ABORT); + env->DeleteLocalRef(jInnerArray); + middleArray.push_back(innerVector); + } + env->DeleteLocalRef(jMiddleArray); + value.push_back(middleArray); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueStringArray +* Signature: (Ljava/lang/String;[Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueStringArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueStringArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + + std::vector value; + JniUtils::convertJavaStrArrToStrVector(env, jValue, value); + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueString2DArray +* Signature: (Ljava/lang/String;[[Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueString2DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueString2DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize j = 0; j < lenOuter; ++j) + { + jobjectArray jInnerArray = static_cast(env->GetObjectArrayElement(jValue, j)); + std::vector innerVector; + JniUtils::convertJavaStrArrToStrVector(env, jInnerArray, innerVector); + env->DeleteLocalRef(jInnerArray); + value.push_back(innerVector); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueString3DArray +* Signature: (Ljava/lang/String;[[[Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueString3DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueString3DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector>> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize k = 0; k < lenOuter; ++k) + { + jobjectArray jMiddleArray = static_cast(env->GetObjectArrayElement(jValue, k)); + const jsize lenMiddle = env->GetArrayLength(jMiddleArray); + std::vector> middleArray; + for (jsize j = 0; j < lenMiddle; ++j) + { + jobjectArray jInnerArray = static_cast(env->GetObjectArrayElement(jMiddleArray, j)); + std::vector innerVector; + JniUtils::convertJavaStrArrToStrVector(env, jInnerArray, innerVector); + env->DeleteLocalRef(jInnerArray); + middleArray.push_back(innerVector); + } + env->DeleteLocalRef(jMiddleArray); + value.push_back(middleArray); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueRepresentationArray +* Signature: (Ljava/lang/String;[Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentationArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueRepresentationArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + + std::vector value; + JniUtils::convertJavaRepresentationArrToVector(env, jValue, value); + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueRepresentation2DArray +* Signature: (Ljava/lang/String;[[Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation2DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueRepresentation2DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize j = 0; j < lenOuter; ++j) + { + jobjectArray jInnerArray = static_cast(env->GetObjectArrayElement(jValue, j)); + std::vector innerVector; + JniUtils::convertJavaRepresentationArrToVector(env, jInnerArray, innerVector); + env->DeleteLocalRef(jInnerArray); + value.push_back(innerVector); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setValueRepresentation3DArray +* Signature: (Ljava/lang/String;[[[Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation3DArray +(JNIEnv *env, jobject thiz, jstring jKey, jobjectArray jValue) +{ + LOGD("OcRepresentation_setValueRepresentation3DArray"); + if (!jKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "key cannot be null"); + return; + } + std::vector>> value; + const jsize lenOuter = env->GetArrayLength(jValue); + for (jsize k = 0; k < lenOuter; ++k) + { + jobjectArray jMiddleArray = static_cast(env->GetObjectArrayElement(jValue, k)); + const jsize lenMiddle = env->GetArrayLength(jMiddleArray); + std::vector> middleArray; + for (jsize j = 0; j < lenMiddle; ++j) + { + jobjectArray jInnerArray = static_cast(env->GetObjectArrayElement(jMiddleArray, j)); + std::vector innerVector; + JniUtils::convertJavaRepresentationArrToVector(env, jInnerArray, innerVector); + env->DeleteLocalRef(jInnerArray); + middleArray.push_back(innerVector); + } + env->DeleteLocalRef(jMiddleArray); + value.push_back(middleArray); + } + + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string key = env->GetStringUTFChars(jKey, NULL); + rep->setValue(key, value); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getJSONRepresentation +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_getJSONRepresentation"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + std::string jsonStr = rep->getJSONRepresentation(); + return env->NewStringUTF(jsonStr.c_str()); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: addChild +* Signature: (Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_addChild +(JNIEnv *env, jobject thiz, jobject jOcRepresentation) +{ + LOGD("OcRepresentation_addChild"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + OCRepresentation *child = JniOcRepresentation::getOCRepresentationPtr(env, jOcRepresentation); + if (!child) return; + + rep->addChild(*child); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: clearChildren +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_clearChildren +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_clearChildren"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + rep->clearChildren(); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getChildrenArray +* Signature: ()[Lorg/iotivity/base/OcRepresentation; +*/ +JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcRepresentation_getChildrenArray +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_getChildrenArray"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + return JniUtils::convertRepresentationVectorToJavaArray(env, rep->getChildren()); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getUri +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getUri +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_getUri"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + std::string uri(rep->getUri()); + return env->NewStringUTF(uri.c_str()); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setUri +* Signature: (Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setUri +(JNIEnv *env, jobject thiz, jstring jUri) +{ + LOGD("OcRepresentation_setUri"); + if (!jUri) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "uri cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + rep->setUri(env->GetStringUTFChars(jUri, NULL)); +} + +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_hasAttribute +(JNIEnv *env, jobject thiz, jstring jstr) +{ + LOGD("OcRepresentation_hasAttribute"); + if (!jstr) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "attributeKey cannot be null"); + return false; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return false; + + std::string str = env->GetStringUTFChars(jstr, NULL); + return rep->hasAttribute(str); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getResourceTypes +* Signature: ()Ljava/util/List; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getResourceTypes +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_getResourceTypes"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + std::vector resourceTypes = rep->getResourceTypes(); + return JniUtils::convertStrVectorToJavaStrList(env, resourceTypes); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setResourceTypeArray +* Signature: ([Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setResourceTypeArray +(JNIEnv *env, jobject thiz, jobjectArray jResourceTypeArray) +{ + LOGD("OcRepresentation_setResourceTypeArray"); + if (!jResourceTypeArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceTypeList cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::vector resourceTypes; + JniUtils::convertJavaStrArrToStrVector(env, jResourceTypeArray, resourceTypes); + rep->setResourceTypes(resourceTypes); +} +/* +* Class: org_iotivity_base_OcRepresentation +* Method: getResourceInterfaces +* Signature: ()Ljava/util/List; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getResourceInterfaces +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_getResourceInterfaces"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return nullptr; + + std::vector resourceInterfaces = rep->getResourceInterfaces(); + return JniUtils::convertStrVectorToJavaStrList(env, resourceInterfaces); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setResourceInterfaceArray +* Signature: ([Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setResourceInterfaceArray +(JNIEnv *env, jobject thiz, jobjectArray jResourceInterfaceArray) +{ + LOGD("OcRepresentation_setResourceInterfaceArray"); + if (!jResourceInterfaceArray) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceInterfaceList cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::vector resourceInterfaces; + JniUtils::convertJavaStrArrToStrVector(env, jResourceInterfaceArray, resourceInterfaces); + rep->setResourceInterfaces(resourceInterfaces); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: isEmpty +* Signature: ()Z +*/ +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_isEmpty +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_isEmpty"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return false; + + return static_cast(rep->empty()); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: size +* Signature: ()I +*/ +JNIEXPORT jint JNICALL Java_org_iotivity_base_OcRepresentation_size +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_size"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return -1; + + return static_cast(rep->numberOfAttributes()); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: remove +* Signature: (Ljava/lang/String;)Z +*/ +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_remove +(JNIEnv *env, jobject thiz, jstring jAttributeKey) +{ + LOGD("OcRepresentation_remove"); + if (!jAttributeKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "attributeKey cannot be null"); + return false; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return false; + + std::string attributeKey = env->GetStringUTFChars(jAttributeKey, NULL); + return static_cast(rep->erase(attributeKey)); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: setNull +* Signature: (Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setNull +(JNIEnv *env, jobject thiz, jstring jAttributeKey) +{ + LOGD("OcRepresentation_setNull"); + if (!jAttributeKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "attributeKey cannot be null"); + return; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return; + + std::string attributeKey = env->GetStringUTFChars(jAttributeKey, NULL); + rep->setNULL(attributeKey); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: isNull +* Signature: (Ljava/lang/String;)Z +*/ +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_isNull +(JNIEnv *env, jobject thiz, jstring jAttributeKey) +{ + LOGD("OcRepresentation_isNull"); + if (!jAttributeKey) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "attributeKey cannot be null"); + return false; + } + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + if (!rep) return false; + + std::string attributeKey = env->GetStringUTFChars(jAttributeKey, NULL); + return static_cast(rep->isNULL(attributeKey)); +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: create +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_create +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRepresentation_create"); + OCRepresentation *rep = new OCRepresentation(); + SetHandle(env, thiz, rep); + if (env->ExceptionCheck()) + { + LOGE("Failed to set native handle for OcRepresentation"); + delete rep; + } +} + +/* +* Class: org_iotivity_base_OcRepresentation +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_dispose +(JNIEnv *env, jobject thiz, jboolean jNeedsDelete) +{ + LOGD("OcRepresentation_dispose"); + OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, thiz); + + if (jNeedsDelete) + { + delete rep; + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcRepresentation.h b/android/android_api/base/jni/JniOcRepresentation.h new file mode 100644 index 0000000..3f25c29 --- /dev/null +++ b/android/android_api/base/jni/JniOcRepresentation.h @@ -0,0 +1,769 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include + +#ifndef _Included_org_iotivity_base_OcRepresentation +#define _Included_org_iotivity_base_OcRepresentation + +using namespace OC; + +class JniOcRepresentation +{ +public: + static OCRepresentation* getOCRepresentationPtr(JNIEnv *env, jobject thiz); +}; + +struct JObjectConverter : boost::static_visitor < jobject > +{ + JObjectConverter(JNIEnv *env) : env(env){} + + jobject operator()(const NullType&) const { return nullptr; } + jobject operator()(const int& val) const + { + jobject jobj = env->NewObject( + g_cls_Integer, + g_mid_Integer_ctor, + static_cast(val)); + return jobj; + } + jobject operator()(const double& val) const + { + jobject jobj = env->NewObject( + g_cls_Double, + g_mid_Double_ctor, + static_cast(val)); + return jobj; + } + jobject operator()(const bool& val) const + { + jobject jobj = env->NewObject( + g_cls_Boolean, + g_mid_Boolean_ctor, + static_cast(val)); + return jobj; + } + jobject operator()(const std::string& val) const + { + jstring jstr = env->NewStringUTF(val.c_str()); + return static_cast(jstr); + } + jobject operator()(const OC::OCRepresentation& val) const + { + OCRepresentation * rep = new OCRepresentation(val); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject( + g_cls_OcRepresentation, + g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + } + return jRepresentation; + } + + // Sequences: + jobject operator()(const std::vector& val) const + { + size_t len = val.size(); + jintArray jIntArray = env->NewIntArray(len); + if (!jIntArray) return nullptr; + const int* ints = &val[0]; + env->SetIntArrayRegion(jIntArray, 0, len, reinterpret_cast(ints)); + return jIntArray; + } + jobject operator()(const std::vector& val) const + { + size_t len = val.size(); + jdoubleArray jDoubleArray = env->NewDoubleArray(len); + if (!jDoubleArray) return nullptr; + const double* doubles = &val[0]; + env->SetDoubleArrayRegion(jDoubleArray, 0, len, reinterpret_cast(doubles)); + return jDoubleArray; + } + jobject operator()(const std::vector& val) const + { + size_t len = val.size(); + jbooleanArray jBooleanArray = env->NewBooleanArray(len); + if (!jBooleanArray) return nullptr; + jboolean* booleans = new jboolean[len]; + for (size_t i = 0; i < len; ++i) { + booleans[i] = static_cast(val[i]); + } + env->SetBooleanArrayRegion(jBooleanArray, 0, len, booleans); + if (env->ExceptionCheck()) return nullptr; + env->ReleaseBooleanArrayElements(jBooleanArray, booleans, 0); + return jBooleanArray; + } + jobject operator()(const std::vector& val) const + { + size_t len = val.size(); + jobjectArray strArr = env->NewObjectArray(len, g_cls_String, NULL); + if (!strArr) return nullptr; + for (size_t i = 0; i < len; ++i) + { + jstring jString = env->NewStringUTF(val[i].c_str()); + env->SetObjectArrayElement(strArr, static_cast(i), jString); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jString); + } + return strArr; + } + jobject operator()(const std::vector& val) const + { + jsize len = static_cast(val.size()); + jobjectArray repArr = env->NewObjectArray(len, g_cls_OcRepresentation, NULL); + if (!repArr) return nullptr; + for (jsize i = 0; i < len; ++i) + { + OCRepresentation* rep = new OCRepresentation(val[i]); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + return nullptr; + } + env->SetObjectArrayElement(repArr, i, jRepresentation); + if (env->ExceptionCheck()) + { + delete rep; + return nullptr; + } + env->DeleteLocalRef(jRepresentation); + } + return repArr; + } + + // Nested sequences: + jobject operator()(const std::vector>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_int1DArray, NULL); + if (!jOuterArr) + { + return nullptr; + } + for (jsize i = 0; i < lenOuter; ++i) + { + size_t lenInner = val[i].size(); + jintArray jIntArray = env->NewIntArray(lenInner); + if (!jIntArray) return nullptr; + const int* ints = &val[i][0]; + env->SetIntArrayRegion(jIntArray, 0, lenInner, reinterpret_cast(ints)); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jOuterArr, i, static_cast(jIntArray)); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jIntArray); + } + return jOuterArr; + } + jobject operator()(const std::vector>>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_int2DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize k = 0; k < lenOuter; ++k) + { + jsize lenMiddle = static_cast(val[k].size()); + jobjectArray jMiddleArr = env->NewObjectArray(lenMiddle, g_cls_int1DArray, NULL); + if (!jMiddleArr) return nullptr; + for (jsize i = 0; i < lenMiddle; ++i) + { + jsize lenInner = static_cast(val[k][i].size()); + jintArray jIntArray = env->NewIntArray(lenInner); + if (!jIntArray) return nullptr; + const int* ints = &val[k][i][0]; + env->SetIntArrayRegion(jIntArray, 0, lenInner, reinterpret_cast(ints)); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jMiddleArr, i, jIntArray); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jIntArray); + } + env->SetObjectArrayElement(jOuterArr, k, jMiddleArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jMiddleArr); + } + return jOuterArr; + } + + jobject operator()(const std::vector>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_double1DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize i = 0; i < lenOuter; ++i) + { + size_t lenInner = val[i].size(); + jdoubleArray jDoubleArray = env->NewDoubleArray(lenInner); + if (!jDoubleArray) return nullptr; + const double* doubles = &val[i][0]; + env->SetDoubleArrayRegion(jDoubleArray, 0, lenInner, reinterpret_cast(doubles)); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jOuterArr, i, jDoubleArray); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jDoubleArray); + } + + return jOuterArr; + } + jobject operator()(const std::vector>>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_double2DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize k = 0; k < lenOuter; ++k) + { + jsize lenMiddle = static_cast(val[k].size()); + jobjectArray jMiddleArr = env->NewObjectArray(lenMiddle, g_cls_double1DArray, NULL); + if (!jMiddleArr) return nullptr; + for (jsize i = 0; i < lenMiddle; ++i) + { + jsize lenInner = static_cast(val[k][i].size()); + jdoubleArray jDoubleArray = env->NewDoubleArray(lenInner); + if (!jDoubleArray) return nullptr; + const double* doubles = &val[k][i][0]; + env->SetDoubleArrayRegion(jDoubleArray, 0, lenInner, reinterpret_cast(doubles)); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jMiddleArr, i, jDoubleArray); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jDoubleArray); + } + env->SetObjectArrayElement(jOuterArr, k, jMiddleArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jMiddleArr); + } + return jOuterArr; + } + + jobject operator()(const std::vector>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_boolean1DArray, 0); + if (!jOuterArr) return nullptr; + for (jsize i = 0; i < lenOuter; ++i) + { + size_t lenInner = val[i].size(); + jbooleanArray jBooleanArray = env->NewBooleanArray(lenInner); + if (!jBooleanArray) return nullptr; + jboolean* booleans = new jboolean[lenInner]; + for (size_t j = 0; j < lenInner; ++j) { + booleans[j] = static_cast(val[i][j]); + } + env->SetBooleanArrayRegion(jBooleanArray, 0, lenInner, booleans); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jOuterArr, i, jBooleanArray); + if (env->ExceptionCheck()) return nullptr; + env->ReleaseBooleanArrayElements(jBooleanArray, booleans, 0); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jBooleanArray); + } + return jOuterArr; + } + jobject operator()(const std::vector>>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_boolean2DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize k = 0; k < lenOuter; ++k) + { + jsize lenMiddle = static_cast(val[k].size()); + jobjectArray jMiddleArr = env->NewObjectArray(lenMiddle, g_cls_boolean1DArray, NULL); + if (!jMiddleArr) return nullptr; + for (jsize i = 0; i < lenMiddle; ++i) + { + size_t lenInner = val[k][i].size(); + jbooleanArray jBooleanArray = env->NewBooleanArray(lenInner); + jboolean* booleans = new jboolean[lenInner]; + for (size_t j = 0; j < lenInner; ++j) { + booleans[j] = val[k][i][j]; + } + env->SetBooleanArrayRegion(jBooleanArray, 0, lenInner, booleans); + if (env->ExceptionCheck()) return nullptr; + env->SetObjectArrayElement(jMiddleArr, i, jBooleanArray); + if (env->ExceptionCheck()) return nullptr; + env->ReleaseBooleanArrayElements(jBooleanArray, booleans, 0); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jBooleanArray); + } + env->SetObjectArrayElement(jOuterArr, k, jMiddleArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jMiddleArr); + } + return jOuterArr; + } + + jobject operator()(const std::vector>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_String1DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize i = 0; i < lenOuter; ++i) + { + jsize lenInner = static_cast(val[i].size()); + jobjectArray strArr = env->NewObjectArray(lenInner, g_cls_String, NULL); + if (!strArr) return nullptr; + for (jsize j = 0; j < lenInner; ++j) + { + jstring jString = env->NewStringUTF(val[i][j].c_str()); + env->SetObjectArrayElement(strArr, j, jString); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jString); + } + env->SetObjectArrayElement(jOuterArr, i, strArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(strArr); + } + + return jOuterArr; + } + jobject operator()(const std::vector>>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_String2DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize k = 0; k < lenOuter; ++k) + { + jsize lenMiddle = static_cast(val[k].size()); + jobjectArray jMiddleArr = env->NewObjectArray(lenMiddle, g_cls_String1DArray, NULL); + if (!jMiddleArr) return nullptr; + for (jsize i = 0; i < lenMiddle; ++i) + { + jsize lenInner = static_cast(val[k][i].size()); + jobjectArray strArr = env->NewObjectArray(lenInner, g_cls_String, NULL); + if (!strArr) return nullptr; + for (jsize j = 0; j < lenInner; ++j) + { + jstring jString = env->NewStringUTF(val[k][i][j].c_str()); + env->SetObjectArrayElement(strArr, j, jString); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jString); + } + env->SetObjectArrayElement(jMiddleArr, i, strArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(strArr); + } + env->SetObjectArrayElement(jOuterArr, k, jMiddleArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jMiddleArr); + } + return jOuterArr; + } + + jobject operator()(const std::vector>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_OcRepresentation1DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize i = 0; i < lenOuter; ++i) + { + jsize lenInner = static_cast(val[i].size()); + jobjectArray repArr = env->NewObjectArray(lenInner, g_cls_OcRepresentation, NULL); + if (!repArr) return nullptr; + for (jsize j = 0; j < lenInner; ++j) + { + OCRepresentation* rep = new OCRepresentation(val[i][j]); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + return nullptr; + } + env->SetObjectArrayElement(repArr, j, jRepresentation); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jRepresentation); + } + env->SetObjectArrayElement(jOuterArr, i, repArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(repArr); + } + return jOuterArr; + } + jobject operator()(const std::vector>>& val) const + { + jsize lenOuter = static_cast(val.size()); + jobjectArray jOuterArr = env->NewObjectArray(lenOuter, g_cls_OcRepresentation2DArray, NULL); + if (!jOuterArr) return nullptr; + for (jsize k = 0; k < lenOuter; ++k) + { + jsize lenMiddle = static_cast(val[k].size()); + jobjectArray jMiddleArr = env->NewObjectArray(lenMiddle, g_cls_OcRepresentation1DArray, NULL); + if (!jMiddleArr) return nullptr; + for (jsize i = 0; i < lenMiddle; ++i) + { + jsize lenInner = static_cast(val[k][i].size()); + jobjectArray repArr = env->NewObjectArray(lenInner, g_cls_OcRepresentation, NULL); + if (!repArr) return nullptr; + for (jsize j = 0; j < lenInner; ++j) + { + OCRepresentation* rep = new OCRepresentation(val[k][i][j]); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + return nullptr; + } + env->SetObjectArrayElement(repArr, j, jRepresentation); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jRepresentation); + } + env->SetObjectArrayElement(jMiddleArr, i, repArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(repArr); + } + env->SetObjectArrayElement(jOuterArr, k, jMiddleArr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jMiddleArr); + } + return jOuterArr; + } + +private: + JNIEnv *env; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getValueN + * Signature: (Ljava/lang/String;)Ljava/lang/Object; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getValueN + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueInteger + * Signature: (Ljava/lang/String;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger + (JNIEnv *, jobject, jstring, jint); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueDouble + * Signature: (Ljava/lang/String;D)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble + (JNIEnv *, jobject, jstring, jdouble); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueBoolean + * Signature: (Ljava/lang/String;Z)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean + (JNIEnv *, jobject, jstring, jboolean); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueStringN + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueStringN + (JNIEnv *, jobject, jstring, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueRepresentation + * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation + (JNIEnv *, jobject, jstring, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueIntegerArray + * Signature: (Ljava/lang/String;[I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueIntegerArray + (JNIEnv *, jobject, jstring, jintArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueInteger2DArray + * Signature: (Ljava/lang/String;[[I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger2DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueInteger3DArray + * Signature: (Ljava/lang/String;[[[I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueInteger3DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueDoubleArray + * Signature: (Ljava/lang/String;[D)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDoubleArray + (JNIEnv *, jobject, jstring, jdoubleArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueDouble2DArray + * Signature: (Ljava/lang/String;[[D)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble2DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueDouble3DArray + * Signature: (Ljava/lang/String;[[[D)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueDouble3DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueBooleanArray + * Signature: (Ljava/lang/String;[Z)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBooleanArray + (JNIEnv *, jobject, jstring, jbooleanArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueBoolean2DArray + * Signature: (Ljava/lang/String;[[Z)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean2DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueBoolean3DArray + * Signature: (Ljava/lang/String;[[[Z)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueBoolean3DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueStringArray + * Signature: (Ljava/lang/String;[Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueStringArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueString2DArray + * Signature: (Ljava/lang/String;[[Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueString2DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueString3DArray + * Signature: (Ljava/lang/String;[[[Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueString3DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueRepresentationArray + * Signature: (Ljava/lang/String;[Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentationArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueRepresentation2DArray + * Signature: (Ljava/lang/String;[[Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation2DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setValueRepresentation3DArray + * Signature: (Ljava/lang/String;[[[Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setValueRepresentation3DArray + (JNIEnv *, jobject, jstring, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getJSONRepresentation + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getJSONRepresentation + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: addChild + * Signature: (Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_addChild + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: clearChildren + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_clearChildren + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getChildrenArray + * Signature: ()[Lorg/iotivity/base/OcRepresentation; + */ + JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcRepresentation_getChildrenArray + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getUri + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcRepresentation_getUri + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setUri + * Signature: (Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setUri + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getResourceTypes + * Signature: ()Ljava/util/List; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getResourceTypes + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setResourceTypeArray + * Signature: ([Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setResourceTypeArray + (JNIEnv *, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: getResourceInterfaces + * Signature: ()Ljava/util/List; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcRepresentation_getResourceInterfaces + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setResourceInterfaceArray + * Signature: ([Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setResourceInterfaceArray + (JNIEnv *, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: isEmpty + * Signature: ()Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_isEmpty + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: size + * Signature: ()I + */ + JNIEXPORT jint JNICALL Java_org_iotivity_base_OcRepresentation_size + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: remove + * Signature: (Ljava/lang/String;)Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_remove + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: hasAttribute + * Signature: (Ljava/lang/String;)Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_hasAttribute + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: setNull + * Signature: (Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_setNull + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: isNull + * Signature: (Ljava/lang/String;)Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcRepresentation_isNull + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: create + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_create + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcRepresentation + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRepresentation_dispose + (JNIEnv *, jobject, jboolean); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcRequestHandle.cpp b/android/android_api/base/jni/JniOcRequestHandle.cpp new file mode 100644 index 0000000..444689d --- /dev/null +++ b/android/android_api/base/jni/JniOcRequestHandle.cpp @@ -0,0 +1,63 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcRequestHandle.h" + +JniOcRequestHandle::JniOcRequestHandle(OCRequestHandle requestHandle) : m_requestHandle(requestHandle) +{} + +JniOcRequestHandle::~JniOcRequestHandle() +{ + LOGD("~JniOcRequestHandle()"); +} + +JniOcRequestHandle* JniOcRequestHandle::getJniOcRequestHandlePtr +(JNIEnv *env, jobject thiz) +{ + JniOcRequestHandle *handle = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcRequestHandle"); + } + if (!handle) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return handle; +} + +OCRequestHandle JniOcRequestHandle::getOCRequestHandle() +{ + return this->m_requestHandle; +} + +/* +* Class: org_iotivity_base_OcRequestHandle +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcRequestHandle_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcRequestHandle_dispose"); + JniOcRequestHandle *handle = JniOcRequestHandle::getJniOcRequestHandlePtr(env, thiz); + delete handle; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcRequestHandle.h b/android/android_api/base/jni/JniOcRequestHandle.h new file mode 100644 index 0000000..2160728 --- /dev/null +++ b/android/android_api/base/jni/JniOcRequestHandle.h @@ -0,0 +1,58 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "ocstack.h" + +#ifndef _Included_org_iotivity_base_OcRequestHandle +#define _Included_org_iotivity_base_OcRequestHandle + +class JniOcRequestHandle +{ +public: + + JniOcRequestHandle(OCRequestHandle request); + ~JniOcRequestHandle(); + + static JniOcRequestHandle* getJniOcRequestHandlePtr(JNIEnv *env, jobject thiz); + + OCRequestHandle getOCRequestHandle(); + +private: + OCRequestHandle m_requestHandle; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcRequestHandle + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcRequestHandle_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/android/android_api/base/jni/JniOcResource.cpp b/android/android_api/base/jni/JniOcResource.cpp new file mode 100644 index 0000000..2850d65 --- /dev/null +++ b/android/android_api/base/jni/JniOcResource.cpp @@ -0,0 +1,1520 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOcResource.h" +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +JniOcResource::JniOcResource(std::shared_ptr resource) + : m_sharedResource(resource) +{} + +JniOcResource::~JniOcResource() +{ + LOGD("~JniOcResource()"); + m_sharedResource = NULL; + + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + m_onGetManager.removeAllListeners(env); + m_onPutManager.removeAllListeners(env); + m_onPostManager.removeAllListeners(env); + m_onDeleteManager.removeAllListeners(env); + m_onObserveManager.removeAllListeners(env); + + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + + GetCallback getCallback = [onGetListener]( + const HeaderOptions& opts, + const OCRepresentation& rep, + const int eCode) + { + onGetListener->onGetCallback(opts, rep, eCode); + }; + + return m_sharedResource->get(queryParametersMap, getCallback); +} + +OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, + QualityOfService QoS) +{ + JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + + GetCallback getCallback = [onGetListener](const HeaderOptions& opts, const OCRepresentation& rep, + const int eCode) + { + onGetListener->onGetCallback(opts, rep, eCode); + }; + + return m_sharedResource->get(queryParametersMap, getCallback, QoS); +} + +OCStackResult JniOcResource::get( + JNIEnv* env, + const std::string &resourceType, + const std::string &resourceInterface, + const QueryParamsMap &queryParametersMap, + jobject jListener) +{ + JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + + GetCallback getCallback = [onGetListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onGetListener->onGetCallback(opts, rep, eCode); + }; + + return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, + getCallback); +} + +OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType, + const std::string &resourceInterface, const QueryParamsMap &queryParametersMap, + jobject jListener, QualityOfService QoS) +{ + JniOnGetListener *onGetListener = addOnGetListener(env, jListener); + + GetCallback getCallback = [onGetListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onGetListener->onGetCallback(opts, rep, eCode); + }; + + return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap, + getCallback, QoS); +} + +OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + + PutCallback putCallback = [onPutListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPutListener->onPutCallback(opts, rep, eCode); + }; + + return m_sharedResource->put(representation, queryParametersMap, putCallback); +} + +OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) +{ + JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + + PutCallback putCallback = [onPutListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPutListener->onPutCallback(opts, rep, eCode); + }; + + return m_sharedResource->put(representation, queryParametersMap, putCallback, QoS); +} + +OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType, + const std::string &resourceInterface, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + + PutCallback putCallback = [onPutListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPutListener->onPutCallback(opts, rep, eCode); + }; + + return m_sharedResource->put(resourceType, resourceInterface, representation, + queryParametersMap, putCallback); +} + +OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType, + const std::string &resourceInterface, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) +{ + JniOnPutListener *onPutListener = addOnPutListener(env, jListener); + + PutCallback putCallback = [onPutListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPutListener->onPutCallback(opts, rep, eCode); + }; + + return m_sharedResource->put(resourceType, resourceInterface, representation, + queryParametersMap, putCallback, QoS); +} + +OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + + PostCallback postCallback = [onPostListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPostListener->onPostCallback(opts, rep, eCode); + }; + + return m_sharedResource->post(representation, queryParametersMap, postCallback); +} + +OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) +{ + JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + + PostCallback postCallback = [onPostListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPostListener->onPostCallback(opts, rep, eCode); + }; + + return m_sharedResource->post(representation, queryParametersMap, postCallback, QoS); +} + +OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType, + const std::string &resourceInterface, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + + PostCallback postCallback = [onPostListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPostListener->onPostCallback(opts, rep, eCode); + }; + + return m_sharedResource->post(resourceType, resourceInterface, representation, + queryParametersMap, postCallback); +} + +OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType, + const std::string &resourceInterface, const OCRepresentation &representation, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) +{ + JniOnPostListener *onPostListener = addOnPostListener(env, jListener); + + PostCallback postCallback = [onPostListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int eCode) + { + onPostListener->onPostCallback(opts, rep, eCode); + }; + + return m_sharedResource->post(resourceType, resourceInterface, representation, + queryParametersMap, postCallback, QoS); +} + +OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener) +{ + JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + + DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, + const int eCode) + { + onDeleteListener->onDeleteCallback(opts, eCode); + }; + + return m_sharedResource->deleteResource(deleteCallback); +} + +OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS) +{ + JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener); + + DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, const int eCode) + { + onDeleteListener->onDeleteCallback(opts, eCode); + }; + + return m_sharedResource->deleteResource(deleteCallback, QoS); +} + +OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType, + const QueryParamsMap &queryParametersMap, jobject jListener) +{ + JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + + ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + { + onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); + }; + + return m_sharedResource->observe(observeType, queryParametersMap, observeCallback); +} + +OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS) +{ + JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener); + + ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts, + const OCRepresentation& rep, const int& eCode, const int& sequenceNumber) + { + onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber); + }; + + return m_sharedResource->observe(observeType, queryParametersMap, observeCallback, QoS); +} + +OCStackResult JniOcResource::cancelObserve(JNIEnv* env) +{ + this->m_onObserveManager.removeAllListeners(env); + return m_sharedResource->cancelObserve(); +} + +OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos) +{ + //TODO confirm behavior + //add removal of java listeners by qos + this->m_onObserveManager.removeAllListeners(env); + return m_sharedResource->cancelObserve(qos); +} + +void JniOcResource::setHeaderOptions(const HeaderOptions &headerOptions) +{ + m_sharedResource->setHeaderOptions(headerOptions); +} + +void JniOcResource::unsetHeaderOptions() +{ + m_sharedResource->unsetHeaderOptions(); +} + +std::string JniOcResource::host() +{ + return m_sharedResource->host(); +} + +std::string JniOcResource::uri() +{ + return m_sharedResource->uri(); +} + +OCConnectivityType JniOcResource::connectivityType() const +{ + return m_sharedResource->connectivityType(); +} + +bool JniOcResource::isObservable() +{ + return m_sharedResource->isObservable(); +} + +std::vector< std::string > JniOcResource::getResourceTypes() const +{ + return m_sharedResource->getResourceTypes(); +} + +std::vector< std::string > JniOcResource::getResourceInterfaces(void) const +{ + return m_sharedResource->getResourceInterfaces(); +} + +OCResourceIdentifier JniOcResource::uniqueIdentifier() const +{ + return m_sharedResource->uniqueIdentifier(); +} + +std::string JniOcResource::sid() const +{ + return m_sharedResource->sid(); +} + +JniOnGetListener* JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener) +{ + return this->m_onGetManager.addListener(env, jListener, this); +} + +JniOnPutListener* JniOcResource::addOnPutListener(JNIEnv* env, jobject jListener) +{ + return this->m_onPutManager.addListener(env, jListener, this); +} + +JniOnPostListener* JniOcResource::addOnPostListener(JNIEnv* env, jobject jListener) +{ + return this->m_onPostManager.addListener(env, jListener, this); +} + +JniOnDeleteListener* JniOcResource::addOnDeleteListener(JNIEnv* env, jobject jListener) +{ + return this->m_onDeleteManager.addListener(env, jListener, this); +} + +JniOnObserveListener* JniOcResource::addOnObserveListener(JNIEnv* env, jobject jListener) +{ + return this->m_onObserveManager.addListener(env, jListener, this); +} + +void JniOcResource::removeOnGetListener(JNIEnv* env, jobject jListener) +{ + this->m_onGetManager.removeListener(env, jListener); +} + +void JniOcResource::removeOnPutListener(JNIEnv* env, jobject jListener) +{ + this->m_onPutManager.removeListener(env, jListener); +} + +void JniOcResource::removeOnPostListener(JNIEnv* env, jobject jListener) +{ + this->m_onPostManager.removeListener(env, jListener); +} + +void JniOcResource::removeOnDeleteListener(JNIEnv* env, jobject jListener) +{ + this->m_onDeleteManager.removeListener(env, jListener); +} + +void JniOcResource::removeOnObserveListener(JNIEnv* env, jobject jListener) +{ + this->m_onObserveManager.removeListener(env, jListener); +} + +std::shared_ptr JniOcResource::getOCResource() +{ + return this->m_sharedResource; +} + +JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz) +{ + JniOcResource *resource = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcResource"); + } + if (!resource) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return resource; +} + +/* +* Class: org_iotivity_base_OcResource +* Method: get +* Signature: (Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get +(JNIEnv *env, jobject thiz, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_get"); + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onGetListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->get( + env, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_get"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: get1 +* Signature: (Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get1 +(JNIEnv *env, jobject thiz, jobject jQueryParamsMap, jobject jListener, jint jQoS) +{ + LOGD("OcResource_get"); + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onGetListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->get( + env, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_get"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: get2 +* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnGetListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get2 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, +jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_get"); + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onGetListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + try + { + OCStackResult result = resource->get( + env, + resourceType, + resourceInterface, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_get"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: get3 +* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnGetListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get3 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, +jobject jQueryParamsMap, jobject jListener, jint jQoS) +{ + LOGD("OcResource_get"); + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onGetListener cannot be null"); + return; + } + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->get( + env, + resourceType, + resourceInterface, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_get"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: put +* Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnPutListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put +(JNIEnv *env, jobject thiz, jobject jRepresentation, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_put"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPutListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->put( + env, + *representation, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_put"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: put1 +* Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnPutListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put1 +(JNIEnv *env, jobject thiz, jobject jRepresentation, jobject jQueryParamsMap, +jobject jListener, jint jQoS) +{ + LOGD("OcResource_put"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPutListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->put( + env, + *representation, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_put"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: put2 +* Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation; +Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put2 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, +jobject jRepresentation, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_put"); + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPutListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->put( + env, + resourceType, + resourceInterface, + *representation, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_put"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: put3 +* Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation; +Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put3 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, jobject jRepresentation, +jobject jQueryParamsMap, jobject jListener, jint jQoS) +{ + LOGD("OcResource_put"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "representation cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPutListener cannot be null"); + return; + } + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->put( + env, + resourceType, + resourceInterface, + *representation, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_put"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: post +* Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post +(JNIEnv *env, jobject thiz, jobject jRepresentation, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_post"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "representation cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPostListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->post( + env, + *representation, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_post"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: post1 +* Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post1 +(JNIEnv *env, jobject thiz, jobject jRepresentation, jobject jQueryParamsMap, jobject jListener, jint jQoS) +{ + LOGD("OcResource_post"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "representation cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPostListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->post( + env, + *representation, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_post"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: post2 +* Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation; +Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post2 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, +jobject jRepresentation, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_post"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "representation cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPostListener cannot be null"); + return; + } + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->post( + env, + resourceType, + resourceInterface, + *representation, + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_post"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: post3 +* Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation; +Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post3 +(JNIEnv *env, jobject thiz, jstring jResourceType, jstring jResourceInterface, +jobject jRepresentation, jobject jQueryParamsMap, jobject jListener, jint jQoS) +{ + LOGD("OcResource_post"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "representation cannot be null"); + return; + } + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onPostListener cannot be null"); + return; + } + std::string resourceType; + if (jResourceType) + { + resourceType = env->GetStringUTFChars(jResourceType, NULL); + } + std::string resourceInterface; + if (jResourceInterface) + { + resourceInterface = env->GetStringUTFChars(jResourceInterface, NULL); + } + + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, jRepresentation); + if (!representation) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->post( + env, + resourceType, + resourceInterface, + *representation, + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_post"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: deleteResource +* Signature: (Lorg/iotivity/base/OcResource/OnDeleteListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_deleteResource +(JNIEnv *env, jobject thiz, jobject jListener) +{ + LOGD("OcResource_deleteResource"); + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onDeleteListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + try + { + OCStackResult result = resource->deleteResource( + env, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_deleteResource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: deleteResource1 +* Signature: (Lorg/iotivity/base/OcResource/OnDeleteListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_deleteResource1 +(JNIEnv *env, jobject thiz, jobject jListener, jint jQoS) +{ + LOGD("OcResource_deleteResource"); + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onDeleteListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + try + { + OCStackResult result = resource->deleteResource( + env, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_deleteResource"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: observe +* Signature: (Lorg/iotivity/base/ObserveType;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnObserveListener;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_observe +(JNIEnv *env, jobject thiz, jint observeType, jobject jQueryParamsMap, jobject jListener) +{ + LOGD("OcResource_observe"); + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onObserveListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->observe( + env, + JniUtils::getObserveType(env, static_cast(observeType)), + qpm, + jListener); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_observe"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: observe1 +* Signature: (Lorg/iotivity/base/ObserveType;Ljava/util/Map; +Lorg/iotivity/base/OcResource/OnObserveListener;I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_observe1 +(JNIEnv *env, jobject thiz, jint observeType, jobject jQueryParamsMap, +jobject jListener, jint jQoS) +{ + LOGD("OcResource_observe"); + if (!jQueryParamsMap) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "queryParamsMap cannot be null"); + return; + } + if (!jListener) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "onObserveListener cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + QueryParamsMap qpm; + JniUtils::convertJavaMapToQueryParamsMap(env, jQueryParamsMap, qpm); + + try + { + OCStackResult result = resource->observe( + env, + JniUtils::getObserveType(env, static_cast(observeType)), + qpm, + jListener, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_observe"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: cancelObserve +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_cancelObserve +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_cancelObserve"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + try + { + OCStackResult result = resource->cancelObserve(env); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_cancelObserve"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: cancelObserve1 +* Signature: I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_cancelObserve1 +(JNIEnv *env, jobject thiz, jint jQoS) +{ + LOGD("OcResource_cancelObserve1"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + try + { + OCStackResult result = resource->cancelObserve( + env, + JniUtils::getQOS(env, static_cast(jQoS))); + + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OcResource_cancelObserve"); + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(e.code(), e.reason().c_str()); + } +} + +/* +* Class: org_iotivity_base_OcResource +* Method: setHeaderOptions +* Signature: ([Lorg/iotivity/OcHeaderOption;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_setHeaderOptions +(JNIEnv *env, jobject thiz, jobjectArray jheaderOptionArr) +{ + LOGD("OcResource_setHeaderOptions"); + if (!jheaderOptionArr) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "headerOptionList cannot be null"); + return; + } + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + HeaderOptions headerOptions; + JniUtils::convertJavaHeaderOptionsArrToVector(env, jheaderOptionArr, headerOptions); + + resource->setHeaderOptions(headerOptions); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: unsetHeaderOptions +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_unsetHeaderOptions +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_unsetHeaderOptions"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return; + + resource->unsetHeaderOptions(); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getHost +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getHost +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getHost"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + return env->NewStringUTF(resource->host().c_str()); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getUri +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getUri +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getUri"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + return env->NewStringUTF(resource->uri().c_str()); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getConnectivityTypeN +* Signature: ()I +*/ +JNIEXPORT jint JNICALL Java_org_iotivity_base_OcResource_getConnectivityTypeN +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getConnectivityType"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return -1; + + OCConnectivityType connectivityType = resource->connectivityType(); + return static_cast(connectivityType); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: isObservable +* Signature: ()Z +*/ +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcResource_isObservable +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_isObservable"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + return (jboolean)resource->isObservable(); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getResourceTypes +* Signature: ()Ljava/util/List; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getResourceTypes +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getResourceTypes"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + std::vector resourceTypes = resource->getResourceTypes(); + + return JniUtils::convertStrVectorToJavaStrList(env, resourceTypes); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getResourceInterfaces +* Signature: ()Ljava/util/List; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getResourceInterfaces +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getResourceInterfaces"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + std::vector resourceInterfaces = resource->getResourceInterfaces(); + + return JniUtils::convertStrVectorToJavaStrList(env, resourceInterfaces); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getUniqueIdentifier +* Signature: ()Lorg/iotivity/base/OcResourceIdentifier; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getUniqueIdentifier +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getUniqueIdentifier"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + JniOcResourceIdentifier *jniResourceIdentifier = + new JniOcResourceIdentifier(resource->uniqueIdentifier()); + if (!jniResourceIdentifier) return nullptr; + + jlong handle = reinterpret_cast(jniResourceIdentifier); + jobject jResourceIdentifier = env->NewObject(g_cls_OcResourceIdentifier, + g_mid_OcResourceIdentifier_N_ctor, handle); + if (!jResourceIdentifier) + { + delete jniResourceIdentifier; + } + return jResourceIdentifier; +} + +/* +* Class: org_iotivity_base_OcResource +* Method: getServerId +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getServerId +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_getServerId"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + if (!resource) return nullptr; + + return env->NewStringUTF(resource->sid().c_str()); +} + +/* +* Class: org_iotivity_base_OcResource +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResource_dispose"); + JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz); + delete resource; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResource.h b/android/android_api/base/jni/JniOcResource.h new file mode 100644 index 0000000..737dd5f --- /dev/null +++ b/android/android_api/base/jni/JniOcResource.h @@ -0,0 +1,359 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOcStack.h" +#include "OCResource.h" +#include "JniListenerManager.h" +#include "JniOnGetListener.h" +#include "JniOnPutListener.h" +#include "JniOnPostListener.h" +#include "JniOnDeleteListener.h" +#include "JniOnObserveListener.h" +#include "JniOcResourceIdentifier.h" + +#ifndef _Included_org_iotivity_base_OcResource +#define _Included_org_iotivity_base_OcResource + +using namespace OC; + +class JniOcResource +{ +public: + JniOcResource(std::shared_ptr resource); + ~JniOcResource(); + + OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener); + OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener, + QualityOfService QoS); + OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const QueryParamsMap &queryParametersMap, jobject jListener); + OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS); + + OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, + jobject jListener); + OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, + jobject jListener, QualityOfService QoS); + OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener); + OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS); + + OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, + jobject jListener); + OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, + jobject jListener, QualityOfService QoS); + OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener); + OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface, + const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS); + + OCStackResult deleteResource(JNIEnv* env, jobject jListener); + OCStackResult deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS); + + OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap, + jobject jListener); + OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap, + jobject jListener, QualityOfService qos); + + OCStackResult cancelObserve(JNIEnv* env); + OCStackResult cancelObserve(JNIEnv* env, QualityOfService qos); + + void setHeaderOptions(const HeaderOptions &headerOptions); + void unsetHeaderOptions(); + std::string host(); + std::string uri(); + OCConnectivityType connectivityType() const; + bool isObservable(); + std::vector< std::string > getResourceTypes() const; + std::vector< std::string > getResourceInterfaces(void) const; + OCResourceIdentifier uniqueIdentifier() const; + std::string sid() const; + + JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener); + JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener); + JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener); + JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener); + JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener); + + void removeOnGetListener(JNIEnv* env, jobject jListener); + void removeOnPutListener(JNIEnv* env, jobject jListener); + void removeOnPostListener(JNIEnv* env, jobject jListener); + void removeOnDeleteListener(JNIEnv* env, jobject jListener); + void removeOnObserveListener(JNIEnv* env, jobject jListener); + + std::shared_ptr getOCResource(); + + static JniOcResource* getJniOcResourcePtr(JNIEnv *env, jobject thiz); + +private: + JniListenerManager m_onGetManager; + JniListenerManager m_onPutManager; + JniListenerManager m_onPostManager; + JniListenerManager m_onDeleteManager; + JniListenerManager m_onObserveManager; + + std::shared_ptr m_sharedResource; +}; + +/* DO NOT EDIT THIS FILE BEYOND THIS LINE - it is machine generated */ + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcResource + * Method: get + * Signature: (Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get + (JNIEnv *, jobject, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: get1 + * Signature: (Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get1 + (JNIEnv *, jobject, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: get2 + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get2 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: get3 + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnGetListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_get3 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: put + * Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put + (JNIEnv *, jobject, jobject, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: put1 + * Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put1 + (JNIEnv *, jobject, jobject, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: put2 + * Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put2 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: put3 + * Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPutListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_put3 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: post + * Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post + (JNIEnv *, jobject, jobject, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: post1 + * Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post1 + (JNIEnv *, jobject, jobject, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: post2 + * Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post2 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: post3 + * Signature: (Ljava/lang/String;Ljava/lang/String;Lorg/iotivity/base/OcRepresentation;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnPostListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_post3 + (JNIEnv *, jobject, jstring, jstring, jobject, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: deleteResource + * Signature: (Lorg/iotivity/base/OcResource/OnDeleteListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_deleteResource + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: deleteResource1 + * Signature: (Lorg/iotivity/base/OcResource/OnDeleteListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_deleteResource1 + (JNIEnv *, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: observe + * Signature: (Lorg/iotivity/base/ObserveType;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnObserveListener;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_observe + (JNIEnv *, jobject, jint, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: observe1 + * Signature: (Lorg/iotivity/base/ObserveType;Ljava/util/Map;Lorg/iotivity/base/OcResource/OnObserveListener;I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_observe1 + (JNIEnv *, jobject, jint, jobject, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: cancelObserve + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_cancelObserve + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: cancelObserve1 + * Signature: (I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_cancelObserve1 + (JNIEnv *, jobject, jint); + + /* + * Class: org_iotivity_base_OcResource + * Method: setHeaderOptions + * Signature: ([Lorg/iotivity/OcHeaderOption;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_setHeaderOptions + (JNIEnv *, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcResource + * Method: unsetHeaderOptions + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_unsetHeaderOptions + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getHost + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getHost + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getUri + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getUri + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getConnectivityTypeN + * Signature: ()I + */ + JNIEXPORT jint JNICALL Java_org_iotivity_base_OcResource_getConnectivityTypeN + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: isObservable + * Signature: ()Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcResource_isObservable + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getResourceTypes + * Signature: ()Ljava/util/List; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getResourceTypes + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getResourceInterfaces + * Signature: ()Ljava/util/List; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getResourceInterfaces + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getUniqueIdentifier + * Signature: ()Lorg/iotivity/base/OcResourceIdentifier; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResource_getUniqueIdentifier + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: getServerId + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getServerId + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResource + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResource_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceHandle.cpp b/android/android_api/base/jni/JniOcResourceHandle.cpp new file mode 100644 index 0000000..84f748e --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceHandle.cpp @@ -0,0 +1,66 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcResourceHandle.h" + +using namespace OC; + +JniOcResourceHandle::JniOcResourceHandle(OCResourceHandle resourceHandle) + : m_resourceHandle(resourceHandle) +{} + +JniOcResourceHandle::~JniOcResourceHandle() +{ + LOGD("~JniOcResourceHandle()"); +} + +JniOcResourceHandle* JniOcResourceHandle::getJniOcResourceHandlePtr +(JNIEnv *env, jobject thiz) +{ + JniOcResourceHandle *handle = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcResourceHandle"); + } + if (!handle) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return handle; +} + +OCResourceHandle JniOcResourceHandle::getOCResourceHandle() +{ + return this->m_resourceHandle; +} + +/* +* Class: org_iotivity_base_OcResourceHandle +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceHandle_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceHandle_dispose"); + JniOcResourceHandle *resourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(env, thiz); + delete resourceHandle; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceHandle.h b/android/android_api/base/jni/JniOcResourceHandle.h new file mode 100644 index 0000000..b8b4e1c --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceHandle.h @@ -0,0 +1,56 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "JniEntityHandler.h" + +#ifndef _Included_org_iotivity_base_OcResourceHandle +#define _Included_org_iotivity_base_OcResourceHandle + +class JniOcResourceHandle +{ +public: + JniOcResourceHandle(OCResourceHandle resourceHandle); + ~JniOcResourceHandle(); + + static JniOcResourceHandle* getJniOcResourceHandlePtr(JNIEnv *env, jobject thiz); + + OCResourceHandle getOCResourceHandle(); +private: + OCResourceHandle m_resourceHandle; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcResourceHandle + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceHandle_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/android/android_api/base/jni/JniOcResourceIdentifier.cpp b/android/android_api/base/jni/JniOcResourceIdentifier.cpp new file mode 100644 index 0000000..59b918c --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceIdentifier.cpp @@ -0,0 +1,89 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOcResourceIdentifier.h" + +JniOcResourceIdentifier::JniOcResourceIdentifier(OC::OCResourceIdentifier resourceIdentifier) + : m_resourceIdentifier(resourceIdentifier) +{} + +JniOcResourceIdentifier::~JniOcResourceIdentifier() +{ + LOGD("~JniOcResourceIdentifier()"); +} + +OC::OCResourceIdentifier JniOcResourceIdentifier::getOCResourceIdentifier() +{ + return this->m_resourceIdentifier; +} + +JniOcResourceIdentifier* JniOcResourceIdentifier::getJniOcResourceIdentifierPtr +(JNIEnv *env, jobject thiz) +{ + JniOcResourceIdentifier *identifier = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcResourceIdentifier"); + } + if (!identifier) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return identifier; +} + +/* +* Class: org_iotivity_base_OcResourceIdentifier +* Method: equalsN +* Signature: (Lorg/iotivity/base/OcResourceIdentifier;)Z +*/ +JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcResourceIdentifier_equalsN +(JNIEnv *env, jobject jThiz, jobject jOther) +{ + JniOcResourceIdentifier *thiz = JniOcResourceIdentifier::getJniOcResourceIdentifierPtr(env, jThiz); + if (!thiz) return false; + + JniOcResourceIdentifier *other = JniOcResourceIdentifier::getJniOcResourceIdentifierPtr(env, jOther); + if (!other) return false; + + if (thiz->getOCResourceIdentifier() == other->getOCResourceIdentifier()) + { + return true; + } + else + { + return false; + } +} + +/* +* Class: org_iotivity_base_OcResourceIdentifier +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceIdentifier_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("JniOcResourceIdentifier_dispose"); + JniOcResourceIdentifier *identifier = JniOcResourceIdentifier::getJniOcResourceIdentifierPtr(env, thiz); + delete identifier; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceIdentifier.h b/android/android_api/base/jni/JniOcResourceIdentifier.h new file mode 100644 index 0000000..9c7651a --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceIdentifier.h @@ -0,0 +1,65 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "OCResource.h" + +#ifndef _Included_org_iotivity_base_OcResourceIdentifier +#define _Included_org_iotivity_base_OcResourceIdentifier + +class JniOcResourceIdentifier +{ +public: + + JniOcResourceIdentifier(OC::OCResourceIdentifier identifier); + ~JniOcResourceIdentifier(); + + static JniOcResourceIdentifier* getJniOcResourceIdentifierPtr(JNIEnv *env, jobject thiz); + + OC::OCResourceIdentifier getOCResourceIdentifier(); + +private: + OC::OCResourceIdentifier m_resourceIdentifier; +}; + +#ifdef __cplusplus +extern "C" { +#endif + /* + * Class: org_iotivity_base_OcResourceIdentifier + * Method: equalsN + * Signature: (Lorg/iotivity/base/OcResourceIdentifier;)Z + */ + JNIEXPORT jboolean JNICALL Java_org_iotivity_base_OcResourceIdentifier_equalsN + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResourceIdentifier + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceIdentifier_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceRequest.cpp b/android/android_api/base/jni/JniOcResourceRequest.cpp new file mode 100644 index 0000000..b1d981c --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceRequest.cpp @@ -0,0 +1,321 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcResourceRequest.h" +#include "OCResourceRequest.h" +#include "JniOcResourceHandle.h" +#include "JniOcRequestHandle.h" +#include "JniUtils.h" + +using namespace OC; + +JniOcResourceRequest::JniOcResourceRequest(const std::shared_ptr request) + : m_request(request) +{} + +JniOcResourceRequest::~JniOcResourceRequest() +{} + +std::string +JniOcResourceRequest::getRequestType() +{ + return m_request->getRequestType(); +} + +const QueryParamsMap& +JniOcResourceRequest::getQueryParameters() const +{ + return m_request->getQueryParameters(); +} + +int +JniOcResourceRequest::getRequestHandlerFlag() const +{ + return m_request->getRequestHandlerFlag(); +} + +const OCRepresentation& +JniOcResourceRequest::getResourceRepresentation() const +{ + return m_request->getResourceRepresentation(); +} + +const ObservationInfo& +JniOcResourceRequest::getObservationInfo() const +{ + return m_request->getObservationInfo(); +} + +void +JniOcResourceRequest::setResourceUri(const std::string resourceUri) +{ + m_request->setResourceUri(resourceUri); +} + +std::string +JniOcResourceRequest::getResourceUri(void) +{ + return m_request->getResourceUri(); +} + +const HeaderOptions& +JniOcResourceRequest::getHeaderOptions() const +{ + return m_request->getHeaderOptions(); +} + +const OCRequestHandle& +JniOcResourceRequest::getRequestHandle() const +{ + return m_request->getRequestHandle(); +} + +const OCResourceHandle& +JniOcResourceRequest::getResourceHandle() const +{ + return m_request->getResourceHandle(); +} + +JniOcResourceRequest* JniOcResourceRequest::getJniOcResourceRequestPtr +(JNIEnv *env, jobject thiz) +{ + JniOcResourceRequest *request = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from OcResourceRequest"); + } + if (!request) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return request; +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getRequestTypeNative +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestTypeNative +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getRequestTypeNative"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + std::string requestType = request->getRequestType(); + return env->NewStringUTF(requestType.c_str()); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getQueryParameters +* Signature: ()Ljava/util/Map; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getQueryParameters +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getQueryParameters"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + return JniUtils::convertQueryParamsMapToJavaMap(env, request->getQueryParameters()); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getRequestHandlerFlagNative +* Signature: ()I +*/ +JNIEXPORT jint JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestHandlerFlagNative +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getRequestHandlerFlagNative"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return -1; + + return static_cast(request->getRequestHandlerFlag()); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getResourceRepresentation +* Signature: ()Lorg/iotivity/base/OcRepresentation; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceRepresentation +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getResourceRepresentation"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + OCRepresentation *ocRepresentation = new OCRepresentation(request->getResourceRepresentation()); + if (!ocRepresentation) return nullptr; + + jlong handle = reinterpret_cast(ocRepresentation); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + LOGE("Failed to create OcRepresentation"); + delete ocRepresentation; + } + + return jRepresentation; +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getObservationInfo +* Signature: ()Lorg/iotivity/base/ObservationInfo; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getObservationInfo +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getObservationInfo"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + ObservationInfo oInfo = request->getObservationInfo(); + + jobject jObservationInfo = env->NewObject(g_cls_ObservationInfo, g_mid_ObservationInfo_N_ctor, + (jint)oInfo.action, (jbyte)oInfo.obsId); + + if (!jObservationInfo) + { + LOGE("Failed to create ObservationInfo"); + } + + return jObservationInfo; +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: setResourceUri +* Signature: (Ljava/lang/String); +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceRequest_setResourceUri +(JNIEnv *env, jobject thiz, jstring jUri) +{ + LOGD("OcResourceRequest_setResourceUri"); + if (!jUri) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "URI cannot be null"); + return; + } + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return; + + request->setResourceUri(env->GetStringUTFChars(jUri, 0)); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getResourceUri +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceUri +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getResourceUri"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + std::string requestUri = request->getResourceUri(); + return env->NewStringUTF(requestUri.c_str()); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getHeaderOptions +* Signature: ()Ljava/util/List; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getHeaderOptions +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getHeaderOptions"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + return JniUtils::convertHeaderOptionsVectorToJavaList(env, request->getHeaderOptions()); +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getRequestHandle +* Signature: ()Lorg/iotivity/base/OcRequestHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestHandle +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getRequestHandle"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + JniOcRequestHandle* jniHandle = new JniOcRequestHandle(request->getRequestHandle()); + jlong handle = reinterpret_cast(jniHandle); + jobject jRequestHandle = env->NewObject(g_cls_OcRequestHandle, g_mid_OcRequestHandle_N_ctor, handle); + if (!jRequestHandle) + { + LOGE("Failed to create OcRequestHandle"); + delete jniHandle; + } + + return jRequestHandle; +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: getResourceHandle +* Signature: ()Lorg/iotivity/base/OcResourceHandle; +*/ +JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceHandle +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_getResourceHandle"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + if (!request) return nullptr; + + JniOcResourceHandle* jniHandle = new JniOcResourceHandle( + request->getResourceHandle()); + jlong handle = reinterpret_cast(jniHandle); + jobject jResourceHandle = env->NewObject(g_cls_OcResourceHandle, g_mid_OcResourceHandle_N_ctor, handle); + if (!jResourceHandle) + { + LOGE("Failed to create OcResourceHandle"); + delete jniHandle; + } + + return jResourceHandle; +} + +/* +* Class: org_iotivity_base_OcResourceRequest +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceRequest_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceRequest_dispose"); + JniOcResourceRequest *request = JniOcResourceRequest::getJniOcResourceRequestPtr(env, thiz); + delete request; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceRequest.h b/android/android_api/base/jni/JniOcResourceRequest.h new file mode 100644 index 0000000..5b58f0c --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceRequest.h @@ -0,0 +1,158 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResourceRequest +#define _Included_org_iotivity_base_OcResourceRequest + +using namespace OC; + +class JniOcResourceRequest +{ +public: + JniOcResourceRequest(const std::shared_ptr resourceRequest); + + ~JniOcResourceRequest(); + + std::string getRequestType(); + + const QueryParamsMap& getQueryParameters() const; + + int getRequestHandlerFlag() const; + + const OCRepresentation& getResourceRepresentation() const; + + const ObservationInfo& getObservationInfo() const; + + void setResourceUri(const std::string resourceUri); + + std::string getResourceUri(void); + + const HeaderOptions& getHeaderOptions() const; + + const OCRequestHandle& getRequestHandle() const; + + const OCResourceHandle& getResourceHandle() const; + + static JniOcResourceRequest* getJniOcResourceRequestPtr + (JNIEnv *env, jobject thiz); + +private: + std::shared_ptr m_request; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getRequestTypeNative + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestTypeNative + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getQueryParameters + * Signature: ()Ljava/util/Map; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getQueryParameters + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getRequestHandlerFlagNative + * Signature: ()I + */ + JNIEXPORT jint JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestHandlerFlagNative + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getResourceRepresentation + * Signature: ()Lorg/iotivity/base/OcRepresentation; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceRepresentation + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getObservationInfo + * Signature: ()Lorg/iotivity/base/ObservationInfo; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getObservationInfo + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: setResourceUri + * Signature: (Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceRequest_setResourceUri + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getResourceUri + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceUri + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getHeaderOptions + * Signature: ()Ljava/util/List; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getHeaderOptions + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getRequestHandle + * Signature: ()Lorg/iotivity/base/OcRequestHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getRequestHandle + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: getResourceHandle + * Signature: ()Lorg/iotivity/base/OcResourceHandle; + */ + JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcResourceRequest_getResourceHandle + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceRequest + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceRequest_dispose + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceResponse.cpp b/android/android_api/base/jni/JniOcResourceResponse.cpp new file mode 100644 index 0000000..f8771c3 --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceResponse.cpp @@ -0,0 +1,320 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcResourceResponse.h" +#include "OCResourceResponse.h" +#include "JniOcRepresentation.h" +#include "JniOcRequestHandle.h" +#include "JniOcResourceHandle.h" +#include "JniUtils.h" + +using namespace OC; + +JniOcResourceResponse::JniOcResourceResponse +(std::shared_ptr resourceResponse) +: m_response(resourceResponse){} + +JniOcResourceResponse::~JniOcResourceResponse() +{} + +void JniOcResourceResponse::setErrorCode(const int eCode) +{ + this->m_response->setErrorCode(eCode); +} + +std::string JniOcResourceResponse::getNewResourceUri(void) +{ + this->m_response->getNewResourceUri(); +} + +void +JniOcResourceResponse::setNewResourceUri(const std::string newResourceUri) +{ + this->m_response->setNewResourceUri(newResourceUri); +} + +void JniOcResourceResponse::setHeaderOptions(const HeaderOptions& headerOptions) +{ + this->m_response->setHeaderOptions(headerOptions); +} + +void JniOcResourceResponse::setRequestHandle(const OCRequestHandle& requestHandle) +{ + this->m_response->setRequestHandle(requestHandle); +} + +void JniOcResourceResponse::setResourceHandle(const OCResourceHandle& resourceHandle) +{ + this->m_response->setResourceHandle(resourceHandle); +} + +void JniOcResourceResponse::setResponseResult(const OCEntityHandlerResult& responseResult) +{ + this->m_response->setResponseResult(responseResult); +} + +void JniOcResourceResponse::setResourceRepresentation(OCRepresentation& rep, + std::string interfaceStr) +{ + this->m_response->setResourceRepresentation(rep, interfaceStr); +} + +void JniOcResourceResponse::setResourceRepresentation(OCRepresentation& rep) +{ + this->m_response->setResourceRepresentation(rep); +} + +std::shared_ptr JniOcResourceResponse::getOCResourceResponse() +{ + return this->m_response; +} + +JniOcResourceResponse* JniOcResourceResponse::getJniOcResourceResponsePtr +(JNIEnv *env, jobject thiz) +{ + JniOcResourceResponse *request = GetHandle(env, thiz); + if (env->ExceptionCheck()) + { + LOGE("Failed to get native handle from JniOcResourceResponse"); + } + if (!request) + { + ThrowOcException(JNI_NO_NATIVE_POINTER, ""); + } + return request; +} +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setErrorCode +* Signature: (I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setErrorCode +(JNIEnv *env, jobject thiz, jint eCode) +{ + LOGD("OcResourceResponse_setErrorCode"); + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!response) return; + + response->setErrorCode(static_cast(eCode)); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: getNewResourceUri +* Signature: ()Ljava/lang/String; +*/ +JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceResponse_getNewResourceUri +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceResponse_getNewResourceUri"); + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!response) return nullptr; + + return env->NewStringUTF(response->getNewResourceUri().c_str()); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setNewResourceUri +* Signature: (Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setNewResourceUri +(JNIEnv *env, jobject thiz, jstring jstr) +{ + LOGD("OcResourceResponse_setNewResourceUri"); + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!response) return; + + response->setNewResourceUri(env->GetStringUTFChars(jstr, 0)); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setHeaderOptions +* Signature: (Ljava/util/List;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setHeaderOptions +(JNIEnv *env, jobject thiz, jobjectArray jHeaderOptions) +{ + LOGD("OcResourceResponse_setHeaderOptions"); + if (!jHeaderOptions) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "headerOptionList cannot be null"); + return; + } + JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!jniResponse) return; + + HeaderOptions headerOptions; + JniUtils::convertJavaHeaderOptionsArrToVector(env, jHeaderOptions, headerOptions); + + jniResponse->setHeaderOptions(headerOptions); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setRequestHandle +* Signature: (Lorg/iotivity/base/OcRequestHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setRequestHandle +(JNIEnv *env, jobject thiz, jobject jRequestHandle) +{ + LOGI("OcResourceResponse_setRequestHandle"); + if (!jRequestHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "requestHandle cannot be null"); + return; + } + JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!jniResponse) return; + + JniOcRequestHandle* jniOcRequestHandle = JniOcRequestHandle::getJniOcRequestHandlePtr(env, jRequestHandle); + if (!jniOcRequestHandle) return; + + jniResponse->setRequestHandle(jniOcRequestHandle->getOCRequestHandle()); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setResourceHandle +* Signature: (Lorg/iotivity/base/OcResourceHandle;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceHandle +(JNIEnv *env, jobject thiz, jobject jResourceHandle) +{ + LOGI("OcResourceResponse_setResourceHandle"); + if (!jResourceHandle) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "resourceHandle cannot be null"); + return; + } + JniOcResourceResponse *jniResponse = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!jniResponse) return; + + JniOcResourceHandle* jniOcResourceHandle = JniOcResourceHandle::getJniOcResourceHandlePtr(env, jResourceHandle); + if (!jniOcResourceHandle) return; + + jniResponse->setResourceHandle(jniOcResourceHandle->getOCResourceHandle()); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setResponseResult +* Signature: (I)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResponseResult +(JNIEnv *env, jobject thiz, jint responseResult) +{ + LOGD("OcResourceResponse_setResponseResult"); + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!response) return; + + response->setResponseResult(JniUtils::getOCEntityHandlerResult(env, static_cast(responseResult))); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setResourceRepresentation +* Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/lang/String;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceRepresentation +(JNIEnv *env, jobject thiz, jobject jRepresentation, jstring jstr) +{ + LOGD("OcResourceResponse_setResourceRepresentation"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "Representation cannot be null"); + return; + } + if (!jstr) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "interface cannot be null"); + return; + } + + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, + thiz); + if (!response) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, + jRepresentation); + if (!representation) return; + + response->setResourceRepresentation(*representation, env->GetStringUTFChars(jstr, 0)); +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: setResourceRepresentation1 +* Signature: (Lorg/iotivity/base/OcRepresentation;)V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceRepresentation1 +(JNIEnv *env, jobject thiz, jobject jRepresentation) +{ + LOGD("OcResourceResponse_setResourceRepresentation"); + if (!jRepresentation) + { + ThrowOcException(OC_STACK_INVALID_PARAM, "Representation cannot be null"); + return; + } + JniOcResourceResponse *response = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + if (!response) return; + + OCRepresentation *representation = JniOcRepresentation::getOCRepresentationPtr(env, + jRepresentation); + + if (representation) + { + response->setResourceRepresentation(*representation); + } +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: create +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_create +(JNIEnv *env, jobject thiz) +{ + LOGI("OcResourceResponse_create"); + auto pResponse = std::make_shared(); + JniOcResourceResponse* jniResourceResponse = new JniOcResourceResponse(pResponse); + SetHandle(env, thiz, jniResourceResponse); + if (env->ExceptionCheck()) + { + LOGE("Failed to create OcResourceResponse"); + delete jniResourceResponse; + } +} + +/* +* Class: org_iotivity_base_OcResourceResponse +* Method: dispose +* Signature: ()V +*/ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_dispose +(JNIEnv *env, jobject thiz) +{ + LOGD("OcResourceResponse_dispose"); + JniOcResourceResponse *resp = JniOcResourceResponse::getJniOcResourceResponsePtr(env, thiz); + delete resp; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcResourceResponse.h b/android/android_api/base/jni/JniOcResourceResponse.h new file mode 100644 index 0000000..acabdf6 --- /dev/null +++ b/android/android_api/base/jni/JniOcResourceResponse.h @@ -0,0 +1,144 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "OCResourceResponse.h" + +#ifndef _Included_org_iotivity_base_OcResourceResponse +#define _Included_org_iotivity_base_OcResourceResponse + +using namespace OC; + +class JniOcResourceResponse +{ +public: + JniOcResourceResponse(std::shared_ptr resourceResponse); + ~JniOcResourceResponse(); + void setErrorCode(const int eCode); + std::string getNewResourceUri(void); + void setNewResourceUri(const std::string newResourceUri); + void setHeaderOptions(const HeaderOptions& headerOptions); + void setRequestHandle(const OCRequestHandle& requestHandle); + void setResourceHandle(const OCResourceHandle& resourceHandle); + void setResponseResult(const OCEntityHandlerResult& responseResult); + void setResourceRepresentation(OCRepresentation& rep, std::string interfaceStr); + void setResourceRepresentation(OCRepresentation& rep); + std::shared_ptr getOCResourceResponse(); + static JniOcResourceResponse* getJniOcResourceResponsePtr(JNIEnv *env, jobject thiz); +private: + std::shared_ptr m_response; +}; + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setErrorCode + * Signature: (I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setErrorCode + (JNIEnv *, jobject, jint); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: getNewResourceUri + * Signature: ()Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResourceResponse_getNewResourceUri + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setNewResourceUri + * Signature: (Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setNewResourceUri + (JNIEnv *, jobject, jstring); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setHeaderOptions + * Signature: (Ljava/util/List;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setHeaderOptions + (JNIEnv *, jobject, jobjectArray); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setRequestHandle + * Signature: (Lorg/iotivity/base/OcRequestHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setRequestHandle + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setResourceHandle + * Signature: (Lorg/iotivity/base/OcResourceHandle;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceHandle + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setResponseResult + * Signature: (I)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResponseResult + (JNIEnv *, jobject, jint); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setResourceRepresentation + * Signature: (Lorg/iotivity/base/OcRepresentation;Ljava/lang/String;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceRepresentation + (JNIEnv *, jobject, jobject, jstring); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: setResourceRepresentation1 + * Signature: (Lorg/iotivity/base/OcRepresentation;)V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_setResourceRepresentation1 + (JNIEnv *, jobject, jobject); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: create + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_create + (JNIEnv *, jobject); + + /* + * Class: org_iotivity_base_OcResourceResponse + * Method: dispose + * Signature: ()V + */ + JNIEXPORT void JNICALL Java_org_iotivity_base_OcResourceResponse_dispose + (JNIEnv *, jobject); +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcStack.cpp b/android/android_api/base/jni/JniOcStack.cpp new file mode 100644 index 0000000..5f6c1d4 --- /dev/null +++ b/android/android_api/base/jni/JniOcStack.cpp @@ -0,0 +1,449 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include "OCApi.h" +#include "OCPlatform.h" +#include "OCRepresentation.h" +#include "JniUtils.h" + +JavaVM* g_jvm = NULL; + +jclass g_cls_Integer = NULL; +jclass g_cls_int1DArray = NULL; +jclass g_cls_int2DArray = NULL; +jclass g_cls_Double = NULL; +jclass g_cls_double1DArray = NULL; +jclass g_cls_double2DArray = NULL; +jclass g_cls_Boolean = NULL; +jclass g_cls_boolean1DArray = NULL; +jclass g_cls_boolean2DArray = NULL; +jclass g_cls_String = NULL; +jclass g_cls_String1DArray = NULL; +jclass g_cls_String2DArray = NULL; +jclass g_cls_LinkedList = NULL; +jclass g_cls_Map = NULL; +jclass g_cls_MapEntry = NULL; +jclass g_cls_Set = NULL; +jclass g_cls_Iterator = NULL; +jclass g_cls_HashMap = NULL; +jclass g_cls_OcException = NULL; +jclass g_cls_OcResource = NULL; +jclass g_cls_OcRepresentation = NULL; +jclass g_cls_OcRepresentation1DArray = NULL; +jclass g_cls_OcRepresentation2DArray = NULL; +jclass g_cls_OcResourceRequest = NULL; +jclass g_cls_OcResourceResponse = NULL; +jclass g_cls_OcResourceHandle = NULL; +jclass g_cls_OcPresenceHandle = NULL; +jclass g_cls_OcRequestHandle = NULL; +jclass g_cls_OcPresenceStatus = NULL; +jclass g_cls_OcHeaderOption = NULL; +jclass g_cls_ObservationInfo = NULL; +jclass g_cls_OcResourceIdentifier = NULL; + +jmethodID g_mid_Integer_ctor = NULL; +jmethodID g_mid_Double_ctor = NULL; +jmethodID g_mid_Boolean_ctor = NULL; +jmethodID g_mid_LinkedList_ctor = NULL; +jmethodID g_mid_LinkedList_add_object = NULL; +jmethodID g_mid_Map_entrySet = NULL; +jmethodID g_mid_MapEntry_getKey = NULL; +jmethodID g_mid_MapEntry_getValue = NULL; +jmethodID g_mid_Set_iterator = NULL; +jmethodID g_mid_Iterator_hasNext = NULL; +jmethodID g_mid_Iterator_next = NULL; +jmethodID g_mid_HashMap_ctor = NULL; +jmethodID g_mid_HashMap_put = NULL; +jmethodID g_mid_OcException_ctor = NULL; +jmethodID g_mid_OcException_setNativeExceptionLocation = NULL; +jmethodID g_mid_OcResource_ctor = NULL; +jmethodID g_mid_OcRepresentation_N_ctor = NULL; +jmethodID g_mid_OcRepresentation_N_ctor_bool = NULL; +jmethodID g_mid_OcResourceRequest_N_ctor = NULL; +jmethodID g_mid_OcResourceResponse_N_ctor = NULL; +jmethodID g_mid_OcResourceHandle_N_ctor = NULL; +jmethodID g_mid_OcPresenceHandle_N_ctor = NULL; +jmethodID g_mid_OcRequestHandle_N_ctor = NULL; +jmethodID g_mid_OcHeaderOption_ctor = NULL; +jmethodID g_mid_OcHeaderOption_get_id = NULL; +jmethodID g_mid_OcHeaderOption_get_data = NULL; +jmethodID g_mid_ObservationInfo_N_ctor = NULL; +jmethodID g_mid_OcPresenceStatus_get = NULL; +jmethodID g_mid_OcResourceIdentifier_N_ctor = NULL; + +jobject getOcException(JNIEnv* env, const char* file, const char* functionName, + const int line, const int code, const char* message) +{ + std::string codeStr = JniUtils::stackResultToStr(code); + if (codeStr.empty()) + { + codeStr = JniUtils::stackResultToStr(JNI_INVALID_VALUE); + } + jobject ex = env->NewObject(g_cls_OcException, + g_mid_OcException_ctor, + env->NewStringUTF(codeStr.c_str()), + env->NewStringUTF(message)); + if (!ex) + { + return nullptr; + } + env->CallVoidMethod(ex, + g_mid_OcException_setNativeExceptionLocation, + env->NewStringUTF(file), + env->NewStringUTF(functionName), + line); + if (env->ExceptionCheck()) + { + return nullptr; + } + return ex; +} + +void throwOcException(JNIEnv* env, jobject ex) +{ + env->Throw((jthrowable)ex); +} + +// JNI OnLoad +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) +{ + LOGI("JNI_OnLoad"); + JNIEnv* env; + g_jvm = vm; + + if (g_jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK) + { + LOGE("Failed to get the environment using GetEnv()"); + return JNI_ERR; + } + + jclass clazz = nullptr; + + //Integer + clazz = env->FindClass("java/lang/Integer"); + if (!clazz) return JNI_ERR; + g_cls_Integer = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Integer_ctor = env->GetMethodID(g_cls_Integer, "", "(I)V"); + if (!g_mid_Integer_ctor) return JNI_ERR; + + clazz = env->FindClass("[I"); + if (!clazz) return JNI_ERR; + g_cls_int1DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[[I"); + if (!clazz) return JNI_ERR; + g_cls_int2DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + //Double + clazz = env->FindClass("java/lang/Double"); + if (!clazz) return JNI_ERR; + g_cls_Double = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Double_ctor = env->GetMethodID(g_cls_Double, "", "(D)V"); + if (!g_mid_Double_ctor) return JNI_ERR; + + clazz = env->FindClass("[D"); + if (!clazz) return JNI_ERR; + g_cls_double1DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[[D"); + if (!clazz) return JNI_ERR; + g_cls_double2DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + //Boolean + clazz = env->FindClass("java/lang/Boolean"); + if (!clazz) return JNI_ERR; + g_cls_Boolean = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Boolean_ctor = env->GetMethodID(g_cls_Boolean, "", "(Z)V"); + if (!g_mid_Boolean_ctor) return JNI_ERR; + + clazz = env->FindClass("[Z"); + if (!clazz) return JNI_ERR; + g_cls_boolean1DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[[Z"); + if (!clazz) return JNI_ERR; + g_cls_boolean2DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + //String + clazz = env->FindClass("java/lang/String"); + if (!clazz) return JNI_ERR; + g_cls_String = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[Ljava/lang/String;"); + if (!clazz) return JNI_ERR; + g_cls_String1DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[[Ljava/lang/String;"); + if (!clazz) return JNI_ERR; + g_cls_String2DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + //LinkedList + clazz = env->FindClass("java/util/LinkedList"); + if (!clazz) return JNI_ERR; + g_cls_LinkedList = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_LinkedList_ctor = env->GetMethodID(g_cls_LinkedList, "", "()V"); + if (!g_mid_LinkedList_ctor) return JNI_ERR; + + g_mid_LinkedList_add_object = env->GetMethodID(g_cls_LinkedList, "add", "(Ljava/lang/Object;)Z"); + if (!g_mid_LinkedList_add_object) return JNI_ERR; + + //Map + clazz = env->FindClass("java/util/Map"); + if (!clazz) return JNI_ERR; + g_cls_Map = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Map_entrySet = env->GetMethodID(g_cls_Map, "entrySet", "()Ljava/util/Set;"); + if (!g_mid_Map_entrySet) return JNI_ERR; + + //MapEntry + clazz = env->FindClass("java/util/Map$Entry"); + if (!clazz) return JNI_ERR; + g_cls_MapEntry = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_MapEntry_getKey = env->GetMethodID(g_cls_MapEntry, "getKey", "()Ljava/lang/Object;"); + if (!g_mid_MapEntry_getKey) return JNI_ERR; + g_mid_MapEntry_getValue = env->GetMethodID(g_cls_MapEntry, "getValue", "()Ljava/lang/Object;"); + if (!g_mid_MapEntry_getValue) return JNI_ERR; + + //Set + clazz = env->FindClass("java/util/Set"); + if (!clazz) return JNI_ERR; + g_cls_Set = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Set_iterator = env->GetMethodID(g_cls_Set, "iterator", "()Ljava/util/Iterator;"); + if (!g_mid_Set_iterator) return JNI_ERR; + + //Iterator + clazz = env->FindClass("java/util/Iterator"); + if (!clazz) return JNI_ERR; + g_cls_Iterator = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_Iterator_hasNext = env->GetMethodID(g_cls_Iterator, "hasNext", "()Z"); + if (!g_mid_Iterator_hasNext) return JNI_ERR; + + g_mid_Iterator_next = env->GetMethodID(g_cls_Iterator, "next", "()Ljava/lang/Object;"); + if (!g_mid_Iterator_next) return JNI_ERR; + + //HashMap + clazz = env->FindClass("java/util/HashMap"); + if (!clazz) return JNI_ERR; + g_cls_HashMap = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_HashMap_ctor = env->GetMethodID(g_cls_HashMap, "", "()V"); + if (!g_mid_HashMap_ctor) return JNI_ERR; + + g_mid_HashMap_put = env->GetMethodID(g_cls_HashMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + if (!g_mid_HashMap_put) return JNI_ERR; + + //OcException + clazz = env->FindClass("org/iotivity/base/OcException"); + if (!clazz) return JNI_ERR; + g_cls_OcException = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_OcException_ctor = env->GetMethodID(g_cls_OcException, "", "(Ljava/lang/String;Ljava/lang/String;)V"); + if (!g_mid_OcException_ctor) return JNI_ERR; + + g_mid_OcException_setNativeExceptionLocation = env->GetMethodID(g_cls_OcException, "setNativeExceptionLocation", + "(Ljava/lang/String;""Ljava/lang/String;""I)V"); + if (!g_mid_OcException_setNativeExceptionLocation) return JNI_ERR; + + //OcResource + clazz = env->FindClass("org/iotivity/base/OcResource"); + if (!clazz) return JNI_ERR; + g_cls_OcResource = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_OcResource_ctor = env->GetMethodID(g_cls_OcResource, "", "(J)V"); + if (!g_mid_OcResource_ctor) return JNI_ERR; + + //OcRepresentation + clazz = env->FindClass("org/iotivity/base/OcRepresentation"); + if (!clazz) return JNI_ERR; + g_cls_OcRepresentation = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_OcRepresentation_N_ctor = env->GetMethodID(g_cls_OcRepresentation, "", "(J)V"); + if (!g_mid_OcRepresentation_N_ctor) return JNI_ERR; + + g_mid_OcRepresentation_N_ctor_bool = env->GetMethodID(g_cls_OcRepresentation, "", "(JZ)V"); + if (!g_mid_OcRepresentation_N_ctor_bool) return JNI_ERR; + + clazz = env->FindClass("[Lorg/iotivity/base/OcRepresentation;"); + if (!clazz) return JNI_ERR; + g_cls_OcRepresentation1DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + clazz = env->FindClass("[[Lorg/iotivity/base/OcRepresentation;"); + if (!clazz) return JNI_ERR; + g_cls_OcRepresentation2DArray = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + //HeaderOptions + clazz = env->FindClass("org/iotivity/base/OcHeaderOption"); + if (!clazz) return JNI_ERR; + g_cls_OcHeaderOption = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcHeaderOption_ctor = env->GetMethodID(g_cls_OcHeaderOption, "", "(ILjava/lang/String;)V"); + if (!g_mid_OcHeaderOption_ctor) return JNI_ERR; + + g_mid_OcHeaderOption_get_id = env->GetMethodID(g_cls_OcHeaderOption, "getOptionId", "()I"); + if (!g_mid_OcHeaderOption_get_id) return JNI_ERR; + + g_mid_OcHeaderOption_get_data = env->GetMethodID(g_cls_OcHeaderOption, "getOptionData", "()Ljava/lang/String;"); + if (!g_mid_OcHeaderOption_get_data) return JNI_ERR; + + //OcResourceRequest + clazz = env->FindClass("org/iotivity/base/OcResourceRequest"); + if (!clazz) return JNI_ERR; + g_cls_OcResourceRequest = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_OcResourceRequest_N_ctor = env->GetMethodID(g_cls_OcResourceRequest, "", "(J)V"); + if (!g_mid_OcResourceRequest_N_ctor) return JNI_ERR; + + //OcResourceResponse + clazz = env->FindClass("org/iotivity/base/OcResourceResponse"); + if (!clazz) return JNI_ERR; + g_cls_OcResourceResponse = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + + g_mid_OcResourceResponse_N_ctor = env->GetMethodID(g_cls_OcResourceResponse, "", "(J)V"); + if (!g_mid_OcResourceResponse_N_ctor) return JNI_ERR; + + //OcResourceHandle + clazz = env->FindClass("org/iotivity/base/OcResourceHandle"); + if (!clazz) return JNI_ERR; + g_cls_OcResourceHandle = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcResourceHandle_N_ctor = env->GetMethodID(g_cls_OcResourceHandle, "", "(J)V"); + if (!g_mid_OcResourceHandle_N_ctor) return JNI_ERR; + + //OcPresenceHandle + clazz = env->FindClass("org/iotivity/base/OcPresenceHandle"); + if (!clazz) return JNI_ERR; + g_cls_OcPresenceHandle = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcPresenceHandle_N_ctor = env->GetMethodID(g_cls_OcPresenceHandle, "", "(J)V"); + if (!g_mid_OcPresenceHandle_N_ctor) return JNI_ERR; + + //OcRequestHandle + clazz = env->FindClass("org/iotivity/base/OcRequestHandle"); + if (!clazz) return JNI_ERR; + g_cls_OcRequestHandle = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcRequestHandle_N_ctor = env->GetMethodID(g_cls_OcRequestHandle, "", "(J)V"); + if (!g_mid_OcRequestHandle_N_ctor) return JNI_ERR; + + //OcPresenceStatus + clazz = env->FindClass("org/iotivity/base/OcPresenceStatus"); + if (!clazz) return JNI_ERR; + g_cls_OcPresenceStatus = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcPresenceStatus_get = env->GetStaticMethodID(g_cls_OcPresenceStatus, "get", + "(Ljava/lang/String;)Lorg/iotivity/base/OcPresenceStatus;"); + if (!g_mid_OcPresenceStatus_get) return JNI_ERR; + + //ObservationInfo + clazz = env->FindClass("org/iotivity/base/ObservationInfo"); + if (!clazz) return JNI_ERR; + g_cls_ObservationInfo = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_ObservationInfo_N_ctor = env->GetMethodID(g_cls_ObservationInfo, "", "(IB)V"); + if (!g_mid_ObservationInfo_N_ctor) return JNI_ERR; + + clazz = env->FindClass("org/iotivity/base/OcResourceIdentifier"); + if (!clazz) return JNI_ERR; + g_cls_OcResourceIdentifier = (jclass)env->NewGlobalRef(clazz); + env->DeleteLocalRef(clazz); + g_mid_OcResourceIdentifier_N_ctor = env->GetMethodID(g_cls_OcResourceIdentifier, "", "(J)V"); + if (!g_mid_OcResourceIdentifier_N_ctor) return JNI_ERR; + + return JNI_CURRENT_VERSION; +} + +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) +{ + LOGI("JNI_OnUnload"); + JNIEnv* env; + + if (g_jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK) + { + LOGE("Failed to get the environment using GetEnv()"); + return; + } + + env->DeleteGlobalRef(g_cls_Integer); + env->DeleteGlobalRef(g_cls_int1DArray); + env->DeleteGlobalRef(g_cls_int2DArray); + env->DeleteGlobalRef(g_cls_Double); + env->DeleteGlobalRef(g_cls_double1DArray); + env->DeleteGlobalRef(g_cls_double2DArray); + env->DeleteGlobalRef(g_cls_Boolean); + env->DeleteGlobalRef(g_cls_boolean1DArray); + env->DeleteGlobalRef(g_cls_boolean2DArray); + env->DeleteGlobalRef(g_cls_String); + env->DeleteGlobalRef(g_cls_String1DArray); + env->DeleteGlobalRef(g_cls_String2DArray); + env->DeleteGlobalRef(g_cls_LinkedList); + env->DeleteGlobalRef(g_cls_Map); + env->DeleteGlobalRef(g_cls_MapEntry); + env->DeleteGlobalRef(g_cls_Set); + env->DeleteGlobalRef(g_cls_Iterator); + env->DeleteGlobalRef(g_cls_HashMap); + env->DeleteGlobalRef(g_cls_OcResource); + env->DeleteGlobalRef(g_cls_OcException); + env->DeleteGlobalRef(g_cls_OcRepresentation); + env->DeleteGlobalRef(g_cls_OcRepresentation1DArray); + env->DeleteGlobalRef(g_cls_OcRepresentation2DArray); + env->DeleteGlobalRef(g_cls_OcResourceRequest); + env->DeleteGlobalRef(g_cls_OcResourceResponse); + env->DeleteGlobalRef(g_cls_OcResourceHandle); + env->DeleteGlobalRef(g_cls_OcPresenceHandle); + env->DeleteGlobalRef(g_cls_OcRequestHandle); + env->DeleteGlobalRef(g_cls_OcPresenceStatus); + env->DeleteGlobalRef(g_cls_OcHeaderOption); + env->DeleteGlobalRef(g_cls_ObservationInfo); + env->DeleteGlobalRef(g_cls_OcResourceIdentifier); +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOcStack.h b/android/android_api/base/jni/JniOcStack.h new file mode 100644 index 0000000..bd0ddd5 --- /dev/null +++ b/android/android_api/base/jni/JniOcStack.h @@ -0,0 +1,169 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include +#include +#include "OCApi.h" + +#ifndef _Included_org_iotivity_base_ocstack +#define _Included_org_iotivity_base_ocstack + +#define TAG "OIC-JNI" + +#define JNI_CURRENT_VERSION JNI_VERSION_1_6 + +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) + +#define JNI_EXCEPTION 1000 +#define JNI_NO_NATIVE_POINTER 1001 +#define JNI_INVALID_VALUE 1002 +#define JNI_NO_SUCH_KEY 1003 + +jobject getOcException(JNIEnv* env, const char* file, const char* functionName, const int line, + const int code, const char* message); +void throwOcException(JNIEnv* env, jobject ex); +#define GetOcException(code, message) getOcException (env,__FILE__,__func__,__LINE__,code,message) +#define ThrowOcException(code, message) throwOcException (env, GetOcException(code, message)) + +extern JavaVM* g_jvm; + +extern jclass g_cls_Integer; +extern jclass g_cls_int1DArray; +extern jclass g_cls_int2DArray; +extern jclass g_cls_Double; +extern jclass g_cls_double1DArray; +extern jclass g_cls_double2DArray; +extern jclass g_cls_Boolean; +extern jclass g_cls_boolean1DArray; +extern jclass g_cls_boolean2DArray; +extern jclass g_cls_String; +extern jclass g_cls_String1DArray; +extern jclass g_cls_String2DArray; +extern jclass g_cls_LinkedList; +extern jclass g_cls_Map; +extern jclass g_cls_MapEntry; +extern jclass g_cls_Set; +extern jclass g_cls_Iterator; +extern jclass g_cls_HashMap; +extern jclass g_cls_OcException; +extern jclass g_cls_OcResource; +extern jclass g_cls_OcRepresentation; +extern jclass g_cls_OcRepresentation1DArray; +extern jclass g_cls_OcRepresentation2DArray; +extern jclass g_cls_OcResourceRequest; +extern jclass g_cls_OcResourceResponse; +extern jclass g_cls_OcResourceHandle; +extern jclass g_cls_OcPresenceHandle; +extern jclass g_cls_OcRequestHandle; +extern jclass g_cls_OcPresenceStatus; +extern jclass g_cls_OcHeaderOption; +extern jclass g_cls_ObservationInfo; +extern jclass g_cls_OcResourceIdentifier; + +extern jmethodID g_mid_Integer_ctor; +extern jmethodID g_mid_Double_ctor; +extern jmethodID g_mid_Boolean_ctor; +extern jmethodID g_mid_LinkedList_ctor; +extern jmethodID g_mid_LinkedList_add_object; +extern jmethodID g_mid_Map_entrySet; +extern jmethodID g_mid_MapEntry_getKey; +extern jmethodID g_mid_MapEntry_getValue; +extern jmethodID g_mid_Set_iterator; +extern jmethodID g_mid_Iterator_hasNext; +extern jmethodID g_mid_Iterator_next; +extern jmethodID g_mid_HashMap_ctor; +extern jmethodID g_mid_HashMap_put; +extern jmethodID g_mid_OcException_ctor; +extern jmethodID g_mid_OcException_setNativeExceptionLocation; +extern jmethodID g_mid_OcResource_ctor; +extern jmethodID g_mid_OcRepresentation_N_ctor; +extern jmethodID g_mid_OcRepresentation_N_ctor_bool; +extern jmethodID g_mid_OcResourceRequest_N_ctor; +extern jmethodID g_mid_OcResourceResponse_N_ctor; +extern jmethodID g_mid_OcResourceHandle_N_ctor; +extern jmethodID g_mid_OcPresenceHandle_N_ctor; +extern jmethodID g_mid_OcRequestHandle_N_ctor; +extern jmethodID g_mid_OcHeaderOption_ctor; +extern jmethodID g_mid_OcHeaderOption_get_id; +extern jmethodID g_mid_OcHeaderOption_get_data; +extern jmethodID g_mid_ObservationInfo_N_ctor; +extern jmethodID g_mid_OcPresenceStatus_get; +extern jmethodID g_mid_OcResourceIdentifier_N_ctor; + +typedef void(*RemoveListenerCallback)(JNIEnv* env, jobject jListener); + +static jfieldID GetHandleField(JNIEnv *env, jobject jobj) +{ + jclass cls = env->GetObjectClass(jobj); + return env->GetFieldID(cls, "mNativeHandle", "J"); +} + +template +static T *GetHandle(JNIEnv *env, jobject jobj) +{ + jlong handle = env->GetLongField(jobj, GetHandleField(env, jobj)); + return reinterpret_cast(handle); +} + +template +static void SetHandle(JNIEnv *env, jobject jobj, T *type) +{ + jlong handle = reinterpret_cast(type); + + env->SetLongField(jobj, GetHandleField(env, jobj), handle); +} + +static JNIEnv* GetJNIEnv(jint& ret) +{ + JNIEnv *env = NULL; + + ret = g_jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION); + switch (ret) { + case JNI_OK: + return env; + case JNI_EDETACHED: + if (g_jvm->AttachCurrentThread(&env, NULL) < 0) + { + LOGE("Failed to get the environment"); + return nullptr; + } + else + { + return env; + } + + case JNI_EVERSION: + LOGE("JNI version not supported"); + default: + LOGE("Failed to get the environment"); + return nullptr; + } +} + +static void DuplicateString(char ** targetString, std::string sourceString) +{ + *targetString = new char[sourceString.length() + 1]; + strncpy(*targetString, sourceString.c_str(), (sourceString.length() + 1)); +} + +#endif // _Included_org_iotivity_base_ocstack \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnDeleteListener.cpp b/android/android_api/base/jni/JniOnDeleteListener.cpp new file mode 100644 index 0000000..ed39e3b --- /dev/null +++ b/android/android_api/base/jni/JniOnDeleteListener.cpp @@ -0,0 +1,121 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOnDeleteListener.h" +#include "JniOcResource.h" +#include "JniUtils.h" + +JniOnDeleteListener::JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcResource* owner) + : m_ownerResource(owner) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); +} + +JniOnDeleteListener::~JniOnDeleteListener() +{ + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + env->DeleteWeakGlobalRef(m_jwListener); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnDeleteListener::onDeleteCallback(const HeaderOptions& headerOptions, const int eCode) +{ + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + if (OC_STACK_RESOURCE_DELETED != eCode) + { + jobject ex = GetOcException(eCode, "stack error in onDeleteCallback"); + if (!ex) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onDeleteFailed", "(Ljava/lang/Throwable;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, ex); + } + else + { + jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env, headerOptions); + if (!jHeaderOptionList) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + jmethodID midL = env->GetMethodID(clsL, "onDeleteCompleted", "(Ljava/util/List;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, jHeaderOptionList); + } + + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +void JniOnDeleteListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnDeleteListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_ownerResource->removeOnDeleteListener(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnDeleteListener.h b/android/android_api/base/jni/JniOnDeleteListener.h new file mode 100644 index 0000000..45ae34b --- /dev/null +++ b/android/android_api/base/jni/JniOnDeleteListener.h @@ -0,0 +1,45 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResource_OnDeleteListener +#define _Included_org_iotivity_base_OcResource_OnDeleteListener + +using namespace OC; + +class JniOcResource; + +class JniOnDeleteListener +{ +public: + JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcResource* owner); + ~JniOnDeleteListener(); + + void onDeleteCallback(const HeaderOptions&, const int eCode); + +private: + jweak m_jwListener; + JniOcResource* m_ownerResource; + void checkExAndRemoveListener(JNIEnv *env); +}; + +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnDeviceInfoListener.cpp b/android/android_api/base/jni/JniOnDeviceInfoListener.cpp new file mode 100644 index 0000000..483fac6 --- /dev/null +++ b/android/android_api/base/jni/JniOnDeviceInfoListener.cpp @@ -0,0 +1,113 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnDeviceInfoListener.h" +#include "JniOcRepresentation.h" + +JniOnDeviceInfoListener::JniOnDeviceInfoListener(JNIEnv *env, jobject jListener, + RemoveListenerCallback removeListenerCallback) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); + m_removeListenerCallback = removeListenerCallback; +} + +JniOnDeviceInfoListener::~JniOnDeviceInfoListener() +{ + LOGI("~JniOnDeviceInfoListener"); + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + env->DeleteWeakGlobalRef(m_jwListener); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnDeviceInfoListener::foundDeviceCallback(const OC::OCRepresentation& ocRepresentation) +{ + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + LOGI("Java onDeviceInfoListener object is already destroyed, quiting"); + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + OCRepresentation* rep = new OCRepresentation(ocRepresentation); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onDeviceFound", "(Lorg/iotivity/base/OcRepresentation;)V"); + if (!midL) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + env->CallVoidMethod(jListener, midL, jRepresentation); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete rep; + checkExAndRemoveListener(env); + } + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); +} + +void JniOnDeviceInfoListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_removeListenerCallback(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_removeListenerCallback(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnDeviceInfoListener.h b/android/android_api/base/jni/JniOnDeviceInfoListener.h new file mode 100644 index 0000000..152ca8c --- /dev/null +++ b/android/android_api/base/jni/JniOnDeviceInfoListener.h @@ -0,0 +1,42 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcPlatform_OnDeviceFoundListener +#define _Included_org_iotivity_base_OcPlatform_OnDeviceFoundListener + +class JniOnDeviceInfoListener +{ +public: + JniOnDeviceInfoListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener); + ~JniOnDeviceInfoListener(); + + void foundDeviceCallback(const OC::OCRepresentation& ocRepresentation); + +private: + jweak m_jwListener; + RemoveListenerCallback m_removeListenerCallback; + void checkExAndRemoveListener(JNIEnv* env); +}; + +#endif diff --git a/android/android_api/base/jni/JniOnGetListener.cpp b/android/android_api/base/jni/JniOnGetListener.cpp new file mode 100644 index 0000000..4ac19bc --- /dev/null +++ b/android/android_api/base/jni/JniOnGetListener.cpp @@ -0,0 +1,144 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnGetListener.h" +#include "JniOcResource.h" +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +JniOnGetListener::JniOnGetListener(JNIEnv *env, jobject jListener, JniOcResource* owner) + : m_ownerResource(owner) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); +} + +JniOnGetListener::~JniOnGetListener() +{ + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + env->DeleteWeakGlobalRef(m_jwListener); + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnGetListener::onGetCallback(const HeaderOptions& headerOptions, + const OCRepresentation& ocRepresentation, const int eCode) +{ + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + if (OC_STACK_OK != eCode) + { + jobject ex = GetOcException(eCode, "stack error in onGetCallback"); + if (!ex) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onGetFailed", "(Ljava/lang/Throwable;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, ex); + } + else + { + jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env, headerOptions); + if (!jHeaderOptionList) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + OCRepresentation* rep = new OCRepresentation(ocRepresentation); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + jmethodID midL = env->GetMethodID(clsL, "onGetCompleted", + "(Ljava/util/List;Lorg/iotivity/base/OcRepresentation;)V"); + if (!midL) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, jHeaderOptionList, jRepresentation); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete rep; + } + } + + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +void JniOnGetListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnGetListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_ownerResource->removeOnGetListener(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnGetListener.h b/android/android_api/base/jni/JniOnGetListener.h new file mode 100644 index 0000000..af69f1b --- /dev/null +++ b/android/android_api/base/jni/JniOnGetListener.h @@ -0,0 +1,43 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResource_OnGetListener +#define _Included_org_iotivity_base_OcResource_OnGetListener + +using namespace OC; + +class JniOcResource; + +class JniOnGetListener +{ +public: + JniOnGetListener(JNIEnv *env, jobject listener, JniOcResource* resource); + ~JniOnGetListener(); + void onGetCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); +private: + jweak m_jwListener; + JniOcResource* m_ownerResource; + void checkExAndRemoveListener(JNIEnv *env); +}; + +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnObserveListener.cpp b/android/android_api/base/jni/JniOnObserveListener.cpp new file mode 100644 index 0000000..7afb1e1 --- /dev/null +++ b/android/android_api/base/jni/JniOnObserveListener.cpp @@ -0,0 +1,147 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnObserveListener.h" +#include "JniOcResource.h" +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +JniOnObserveListener::JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcResource* owner) + : m_ownerResource(owner) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); +} + +JniOnObserveListener::~JniOnObserveListener() +{ + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + env->DeleteWeakGlobalRef(m_jwListener); + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnObserveListener::onObserveCallback(const HeaderOptions headerOptions, + const OCRepresentation& ocRepresentation, const int& eCode, const int& sequenceNumber) +{ + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + if (OC_STACK_OK != eCode && OC_STACK_RESOURCE_CREATED != eCode && OC_STACK_RESOURCE_DELETED != eCode) + { + jobject ex = GetOcException(eCode, "stack error in onObserveCallback"); + if (!ex) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onObserveFailed", "(Ljava/lang/Throwable;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, ex); + } + else + { + jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env, headerOptions); + if (!jHeaderOptionList) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + OCRepresentation * rep = new OCRepresentation(ocRepresentation); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, + g_mid_OcRepresentation_N_ctor_bool, handle, true); + if (!jRepresentation) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + jmethodID midL = env->GetMethodID(clsL, "onObserveCompleted", + "(Ljava/util/List;Lorg/iotivity/base/OcRepresentation;I)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + env->CallVoidMethod(jListener, midL, jHeaderOptionList, jRepresentation, + static_cast(sequenceNumber)); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete rep; + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnObserveListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + } + + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +void JniOnObserveListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnObserveListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_ownerResource->removeOnObserveListener(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnObserveListener.h b/android/android_api/base/jni/JniOnObserveListener.h new file mode 100644 index 0000000..ae1d042 --- /dev/null +++ b/android/android_api/base/jni/JniOnObserveListener.h @@ -0,0 +1,44 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResource_OnObserveListener +#define _Included_org_iotivity_base_OcResource_OnObserveListener + +using namespace OC; + +class JniOcResource; + +class JniOnObserveListener +{ +public: + JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcResource* owner); + ~JniOnObserveListener(); + void onObserveCallback(const HeaderOptions headerOptions, const OCRepresentation& rep, + const int& eCode, const int& sequenceNumber); +private: + jweak m_jwListener; + JniOcResource* m_ownerResource; + void checkExAndRemoveListener(JNIEnv *env); +}; + +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnPostListener.cpp b/android/android_api/base/jni/JniOnPostListener.cpp new file mode 100644 index 0000000..b9eb997 --- /dev/null +++ b/android/android_api/base/jni/JniOnPostListener.cpp @@ -0,0 +1,143 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnPostListener.h" +#include "JniOcResource.h" +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +JniOnPostListener::JniOnPostListener(JNIEnv *env, jobject jListener, JniOcResource* owner) + : m_ownerResource(owner) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); +} + +JniOnPostListener::~JniOnPostListener() +{ + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + env->DeleteWeakGlobalRef(m_jwListener); + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnPostListener::onPostCallback(const HeaderOptions& headerOptions, + const OCRepresentation& ocRepresentation, const int eCode) +{ + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + if (OC_STACK_OK != eCode && OC_STACK_RESOURCE_CREATED != eCode) + { + jobject ex = GetOcException(eCode, "stack error in onPostCallback"); + if (!ex) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onPostFailed", "(Ljava/lang/Throwable;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, ex); + } + else + { + jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env, headerOptions); + if (!jHeaderOptionList) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + OCRepresentation * rep = new OCRepresentation(ocRepresentation); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + jmethodID midL = env->GetMethodID(clsL, "onPostCompleted", + "(Ljava/util/List;Lorg/iotivity/base/OcRepresentation;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + env->CallVoidMethod(jListener, midL, jHeaderOptionList, jRepresentation); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete rep; + } + } + + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +void JniOnPostListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnPostListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_ownerResource->removeOnPostListener(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnPostListener.h b/android/android_api/base/jni/JniOnPostListener.h new file mode 100644 index 0000000..9090507 --- /dev/null +++ b/android/android_api/base/jni/JniOnPostListener.h @@ -0,0 +1,45 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResource_OnPostListener +#define _Included_org_iotivity_base_OcResource_OnPostListener + +using namespace OC; + +class JniOcResource; + +class JniOnPostListener +{ +public: + JniOnPostListener(JNIEnv *env, jobject jListener, JniOcResource* owner); + ~JniOnPostListener(); + + void onPostCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + +private: + jweak m_jwListener; + JniOcResource* m_ownerResource; + void checkExAndRemoveListener(JNIEnv *env); +}; + +#endif \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnPresenceListener.cpp b/android/android_api/base/jni/JniOnPresenceListener.cpp new file mode 100644 index 0000000..7c99445 --- /dev/null +++ b/android/android_api/base/jni/JniOnPresenceListener.cpp @@ -0,0 +1,133 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnPresenceListener.h" +#include "JniUtils.h" + +JniOnPresenceListener::JniOnPresenceListener(JNIEnv *env, jobject jListener, + RemoveListenerCallback removeListenerCallback) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); + m_removeListenerCallback = removeListenerCallback; +} + +JniOnPresenceListener::~JniOnPresenceListener() +{ + LOGD("~JniOnPresenceListener"); + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + env->DeleteWeakGlobalRef(m_jwListener); + m_jwListener = nullptr; + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnPresenceListener::onPresenceCallback(OCStackResult result, const unsigned int nonce, + const std::string& hostAddress) +{ + LOGI("JniOnPresenceListener::onPresenceCallback"); + if (!m_jwListener) return; + + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + if (OC_STACK_OK != result && OC_STACK_PRESENCE_STOPPED != result && + OC_STACK_PRESENCE_TIMEOUT != result && OC_STACK_PRESENCE_DO_NOT_HANDLE != result) + { + ThrowOcException(result, "onPresenceCallback: stack failure"); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + std::string enumField = JniUtils::stackResultToStr(result); + if (enumField.empty()) + { + ThrowOcException(JNI_INVALID_VALUE, "Unexpected OCStackResult value"); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + jobject jPresenceStatus = env->CallStaticObjectMethod(g_cls_OcPresenceStatus, + g_mid_OcPresenceStatus_get, env->NewStringUTF(enumField.c_str())); + if (!jPresenceStatus) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onPresence", + "(Lorg/iotivity/base/OcPresenceStatus;ILjava/lang/String;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + env->CallVoidMethod(jListener, midL, jPresenceStatus, + (jint)nonce, env->NewStringUTF(hostAddress.c_str())); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + checkExAndRemoveListener(env); + } + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); +} + +void JniOnPresenceListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_removeListenerCallback(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_removeListenerCallback(env, m_jwListener); + } +} + +jweak JniOnPresenceListener::getJWListener() +{ + return this->m_jwListener; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnPresenceListener.h b/android/android_api/base/jni/JniOnPresenceListener.h new file mode 100644 index 0000000..7cea026 --- /dev/null +++ b/android/android_api/base/jni/JniOnPresenceListener.h @@ -0,0 +1,43 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" +#include + +#ifndef _Included_org_iotivity_base_OcPlatform_OnPresenceListener +#define _Included_org_iotivity_base_OcPlatform_OnPresenceListener + +class JniOnPresenceListener +{ +public: + JniOnPresenceListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener); + ~JniOnPresenceListener(); + + void onPresenceCallback(OCStackResult result, const unsigned int nonce, const std::string& hostAddress); + jweak getJWListener(); + +private: + RemoveListenerCallback m_removeListenerCallback; + jweak m_jwListener; + void checkExAndRemoveListener(JNIEnv* env); +}; + +#endif diff --git a/android/android_api/base/jni/JniOnPutListener.cpp b/android/android_api/base/jni/JniOnPutListener.cpp new file mode 100644 index 0000000..df18490 --- /dev/null +++ b/android/android_api/base/jni/JniOnPutListener.cpp @@ -0,0 +1,144 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnPutListener.h" +#include "JniOcResource.h" +#include "JniOcRepresentation.h" +#include "JniUtils.h" + +JniOnPutListener::JniOnPutListener(JNIEnv *env, jobject jListener, JniOcResource* owner) + : m_ownerResource(owner) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); +} + +JniOnPutListener::~JniOnPutListener() +{ + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + env->DeleteWeakGlobalRef(m_jwListener); + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnPutListener::onPutCallback(const HeaderOptions& headerOptions, + const OCRepresentation& ocRepresentation, const int eCode) +{ + jint envRet; + JNIEnv *env = GetJNIEnv(envRet); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + if (OC_STACK_OK != eCode) + { + jobject ex = GetOcException(eCode, "stack error in onPutCallback"); + if (!ex) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onPutFailed", "(Ljava/lang/Throwable;)V"); + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, ex); + } + else + { + jobject jHeaderOptionList = JniUtils::convertHeaderOptionsVectorToJavaList(env, headerOptions); + if (!jHeaderOptionList) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + OCRepresentation * rep = new OCRepresentation(ocRepresentation); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + jmethodID midL = env->GetMethodID(clsL, "onPutCompleted", + "(Ljava/util/List;Lorg/iotivity/base/OcRepresentation;)V"); + + if (!midL) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); + return; + } + + env->CallVoidMethod(jListener, midL, jHeaderOptionList, jRepresentation); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete rep; + } + } + + checkExAndRemoveListener(env); + if (JNI_EDETACHED == envRet) g_jvm->DetachCurrentThread(); +} + +void JniOnPutListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_ownerResource->removeOnPutListener(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_ownerResource->removeOnPutListener(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnPutListener.h b/android/android_api/base/jni/JniOnPutListener.h new file mode 100644 index 0000000..f29e43f --- /dev/null +++ b/android/android_api/base/jni/JniOnPutListener.h @@ -0,0 +1,45 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcResource_OnPutListener +#define _Included_org_iotivity_base_OcResource_OnPutListener + +using namespace OC; + +class JniOcResource; + +class JniOnPutListener +{ +public: + JniOnPutListener(JNIEnv *env, jobject jListener, JniOcResource* resource); + ~JniOnPutListener(); + + void onPutCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode); + +private: + jweak m_jwListener; + JniOcResource* m_ownerResource; + void checkExAndRemoveListener(JNIEnv *env); +}; + +#endif diff --git a/android/android_api/base/jni/JniOnResourceFoundListener.cpp b/android/android_api/base/jni/JniOnResourceFoundListener.cpp new file mode 100644 index 0000000..652e0cb --- /dev/null +++ b/android/android_api/base/jni/JniOnResourceFoundListener.cpp @@ -0,0 +1,118 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include "JniOnResourceFoundListener.h" +#include "JniOcResource.h" + +JniOnResourceFoundListener::JniOnResourceFoundListener(JNIEnv *env, jobject jListener, + RemoveListenerCallback removeListenerCallback) +{ + m_jwListener = env->NewWeakGlobalRef(jListener); + m_removeListenerCallback = removeListenerCallback; +} + +JniOnResourceFoundListener::~JniOnResourceFoundListener() +{ + LOGI("~JniOnResourceFoundListener()"); + if (m_jwListener) + { + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + env->DeleteWeakGlobalRef(m_jwListener); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + } +} + +void JniOnResourceFoundListener::foundResourceCallback(std::shared_ptr resource) +{ + jint ret; + JNIEnv *env = GetJNIEnv(ret); + if (NULL == env) return; + + jobject jListener = env->NewLocalRef(m_jwListener); + if (!jListener) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + jobject jResource = env->NewObject(g_cls_OcResource, g_mid_OcResource_ctor); + if (!jResource) + { + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + JniOcResource *jniOcResource = new JniOcResource(resource); + SetHandle(env, jResource, jniOcResource); + if (env->ExceptionCheck()) + { + delete jniOcResource; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + jclass clsL = env->GetObjectClass(jListener); + if (!clsL) + { + delete jniOcResource; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + jmethodID midL = env->GetMethodID(clsL, "onResourceFound", "(Lorg/iotivity/base/OcResource;)V"); + if (!midL) + { + delete jniOcResource; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + env->CallVoidMethod(jListener, midL, jResource); + if (env->ExceptionCheck()) + { + LOGE("Java exception is thrown"); + delete jniOcResource; + checkExAndRemoveListener(env); + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); + return; + } + + if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread(); +} + +void JniOnResourceFoundListener::checkExAndRemoveListener(JNIEnv* env) +{ + if (env->ExceptionCheck()) + { + jthrowable ex = env->ExceptionOccurred(); + env->ExceptionClear(); + m_removeListenerCallback(env, m_jwListener); + env->Throw((jthrowable)ex); + } + else + { + m_removeListenerCallback(env, m_jwListener); + } +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniOnResourceFoundListener.h b/android/android_api/base/jni/JniOnResourceFoundListener.h new file mode 100644 index 0000000..2cb9749 --- /dev/null +++ b/android/android_api/base/jni/JniOnResourceFoundListener.h @@ -0,0 +1,43 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ +#include +#include "JniOcStack.h" + +#ifndef _Included_org_iotivity_base_OcPlatform_OnResourceFoundListener +#define _Included_org_iotivity_base_OcPlatform_OnResourceFoundListener + +class JniOnResourceFoundListener +{ +public: + JniOnResourceFoundListener(JNIEnv *env, jobject jListener, + RemoveListenerCallback removeListenerCallback); + ~JniOnResourceFoundListener(); + + void foundResourceCallback(std::shared_ptr resource); + +private: + RemoveListenerCallback m_removeListenerCallback; + jweak m_jwListener; + void checkExAndRemoveListener(JNIEnv* env); +}; + +#endif diff --git a/android/android_api/base/jni/JniUtils.cpp b/android/android_api/base/jni/JniUtils.cpp new file mode 100644 index 0000000..6ec806c --- /dev/null +++ b/android/android_api/base/jni/JniUtils.cpp @@ -0,0 +1,193 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniUtils.h" +#include "JniOcRepresentation.h" + +jobject JniUtils::convertStrVectorToJavaStrList(JNIEnv *env, std::vector &vector) +{ + jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor); + if (!jList) return nullptr; + for (size_t i = 0; i < vector.size(); ++i) + { + jstring jStr = env->NewStringUTF(vector[i].c_str()); + if (!jStr) return nullptr; + env->CallBooleanMethod(jList, g_mid_LinkedList_add_object, jStr); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jStr); + } + return jList; +} + +void JniUtils::convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr, std::vector &vector) +{ + if (!jStrArr) return; + + jsize len = env->GetArrayLength(jStrArr); + for (jsize i = 0; i < len; ++i) + { + jstring jStr = (jstring)env->GetObjectArrayElement(jStrArr, i); + if (!jStr) return; + vector.push_back(env->GetStringUTFChars(jStr, NULL)); + if (env->ExceptionCheck()) return; + env->DeleteLocalRef(jStr); + } +} + +void JniUtils::convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions, + OC::HeaderOptions &headerOptions) +{ + if (!jHeaderOptions) return; + + jsize len = env->GetArrayLength(jHeaderOptions); + for (jsize i = 0; i < len; ++i) + { + jobject header = env->GetObjectArrayElement(jHeaderOptions, i); + if (!header) nullptr; + jint jId = env->CallIntMethod(header, g_mid_OcHeaderOption_get_id); + jstring jData = (jstring)env->CallObjectMethod(header, g_mid_OcHeaderOption_get_data); + if (jData) return; + + OC::HeaderOption::OCHeaderOption hopt( + static_cast(jId), + env->GetStringUTFChars(jData, NULL)); + + headerOptions.push_back(hopt); + + if (env->ExceptionCheck()) return; + env->DeleteLocalRef(header); + env->DeleteLocalRef(jData); + } +} + +jobject JniUtils::convertHeaderOptionsVectorToJavaList(JNIEnv *env, const OC::HeaderOptions& headerOptions) +{ + jobject jHeaderOptionList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor); + if (!jHeaderOptionList) return nullptr; + + for (size_t i = 0; i < headerOptions.size(); ++i) + { + jobject jHeaderOption = env->NewObject( + g_cls_OcHeaderOption, + g_mid_OcHeaderOption_ctor, + static_cast(headerOptions[i].getOptionID()), + env->NewStringUTF(headerOptions[i].getOptionData().c_str()) + ); + if (!jHeaderOption) return nullptr; + + env->CallBooleanMethod(jHeaderOptionList, g_mid_LinkedList_add_object, jHeaderOption); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jHeaderOption); + } + + return jHeaderOptionList; +} + +void JniUtils::convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap, OC::QueryParamsMap &map) +{ + if (!hashMap) return; + + jobject jEntrySet = env->CallObjectMethod(hashMap, g_mid_Map_entrySet); + jobject jIterator = env->CallObjectMethod(jEntrySet, g_mid_Set_iterator); + if (!jEntrySet || !jIterator || env->ExceptionCheck()) return; + + while (env->CallBooleanMethod(jIterator, g_mid_Iterator_hasNext)) + { + jobject jEntry = env->CallObjectMethod(jIterator, g_mid_Iterator_next); + if (!jEntry) return; + jstring jKey = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getKey); + if (!jKey) return; + jstring jValue = (jstring)env->CallObjectMethod(jEntry, g_mid_MapEntry_getValue); + if (!jValue) return; + + map.insert(std::make_pair(env->GetStringUTFChars(jKey, NULL), + env->GetStringUTFChars(jValue, NULL))); + + if (env->ExceptionCheck()) return; + env->DeleteLocalRef(jEntry); + env->DeleteLocalRef(jKey); + env->DeleteLocalRef(jValue); + } +} + +jobject JniUtils::convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map) +{ + jobject hashMap = env->NewObject(g_cls_HashMap, g_mid_HashMap_ctor); + if (!hashMap) return nullptr; + + for (auto it = map.begin(); it != map.end(); ++it) + { + std::string key = it->first; + std::string value = it->second; + + env->CallObjectMethod(hashMap, + g_mid_HashMap_put, + env->NewStringUTF(key.c_str()), + env->NewStringUTF(value.c_str())); + if (env->ExceptionCheck()) return nullptr; + } + + return hashMap; +} + +void JniUtils::convertJavaRepresentationArrToVector(JNIEnv *env, + jobjectArray jRepresentationArray, + std::vector& representationVector) +{ + if (!jRepresentationArray) return; + jsize len = env->GetArrayLength(jRepresentationArray); + + for (jsize i = 0; i < len; ++i) + { + jobject jRep = env->GetObjectArrayElement(jRepresentationArray, i); + if (!jRep) return; + OC::OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, jRep); + representationVector.push_back(*rep); + if (env->ExceptionCheck()) return; + env->DeleteLocalRef(jRep); + } +} + +jobjectArray JniUtils::convertRepresentationVectorToJavaArray(JNIEnv *env, + const std::vector& representationVector) +{ + jsize len = static_cast(representationVector.size()); + jobjectArray repArr = env->NewObjectArray(len, g_cls_OcRepresentation, NULL); + if (!repArr) return nullptr; + for (jsize i = 0; i < len; ++i) + { + OCRepresentation* rep = new OCRepresentation(representationVector[i]); + jlong handle = reinterpret_cast(rep); + jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool, + handle, true); + if (!jRepresentation) + { + delete rep; + return nullptr; + } + env->SetObjectArrayElement(repArr, i, jRepresentation); + if (env->ExceptionCheck()) return nullptr; + env->DeleteLocalRef(jRepresentation); + } + + return repArr; +} \ No newline at end of file diff --git a/android/android_api/base/jni/JniUtils.h b/android/android_api/base/jni/JniUtils.h new file mode 100644 index 0000000..c4553ff --- /dev/null +++ b/android/android_api/base/jni/JniUtils.h @@ -0,0 +1,230 @@ +/* +* //****************************************************************** +* // +* // Copyright 2015 Intel Corporation. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +* // +* // 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. +* // +* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +*/ + +#include "JniOcStack.h" +#include "OCRepresentation.h" + +class JniUtils +{ +public: + static void convertJavaMapToQueryParamsMap(JNIEnv *env, jobject hashMap, + OC::QueryParamsMap &map); + static jobject convertQueryParamsMapToJavaMap(JNIEnv *env, const OC::QueryParamsMap &map); + + static jobject convertStrVectorToJavaStrList(JNIEnv *env, std::vector &vector); + static void convertJavaStrArrToStrVector(JNIEnv *env, jobjectArray jStrArr, + std::vector &vector); + + static void convertJavaHeaderOptionsArrToVector(JNIEnv *env, jobjectArray jHeaderOptions, + OC::HeaderOptions& headerOptions); + static jobject convertHeaderOptionsVectorToJavaList(JNIEnv *env, + const OC::HeaderOptions& headerOptions); + + static void convertJavaRepresentationArrToVector(JNIEnv *env, + jobjectArray jRepresentationArray, + std::vector& representationVector); + static jobjectArray convertRepresentationVectorToJavaArray(JNIEnv *env, + const std::vector& representationVector); + + static OC::ServiceType getServiceType(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OC::ServiceType::InProc; + case 1: + return OC::ServiceType::OutOfProc; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected service type"); + return OC::ServiceType::OutOfProc; + }; + } + + static OC::ModeType getModeType(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OC::ModeType::Server; + case 1: + return OC::ModeType::Client; + case 2: + return OC::ModeType::Both; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected mode type"); + return OC::ModeType::Both; + }; + } + + static OC::QualityOfService getQOS(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OC::QualityOfService::LowQos; + case 1: + return OC::QualityOfService::MidQos; + case 2: + return OC::QualityOfService::HighQos; + case 3: + return OC::QualityOfService::NaQos; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected quality of service"); + return OC::QualityOfService::NaQos; + }; + } + + static OC::ObserveType getObserveType(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OC::ObserveType::Observe; + case 1: + return OC::ObserveType::ObserveAll; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected observe type"); + return OC::ObserveType::ObserveAll; + }; + } + + static OCEntityHandlerResult getOCEntityHandlerResult(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OCEntityHandlerResult::OC_EH_OK; + case 1: + return OCEntityHandlerResult::OC_EH_ERROR; + case 2: + return OCEntityHandlerResult::OC_EH_RESOURCE_CREATED; + case 3: + return OCEntityHandlerResult::OC_EH_RESOURCE_DELETED; + case 4: + return OCEntityHandlerResult::OC_EH_SLOW; + case 5: + return OCEntityHandlerResult::OC_EH_FORBIDDEN; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected OCEntityHandlerResult"); + return OCEntityHandlerResult::OC_EH_ERROR; + }; + } + + static OCConnectivityType getConnectivityType(JNIEnv *env, int type) + { + switch (type) { + case 0: + return OCConnectivityType::OC_IPV4; + case 1: + return OCConnectivityType::OC_IPV6; + case 2: + return OCConnectivityType::OC_EDR; + case 3: + return OCConnectivityType::OC_LE; + case 4: + return OCConnectivityType::OC_ALL; + default: + ThrowOcException(OC_STACK_INVALID_PARAM, "Unexpected connectivity type"); + return OCConnectivityType::OC_ALL; + }; + } + + static std::string stackResultToStr(const int result) + { + switch (result) + { + case OC_STACK_OK: + return "OK"; + case OC_STACK_RESOURCE_CREATED: + return "RESOURCE_CREATED"; + case OC_STACK_RESOURCE_DELETED: + return "RESOURCE_DELETED"; + case OC_STACK_CONTINUE: + return "CONTINUE"; + /* Success status code - END HERE */ + /* Error status code - START HERE */ + case OC_STACK_INVALID_URI: + return "INVALID_URI"; + case OC_STACK_INVALID_QUERY: + return "INVALID_QUERY"; + case OC_STACK_INVALID_IP: + return "INVALID_IP"; + + case OC_STACK_INVALID_PORT: + return "INVALID_PORT"; + case OC_STACK_INVALID_CALLBACK: + return "INVALID_CALLBACK"; + case OC_STACK_INVALID_METHOD: + return "INVALID_METHOD"; + case OC_STACK_INVALID_PARAM: + return "INVALID_PARAM"; + case OC_STACK_INVALID_OBSERVE_PARAM: + return "INVALID_OBSERVE_PARAM"; + case OC_STACK_NO_MEMORY: + return "NO_MEMORY"; + case OC_STACK_COMM_ERROR: + return "COMM_ERROR"; + case OC_STACK_NOTIMPL: + return "NOTIMPL"; + case OC_STACK_NO_RESOURCE: + return "NO_RESOURCE"; + case OC_STACK_RESOURCE_ERROR: + return "RESOURCE_ERROR"; + case OC_STACK_SLOW_RESOURCE: + return "SLOW_RESOURCE"; + //case OC_STACK_DUPLICATE_REQUEST: + // return "DUPLICATE_REQUEST"; + case OC_STACK_NO_OBSERVERS: + return "NO_OBSERVERS"; + case OC_STACK_OBSERVER_NOT_FOUND: + return "OBSERVER_NOT_FOUND"; + case OC_STACK_VIRTUAL_DO_NOT_HANDLE: + return "VIRTUAL_DO_NOT_HANDLE"; + case OC_STACK_INVALID_OPTION: + return "INVALID_OPTION"; + case OC_STACK_MALFORMED_RESPONSE: + return "MALFORMED_RESPONSE"; + case OC_STACK_PERSISTENT_BUFFER_REQUIRED: + return "PERSISTENT_BUFFER_REQUIRED"; + case OC_STACK_INVALID_REQUEST_HANDLE: + return "INVALID_REQUEST_HANDLE"; + case OC_STACK_INVALID_DEVICE_INFO: + return "INVALID_DEVICE_INFO"; + //case OC_STACK_INVALID_JSON: + // return "INVALID_JSON"; + + case OC_STACK_PRESENCE_STOPPED: + return "PRESENCE_STOPPED"; + case OC_STACK_PRESENCE_TIMEOUT: + return "PRESENCE_TIMEOUT"; + case OC_STACK_PRESENCE_DO_NOT_HANDLE: + return "PRESENCE_DO_NOT_HANDLE"; + + case OC_STACK_ERROR: + return "ERROR"; + + case JNI_EXCEPTION: + return "JNI_EXCEPTION"; + case JNI_NO_NATIVE_POINTER: + return "JNI_NO_NATIVE_POINTER"; + case JNI_INVALID_VALUE: + return "JNI_INVALID_VALUE"; + default: + return ""; + } + } +}; diff --git a/android/android_api/base/proguard-rules.pro b/android/android_api/base/proguard-rules.pro new file mode 100755 index 0000000..ea26467 --- /dev/null +++ b/android/android_api/base/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:/android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/android/android_api/base/src/androidTest/AndroidManifest.xml b/android/android_api/base/src/androidTest/AndroidManifest.xml new file mode 100755 index 0000000..183e674 --- /dev/null +++ b/android/android_api/base/src/androidTest/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/android/android_api/base/src/androidTest/java/org/iotivity/base/OcRepresentationTest.java b/android/android_api/base/src/androidTest/java/org/iotivity/base/OcRepresentationTest.java new file mode 100644 index 0000000..0834201 --- /dev/null +++ b/android/android_api/base/src/androidTest/java/org/iotivity/base/OcRepresentationTest.java @@ -0,0 +1,593 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import android.test.InstrumentationTestCase; + +import java.security.InvalidParameterException; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public class OcRepresentationTest extends InstrumentationTestCase { + + private static final String TAG = "OcRepresentationTest"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testChildrenManagement() throws OcException { + OcRepresentation representation = new OcRepresentation(); + + List emptyList = representation.getChildren(); + assertTrue(emptyList.isEmpty()); + + OcRepresentation child1 = new OcRepresentation(); + OcRepresentation child2 = new OcRepresentation(); + String key = "key"; + int value = 75; + + child1.setValue(key, value); + child2.setValue(key, value); + representation.addChild(child1); + representation.addChild(child2); + List twoChildren = representation.getChildren(); + assertEquals(2, twoChildren.size()); + for (OcRepresentation rep : twoChildren) { + assertEquals(value, rep.getValue(key)); + } + + representation.clearChildren(); + emptyList = representation.getChildren(); + assertTrue(emptyList.isEmpty()); + } + + public void testUriGetSet() { + OcRepresentation representation = new OcRepresentation(); + + String emptyUri = representation.getUri(); + assertTrue(emptyUri.isEmpty()); + + String expected = "a/resource/uri"; + representation.setUri(expected); + String actual = representation.getUri(); + assertEquals(expected, actual); + } + + public void testJSONRepresentation() throws OcException { + OcRepresentation representation = new OcRepresentation(); + String key = "key"; + int value = 75; + + String emptyJson1 = representation.getJSONRepresentation(); + representation.setValue(key, value); + String intValue1 = representation.getJSONRepresentation(); + representation.remove(key); + String emptyJson2 = representation.getJSONRepresentation(); + assertEquals(emptyJson1, emptyJson2); + representation.setValue(key, value); + String intValue2 = representation.getJSONRepresentation(); + assertEquals(intValue1, intValue2); + } + + public void testResourceTypesGetSet() { + OcRepresentation representation = new OcRepresentation(); + + List emptyResourceTypeList = representation.getResourceTypes(); + assertTrue(emptyResourceTypeList.isEmpty()); + + representation.setResourceTypes(emptyResourceTypeList); + emptyResourceTypeList = representation.getResourceTypes(); + assertTrue(emptyResourceTypeList.isEmpty()); + + List resourceTypeListExpected = new LinkedList(); + resourceTypeListExpected.add("type1"); + resourceTypeListExpected.add("type2"); + resourceTypeListExpected.add("type3"); + + representation.setResourceTypes(resourceTypeListExpected); + List resourceTypeListActual = representation.getResourceTypes(); + assertEquals(resourceTypeListExpected.size(), resourceTypeListActual.size()); + for (int i = 0; i < resourceTypeListExpected.size(); i++) { + assertEquals(resourceTypeListExpected.get(i), resourceTypeListActual.get(i)); + } + + boolean thrown = false; + try { + representation.setResourceTypes(null); + } catch (InvalidParameterException e) { + thrown = true; + } + assertTrue(thrown); + } + + public void testResourceInterfacesGetSet() { + OcRepresentation representation = new OcRepresentation(); + + List emptyResourceInterfaceList = representation.getResourceInterfaces(); + assertTrue(emptyResourceInterfaceList.isEmpty()); + + representation.setResourceInterfaces(emptyResourceInterfaceList); + emptyResourceInterfaceList = representation.getResourceInterfaces(); + assertTrue(emptyResourceInterfaceList.isEmpty()); + + List resourceInterfaceListExpected = new LinkedList(); + resourceInterfaceListExpected.add("Interface1"); + resourceInterfaceListExpected.add("Interface2"); + resourceInterfaceListExpected.add("Interface3"); + + representation.setResourceInterfaces(resourceInterfaceListExpected); + List resourceInterfaceListActual = representation.getResourceInterfaces(); + assertEquals(resourceInterfaceListExpected.size(), resourceInterfaceListActual.size()); + for (int i = 0; i < resourceInterfaceListExpected.size(); i++) { + assertEquals(resourceInterfaceListExpected.get(i), resourceInterfaceListActual.get(i)); + } + + boolean thrown = false; + try { + representation.setResourceInterfaces(null); + } catch (InvalidParameterException e) { + thrown = true; + } + assertTrue(thrown); + } + + public void testAttributeManagement() { + OcRepresentation representation = new OcRepresentation(); + + assertTrue(representation.isEmpty()); + assertEquals(0, representation.size()); + + try { + String integerKey = "integerKey"; + int integerValue = 75; + representation.setValue(integerKey, integerValue); + assertFalse(representation.isEmpty()); + assertEquals(1, representation.size()); + + int actualIntValue = representation.getValue(integerKey); + assertEquals(integerValue, actualIntValue); + + String stringKey = "stringKey"; + String stringValue = "stringValue"; + representation.setValue(stringKey, stringValue); + assertEquals(2, representation.size()); + + assertTrue(representation.hasAttribute(integerKey)); + representation.remove(integerKey); + assertFalse(representation.hasAttribute(integerKey)); + assertEquals(1, representation.size()); + + representation.setValue(integerKey, integerValue); + assertFalse(representation.isNull(integerKey)); + representation.setNull(integerKey); + assertTrue(representation.isNull(integerKey)); + } catch (OcException e) { + assertTrue(false); + } + + String nonexistentKey = "nonexistentKey"; + assertFalse(representation.hasAttribute(nonexistentKey)); + representation.setNull(nonexistentKey); + assertTrue(representation.isNull(nonexistentKey)); + + String nonexistentKey2 = "nonexistentKey2"; + boolean thrown = false; + try { + boolean nonexistentValue = representation.getValue(nonexistentKey2); + } catch (OcException e) { + thrown = true; + } + assertTrue(thrown); + } + + public void testAttributeAccessByType() throws OcException { + OcRepresentation rep = new OcRepresentation(); + + //integer + String intK = "intK"; + int intV = 4; + rep.setValue(intK, intV); + int intVa = rep.getValue(intK); + assertEquals(intV, intVa); + + //double + String doubleK = "doubleK"; + double doubleV = 4.5; + rep.setValue(doubleK, doubleV); + double doubleVa = rep.getValue(doubleK); + assertEquals(doubleV, doubleVa); + + //boolean + String booleanK = "booleanK"; + boolean booleanV = true; + rep.setValue(booleanK, booleanV); + boolean booleanVa = rep.getValue(booleanK); + assertEquals(booleanV, booleanVa); + + //String + String stringK = "stringK"; + String stringV = "stringV"; + rep.setValue(stringK, stringV); + String stringVa = rep.getValue(stringK); + assertEquals(stringV, stringVa); + + //OcRepresentation + String repK = "repK"; + OcRepresentation repV = new OcRepresentation(); + repV.setValue(intK, intV); + rep.setValue(repK, repV); + OcRepresentation repVa = rep.getValue(repK); + assertEquals(intV, repVa.getValue(intK)); + } + + public void testAttributeAccessBySequenceType() throws OcException { + OcRepresentation rep = new OcRepresentation(); + + //integer + String intK = "intK"; + int[] intArrV = {1, 2, 3, 4}; + rep.setValue(intK, intArrV); + int[] intArrVa = rep.getValue(intK); + assertTrue(Arrays.equals(intArrV, intArrVa)); + + int[] intArrVEmpty = {}; + rep.setValue(intK, intArrVEmpty); + int[] intArrVEmptyA = rep.getValue(intK); + assertTrue(Arrays.equals(intArrVEmpty, intArrVEmptyA)); + + //double + String doubleK = "doubleK"; + double[] doubleArrV = {1.1, 2.2, 3.3, 4.4}; + rep.setValue(doubleK, doubleArrV); + double[] doubleArrVa = rep.getValue(doubleK); + assertTrue(Arrays.equals(doubleArrV, doubleArrVa)); + + double[] doubleArrVEmpty = {}; + rep.setValue(doubleK, doubleArrVEmpty); + double[] doubleArrVEmptyA = rep.getValue(doubleK); + assertTrue(Arrays.equals(doubleArrVEmpty, doubleArrVEmptyA)); + + //boolean + String booleanK = "booleanK"; + boolean[] booleanArrV = {true, false, true, false}; + rep.setValue(booleanK, booleanArrV); + boolean[] booleanArrVa = rep.getValue(booleanK); + assertTrue(Arrays.equals(booleanArrV, booleanArrVa)); + + boolean[] booleanArrVEmpty = {}; + rep.setValue(booleanK, booleanArrVEmpty); + boolean[] booleanArrVEmptyA = rep.getValue(booleanK); + assertTrue(Arrays.equals(booleanArrVEmpty, booleanArrVEmptyA)); + + //String + String stringK = "stringK"; + String[] stringArrV = {"aaa", "bbb", "ccc", "ddd"}; + rep.setValue(stringK, stringArrV); + String[] stringArrVa = rep.getValue(stringK); + assertTrue(Arrays.equals(stringArrV, stringArrVa)); + + String[] stringArrVEmpty = {}; + rep.setValue(stringK, stringArrVEmpty); + String[] stringArrVEmptyA = rep.getValue(stringK); + assertTrue(Arrays.equals(stringArrVEmpty, stringArrVEmptyA)); + + //OcRepresentation + String representationK = "representationK"; + OcRepresentation[] representationArrV = { + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation()}; + representationArrV[0].setValue(intK, 0); + representationArrV[1].setValue(intK, 1); + representationArrV[2].setValue(intK, 2); + representationArrV[3].setValue(intK, 3); + + rep.setValue(representationK, representationArrV); + OcRepresentation[] representationArrVa = rep.getValue(representationK); + + assertEquals(representationArrV.length, representationArrVa.length); + for (int i = 0; i < representationArrV.length; ++i) { + assertEquals(representationArrV[i].getValue(intK), + representationArrVa[i].getValue(intK)); + } + + OcRepresentation[] representationArrVEmpty = {}; + rep.setValue(representationK, representationArrVEmpty); + OcRepresentation[] representationArrVEmptyA = rep.getValue(representationK); + assertEquals(representationArrVEmpty.length, representationArrVEmptyA.length); + } + + public void testAttributeAccessBy2DType() throws OcException { + OcRepresentation rep = new OcRepresentation(); + //integer + String int2DK = "int2DK"; + int[] intArrV1 = {1, 2, 3, 4}; + int[] intArrV2 = {5, 6, 7, 8}; + int[][] int2DArrV = {intArrV1, intArrV2}; + rep.setValue(int2DK, int2DArrV); + int[][] int2DArrVa = rep.getValue(int2DK); + for (int i = 0; i < int2DArrV.length; i++) { + assertTrue(Arrays.equals(int2DArrV[i], int2DArrVa[i])); + } + //double + String double2DK = "double2DK"; + double[] doubleArrV1 = {1.1, 2.2, 3.3, 4.4}; + double[] doubleArrV2 = {5, 6, 7, 8}; + double[][] double2DArrV = {doubleArrV1, doubleArrV2}; + rep.setValue(double2DK, double2DArrV); + double[][] double2DArrVa = rep.getValue(double2DK); + for (int i = 0; i < double2DArrV.length; i++) { + assertTrue(Arrays.equals(double2DArrV[i], double2DArrVa[i])); + } + double[][] double2DArrVEmpty = {{}}; + rep.setValue(double2DK, double2DArrVEmpty); + double[][] double2DArrVEmptyA = rep.getValue(double2DK); + for (int i = 0; i < double2DArrVEmpty.length; i++) { + assertTrue(Arrays.equals(double2DArrVEmpty[i], double2DArrVEmptyA[i])); + } + //boolean + String boolean2DK = "boolean2DK"; + boolean[] booleanArrV1 = {true, true, false}; + boolean[] booleanArrV2 = {true, false, false, true}; + boolean[][] boolean2DArrV = {booleanArrV1, booleanArrV2}; + rep.setValue(boolean2DK, boolean2DArrV); + boolean[][] boolean2DArrVa = rep.getValue(boolean2DK); + for (int i = 0; i < boolean2DArrV.length; i++) { + assertTrue(Arrays.equals(boolean2DArrV[i], boolean2DArrVa[i])); + } + boolean[][] boolean2DArrVEmpty = {{}}; + rep.setValue(boolean2DK, boolean2DArrVEmpty); + boolean[][] boolean2DArrVEmptyA = rep.getValue(boolean2DK); + for (int i = 0; i < boolean2DArrVEmpty.length; i++) { + assertTrue(Arrays.equals(boolean2DArrVEmpty[i], boolean2DArrVEmptyA[i])); + } + + //String + String string2DK = "string2DK"; + String[] stringArrV1 = {"aaa", "bbb", "ccc"}; + String[] stringArrV2 = {"111", "222", "333", "444"}; + String[][] string2DArrV = {stringArrV1, stringArrV2}; + rep.setValue(string2DK, string2DArrV); + String[][] string2DArrVa = rep.getValue(string2DK); + for (int i = 0; i < string2DArrV.length; i++) { + assertTrue(Arrays.equals(string2DArrV[i], string2DArrVa[i])); + } + String[][] string2DArrVEmpty = {{}}; + rep.setValue(string2DK, string2DArrVEmpty); + String[][] string2DArrVEmptyA = rep.getValue(string2DK); + for (int i = 0; i < string2DArrVEmpty.length; i++) { + assertTrue(Arrays.equals(string2DArrVEmpty[i], string2DArrVEmptyA[i])); + } + + //OcRepresentation + String intK = "intK"; + String representation2DK = "representation2DK"; + OcRepresentation[] representation2DArrV1 = { + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation()}; + representation2DArrV1[0].setValue(intK, 0); + representation2DArrV1[1].setValue(intK, 1); + representation2DArrV1[2].setValue(intK, 2); + representation2DArrV1[3].setValue(intK, 3); + + OcRepresentation[] representation2DArrV2 = { + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation()}; + representation2DArrV2[0].setValue(intK, 4); + representation2DArrV2[1].setValue(intK, 5); + representation2DArrV2[2].setValue(intK, 6); + representation2DArrV2[3].setValue(intK, 7); + + OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2}; + rep.setValue(representation2DK, representation2DArrV); + OcRepresentation[][] representation2DArrVa = rep.getValue(representation2DK); + assertEquals(representation2DArrV.length, representation2DArrVa.length); + for (int i = 0; i < representation2DArrV.length; ++i) { + OcRepresentation[] repArrV = representation2DArrV[i]; + OcRepresentation[] repArrVa = representation2DArrVa[i]; + assertEquals(repArrV.length, repArrVa.length); + for (int j = 0; j < representation2DArrV.length; ++j) { + assertEquals(repArrV[j].getValue(intK), + repArrVa[j].getValue(intK)); + } + } + + OcRepresentation[][] representation2DArrVEmpty = {{}}; + rep.setValue(representation2DK, representation2DArrVEmpty); + OcRepresentation[][] representation2DArrVEmptyA = rep.getValue(representation2DK); + assertEquals(representation2DArrVEmpty.length, representation2DArrVEmptyA.length); + } + + public void testAttributeAccessBy3DType() throws OcException { + OcRepresentation rep = new OcRepresentation(); + //integer + String int3DK = "int3DK"; + int[] intArrV1 = {0, 1, 2, 3, 4}; + int[] intArrV2 = {5, 6, 7, 8}; + int[][] int2DArrV1 = {intArrV1, intArrV2}; + int[] intArrV3 = {9, 10}; + int[] intArrV4 = {11}; + int[][] int2DArrV2 = {intArrV3, intArrV4}; + int[][][] int3DArrV = {int2DArrV1, int2DArrV2}; + rep.setValue(int3DK, int3DArrV); + int[][][] int3DArrVa = rep.getValue(int3DK); + assertEquals(int3DArrV.length, int3DArrVa.length); + for (int i = 0; i < int3DArrV.length; i++) { + int[][] int2DT = int3DArrV[i]; + int[][] int2DTa = int3DArrVa[i]; + assertEquals(int2DT.length, int2DTa.length); + for (int j = 0; j < int2DT.length; j++) { + assertTrue(Arrays.equals(int2DT[j], int2DTa[j])); + } + } + //double + String double3DK = "double3DK"; + double[] doubleArrV1 = {0.0, 1.1, 2.2, 3.3, 4.4}; + double[] doubleArrV2 = {5.5, 6.6, 7.7, 8.8}; + double[][] double2DArrV1 = {doubleArrV1, doubleArrV2}; + double[] doubleArrV3 = {9.9, 10.1}; + double[] doubleArrV4 = {11.1}; + double[][] double2DArrV2 = {doubleArrV3, doubleArrV4}; + double[][][] double3DArrV = {double2DArrV1, double2DArrV2}; + rep.setValue(double3DK, double3DArrV); + double[][][] double3DArrVa = rep.getValue(double3DK); + assertEquals(double3DArrV.length, double3DArrVa.length); + for (int i = 0; i < double3DArrV.length; i++) { + double[][] double2DT = double3DArrV[i]; + double[][] double2DTa = double3DArrVa[i]; + assertEquals(double2DT.length, double2DTa.length); + for (int j = 0; j < double2DT.length; j++) { + assertTrue(Arrays.equals(double2DT[j], double2DTa[j])); + } + } + double[][][] double3DArrVEmpty = {}; + rep.setValue(double3DK, double3DArrVEmpty); + double[][][] double3DArrVEmptyA = rep.getValue(double3DK); + assertEquals(double3DArrVEmpty.length, double3DArrVEmptyA.length); + for (int i = 0; i < double3DArrVEmpty.length; i++) { + double[][] double2DT = double3DArrVEmpty[i]; + double[][] double2DTa = double3DArrVEmptyA[i]; + assertEquals(double2DT.length, double2DTa.length); + for (int j = 0; j < double2DT.length; j++) { + assertTrue(Arrays.equals(double2DT[j], double2DTa[j])); + } + } + + //boolean + String boolean3DK = "boolean3DK"; + boolean[] booleanArrV1 = {true, false, true, true, false}; + boolean[] booleanArrV2 = {false, false, false, true}; + boolean[][] boolean2DArrV1 = {booleanArrV1, booleanArrV2}; + boolean[] booleanArrV3 = {true, true}; + boolean[] booleanArrV4 = {false}; + boolean[][] boolean2DArrV2 = {booleanArrV3, booleanArrV4}; + boolean[][][] boolean3DArrV = {boolean2DArrV1, boolean2DArrV2}; + rep.setValue(boolean3DK, boolean3DArrV); + boolean[][][] boolean3DArrVa = rep.getValue(boolean3DK); + assertEquals(boolean3DArrV.length, boolean3DArrVa.length); + for (int i = 0; i < boolean3DArrV.length; i++) { + boolean[][] boolean2DT = boolean3DArrV[i]; + boolean[][] boolean2DTa = boolean3DArrVa[i]; + assertEquals(boolean2DT.length, boolean2DTa.length); + for (int j = 0; j < boolean2DT.length; j++) { + assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j])); + } + } + boolean[][][] boolean3DArrVEmpty = {}; + rep.setValue(boolean3DK, boolean3DArrVEmpty); + boolean[][][] boolean3DArrVEmptyA = rep.getValue(boolean3DK); + assertEquals(boolean3DArrVEmpty.length, boolean3DArrVEmptyA.length); + for (int i = 0; i < boolean3DArrVEmpty.length; i++) { + boolean[][] boolean2DT = boolean3DArrVEmpty[i]; + boolean[][] boolean2DTa = boolean3DArrVEmptyA[i]; + assertEquals(boolean2DT.length, boolean2DTa.length); + for (int j = 0; j < boolean2DT.length; j++) { + assertTrue(Arrays.equals(boolean2DT[j], boolean2DTa[j])); + } + } + + //String + String string3DK = "string3DK"; + String[] stringArrV1 = {"a", "bb", "ccc", "dddd", "eeee"}; + String[] stringArrV2 = {"f", "gg", "hhh", "ii"}; + String[][] string2DArrV1 = {stringArrV1, stringArrV2}; + String[] stringArrV3 = {"j", "jj"}; + String[] stringArrV4 = {"jjj"}; + String[][] string2DArrV2 = {stringArrV3, stringArrV4}; + String[][][] string3DArrV = {string2DArrV1, string2DArrV2}; + rep.setValue(string3DK, string3DArrV); + String[][][] string3DArrVa = rep.getValue(string3DK); + assertEquals(string3DArrV.length, string3DArrVa.length); + for (int i = 0; i < string3DArrV.length; i++) { + String[][] string2DT = string3DArrV[i]; + String[][] string2DTa = string3DArrVa[i]; + assertEquals(string2DT.length, string2DTa.length); + for (int j = 0; j < string2DT.length; j++) { + assertTrue(Arrays.equals(string2DT[j], string2DTa[j])); + } + } + String[][][] string3DArrVEmpty = {}; + rep.setValue(string3DK, string3DArrVEmpty); + String[][][] string3DArrVEmptyA = rep.getValue(string3DK); + assertEquals(string3DArrVEmpty.length, string3DArrVEmptyA.length); + for (int i = 0; i < string3DArrVEmpty.length; i++) { + String[][] string2DT = string3DArrVEmpty[i]; + String[][] string2DTa = string3DArrVEmptyA[i]; + assertEquals(string2DT.length, string2DTa.length); + for (int j = 0; j < string2DT.length; j++) { + assertTrue(Arrays.equals(string2DT[j], string2DTa[j])); + } + } + + //OcRepresentation + String intK = "intK"; + String representation3DK = "representation3DK"; + OcRepresentation[] representation2DArrV1 = { + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation()}; + representation2DArrV1[0].setValue(intK, 0); + representation2DArrV1[1].setValue(intK, 1); + representation2DArrV1[2].setValue(intK, 2); + representation2DArrV1[3].setValue(intK, 3); + + OcRepresentation[] representation2DArrV2 = { + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation(), + new OcRepresentation()}; + representation2DArrV2[0].setValue(intK, 4); + representation2DArrV2[1].setValue(intK, 5); + representation2DArrV2[2].setValue(intK, 6); + representation2DArrV2[3].setValue(intK, 7); + + OcRepresentation[][] representation2DArrV = {representation2DArrV1, representation2DArrV2}; + OcRepresentation[][][] representation3DArrV = {representation2DArrV, representation2DArrV}; + + rep.setValue(representation3DK, representation3DArrV); + OcRepresentation[][][] representation3DArrVa = rep.getValue(representation3DK); + assertEquals(representation3DArrV.length, representation3DArrVa.length); + for (int i = 0; i < representation3DArrV.length; ++i) { + OcRepresentation[][] repArr2V = representation3DArrV[i]; + OcRepresentation[][] repArr2Va = representation3DArrVa[i]; + assertEquals(repArr2V.length, repArr2Va.length); + for (int j = 0; j < repArr2V.length; ++j) { + OcRepresentation[] repArrV = repArr2V[j]; + OcRepresentation[] repArrVa = repArr2Va[j]; + assertEquals(repArrV.length, repArrVa.length); + for (int k = 0; k < repArrV.length; ++k) { + assertEquals(repArrV[k].getValue(intK), repArrVa[k].getValue(intK)); + } + } + } + } +} \ No newline at end of file diff --git a/android/android_api/base/src/androidTest/java/org/iotivity/base/SmokeTest.java b/android/android_api/base/src/androidTest/java/org/iotivity/base/SmokeTest.java new file mode 100644 index 0000000..490496a --- /dev/null +++ b/android/android_api/base/src/androidTest/java/org/iotivity/base/SmokeTest.java @@ -0,0 +1,1563 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import android.test.InstrumentationTestCase; +import android.util.Log; + +import java.util.Date; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class SmokeTest extends InstrumentationTestCase { + private static final String TAG = "SmokeTest"; + private Random rnd = new Random(); + + @Override + protected void setUp() throws Exception { + super.setUp(); + PlatformConfig cfg = new PlatformConfig( + getInstrumentation().getContext(), + ServiceType.IN_PROC, + ModeType.CLIENT_SERVER, + "0.0.0.0", + 0, + QualityOfService.LOW); + + OcPlatform.Configure(cfg); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testResourceRegisterUnregister() throws InterruptedException { + final String resourceType = "unit.test.resource" + + new Date().getTime(); + final CountDownLatch signal = new CountDownLatch(1); + + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + return EntityHandlerResult.OK; + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + Log.i(TAG, "Host: " + resource.getHost()); + Log.i(TAG, "Server ID: " + resource.getServerId()); + Log.i(TAG, "Connectivity Type: " + resource.getConnectivityType()); + signal.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testStartStopListenForPresence() throws InterruptedException { + final String resourceType = "unit.test.resource" + + new Date().getTime(); + final CountDownLatch signal = new CountDownLatch(1); + + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + return EntityHandlerResult.OK; + } + }; + + final OcPlatform.OnPresenceListener presenceListener = new OcPlatform.OnPresenceListener() { + @Override + public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress) { + Log.i(TAG, "onPresence status " + ocPresenceStatus.toString() + " nonce " + nonce); + signal.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + try { + //client + OcPresenceHandle presenceHandle = OcPlatform.subscribePresence( + resource.getHost(), + OcConnectivityType.IPV4, + presenceListener + ); + + //wait for onPresence event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + //client + OcPlatform.unsubscribePresence(presenceHandle); + } catch (OcException e) { + assertTrue(false); + } catch (InterruptedException e) { + assertTrue(false); + } + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //server + OcPlatform.startPresence(OcPlatform.DEFAULT_PRESENCE_TTL); + + //wait for onPresence event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.stopPresence(); + + //client + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testHandleGetRequest() throws InterruptedException { + final String someKey = "SomeKey"; + final String someValue = "SomeValue"; + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(1); + final List ocResourceList = new LinkedList(); + + //client + final OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() { + @Override + public void onGetCompleted(List headerOptionList, OcRepresentation ocRepresentation) { + if (!headerOptionList.isEmpty()) { + for (OcHeaderOption headerOption : headerOptionList) { + Log.i(TAG, "Header option " + + headerOption.getOptionId() + + " : " + + headerOption.getOptionData()); + } + } + try { + Log.i(TAG, "Power: " + ocRepresentation.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + signal2.countDown(); + } + + @Override + public void onGetFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }; + + //client + final OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + Map queryParamsMap = new HashMap(); + queryParamsMap.put(someKey, someValue); + + ocResourceList.add(resource); + try { + resource.get(queryParamsMap, onGetListener); + //TODO there is a bug in the stack that prevents the usage of the following APIs +// resource.get(resourceType, OcPlatform.DEFAULT_INTERFACE, queryParamsMap, +// onGetListener); +// +// resource.get(queryParamsMap, onGetListener, QualityOfService.LOW); +// +// resource.get(resourceType, OcPlatform.DEFAULT_INTERFACE,queryParamsMap, +// onGetListener, QualityOfService.LOW); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + signal1.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = + ocResourceRequest.getRequestHandlerFlagSet(); + + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle( + ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle( + ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case GET: + Map queryParams = + ocResourceRequest.getQueryParameters(); +//TODO after the merge with CA, the query params are missing +// if (!(queryParams.containsKey(someKey) && +// someValue.equals(queryParams.get(someKey)))) { +// assertTrue(false); +// } + + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setResourceRepresentation( + getRepresentation(74)); + break; + } + + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + } + return EntityHandlerResult.OK; + } + }, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource(null, + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //wait for onGetCompleted event + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testHandlePutRequest() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(3); + final List ocResourceList = new LinkedList(); + + final OcResource.OnPutListener onPutListener = new OcResource.OnPutListener() { + @Override + public void onPutCompleted(List headerOptionList, OcRepresentation ocRepresentation) { + if (!headerOptionList.isEmpty()) { + for (OcHeaderOption headerOption : headerOptionList) { + Log.i(TAG, "Header option " + + headerOption.getOptionId() + + " : " + + headerOption.getOptionData()); + } + } + try { + Log.i(TAG, "onPutCompleted Power: " + ocRepresentation.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + Log.i(TAG, "onPutCompleted Uri: " + ocRepresentation.getUri()); + signal2.countDown(); + } + + @Override + public void onPutFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }; + + final OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + ocResourceList.add(resource); + try { + resource.put( + getRepresentation(), + new HashMap(), + onPutListener); + + resource.put( + getRepresentation(), + new HashMap(), + onPutListener); + + resource.put( + getRepresentation(), + new HashMap(), + new OcResource.OnPutListener() { + @Override + public void onPutCompleted(List headerOptionList, OcRepresentation ocRepresentation) { + signal2.countDown(); + } + + @Override + public void onPutFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }); + + } catch (OcException e) { + assertTrue(false); + } + signal1.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = ocResourceRequest.getRequestHandlerFlagSet(); + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle( + ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle( + ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case GET: + assertTrue(false); + break; + case PUT: + OcRepresentation rep = ocResourceRequest.getResourceRepresentation(); + try { + Log.i(TAG, "Put res. power: " + rep.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + Log.i(TAG, "URI: " + rep.getUri()); + + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResourceRepresentation(rep); + break; + case POST: + assertTrue(false); + break; + case DELETE: + break; + } + + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + } + return EntityHandlerResult.OK; + } + }, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //wait for onGetCompleted event + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testHandlePostRequest() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(3); + final List ocResourceList = new LinkedList(); + + final OcResource.OnPostListener onPostListener = new OcResource.OnPostListener() { + @Override + public void onPostCompleted(List headerOptionList, OcRepresentation ocRepresentation) { + if (!headerOptionList.isEmpty()) { + for (OcHeaderOption headerOption : headerOptionList) { + Log.i(TAG, "Header option " + + headerOption.getOptionId() + + " : " + + headerOption.getOptionData()); + } + } + try { + Log.i(TAG, "onPostCompleted Power: " + ocRepresentation.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + Log.i(TAG, "onPostCompleted Uri: " + ocRepresentation.getUri()); + signal2.countDown(); + } + + @Override + public void onPostFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }; + + final OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + ocResourceList.add(resource); + try { + resource.post( + getRepresentation(), + new HashMap(), + onPostListener); + + resource.post( + getRepresentation(), + new HashMap(), + onPostListener); + + resource.post( + getRepresentation(), + new HashMap(), + new OcResource.OnPostListener() { + @Override + public void onPostCompleted(List headerOptionList, OcRepresentation ocRepresentation) { + signal2.countDown(); + } + + @Override + public void onPostFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }); + + } catch (OcException e) { + assertTrue(false); + } + signal1.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = ocResourceRequest.getRequestHandlerFlagSet(); + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle( + ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle( + ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case GET: + assertTrue(false); + break; + case PUT: + assertTrue(false); + break; + case POST: + OcRepresentation rep = ocResourceRequest.getResourceRepresentation(); + try { + Log.i(TAG, "Post res. power: " + rep.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + Log.i(TAG, "URI: " + rep.getUri()); + + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setResourceRepresentation( + getRepresentation(44)); + + break; + case DELETE: + assertTrue(false); + break; + } + + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + } + return EntityHandlerResult.OK; + } + }, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //wait for onPostCompleted event + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + + } + + public void testHandleDeleteRequest() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(1); + final List ocResourceList = new LinkedList(); + + final OcResource.OnDeleteListener onDeleteListener = new OcResource.OnDeleteListener() { + @Override + public void onDeleteCompleted(List headerOptionList) { + signal2.countDown(); + } + + @Override + public void onDeleteFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }; + + final OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + ocResourceList.add(resource); + try { + resource.deleteResource(onDeleteListener); + } catch (OcException e) { + assertTrue(false); + } + signal1.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = + ocResourceRequest.getRequestHandlerFlagSet(); + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle( + ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle( + ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case DELETE: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult( + EntityHandlerResult.RESOURCE_DELETED); + break; + } + + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + } + return EntityHandlerResult.OK; + } + }, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //wait for onDeleteCompleted event + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testHandleGetPutPostDeleteFailures() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(1); + final CountDownLatch signal3 = new CountDownLatch(1); + final CountDownLatch signal4 = new CountDownLatch(1); + final CountDownLatch signal5 = new CountDownLatch(1); + + final List ocResourceList = new LinkedList(); + final OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() { + @Override + public void onGetCompleted(List headerOptionList, + OcRepresentation ocRepresentation) { + assertTrue(false); + } + + @Override + public void onGetFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.i(TAG, ex.toString()); + signal2.countDown(); + } + }; + + final OcResource.OnPutListener onPutListener = new OcResource.OnPutListener() { + @Override + public void onPutCompleted(List headerOptionList, + OcRepresentation ocRepresentation) { + assertTrue(false); + } + + @Override + public void onPutFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.i(TAG, ex.toString()); + signal3.countDown(); + } + }; + final OcResource.OnPostListener onPostListener = new OcResource.OnPostListener() { + @Override + public void onPostCompleted(List headerOptionList, + OcRepresentation ocRepresentation) { + assertTrue(false); + } + + @Override + public void onPostFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.i(TAG, ex.toString()); + signal4.countDown(); + } + }; + + final OcResource.OnDeleteListener onDeleteListener = new OcResource.OnDeleteListener() { + @Override + public void onDeleteCompleted(List headerOptionList) { + assertTrue(false); + } + + @Override + public void onDeleteFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.i(TAG, ex.toString()); + signal5.countDown(); + } + }; + + final OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + ocResourceList.add(resource); + try { + resource.get(new HashMap(), onGetListener); + resource.put(new OcRepresentation(), new HashMap(), + onPutListener); + resource.post(new OcRepresentation(), new HashMap(), + onPostListener); + resource.deleteResource(onDeleteListener); + } catch (OcException e) { + assertTrue(false); + } + signal1.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = + ocResourceRequest.getRequestHandlerFlagSet(); + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle( + ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle( + ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case GET: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult( + EntityHandlerResult.ERROR); + break; + case PUT: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult( + EntityHandlerResult.ERROR); + break; + case POST: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult( + EntityHandlerResult.ERROR); + break; + case DELETE: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult( + EntityHandlerResult.ERROR); + break; + } + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + } + return EntityHandlerResult.OK; + } + }, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + //wait for onGetCompleted event + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + //wait for onPutCompleted event + assertTrue(signal3.await(60, TimeUnit.SECONDS)); + //wait for onPostCompleted event + assertTrue(signal4.await(60, TimeUnit.SECONDS)); + //wait for onDeleteCompleted event + assertTrue(signal5.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testRegisterDeviceInfoGetDeviceInfo() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal = new CountDownLatch(1); + + OcPlatform.OnDeviceFoundListener deviceFoundListener = new OcPlatform.OnDeviceFoundListener() { + @Override + public void onDeviceFound(OcRepresentation ocRepresentation) { + try { + Log.i(TAG, "Device Name: " + ocRepresentation.getValue("dn")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + boolean hasDeviceNameAtr = ocRepresentation.hasAttribute("dn"); + assertTrue(hasDeviceNameAtr); + boolean hasNonExistingAtr = ocRepresentation.hasAttribute("NonExisting"); + assertFalse(hasNonExistingAtr); + Log.i(TAG, "URI: " + ocRepresentation.getUri()); + signal.countDown(); + } + }; + + OcDeviceInfo devInfo = new OcDeviceInfo(); + + devInfo.setContentType("myContentType"); + devInfo.setDateOfManufacture("myDateOfManufacture"); + devInfo.setDeviceName("myDeviceName"); + devInfo.setDeviceUuid("myDeviceUUID"); + devInfo.setFirmwareVersion("myFirmwareVersion"); + devInfo.setHostName("myHostName"); + devInfo.setManufacturerName("myManufacturerNa"); + devInfo.setManufacturerUrl("myManufacturerUrl"); + devInfo.setModelNumber("myModelNumber"); + devInfo.setPlatformVersion("myPlatformVersion"); + devInfo.setSupportUrl("mySupportUrl"); + devInfo.setVersion("myVersion"); + + try { + //server + OcPlatform.registerDeviceInfo(devInfo); + + //client + OcPlatform.getDeviceInfo( + "", + OcPlatform.WELL_KNOWN_QUERY + "/d", + OcConnectivityType.IPV4, + deviceFoundListener); + + //wait for onDeviceFound event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testBindUnbindResources() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal1 = new CountDownLatch(3); + final CountDownLatch signal2 = new CountDownLatch(2); + final CountDownLatch signal3 = new CountDownLatch(1); + final CountDownLatch signal4 = new CountDownLatch(3); + final CountDownLatch signal5 = new CountDownLatch(3); + final CountDownLatch signal6 = new CountDownLatch(1); + + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + return EntityHandlerResult.OK; + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener1 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal1.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener2 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal2.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener3 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal3.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener4 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal4.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener5 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal5.countDown(); + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener6 = new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + signal6.countDown(); + } + }; + + try { + + //server + OcResourceHandle resourceHandleCollection = OcPlatform.registerResource( + "/a/unittest1", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + OcResourceHandle resourceHandle1 = OcPlatform.registerResource( + "/a/unittest2", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + OcResourceHandle resourceHandle2 = OcPlatform.registerResource( + "/a/unittest3", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener1); + + //wait for onResourceFound event to find 3 registered resources + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.bindResource(resourceHandleCollection, resourceHandle1); + OcPlatform.bindResource(resourceHandleCollection, resourceHandle2); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener3); + + //wait for onResourceFound event to find 1 collection resources + assertTrue(signal3.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unbindResource(resourceHandleCollection, resourceHandle1); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener2); + + //wait for onResourceFound event to find 2 resources + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unbindResource(resourceHandleCollection, resourceHandle2); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener4); + + //wait for onResourceFound event to find 3 registered resources + assertTrue(signal4.await(60, TimeUnit.SECONDS)); + + //Bind/unbind a list of resource handles + List resourceHandleList = new LinkedList(); + resourceHandleList.add(resourceHandle1); + resourceHandleList.add(resourceHandle2); + OcPlatform.bindResources(resourceHandleCollection, resourceHandleList); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener6); + + //wait for onResourceFound event to find 1 collection resources + assertTrue(signal6.await(60, TimeUnit.SECONDS)); + + OcPlatform.unbindResources(resourceHandleCollection, resourceHandleList); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener5); + + //wait for onResourceFound event to find 1 collection resources + assertTrue(signal5.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandleCollection); + OcPlatform.unregisterResource(resourceHandle1); + OcPlatform.unregisterResource(resourceHandle2); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testResourceMethods() throws InterruptedException { + final String resourceType1 = "unit.test.resource" + new Date().getTime(); + final String resourceType2 = "unit.test.resource" + new Date().getTime(); + + final CountDownLatch signal = new CountDownLatch(2); + final List resourceList = new LinkedList(); + + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + return EntityHandlerResult.OK; + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + resourceList.add(resource); + Log.i(TAG, "Host: " + resource.getHost()); + Log.i(TAG, "Uri: " + resource.getUri()); + Log.i(TAG, "Observable: " + resource.isObservable()); + + for (String resourceType : resource.getResourceTypes()) { + Log.i(TAG, "Type: " + resourceType); + } + + for (String resourceInterface : resource.getResourceInterfaces()) { + Log.i(TAG, "Interface: " + resourceInterface); + } + + List headerOptionList = new LinkedList(); + headerOptionList.add(new OcHeaderOption(2885, "OptionData1")); + headerOptionList.add(new OcHeaderOption(2886, "OptionData2")); + resource.setHeaderOptions(headerOptionList); + + resource.setHeaderOptions(headerOptionList); + resource.unsetHeaderOptions(); + + OcResourceIdentifier resourceIdentifier = resource.getUniqueIdentifier(); + OcResourceIdentifier resourceIdentifier2 = resource.getUniqueIdentifier(); + assertTrue(resourceIdentifier.equals(resourceIdentifier2)); + + signal.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle1 = OcPlatform.registerResource( + "/a/unittest1", + resourceType1, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + OcResourceHandle resourceHandle2 = OcPlatform.registerResource( + "/a/unittest2", + resourceType2, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType1, + OcConnectivityType.IPV4, + resourceFoundListener); + + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType2, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + assertTrue(2 == resourceList.size()); + + OcResource res0 = resourceList.get(0); + OcResource res1 = resourceList.get(1); + assertFalse(res0.getUniqueIdentifier().equals(res1.getUniqueIdentifier())); + assertTrue(res0.getUniqueIdentifier().equals(res0.getUniqueIdentifier())); + + //server + OcPlatform.unregisterResource(resourceHandle1); + OcPlatform.unregisterResource(resourceHandle2); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testCreateResourceProxy() throws InterruptedException { + final String resourceType = "unit.test.resource" + new Date().getTime(); + final CountDownLatch signal = new CountDownLatch(1); + + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + return EntityHandlerResult.OK; + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + + try { + //client: construct resource proxy + OcResource resourceProxy = OcPlatform.constructResourceObject( + resource.getHost(), + resource.getUri(), + OcConnectivityType.IPV4, + resource.isObservable(), + resource.getResourceTypes(), + resource.getResourceInterfaces()); + + //client: register resource proxy + OcResourceHandle resourceProxyHandle = + OcPlatform.registerResource(resourceProxy); + + OcPlatform.unregisterResource(resourceProxyHandle); + } catch (OcException e) { + assertTrue(false); + } + signal.countDown(); + } + }; + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE) + ); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + public void testObserveClientServer() throws InterruptedException { + final int NUM_OBSERVES = 20; + final Timer timer = new Timer(); + final List resourceList = new LinkedList(); + final List resourceHandleList = new LinkedList(); + final CountDownLatch signal1 = new CountDownLatch(1); + final CountDownLatch signal2 = new CountDownLatch(NUM_OBSERVES); + final CountDownLatch signal3 = new CountDownLatch(1); + + final String resourceType = "unit.test.resource" + new Date().getTime(); + + final OcResource.OnObserveListener observeListener = new OcResource.OnObserveListener() { + @Override + public void onObserveCompleted( + List headerOptionList, + OcRepresentation ocRepresentation, + int sequenceNumber) { + + try { + Log.i(TAG, "Observe #" + sequenceNumber + " power: " + + ocRepresentation.getValue("power")); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + signal2.countDown(); + } + + @Override + public void onObserveFailed(Throwable ex) { + if (ex instanceof OcException) { + OcException ocEx = (OcException) ex; + ErrorCode errCode = ocEx.getErrorCode(); + } + Log.e(TAG, ex.toString()); + assertTrue(false); + } + }; + + final List observationIdList = new LinkedList(); + OcPlatform.EntityHandler entityHandler = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + EnumSet handlerFlagSet = ocResourceRequest.getRequestHandlerFlagSet(); + RequestType requestType = ocResourceRequest.getRequestType(); + + if (handlerFlagSet.contains(RequestHandlerFlag.INIT)) { + + } + if (handlerFlagSet.contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle(ocResourceRequest.getRequestHandle()); + ocResourceResponse.setResourceHandle(ocResourceRequest.getResourceHandle()); + + switch (requestType) { + case GET: + ocResourceResponse.setErrorCode(200); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setResourceRepresentation( + getRepresentation( + rnd.nextInt(100))); + try { + OcPlatform.sendResponse(ocResourceResponse); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + break; + } + } + + if (handlerFlagSet.contains(RequestHandlerFlag.OBSERVER)) { + ObservationInfo observationInfo = ocResourceRequest.getObservationInfo(); + + switch (observationInfo.getObserveAction()) { + case REGISTER: + synchronized (observationIdList) { + observationIdList.add(observationInfo.getOcObservationId()); + timer.schedule(new TimerTask() { + int numNotified = 1; + + @Override + public void run() { + if (0 < resourceHandleList.size()) { + synchronized (observationIdList) { + if (numNotified > NUM_OBSERVES) { + timer.cancel(); + timer.purge(); + signal3.countDown(); + } else { + try { + OcPlatform.notifyAllObservers( + resourceHandleList.get(0)); + } catch (OcException e) { + if (ErrorCode.NO_OBSERVERS == e.getErrorCode()) { + timer.cancel(); + timer.purge(); + signal3.countDown(); + } + Log.e(TAG, e.getMessage()); + } + numNotified++; + } + } + } + + } + }, 0, 100); + } + break; + case UNREGISTER: + //TODO unregister isn't implemented in C++ API, yet + synchronized (observationIdList) { + timer.cancel(); + break; + } + } + } + return EntityHandlerResult.OK; + } + }; + + OcPlatform.OnResourceFoundListener resourceFoundListener = + new OcPlatform.OnResourceFoundListener() { + @Override + public void onResourceFound(OcResource resource) { + resourceList.add(resource); + if (resource.isObservable()) { + try { + resource.observe( + ObserveType.OBSERVE, + new HashMap(), + observeListener); + + signal1.countDown(); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + } + }; + try { + //server + OcResourceHandle resourceHandle = OcPlatform.registerResource( + "/a/unittest", + resourceType, + OcPlatform.DEFAULT_INTERFACE, + entityHandler, + EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE) + ); + + resourceHandleList.add(resourceHandle); + + //client + OcPlatform.findResource("", + OcPlatform.WELL_KNOWN_QUERY + "?rt=" + resourceType, + OcConnectivityType.IPV4, + resourceFoundListener); + + //wait for onResourceFound event + assertTrue(signal1.await(60, TimeUnit.SECONDS)); + + //wait for OnObserveListener event to observe 20 values + assertTrue(signal2.await(60, TimeUnit.SECONDS)); + + if (resourceList.size() > 0) { + OcResource resource = resourceList.get(0); + if (resource.isObservable()) { + resource.cancelObserve(); + } + } + + //wait for server to finish + assertTrue(signal3.await(60, TimeUnit.SECONDS)); + + //server + OcPlatform.unregisterResource(resourceHandle); + + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + assertTrue(false); + } + } + + private OcRepresentation getRepresentation(int value) { + OcRepresentation rep = new OcRepresentation(); + try { + rep.setValue("power", value); + } catch (OcException e) { + Log.e(TAG, e.toString()); + assertTrue(false); + } + return rep; + } + + private OcRepresentation getRepresentation() { + return getRepresentation(74); + } +} diff --git a/android/android_api/base/src/main/AndroidManifest.xml b/android/android_api/base/src/main/AndroidManifest.xml new file mode 100755 index 0000000..183e674 --- /dev/null +++ b/android/android_api/base/src/main/AndroidManifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + diff --git a/android/android_api/base/src/main/java/org/iotivity/base/EntityHandlerResult.java b/android/android_api/base/src/main/java/org/iotivity/base/EntityHandlerResult.java new file mode 100644 index 0000000..d8ed2fb --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/EntityHandlerResult.java @@ -0,0 +1,42 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum EntityHandlerResult { + OK(0), + ERROR(1), + RESOURCE_CREATED(2), + RESOURCE_DELETED(3), + SLOW(4), + FORBIDDEN(5); + + private int value; + + private EntityHandlerResult(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java b/android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java new file mode 100644 index 0000000..d1862e0 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ErrorCode.java @@ -0,0 +1,95 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ErrorCode { + /* Success status code - START HERE */ + OK("OK", ""), + RESOURCE_CREATED("RESOURCE_CREATED", ""), + RESOURCE_DELETED("RESOURCE_DELETED", ""), + CONTINUE("CONTINUE", ""), + /* Success status code - END HERE */ + /* Error status code - START HERE */ + INVALID_URI("INVALID_URI", ""), + INVALID_QUERY("INVALID_QUERY", ""), + INVALID_IP("INVALID_IP", ""), + INVALID_PORT("INVALID_PORT", ""), + INVALID_CALLBACK("INVALID_CALLBACK", ""), + INVALID_METHOD("INVALID_METHOD", ""), + INVALID_PARAM("INVALID_PARAM", ""), + INVALID_OBSERVE_PARAM("INVALID_OBSERVE_PARAM", ""), + NO_MEMORY("NO_MEMORY", ""), + COMM_ERROR("COMM_ERROR", ""), + NOT_IMPL("NOTIMPL", ""), + NO_RESOURCE("NO_RESOURCE", "Resource not found"), + RESOURCE_ERROR("RESOURCE_ERROR", "Not supported method or interface"), + SLOW_RESOURCE("SLOW_RESOURCE", ""), + NO_OBSERVERS("NO_OBSERVERS", "Resource has no registered observers"), + OBSERVER_NOT_FOUND("OBSERVER_NOT_FOUND", ""), + PRESENCE_STOPPED("PRESENCE_STOPPED", ""), + PRESENCE_TIMEOUT("PRESENCE_TIMEOUT", ""), + PRESENCE_DO_NOT_HANDLE("PRESENCE_DO_NOT_HANDLE", ""), + VIRTUAL_DO_NOT_HANDLE("VIRTUAL_DO_NOT_HANDLE", ""), + INVALID_OPTION("INVALID_OPTION", ""), + MALFORMED_RESPONSE("MALFORMED_RESPONSE", "Remote reply contained malformed data"), + PERSISTENT_BUFFER_REQUIRED("PERSISTENT_BUFFER_REQUIRED", ""), + INVALID_REQUEST_HANDLE("INVALID_REQUEST_HANDLE", ""), + INVALID_DEVICE_INFO("INVALID_DEVICE_INFO", ""), + ERROR("ERROR", "Generic error"), + + JNI_EXCEPTION("JNI_EXCEPTION", "Generic Java binder error"), + JNI_NO_NATIVE_OBJECT("JNI_NO_NATIVE_OBJECT", ""), + JNI_INVALID_VALUE("JNI_INVALID_VALUE", ""), + + INVALID_CLASS_CAST("INVALID_CLASS_CAST", ""),; + + private String error; + private String description; + + private ErrorCode(String error, String description) { + this.error = error; + this.description = description; + } + + public String getError() { + return error; + } + + public String getDescription() { + return description; + } + + public static ErrorCode get(String errorCode) { + for (ErrorCode eCode : ErrorCode.values()) { + if (eCode.getError().equals(errorCode)) { + return eCode; + } + } + throw new IllegalArgumentException("Unexpected ErrorCode value"); + } + + @Override + public String toString() { + return error + (description.isEmpty() ? "" : " : " + description); + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ModeType.java b/android/android_api/base/src/main/java/org/iotivity/base/ModeType.java new file mode 100644 index 0000000..81ea7c7 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ModeType.java @@ -0,0 +1,39 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ModeType { + SERVER(0), + CLIENT(1), + CLIENT_SERVER(2),; + + private int value; + + private ModeType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ObservationInfo.java b/android/android_api/base/src/main/java/org/iotivity/base/ObservationInfo.java new file mode 100644 index 0000000..483d4cb --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ObservationInfo.java @@ -0,0 +1,55 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class ObservationInfo { + + private ObserveAction mObserveAction; + private byte mOcObservationId; + + private ObservationInfo(int observationAction, byte observationId) { + this.mObserveAction = ObserveAction.get(observationAction); + this.mOcObservationId = observationId; + } + + public ObservationInfo(ObserveAction observeAction, byte observationId) { + this.mObserveAction = observeAction; + this.mOcObservationId = observationId; + } + + public ObserveAction getObserveAction() { + return mObserveAction; + } + + public void setObserveAction(ObserveAction observeAction) { + this.mObserveAction = observeAction; + } + + public byte getOcObservationId() { + return mOcObservationId; + } + + public void setOcObservationId(byte ocObservationId) { + this.mOcObservationId = ocObservationId; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ObserveAction.java b/android/android_api/base/src/main/java/org/iotivity/base/ObserveAction.java new file mode 100644 index 0000000..3e7c5ec --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ObserveAction.java @@ -0,0 +1,47 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ObserveAction { + REGISTER(0), + UNREGISTER(1),; + + private int value; + + private ObserveAction(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + public static ObserveAction get(int val) { + for (ObserveAction observeAction : ObserveAction.values()) { + if (observeAction.getValue() == val) + return observeAction; + } + + throw new IllegalArgumentException("Unexpected ObserveAction value"); + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ObserveType.java b/android/android_api/base/src/main/java/org/iotivity/base/ObserveType.java new file mode 100644 index 0000000..3432a47 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ObserveType.java @@ -0,0 +1,38 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ObserveType { + OBSERVE(0), + OBSERVE_ALL(1),; + + private int value; + + private ObserveType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcConnectivityType.java b/android/android_api/base/src/main/java/org/iotivity/base/OcConnectivityType.java new file mode 100644 index 0000000..db38881 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcConnectivityType.java @@ -0,0 +1,52 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.security.InvalidParameterException; + +public enum OcConnectivityType { + IPV4 (0), + IPV6 (1), + EDR (2), + LE (3), + ALL (4), + ; + + private int value; + + private OcConnectivityType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + public static OcConnectivityType get(int val) { + for (OcConnectivityType v : OcConnectivityType.values()) { + if (v.getValue() == val) + return v; + } + throw new InvalidParameterException("Unexpected OcConnectivityType value:" + val); + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcDeviceInfo.java b/android/android_api/base/src/main/java/org/iotivity/base/OcDeviceInfo.java new file mode 100644 index 0000000..65e1497 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcDeviceInfo.java @@ -0,0 +1,177 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcDeviceInfo { + + private String deviceName; + private String hostName; + private String deviceUuid; + private String contentType; + private String version; + private String manufacturerName; + private String manufacturerUrl; + private String modelNumber; + private String dateOfManufacture; + private String platformVersion; + private String firmwareVersion; + private String supportUrl; + + public OcDeviceInfo() { + deviceName = ""; + hostName = ""; + deviceUuid = ""; + contentType = ""; + version = ""; + manufacturerName = ""; + manufacturerUrl = ""; + modelNumber = ""; + dateOfManufacture = ""; + platformVersion = ""; + firmwareVersion = ""; + supportUrl = ""; + } + + public OcDeviceInfo( + String deviceName, + String hostName, + String deviceUuid, + String contentType, + String version, + String manufacturerName, + String manufacturerUrl, + String modelNumber, + String dateOfManufacture, + String platformVersion, + String firmwareVersion, + String supportUrl) { + this.deviceName = deviceName; + this.hostName = hostName; + this.deviceUuid = deviceUuid; + this.contentType = contentType; + this.version = version; + this.manufacturerName = manufacturerName; + this.manufacturerUrl = manufacturerUrl; + this.modelNumber = modelNumber; + this.dateOfManufacture = dateOfManufacture; + this.platformVersion = platformVersion; + this.firmwareVersion = firmwareVersion; + this.supportUrl = supportUrl; + } + + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public String getDeviceUuid() { + return deviceUuid; + } + + public void setDeviceUuid(String deviceUuid) { + this.deviceUuid = deviceUuid; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getManufacturerName() { + return manufacturerName; + } + + public void setManufacturerName(String manufacturerName) { + this.manufacturerName = manufacturerName; + } + + public String getManufacturerUrl() { + return manufacturerUrl; + } + + public void setManufacturerUrl(String manufacturerUrl) { + this.manufacturerUrl = manufacturerUrl; + } + + public String getModelNumber() { + return modelNumber; + } + + public void setModelNumber(String modelNumber) { + this.modelNumber = modelNumber; + } + + public String getDateOfManufacture() { + return dateOfManufacture; + } + + public void setDateOfManufacture(String dateOfManufacture) { + this.dateOfManufacture = dateOfManufacture; + } + + public String getPlatformVersion() { + return platformVersion; + } + + public void setPlatformVersion(String platformVersion) { + this.platformVersion = platformVersion; + } + + public String getFirmwareVersion() { + return firmwareVersion; + } + + public void setFirmwareVersion(String firmwareVersion) { + this.firmwareVersion = firmwareVersion; + } + + public String getSupportUrl() { + return supportUrl; + } + + public void setSupportUrl(String supportUrl) { + this.supportUrl = supportUrl; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcException.java b/android/android_api/base/src/main/java/org/iotivity/base/OcException.java new file mode 100644 index 0000000..f83bf6c --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcException.java @@ -0,0 +1,58 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcException extends Exception { + + private ErrorCode errorCode; + + public OcException(ErrorCode errorCode, String errMessage) { + super(errMessage + " " + errorCode.toString()); + this.errorCode = errorCode; + } + + private OcException(String error, String errMessage) { + super(errMessage + " " + error); + this.errorCode = ErrorCode.get(error); + } + + public ErrorCode getErrorCode() { + return errorCode; + } + + private static void addStackTrace(Throwable throwable, + String file, + String functionName, + int line) { + StackTraceElement[] stack = throwable.getStackTrace(); + StackTraceElement[] newStack = new StackTraceElement[stack.length + 1]; + + System.arraycopy(stack, 0, newStack, 1, stack.length); + newStack[0] = new StackTraceElement("", functionName, file, line); + throwable.setStackTrace(newStack); + } + + private void setNativeExceptionLocation(String file, String functionName, int line) { + OcException.addStackTrace(this, file, functionName, line); + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcHeaderOption.java b/android/android_api/base/src/main/java/org/iotivity/base/OcHeaderOption.java new file mode 100644 index 0000000..984bc27 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcHeaderOption.java @@ -0,0 +1,70 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.security.InvalidParameterException; + +/** + * OcHeaderOption class allows to create instances which comprises optionId + * and optionData as members. These are used in setting Header options. + * After creating instances of OcHeaderOptions, use setHeaderOptions API + * (in OcResource) to set header Options. + * NOTE: optionId is an integer value which MUST be within + * range of 2048 to 3000 inclusive of lower and upper bound. + * HeaderOption instance creation fails if above condition is not satisfied. + */ +public class OcHeaderOption { + + public static final int MIN_HEADER_OPTION_ID = 2048; + public static final int MAX_HEADER_OPTION_ID = 3000; + + private int mOptionId; + private String mOptionData; + + public OcHeaderOption(int optionId, String optionData) { + if (!(optionId >= MIN_HEADER_OPTION_ID && optionId <= MAX_HEADER_OPTION_ID)) { + throw new InvalidParameterException("Option ID range is invalid"); + } + + this.mOptionId = optionId; + this.mOptionData = optionData; + } + + /** + * API to get Option ID + * + * @return option ID + */ + public int getOptionId() { + return mOptionId; + } + + /** + * API to get Option data + * + * @return option data + */ + public String getOptionData() { + return mOptionData; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java new file mode 100644 index 0000000..f55269b --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java @@ -0,0 +1,777 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import org.iotivity.ca.CaInterface; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; + +/** + * Contains the main entrance/functionality of the product. To set a custom configuration, the + * implementer must make a call to OcPlatform.Configure before the first usage of a function in this + * class. + */ +public final class OcPlatform { + + static { + System.loadLibrary("oc_logger"); + System.loadLibrary("octbstack"); + System.loadLibrary("connectivity_abstraction"); + System.loadLibrary("oc"); + System.loadLibrary("ocstack-jni"); + } + + /** + * Default interface + */ + public static final String DEFAULT_INTERFACE = "oc.mi.def"; + + /** + * Used in discovering (GET) links to other resources of a collection + */ + public static final String LINK_INTERFACE = "oc.mi.ll"; + + /** + * Used in GET, PUT, POST, DELETE methods on links to other resources of a collection + */ + public static final String BATCH_INTERFACE = "oc.mi.b"; + + /** + * Used in GET, PUT, POST methods on links to other remote resources of a group + */ + public static final String GROUP_INTERFACE = "oc.mi.grp"; + + public static final String WELL_KNOWN_QUERY = "224.0.1.187:5683/oc/core"; + public static final String MULTICAST_PREFIX = "224.0.1.187:5683"; + public static final String MULTICAST_IP = "224.0.1.187"; + public static final int MULTICAST_PORT = 5683; + public static final int DEFAULT_PRESENCE_TTL = 60; + public static final String PRESENCE_URI = "/oc/presence"; + + private static volatile boolean sIsPlatformInitialized = false; + + private OcPlatform() { + } + + /** + * API for setting the configuration of the OcPlatform. + * Note: Any calls made to this AFTER the first call to OcPlatform.Configure will have no affect + * + * @param platformConfig platform configuration + */ + public synchronized static void Configure(PlatformConfig platformConfig) { + if (!sIsPlatformInitialized) { + CaInterface.initialize(platformConfig.getContext()); + + OcPlatform.configure( + platformConfig.getServiceType().getValue(), + platformConfig.getModeType().getValue(), + platformConfig.getIpAddress(), + platformConfig.getPort(), + platformConfig.getQualityOfService().getValue() + ); + + sIsPlatformInitialized = true; + } + } + + private static native void configure(int serviceType, + int modeType, + String ipAddress, + int port, + int qualityOfService); + + /** + * API for notifying base that resource's attributes have changed. + * + * @param ocResourceHandle resource handle of the resource + * @throws OcException + */ + public static void notifyAllObservers( + OcResourceHandle ocResourceHandle) throws OcException { + OcPlatform.initCheck(); + OcPlatform.notifyAllObservers0(ocResourceHandle); + } + + private static native void notifyAllObservers0( + OcResourceHandle ocResourceHandle) throws OcException; + + /** + * API for notifying base that resource's attributes have changed. + * + * @param ocResourceHandle resource handle of the resource + * @param qualityOfService the quality of communication + * @throws OcException + */ + public static void notifyAllObservers( + OcResourceHandle ocResourceHandle, + QualityOfService qualityOfService) throws OcException { + OcPlatform.initCheck(); + OcPlatform.notifyAllObservers1(ocResourceHandle, qualityOfService.getValue()); + } + + private static native void notifyAllObservers1( + OcResourceHandle ocResourceHandle, + int qualityOfService) throws OcException; + + /** + * API for notifying only specific clients that resource's attributes have changed. + * + * @param ocResourceHandle resource handle of the resource + * @param ocObservationIdList These set of ids are ones which which will be notified upon + * resource change. + * @param ocResourceResponse OcResourceResponse object used by app to fill the response for + * this resource change + * @throws OcException + */ + public static void notifyListOfObservers( + OcResourceHandle ocResourceHandle, + List ocObservationIdList, + OcResourceResponse ocResourceResponse) throws OcException { + OcPlatform.initCheck(); + + byte[] idArr = new byte[ocObservationIdList.size()]; + Iterator it = ocObservationIdList.iterator(); + int i = 0; + while (it.hasNext()) { + idArr[i++] = (byte) it.next(); + } + + OcPlatform.notifyListOfObservers2( + ocResourceHandle, + idArr, + ocResourceResponse); + } + + private static native void notifyListOfObservers2( + OcResourceHandle ocResourceHandle, + byte[] ocObservationIdArray, + OcResourceResponse ocResourceResponse) throws OcException; + + /** + * API for notifying only specific clients that resource's attributes have changed. + * + * @param ocResourceHandle resource handle of the resource + * @param ocObservationIdList These set of ids are ones which which will be notified upon + * resource change. + * @param ocResourceResponse OcResourceResponse object used by app to fill the response for + * this resource change + * @param qualityOfService the quality of communication + * @throws OcException + */ + public static void notifyListOfObservers( + OcResourceHandle ocResourceHandle, + List ocObservationIdList, + OcResourceResponse ocResourceResponse, + QualityOfService qualityOfService) throws OcException { + OcPlatform.initCheck(); + + byte[] idArr = new byte[ocObservationIdList.size()]; + Iterator it = ocObservationIdList.iterator(); + int i = 0; + while (it.hasNext()) { + idArr[i++] = (byte) it.next(); + } + + OcPlatform.notifyListOfObservers3( + ocResourceHandle, + idArr, + ocResourceResponse, + qualityOfService.getValue() + ); + } + + private static native void notifyListOfObservers3( + OcResourceHandle ocResourceHandle, + byte[] ocObservationIdArray, + OcResourceResponse ocResourceResponse, + int qualityOfService) throws OcException; + + /** + * API for Service and Resource Discovery. NOTE: This API applies to client side only + * + * @param host Host IP Address of a service to direct resource discovery query. + * If empty, performs multicast resource discovery query + * @param resourceUri name of the resource. If null or empty, performs search for all + * resource names + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onResourceFoundListener Handles events, success states and failure states. + * @throws OcException + */ + public static void findResource( + String host, + String resourceUri, + OcConnectivityType connectivityType, + OnResourceFoundListener onResourceFoundListener) throws OcException { + OcPlatform.initCheck(); + OcPlatform.findResource0( + host, + resourceUri, + connectivityType.getValue(), + onResourceFoundListener + ); + } + + private static native void findResource0( + String host, + String resourceUri, + int connectivityType, + OnResourceFoundListener onResourceFoundListener) throws OcException; + + /** + * API for Service and Resource Discovery. NOTE: This API applies to client side only + * + * @param host Host IP Address of a service to direct resource discovery query. + * If empty, performs multicast resource discovery query + * @param resourceUri name of the resource. If null or empty, performs search for all + * resource names + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onResourceFoundListener Handles events, success states and failure states. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public static void findResource( + String host, + String resourceUri, + OcConnectivityType connectivityType, + OnResourceFoundListener onResourceFoundListener, + QualityOfService qualityOfService) throws OcException { + OcPlatform.initCheck(); + OcPlatform.findResource1(host, + resourceUri, + connectivityType.getValue(), + onResourceFoundListener, + qualityOfService.getValue() + ); + } + + private static native void findResource1( + String host, + String resourceUri, + int connectivityType, + OnResourceFoundListener onResourceFoundListener, + int qualityOfService) throws OcException; + + /** + * API for Device Discovery + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param deviceUri Uri containing address to the virtual device + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onDeviceFoundListener Handles events, success states and failure states. + * @throws OcException + */ + public static void getDeviceInfo( + String host, + String deviceUri, + OcConnectivityType connectivityType, + OnDeviceFoundListener onDeviceFoundListener) throws OcException { + OcPlatform.initCheck(); + OcPlatform.getDeviceInfo0( + host, + deviceUri, + connectivityType.getValue(), + onDeviceFoundListener + ); + } + + private static native void getDeviceInfo0( + String host, + String deviceUri, + int connectivityType, + OnDeviceFoundListener onDeviceFoundListener) throws OcException; + + /** + * API for Device Discovery + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param deviceUri Uri containing address to the virtual device + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onDeviceFoundListener Handles events, success states and failure states. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public static void getDeviceInfo( + String host, + String deviceUri, + OcConnectivityType connectivityType, + OnDeviceFoundListener onDeviceFoundListener, + QualityOfService qualityOfService) throws OcException { + OcPlatform.initCheck(); + OcPlatform.getDeviceInfo1( + host, + deviceUri, + connectivityType.getValue(), + onDeviceFoundListener, + qualityOfService.getValue() + ); + } + + private static native void getDeviceInfo1( + String host, + String deviceUri, + int connectivityType, + OnDeviceFoundListener onDeviceFoundListener, + int qualityOfService) throws OcException; + + /** + * This API registers a resource with the server NOTE: This API applies to server side only. + * + * @param ocResource The instance of OcResource with all data filled + * @return resource handle + * @throws OcException + */ + public static OcResourceHandle registerResource( + OcResource ocResource) throws OcException { + OcPlatform.initCheck(); + return OcPlatform.registerResource0(ocResource); + } + + private static native OcResourceHandle registerResource0( + OcResource ocResource) throws OcException; + + /** + * This API registers a resource with the server NOTE: This API applies to server side only. + * + * @param resourceUri The URI of the resource. Example: "a/light" + * @param resourceTypeName The resource type. Example: "light" + * @param resourceInterface The resource interface (whether it is collection etc). + * @param entityHandler entity handler. + * @param resourcePropertySet indicates the property of the resource + * @return resource handle + * @throws OcException + */ + public static OcResourceHandle registerResource( + String resourceUri, + String resourceTypeName, + String resourceInterface, + EntityHandler entityHandler, + EnumSet resourcePropertySet) throws OcException { + OcPlatform.initCheck(); + + int resProperty = 0; + + for (ResourceProperty prop : ResourceProperty.values()) { + if (resourcePropertySet.contains(prop)) + resProperty |= prop.getValue(); + } + + return OcPlatform.registerResource1(resourceUri, + resourceTypeName, + resourceInterface, + entityHandler, + resProperty); + } + + private static native OcResourceHandle registerResource1( + String resourceUri, + String resourceTypeName, + String resourceInterface, + EntityHandler entityHandler, + int resourceProperty) throws OcException; + + /** + * Register Device Info + * + * @param ocDeviceInfo object containing all the device specific information + * @throws OcException + */ + public static void registerDeviceInfo( + OcDeviceInfo ocDeviceInfo) throws OcException { + OcPlatform.initCheck(); + OcPlatform.registerDeviceInfo0( + ocDeviceInfo.getDeviceName(), + ocDeviceInfo.getHostName(), + ocDeviceInfo.getDeviceUuid(), + ocDeviceInfo.getContentType(), + ocDeviceInfo.getVersion(), + ocDeviceInfo.getManufacturerName(), + ocDeviceInfo.getManufacturerUrl(), + ocDeviceInfo.getModelNumber(), + ocDeviceInfo.getDateOfManufacture(), + ocDeviceInfo.getPlatformVersion(), + ocDeviceInfo.getFirmwareVersion(), + ocDeviceInfo.getSupportUrl() + ); + } + + private static native void registerDeviceInfo0( + String deviceName, + String hostName, + String deviceUUID, + String contentType, + String version, + String manufacturerName, + String manufacturerUrl, + String modelNumber, + String dateOfManufacture, + String platformVersion, + String firmwareVersion, + String supportUrl) throws OcException; + + /** + * This API unregisters a resource with the server NOTE: This API applies to server side only. + * + * @param ocResourceHandle This is the resource handle which we which to unregister from the + * server + * @throws OcException + */ + public static void unregisterResource( + OcResourceHandle ocResourceHandle) throws OcException { + OcPlatform.initCheck(); + OcPlatform.unregisterResource0(ocResourceHandle); + } + + private static native void unregisterResource0( + OcResourceHandle ocResourceHandle) throws OcException; + + + /** + * Add a resource to a collection resource + * + * @param ocResourceCollectionHandle handle to the collection resource + * @param ocResourceHandle handle to resource to be added to the collection resource + * @throws OcException + */ + public static void bindResource( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle ocResourceHandle) throws OcException { + OcPlatform.initCheck(); + OcPlatform.bindResource0(ocResourceCollectionHandle, ocResourceHandle); + } + + private static native void bindResource0( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle ocResourceHandle) throws OcException; + + /** + * Add multiple resources to a collection resource. + * + * @param ocResourceCollectionHandle handle to the collection resource + * @param ocResourceHandleList reference to list of resource handles to be added to the + * collection resource + * @throws OcException + */ + public static void bindResources( + OcResourceHandle ocResourceCollectionHandle, + List ocResourceHandleList) throws OcException { + OcPlatform.initCheck(); + OcPlatform.bindResources0( + ocResourceCollectionHandle, + ocResourceHandleList.toArray( + new OcResourceHandle[ocResourceHandleList.size()]) + ); + } + + private static native void bindResources0( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle[] ocResourceHandleArray) throws OcException; + + /** + * Unbind a resource from a collection resource. + * + * @param ocResourceCollectionHandle handle to the collection resource + * @param ocResourceHandle resource handle to be unbound from the collection resource + * @throws OcException + */ + public static void unbindResource( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle ocResourceHandle) throws OcException { + OcPlatform.initCheck(); + OcPlatform.unbindResource0(ocResourceCollectionHandle, ocResourceHandle); + } + + private static native void unbindResource0( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle ocResourceHandle) throws OcException; + + /** + * Unbind resources from a collection resource. + * + * @param ocResourceCollectionHandle Handle to the collection resource + * @param ocResourceHandleList List of resource handles to be unbound from the collection + * resource + * @throws OcException + */ + public static void unbindResources( + OcResourceHandle ocResourceCollectionHandle, + List ocResourceHandleList) throws OcException { + OcPlatform.initCheck(); + OcPlatform.unbindResources0( + ocResourceCollectionHandle, + ocResourceHandleList.toArray( + new OcResourceHandle[ocResourceHandleList.size()]) + ); + } + + private static native void unbindResources0( + OcResourceHandle ocResourceCollectionHandle, + OcResourceHandle[] ocResourceHandleArray) throws OcException; + + /** + * Binds a type to a particular resource + * + * @param ocResourceHandle handle to the resource + * @param resourceTypeName new typename to bind to the resource + * @throws OcException + */ + public static void bindTypeToResource( + OcResourceHandle ocResourceHandle, + String resourceTypeName) throws OcException { + OcPlatform.initCheck(); + OcPlatform.bindTypeToResource0(ocResourceHandle, resourceTypeName); + } + + private static native void bindTypeToResource0( + OcResourceHandle ocResourceHandle, + String resourceTypeName) throws OcException; + + /** + * Binds an interface to a particular resource + * + * @param ocResourceHandle handle to the resource + * @param resourceInterfaceName new interface to bind to the resource + * @throws OcException + */ + public static void bindInterfaceToResource( + OcResourceHandle ocResourceHandle, + String resourceInterfaceName) throws OcException { + OcPlatform.initCheck(); + OcPlatform.bindInterfaceToResource0(ocResourceHandle, resourceInterfaceName); + } + + private static native void bindInterfaceToResource0( + OcResourceHandle ocResourceHandle, + String resourceInterfaceName) throws OcException; + + /** + * Start Presence announcements. + * + * @param ttl time to live in seconds + * @throws OcException + */ + public static void startPresence(int ttl) throws OcException { + OcPlatform.initCheck(); + OcPlatform.startPresence0(ttl); + } + + private static native void startPresence0(int ttl) throws OcException; + + /** + * Stop Presence announcements. + * + * @throws OcException + */ + public static void stopPresence() throws OcException { + OcPlatform.initCheck(); + OcPlatform.stopPresence0(); + } + + private static native void stopPresence0() throws OcException; + + /** + * Subscribes to a server's presence change events. By making this subscription, every time a + * server adds/removes/alters a resource, starts or is intentionally stopped + * + * @param host The IP address/addressable name of the server to subscribe to + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onPresenceListener listener that will receive notifications/subscription events + * @return a handle object that can be used to identify this subscription request. It can be + * used to unsubscribe from these events in the future + * @throws OcException + */ + public static OcPresenceHandle subscribePresence( + String host, + OcConnectivityType connectivityType, + OnPresenceListener onPresenceListener) throws OcException { + OcPlatform.initCheck(); + return OcPlatform.subscribePresence0( + host, + connectivityType.getValue(), + onPresenceListener + ); + } + + private static native OcPresenceHandle subscribePresence0( + String host, + int connectivityType, + OnPresenceListener onPresenceListener) throws OcException; + + /** + * Subscribes to a server's presence change events. By making this subscription, every time a + * server adds/removes/alters a resource, starts or is intentionally stopped + * + * @param host The IP address/addressable name of the server to subscribe to + * @param resourceType a resource type specified as a filter for subscription events. + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param onPresenceListener listener that will receive notifications/subscription events + * @return a handle object that can be used to identify this subscription request. It can be + * used to unsubscribe from these events in the future + * @throws OcException + */ + public static OcPresenceHandle subscribePresence( + String host, + String resourceType, + OcConnectivityType connectivityType, + OnPresenceListener onPresenceListener) throws OcException { + OcPlatform.initCheck(); + return OcPlatform.subscribePresence1( + host, + resourceType, + connectivityType.getValue(), + onPresenceListener); + } + + private static native OcPresenceHandle subscribePresence1( + String host, + String resourceType, + int connectivityType, + OnPresenceListener onPresenceListener) throws OcException; + + /** + * Unsubscribes from a previously subscribed server's presence events. Note that you may for + * a short time still receive events from the server since it may take time for the + * unsubscribe to take effect. + * + * @param ocPresenceHandle the handle object provided by the subscribePresence call that + * identifies this subscription + * @throws OcException + */ + public static void unsubscribePresence( + OcPresenceHandle ocPresenceHandle) throws OcException { + OcPlatform.initCheck(); + OcPlatform.unsubscribePresence0(ocPresenceHandle); + } + + private static native void unsubscribePresence0( + OcPresenceHandle ocPresenceHandle) throws OcException; + + /** + * Creates a resource proxy object so that get/put/observe functionality can be used without + * discovering the object in advance. Note that the consumer of this method needs to provide + * all of the details required to correctly contact and observe the object. If the consumer + * lacks any of this information, they should discover the resource object normally. + * Additionally, you can only create this object if OcPlatform was initialized to be a Client + * or Client/Server. + * + * @param host a string containing a resolvable host address of the server holding + * the resource + * @param uri the rest of the resource's URI that will permit messages to be + * properly routed. + * Example: /a/light + * @param connectivityType a type of connectivity indicating the interface. Example: IPV4, + * IPV6, ALL + * @param isObservable a boolean containing whether the resource supports observation + * @param resourceTypeList a collection of resource types implemented by the resource + * @param interfaceList a collection of interfaces that the resource supports/implements + * @return new resource object + * @throws OcException + */ + public static OcResource constructResourceObject( + String host, + String uri, + OcConnectivityType connectivityType, + boolean isObservable, + List resourceTypeList, + List interfaceList) throws OcException { + OcPlatform.initCheck(); + return OcPlatform.constructResourceObject0( + host, + uri, + connectivityType.getValue(), + isObservable, + resourceTypeList.toArray(new String[resourceTypeList.size()]), + interfaceList.toArray(new String[interfaceList.size()]) + ); + } + + private static native OcResource constructResourceObject0( + String host, + String uri, + int connectivityType, + boolean isObservable, + String[] resourceTypes, + String[] interfaces) throws OcException; + + /** + * Allows application entity handler to send response to an incoming request. + * + * @param ocResourceResponse resource response + * @throws OcException + */ + public static void sendResponse(OcResourceResponse ocResourceResponse) + throws OcException { + OcPlatform.initCheck(); + OcPlatform.sendResponse0(ocResourceResponse); + } + + private static native void sendResponse0(OcResourceResponse ocResourceResponse) + throws OcException; + + /** + * An OnResourceFoundListener can be registered via the OcPlatform.findResource call. + * Event listeners are notified asynchronously + */ + public interface OnResourceFoundListener { + public void onResourceFound(OcResource resource); + } + + /** + * An OnDeviceFoundListener can be registered via the OcPlatform.getDeviceInfo call. + * Event listeners are notified asynchronously + */ + public interface OnDeviceFoundListener { + public void onDeviceFound(OcRepresentation ocRepresentation); + } + + /** + * An OnPresenceListener can be registered via the OcPlatform.subscribePresence call. + * Event listeners are notified asynchronously + */ + public interface OnPresenceListener { + public void onPresence(OcPresenceStatus ocPresenceStatus, int nonce, String hostAddress); + } + + /** + * An EntityHandler can be registered via the OcPlatform.registerResource call. + * Event listeners are notified asynchronously + */ + public interface EntityHandler { + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest); + } + + private static void initCheck() { + if (!sIsPlatformInitialized) { + throw new IllegalStateException("OcPlatform must be configured by making a call to " + + "OcPlatform.Configure before any other API calls are permitted"); + } + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcPlatformStatus.java b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatformStatus.java new file mode 100644 index 0000000..4ef76da --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcPlatformStatus.java @@ -0,0 +1,39 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + + +public enum OcPlatformStatus { + UP(0), + DOWN(1),; + + private int value; + + private OcPlatformStatus(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceHandle.java b/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceHandle.java new file mode 100644 index 0000000..184be8f --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceHandle.java @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcPresenceHandle { + + private OcPresenceHandle(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceStatus.java b/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceStatus.java new file mode 100644 index 0000000..ff2c7dc --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcPresenceStatus.java @@ -0,0 +1,50 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.security.InvalidParameterException; + +public enum OcPresenceStatus { + OK("OK"), + STOPPED("PRESENCE_STOPPED"), + TIMEOUT("PRESENCE_TIMEOUT"), + DO_NOT_HANDLE("PRESENCE_DO_NOT_HANDLE"); + + private String value; + + private OcPresenceStatus(String value) { + this.value = value; + } + + public static OcPresenceStatus get(String val) { + for (OcPresenceStatus v : OcPresenceStatus.values()) { + if (v.getValue().equals(val)) + return v; + } + throw new InvalidParameterException("Unexpected OcPresenceStatus value"); + } + + public String getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcRepresentation.java b/android/android_api/base/src/main/java/org/iotivity/base/OcRepresentation.java new file mode 100644 index 0000000..98ec0bc --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcRepresentation.java @@ -0,0 +1,358 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.security.InvalidParameterException; +import java.util.Arrays; +import java.util.List; + +/** + * + */ +public class OcRepresentation { + + static { + System.loadLibrary("oc"); + System.loadLibrary("ocstack-jni"); + } + + public OcRepresentation() { + create(); + //Native OCRepresentation object was created using "new" and needs to be deleted + this.mNativeNeedsDelete = true; + } + + private OcRepresentation(long nativeHandle) { + this.mNativeHandle = nativeHandle; + this.mNativeNeedsDelete = false; + } + + private OcRepresentation(long nativeHandle, boolean nativeNeedsDelete) { + this.mNativeHandle = nativeHandle; + this.mNativeNeedsDelete = nativeNeedsDelete; + } + + public T getValue(String key) throws OcException { + Object obj = this.getValueN(key); + @SuppressWarnings("unchecked") + T t = (T) obj; + return t; + } + + private native Object getValueN(String key); + + public void setValue(String key, int value) throws OcException { + this.setValueInteger(key, value); + } + + public void setValue(String key, double value) throws OcException { + this.setValueDouble(key, value); + } + + public void setValue(String key, boolean value) throws OcException { + this.setValueBoolean(key, value); + } + + public void setValue(String key, String value) throws OcException { + this.setValueStringN(key, value); + } + + public void setValue(String key, OcRepresentation value) throws OcException { + this.setValueRepresentation(key, value); + } + + public void setValue(String key, int[] value) throws OcException { + this.setValueIntegerArray(key, value); + } + + public void setValue(String key, int[][] value) throws OcException { + this.setValueInteger2DArray(key, value); + } + + public void setValue(String key, int[][][] value) throws OcException { + this.setValueInteger3DArray(key, value); + } + + public void setValue(String key, double[] value) throws OcException { + this.setValueDoubleArray(key, value); + } + + public void setValue(String key, double[][] value) throws OcException { + this.setValueDouble2DArray(key, value); + } + + public void setValue(String key, double[][][] value) throws OcException { + this.setValueDouble3DArray(key, value); + } + + public void setValue(String key, boolean[] value) throws OcException { + this.setValueBooleanArray(key, value); + } + + public void setValue(String key, boolean[][] value) throws OcException { + this.setValueBoolean2DArray(key, value); + } + + public void setValue(String key, boolean[][][] value) throws OcException { + this.setValueBoolean3DArray(key, value); + } + + public void setValue(String key, String[] value) throws OcException { + this.setValueStringArray(key, value); + } + + public void setValue(String key, String[][] value) throws OcException { + this.setValueString2DArray(key, value); + } + + public void setValue(String key, String[][][] value) throws OcException { + this.setValueString3DArray(key, value); + } + + public void setValue(String key, OcRepresentation[] value) throws OcException { + this.setValueRepresentationArray(key, value); + } + + public void setValue(String key, OcRepresentation[][] value) throws OcException { + this.setValueRepresentation2DArray(key, value); + } + + public void setValue(String key, OcRepresentation[][][] value) throws OcException { + this.setValueRepresentation3DArray(key, value); + } + + private native void setValueInteger(String key, int value) throws OcException; + + private native void setValueDouble(String key, double value) throws OcException; + + private native void setValueBoolean(String key, boolean value) throws OcException; + + private native void setValueStringN(String key, String value) throws OcException; + + private native void setValueRepresentation(String key, OcRepresentation value) throws OcException; + + private native void setValueIntegerArray(String key, int[] value) throws OcException; + + private native void setValueInteger2DArray(String key, int[][] value) throws OcException; + + private native void setValueInteger3DArray(String key, int[][][] value) throws OcException; + + private native void setValueDoubleArray(String key, double[] value) throws OcException; + + private native void setValueDouble2DArray(String key, double[][] value) throws OcException; + + private native void setValueDouble3DArray(String key, double[][][] value) throws OcException; + + private native void setValueBooleanArray(String key, boolean[] value) throws OcException; + + private native void setValueBoolean2DArray(String key, boolean[][] value) throws OcException; + + private native void setValueBoolean3DArray(String key, boolean[][][] value) throws OcException; + + private native void setValueStringArray(String key, String[] value) throws OcException; + + private native void setValueString2DArray(String key, String[][] value) throws OcException; + + private native void setValueString3DArray(String key, String[][][] value) throws OcException; + + private native void setValueRepresentationArray(String key, OcRepresentation[] value) throws OcException; + + private native void setValueRepresentation2DArray(String key, OcRepresentation[][] value) throws OcException; + + private native void setValueRepresentation3DArray(String key, OcRepresentation[][][] value) throws OcException; + + /** + * @deprecated use {@link #getValue(String key)} instead. + */ + @Deprecated + public int getValueInt(String key) { + int value = 0; + try { + value = this.getValue(key); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + return value; + } + + /** + * @deprecated use {@link #getValue(String key)} instead. + */ + @Deprecated + public boolean getValueBool(String key) { + boolean value = false; + try { + value = this.getValue(key); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + return value; + } + + /** + * @deprecated use {@link #getValue(String key)} instead. + */ + @Deprecated + public String getValueString(String key) { + String value = ""; + try { + value = this.getValue(key); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + return value; + } + + /** + * @deprecated use {@link #setValue(String key, int value)} instead. + */ + @Deprecated + public void setValueInt(String key, int value) { + try { + this.setValue(key, value); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + } + + /** + * @deprecated use {@link #setValue(String key, boolean value)} instead. + */ + @Deprecated + public void setValueBool(String key, boolean value) { + try { + this.setValue(key, value); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + } + + /** + * @deprecated use {@link #setValue(String key, String value)} instead. + */ + @Deprecated + public void setValueString(String key, String value) { + try { + this.setValue(key, value); + } catch (OcException e) { + //simply catching here for the deprecated APIs, so the older usages don't have to handle + //it in the code + } + } + + public native String getJSONRepresentation(); + + public native void addChild(OcRepresentation representation); + + public native void clearChildren(); + + public List getChildren() { + return Arrays.asList( + getChildrenArray()); + } + + private native OcRepresentation[] getChildrenArray(); + + public native String getUri(); + + public native void setUri(String uri); + + /** + * Method to get the list of resource types + * + * @return List of resource types + */ + public native List getResourceTypes(); + + /** + * Method to set the list of resource types + * + * @param resourceTypeList list of resources + */ + public void setResourceTypes(List resourceTypeList) { + if (null == resourceTypeList) { + throw new InvalidParameterException("resourceTypeList cannot be null"); + } + + this.setResourceTypeArray( + resourceTypeList.toArray( + new String[resourceTypeList.size()])); + } + + private native void setResourceTypeArray(String[] resourceTypeArray); + + /** + * Method to get the list of resource interfaces + * + * @return List of resource interface + */ + public native List getResourceInterfaces(); + + /** + * Method to set the list of resource interfaces + * + * @param resourceInterfaceList list of interfaces + */ + public void setResourceInterfaces(List resourceInterfaceList) { + if (null == resourceInterfaceList) { + throw new InvalidParameterException("resourceInterfaceList cannot be null"); + } + + this.setResourceInterfaceArray( + resourceInterfaceList.toArray( + new String[resourceInterfaceList.size()])); + } + + private native void setResourceInterfaceArray(String[] resourceInterfaceArray); + + public native boolean isEmpty(); + + public native int size(); + + public native boolean remove(String key); + + public native boolean hasAttribute(String key); + + public native void setNull(String key); + + public native boolean isNull(String key); + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(this.mNativeNeedsDelete); + } + + private native void create(); + + private native void dispose(boolean needsDelete); + + private long mNativeHandle; + private boolean mNativeNeedsDelete; +} \ No newline at end of file diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcRequestHandle.java b/android/android_api/base/src/main/java/org/iotivity/base/OcRequestHandle.java new file mode 100644 index 0000000..73cd14b --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcRequestHandle.java @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcRequestHandle { + + private OcRequestHandle(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcResource.java b/android/android_api/base/src/main/java/org/iotivity/base/OcResource.java new file mode 100644 index 0000000..b3f4b08 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcResource.java @@ -0,0 +1,575 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.util.List; +import java.util.Map; + +/** + * OcResource represents an OC resource. A resource could be a light controller, temperature sensor, + * smoke detector, etc. A resource comes with a well-defined contract or interface onto which you + * can perform different operations, such as turning on the light, getting the current temperature + * or subscribing for event notifications from the smoke detector. A resource can be composed of + * one or more resources. + */ +public class OcResource { + + private OcResource(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + /** + * Method to get the attributes of a resource. + * + * @param queryParamsMap map which can have the query parameter name and value + * @param onGetListener The event handler will be invoked with a map of attribute name and + * values. The event handler will also have the result from this Get + * operation This will have error codes + * @throws OcException + */ + public native void get(Map queryParamsMap, + OnGetListener onGetListener) throws OcException; + + /** + * Method to get the attributes of a resource. + * + * @param queryParamsMap map which can have the query parameter name and value + * @param onGetListener The event handler will be invoked with a map of attribute name and + * values. The event handler will also have the result from this Get + * operation This will have error codes + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void get(Map queryParamsMap, + OnGetListener onGetListener, + QualityOfService qualityOfService) throws OcException { + this.get1(queryParamsMap, onGetListener, qualityOfService.getValue()); + } + + private native void get1(Map queryParamsMap, + OnGetListener onGetListener, + int qualityOfService) throws OcException; + + /** + * Method to get the attributes of a resource. + * + * @param resourceType resourceType of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param queryParamsMap map which can have the query parameter name and value + * @param onGetListener The event handler will be invoked with a map of attribute name and + * values. The event handler will also have the result from this Get + * operation This will have error codes + * @throws OcException + */ + public void get(String resourceType, + String resourceInterface, + Map queryParamsMap, + OnGetListener onGetListener) throws OcException { + this.get2( + resourceType, + resourceInterface, + queryParamsMap, + onGetListener); + } + + private native void get2(String resourceType, + String resourceInterface, + Map queryParamsMap, + OnGetListener onGetListener) throws OcException; + + /** + * Method to get the attributes of a resource. + * + * @param resourceType resourceType of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param queryParamsMap map which can have the query parameter name and value + * @param onGetListener The event handler will be invoked with a map of attribute name and + * values. The event handler will also have the result from this Get + * operation This will have error codes + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void get(String resourceType, + String resourceInterface, + Map queryParamsMap, + OnGetListener onGetListener, + QualityOfService qualityOfService) throws OcException { + this.get3( + resourceType, + resourceInterface, + queryParamsMap, + onGetListener, + qualityOfService.getValue()); + } + + private native void get3(String resourceType, + String resourceInterface, + Map queryParamsMap, + OnGetListener onGetListener, + int qualityOfService) throws OcException; + + /** + * Method to set the representation of a resource (via PUT) + * + * @param representation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPutListener event handler The event handler will be invoked with a map of attribute + * name and values. + * @throws OcException + */ + public native void put(OcRepresentation representation, + Map queryParamsMap, + OnPutListener onPutListener) throws OcException; + + /** + * Method to set the representation of a resource (via PUT) + * + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPutListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void put(OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener, + QualityOfService qualityOfService) throws OcException { + this.put1( + ocRepresentation, + queryParamsMap, + onPutListener, + qualityOfService.getValue()); + } + + private native void put1(OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener, + int qualityOfService) throws OcException; + + /** + * Method to set the representation of a resource (via PUT) + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPutListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @throws OcException + */ + public void put(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener) throws OcException { + this.put2( + resourceType, + resourceInterface, + ocRepresentation, + queryParamsMap, + onPutListener); + } + + private native void put2(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener) throws OcException; + + /** + * Method to set the representation of a resource (via PUT) + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPutListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void put(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener, + QualityOfService qualityOfService) throws OcException { + this.put3( + resourceType, + resourceInterface, + ocRepresentation, + queryParamsMap, + onPutListener, + qualityOfService.getValue()); + } + + private native void put3(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPutListener onPutListener, + int qualityOfService) throws OcException; + + /** + * Method to POST on a resource + * + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPostListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @throws OcException + */ + public native void post(OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener) throws OcException; + + /** + * Method to POST on a resource + * + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPostListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void post(OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener, + QualityOfService qualityOfService) throws OcException { + this.post1( + ocRepresentation, + queryParamsMap, + onPostListener, + qualityOfService.getValue()); + } + + private native void post1(OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener, + int qualityOfService) throws OcException; + + /** + * Method to POST on a resource + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPostListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @throws OcException + */ + public void post(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener) throws OcException { + this.post2( + resourceType, + resourceInterface, + ocRepresentation, + queryParamsMap, + onPostListener); + } + + private native void post2(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener) throws OcException; + + /** + * Method to POST on a resource + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param ocRepresentation representation of the resource + * @param queryParamsMap Map which can have the query parameter name and value + * @param onPostListener event handler The event handler will be invoked with a map of + * attribute name and values. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void post(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener, + QualityOfService qualityOfService) throws OcException { + this.post3( + resourceType, + resourceInterface, + ocRepresentation, + queryParamsMap, + onPostListener, + qualityOfService.getValue()); + } + + private native void post3(String resourceType, + String resourceInterface, + OcRepresentation ocRepresentation, + Map queryParamsMap, + OnPostListener onPostListener, + int qualityOfService) throws OcException; + + /** + * Method to perform DELETE operation + * + * @param onDeleteListener event handler The event handler will have headerOptionList + */ + public native void deleteResource(OnDeleteListener onDeleteListener) throws OcException; + + /** + * Method to perform DELETE operation + * + * @param onDeleteListener event handler The event handler will have headerOptionList + * @param qualityOfService the quality of communication + */ + public void deleteResource(OnDeleteListener onDeleteListener, + QualityOfService qualityOfService) throws OcException { + this.deleteResource1(onDeleteListener, + qualityOfService.getValue()); + } + + private native void deleteResource1(OnDeleteListener onDeleteListener, + int qualityOfService) throws OcException; + + /** + * Method to set observation on the resource + * + * @param observeType allows the client to specify how it wants to observe + * @param queryParamsMap map which can have the query parameter name and value + * @param onObserveListener event handler The handler method will be invoked with a map + * of attribute name and values. + * @throws OcException + */ + public void observe(ObserveType observeType, + Map queryParamsMap, + OnObserveListener onObserveListener) throws OcException { + this.observe( + observeType.getValue(), + queryParamsMap, + onObserveListener); + } + + private synchronized native void observe(int observeType, + Map queryParamsMap, + OnObserveListener onObserveListener) throws OcException; + + /** + * Method to set observation on the resource + * + * @param observeType allows the client to specify how it wants to observe + * @param queryParamsMap map which can have the query parameter name and value + * @param onObserveListener event handler The handler method will be invoked with a map + * of attribute name and values. + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void observe(ObserveType observeType, + Map queryParamsMap, + OnObserveListener onObserveListener, + QualityOfService qualityOfService) throws OcException { + this.observe1( + observeType.getValue(), + queryParamsMap, + onObserveListener, + qualityOfService.getValue()); + } + + private synchronized native void observe1(int observeType, + Map queryParamsMap, + OnObserveListener onObserveListener, + int qualityOfService) throws OcException; + + /** + * Method to cancel the observation on the resource + * + * @throws OcException + */ + public native void cancelObserve() throws OcException; + + /** + * Method to cancel the observation on the resource + * + * @param qualityOfService the quality of communication + * @throws OcException + */ + public void cancelObserve(QualityOfService qualityOfService) throws OcException { + this.cancelObserve1(qualityOfService.getValue()); + } + + private native void cancelObserve1(int qualityOfService) throws OcException; + + /** + * Method to set header options + * + * @param headerOptionList List where header information(header optionID and + * optionData is passed + */ + public void setHeaderOptions(List headerOptionList) { + this.setHeaderOptions(headerOptionList.toArray( + new OcHeaderOption[headerOptionList.size()]) + ); + } + + private native void setHeaderOptions(OcHeaderOption[] headerOptionList); + + /** + * Method to unset header options + */ + public native void unsetHeaderOptions(); + + /** + * Method to get the host address of this resource + * + * @return host address NOTE: This might or might not be exposed in future due to + * security concerns + */ + public native String getHost(); + + /** + * Method to get the URI for this resource + * + * @return resource URI + */ + public native String getUri(); + + /** + * Method to get the connectivity type of this resource + * + * @return OcConnectivityType connectivity type + */ + public OcConnectivityType getConnectivityType() { + return OcConnectivityType.get( + this.getConnectivityTypeN() + ); + } + + private native int getConnectivityTypeN(); + + /** + * Method to provide ability to check if this resource is observable or not + * + * @return true indicates resource is observable; false indicates resource is not observable + */ + public native boolean isObservable(); + + /** + * Method to get the list of resource types + * + * @return List of resource types + */ + public native List getResourceTypes(); + + /** + * Method to get the list of resource interfaces + * + * @return List of resource interface + */ + public native List getResourceInterfaces(); + + /** + * Method to get a unique identifier for this resource across network interfaces. This will + * be guaranteed unique for every resource-per-server independent of how this was discovered. + * + * @return OcResourceIdentifier object, which can be used for all comparison and hashing + */ + public native OcResourceIdentifier getUniqueIdentifier(); + + /** + * Method to get a string representation of the resource's server ID. + * * This is unique per- server independent on how it was discovered. + * + * @return server ID + */ + public native String getServerId(); + + /** + * An OnGetListener can be registered via the resource get call. + * Event listeners are notified asynchronously + */ + public interface OnGetListener { + public void onGetCompleted(List headerOptionList, + OcRepresentation ocRepresentation); + + public void onGetFailed(Throwable ex); + } + + /** + * An OnPutListener can be registered via the resource put call. + * Event listeners are notified asynchronously + */ + public interface OnPutListener { + public void onPutCompleted(List headerOptionList, + OcRepresentation ocRepresentation); + + public void onPutFailed(Throwable ex); + } + + /** + * An OnPostListener can be registered via the resource post call. + * Event listeners are notified asynchronously + */ + public interface OnPostListener { + public void onPostCompleted(List headerOptionList, + OcRepresentation ocRepresentation); + + public void onPostFailed(Throwable ex); + } + + /** + * An OnDeleteListener can be registered via the resource delete call. + * Event listeners are notified asynchronously + */ + public interface OnDeleteListener { + public void onDeleteCompleted(List headerOptionList); + + public void onDeleteFailed(Throwable ex); + } + + /** + * An OnObserveListener can be registered via the resource observe call. + * Event listeners are notified asynchronously + */ + public interface OnObserveListener { + public void onObserveCompleted(List headerOptionList, + OcRepresentation ocRepresentation, + int sequenceNumber); + + public void onObserveFailed(Throwable ex); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcResourceHandle.java b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceHandle.java new file mode 100644 index 0000000..3bab82f --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceHandle.java @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcResourceHandle { + + private OcResourceHandle(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcResourceIdentifier.java b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceIdentifier.java new file mode 100644 index 0000000..a1de037 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceIdentifier.java @@ -0,0 +1,51 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public class OcResourceIdentifier { + private OcResourceIdentifier(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof OcResourceIdentifier)) { + return false; + } + OcResourceIdentifier other = (OcResourceIdentifier) obj; + return equalsN(other); + } + + private native boolean equalsN(OcResourceIdentifier other); + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcResourceRequest.java b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceRequest.java new file mode 100644 index 0000000..5a24b02 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceRequest.java @@ -0,0 +1,135 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.util.EnumSet; +import java.util.List; +import java.util.Map; + +/** + * OcResourceRequest provides APIs to extract details from a request + */ +public class OcResourceRequest { + + private OcResourceRequest(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + /** + * Retrieves the type of request for the entity handler function to operate + * + * @return request type. This could be 'GET'/'PUT'/'POST'/'DELETE' + */ + public RequestType getRequestType() { + return RequestType.get(getRequestTypeNative()); + } + + private native String getRequestTypeNative(); + + /** + * Retrieves the query parameters from the request + * + * @return parameters in the request + */ + public native Map getQueryParameters(); + + /** + * Retrieves the request handler flag set. This can be INIT flag and/or REQUEST flag and/or + * OBSERVE flag. + * NOTE: + * INIT indicates that the vendor's entity handler should go and perform + * initialization operations + * REQUEST indicates that it is a request of certain type (GET/PUT/POST/DELETE) and entity + * handler needs to perform corresponding operations + * OBSERVE indicates that the request is of type Observe and entity handler needs to perform + * corresponding operations + * + * @return Set of handler flags + */ + public EnumSet getRequestHandlerFlagSet() { + return RequestHandlerFlag.convertToEnumSet(getRequestHandlerFlagNative()); + } + + private native int getRequestHandlerFlagNative(); + + /** + * Provides the entire resource attribute representation + * + * @return OcRepresentation object containing the name value pairs representing + * the resource's attributes + */ + public native OcRepresentation getResourceRepresentation(); + + /** + * Object provides observation information + * + * @return observation information + */ + public native ObservationInfo getObservationInfo(); + + /** + * Specifies the resource uri + * + * @param resourceUri resource uri + */ + public native void setResourceUri(String resourceUri); + + /** + * Gets the resource URI + * + * @return resource URI + */ + public native String getResourceUri(); + + /** + * This API retrieves a list of headerOptions which was sent from a client + * + * @return List of header options + */ + public native List getHeaderOptions(); + + /** + * This API retrieves the request handle + * + * @return request handle + */ + public native OcRequestHandle getRequestHandle(); + + /** + * This API retrieves the resource handle + * + * @return resource handle + */ + public native OcResourceHandle getResourceHandle(); + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/OcResourceResponse.java b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceResponse.java new file mode 100644 index 0000000..263de42 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/OcResourceResponse.java @@ -0,0 +1,139 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.util.List; + +/** + * OcResourceResponse provides APIs to set the response details + */ +public class OcResourceResponse { + + static { + System.loadLibrary("oc"); + System.loadLibrary("ocstack-jni"); + } + + public OcResourceResponse() { + super(); + + create(); + } + + private OcResourceResponse(long nativeHandle) { + this.mNativeHandle = nativeHandle; + } + + /** + * This API sets the error code for this response + * + * @param eCode error code to set + */ + public native void setErrorCode(int eCode); + + /** + * Gets new resource uri + * + * @return new resource uri + */ + public native String getNewResourceUri(); + + /** + * Sets new resource uri + * + * @param newResourceUri new resource uri + */ + public native void setNewResourceUri(String newResourceUri); + + /** + * This API allows to set headerOptions in the response + * + * @param headerOptionList List of HeaderOption entries + */ + public void setHeaderOptions(List headerOptionList) { + this.setHeaderOptions(headerOptionList.toArray( + new OcHeaderOption[headerOptionList.size()]) + ); + } + + private native void setHeaderOptions(OcHeaderOption[] headerOptionList); + + /** + * This API allows to set request handle + * + * @param ocRequestHandle request handle + */ + public native void setRequestHandle(OcRequestHandle ocRequestHandle); + + /** + * This API allows to set the resource handle + * + * @param ocResourceHandle resource handle + */ + public native void setResourceHandle(OcResourceHandle ocResourceHandle); + + /** + * This API allows to set the EntityHandler response result + * + * @param responseResult OcEntityHandlerResult type to set the result value + */ + public void setResponseResult(EntityHandlerResult responseResult) { + this.setResponseResult(responseResult.getValue()); + } + + private native void setResponseResult(int responseResult); + + /** + * API to set the entire resource attribute representation + * + * @param ocRepresentation the name value pairs representing the resource's attributes + * @param interfaceStr specifies the interface + */ + public native void setResourceRepresentation(OcRepresentation ocRepresentation, + String interfaceStr); + + /** + * API to set the entire resource attribute representation + * + * @param representation object containing the name value pairs representing the + * resource's attributes + */ + public void setResourceRepresentation(OcRepresentation representation) { + this.setResourceRepresentation1(representation); + } + + private native void setResourceRepresentation1(OcRepresentation representation); + + @Override + protected void finalize() throws Throwable { + super.finalize(); + + dispose(); + } + + private native void create(); + + private native void dispose(); + + private long mNativeHandle; +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/PlatformConfig.java b/android/android_api/base/src/main/java/org/iotivity/base/PlatformConfig.java new file mode 100644 index 0000000..7fd9ac0 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/PlatformConfig.java @@ -0,0 +1,88 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import android.content.Context; + +/** + * Data structure to provide the configuration. + */ +public class PlatformConfig { + + private Context mContext; + private ServiceType mServiceType; + private ModeType mModeType; + private String mIpAddress; + private int mPort; + private QualityOfService mQualityOfService; + + /** + * @param context app context + * @param serviceType indicate IN_PROC or OUT_OF_PROC + * @param modeType indicate whether we want to do server, client or both + * @param ipAddress ip address of server + * if you specify 0.0.0.0 : it listens on any interface + * @param port port of server + * if you specifiy 0 : next available random port is used + * if you specify 5683 : client discovery can work even if they don't + * specify port + * @param qualityOfService quality of service + */ + public PlatformConfig(Context context, + ServiceType serviceType, + ModeType modeType, + String ipAddress, + int port, + QualityOfService qualityOfService) { + this.mContext = context; + this.mServiceType = serviceType; + this.mModeType = modeType; + this.mIpAddress = ipAddress; + this.mPort = port; + this.mQualityOfService = qualityOfService; + } + + public Context getContext() { + return mContext; + } + + public ServiceType getServiceType() { + return mServiceType; + } + + public ModeType getModeType() { + return mModeType; + } + + public String getIpAddress() { + return mIpAddress; + } + + public int getPort() { + return mPort; + } + + public QualityOfService getQualityOfService() { + return mQualityOfService; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/QualityOfService.java b/android/android_api/base/src/main/java/org/iotivity/base/QualityOfService.java new file mode 100644 index 0000000..4c85981 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/QualityOfService.java @@ -0,0 +1,42 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +/** + */ +public enum QualityOfService { + LOW(0), + MEDIUM(1), + HIGH(2), + NA(3); + + private int value; + + private QualityOfService(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/RequestHandlerFlag.java b/android/android_api/base/src/main/java/org/iotivity/base/RequestHandlerFlag.java new file mode 100644 index 0000000..5e1f5ee --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/RequestHandlerFlag.java @@ -0,0 +1,61 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +import java.util.EnumSet; + +public enum RequestHandlerFlag { + INIT(1 << 0), + REQUEST(1 << 1), + OBSERVER(1 << 2),; + + private int value; + + private RequestHandlerFlag(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } + + public static EnumSet convertToEnumSet(int value) { + EnumSet flagSet = null; + + for (RequestHandlerFlag v : values()) { + if (0 != (value & v.getValue())) { + if (flagSet == null) { + flagSet = EnumSet.of(v); + } else { + flagSet.add(v); + } + } + } + + if (null == flagSet || flagSet.isEmpty()) { + throw new IllegalArgumentException("Unexpected RequestHandlerFlag value"); + } + + return flagSet; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/RequestType.java b/android/android_api/base/src/main/java/org/iotivity/base/RequestType.java new file mode 100644 index 0000000..894429d --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/RequestType.java @@ -0,0 +1,48 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum RequestType { + GET("GET"), + PUT("PUT"), + POST("POST"), + DELETE("DELETE"),; + private String value; + + private RequestType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + public static RequestType get(String value) { + for (RequestType v : values()) { + if (v.getValue().equals(value)) { + return v; + } + } + throw new IllegalArgumentException("Unexpected RequestType value"); + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ResourceProperty.java b/android/android_api/base/src/main/java/org/iotivity/base/ResourceProperty.java new file mode 100644 index 0000000..64345db --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ResourceProperty.java @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ResourceProperty { + ACTIVE(1 << 0), + DISCOVERABLE(1 << 1), + OBSERVABLE(1 << 2), + SLOW(1 << 3), + SECURE(1 << 4); + + private int value; + + private ResourceProperty(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/base/ServiceType.java b/android/android_api/base/src/main/java/org/iotivity/base/ServiceType.java new file mode 100644 index 0000000..6dc65a7 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/base/ServiceType.java @@ -0,0 +1,38 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base; + +public enum ServiceType { + IN_PROC(0), + OUT_OF_PROC(1),; + + private int value; + + private ServiceType(int value) { + this.value = value; + } + + public int getValue() { + return this.value; + } +} diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java new file mode 100644 index 0000000..81c457c --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java @@ -0,0 +1,34 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.ca; + +import android.content.Context; + +public class CaInterface { + static { + System.loadLibrary("connectivity_abstraction"); + System.loadLibrary("ca-interface"); + } + + public static native void initialize(Context context); +} \ No newline at end of file diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java new file mode 100644 index 0000000..43d0ace --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java @@ -0,0 +1,70 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.ca; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; + +public class CaIpInterface { + private static Context mContext; + + private CaIpInterface(Context context) { + mContext = context; + registerIpStateReceiver(); + } + + private void registerIpStateReceiver() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + + mContext.registerReceiver(mReceiver, intentFilter); + } + + private static BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) { + stateDisabled(); + } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + ConnectivityManager manager = (ConnectivityManager) + mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + + if(nwInfo.isConnected()) { + stateEnabled(); + } + } + } + }; + + private native static void stateEnabled(); + + private native static void stateDisabled(); +} \ No newline at end of file diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java new file mode 100644 index 0000000..15cac58 --- /dev/null +++ b/android/android_api/base/src/main/java/org/iotivity/ca/CaWiFiInterface.java @@ -0,0 +1,72 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.ca; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.wifi.WifiManager; + +public class CaWiFiInterface { + + private static Context mContext; + + private CaWiFiInterface(Context context) { + mContext = context; + registerWiFiStateReceiver(); + } + + private void registerWiFiStateReceiver() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + + mContext.registerReceiver(mReceiver, intentFilter); + } + + private static BroadcastReceiver mReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) { + CAWiFiStateDisabled(); + } else if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + ConnectivityManager manager = (ConnectivityManager) + mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo nwInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + + if (nwInfo.isConnected()) { + CAWiFiStateEnabled(); + } + } + } + }; + + private native static void CAWiFiStateEnabled(); + + private native static void CAWiFiStateDisabled(); +} \ No newline at end of file diff --git a/android/android_api/build.gradle b/android/android_api/build.gradle new file mode 100755 index 0000000..478166f --- /dev/null +++ b/android/android_api/build.gradle @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2014 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/android/android_api/gradle.properties b/android/android_api/gradle.properties new file mode 100755 index 0000000..42a55d5 --- /dev/null +++ b/android/android_api/gradle.properties @@ -0,0 +1,40 @@ +# +# //****************************************************************** +# // +# // Copyright 2015 Intel Corporation. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# // +# // 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. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# + +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/android/android_api/gradle/wrapper/gradle-wrapper.jar b/android/android_api/gradle/wrapper/gradle-wrapper.jar new file mode 100755 index 0000000..8c0fb64 Binary files /dev/null and b/android/android_api/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/android_api/gradle/wrapper/gradle-wrapper.properties b/android/android_api/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000..c275376 --- /dev/null +++ b/android/android_api/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,28 @@ +# +# //****************************************************************** +# // +# // Copyright 2014 Intel Corporation. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# // +# // 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. +# // +# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# + +#Fri Dec 12 12:28:50 PST 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/android/android_api/gradlew b/android/android_api/gradlew new file mode 100755 index 0000000..583ae08 --- /dev/null +++ b/android/android_api/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/SimpleClient/gradlew.bat b/android/android_api/gradlew.bat old mode 100644 new mode 100755 similarity index 100% rename from android/SimpleClient/gradlew.bat rename to android/android_api/gradlew.bat diff --git a/android/android_api/settings.gradle b/android/android_api/settings.gradle new file mode 100755 index 0000000..d1bcc8a --- /dev/null +++ b/android/android_api/settings.gradle @@ -0,0 +1,23 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +include ':base' diff --git a/android/examples/build.gradle b/android/examples/build.gradle new file mode 100755 index 0000000..50e899c --- /dev/null +++ b/android/examples/build.gradle @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.0.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/android/examples/examples.iml b/android/examples/examples.iml new file mode 100755 index 0000000..8d49284 --- /dev/null +++ b/android/examples/examples.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/android/examples/fridgeclient/.gitignore b/android/examples/fridgeclient/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/android/examples/fridgeclient/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/examples/fridgeclient/build.gradle b/android/examples/fridgeclient/build.gradle new file mode 100755 index 0000000..975453f --- /dev/null +++ b/android/examples/fridgeclient/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.iotivity.base.examples.fridgeclient" + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:21.0.3' + compile project(':message') +} diff --git a/android/examples/fridgeclient/fridgeclient.iml b/android/examples/fridgeclient/fridgeclient.iml new file mode 100755 index 0000000..ea17290 --- /dev/null +++ b/android/examples/fridgeclient/fridgeclient.iml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/examples/fridgeclient/src/main/AndroidManifest.xml b/android/examples/fridgeclient/src/main/AndroidManifest.xml new file mode 100755 index 0000000..d560e70 --- /dev/null +++ b/android/examples/fridgeclient/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + diff --git a/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/FridgeClient.java b/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/FridgeClient.java new file mode 100644 index 0000000..a004c87 --- /dev/null +++ b/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/FridgeClient.java @@ -0,0 +1,362 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeclient; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Message; +import android.support.v4.content.LocalBroadcastManager; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.iotivity.base.ErrorCode; +import org.iotivity.base.ModeType; +import org.iotivity.base.OcConnectivityType; +import org.iotivity.base.OcException; +import org.iotivity.base.OcHeaderOption; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResource; +import org.iotivity.base.PlatformConfig; +import org.iotivity.base.QualityOfService; +import org.iotivity.base.ServiceType; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * FridgeClient + *

+ * FridgeClient is a sample client app which should be started after the fridgeServer is started. + * It creates DeviceResource, DoorResource, LightResource and performs a get operation on them. + * This implements IMessageLogger to display messages on the screen + */ +public class FridgeClient extends Activity implements + OcPlatform.OnResourceFoundListener, IMessageLogger { + private static String TAG = "FridgeClient: "; + + private MessageReceiver mMessageReceiver = new MessageReceiver(); + private TextView mEventsTextView; + private String mDeviceName; + private int mDeviceCode; + private List ifaces; + private final List resourceList = new LinkedList(); + + /** + * configure OIC platform and call findResource + */ + private void initOICStack() { + PlatformConfig cfg = new PlatformConfig( + this, + ServiceType.IN_PROC, + ModeType.CLIENT, + "0.0.0.0", // bind to all available interfaces + 0, + QualityOfService.LOW); + + OcPlatform.Configure(cfg); + try { + OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "intel.fridge", + OcConnectivityType.WIFI, this); + } catch (OcException e) { + logMessage(TAG + " init Error. " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * prints out the appropriate messages depending on the device code + * + * @param representation representation of the OcResource + * @param value clientDeviceCode + */ + private void getResponse(OcRepresentation representation, int value) { + switch (value) { + case 0: + // Get on device + try { + logMessage(TAG + "Name of device: " + + representation.getValue(StringConstants.DEVICE_NAME)); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + break; + case 1: + // get on fridge light + try { + boolean lightOn = representation.getValue(StringConstants.ON); + logMessage(TAG + "The fridge light is " + + (lightOn ? "" : "not " + "on")); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + break; + case 2: + case 3: + // get on fridge door(s) + try { + boolean doorOpen = representation.getValue(StringConstants.OPEN); + logMessage(TAG + "Door is " + (doorOpen ? + "open" : "not open") + " and is on the " + + representation.getValue(StringConstants.SIDE) + " side"); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + break; + case 4: + // get on fridge random door + try { + logMessage("Name of fridge: " + + representation.getValue(StringConstants.DEVICE_NAME)); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + break; + default: + logMessage("Unexpected State"); + break; + } + } + + /** + * this method is used to wait for 1 second between calls to different resources. + * It is added for better readability + */ + private void doWait() { + try { + Thread.sleep(StringConstants.WAIT_TIME); + } catch (InterruptedException e) { + logMessage(TAG + "doWait exception: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + @Override + /** + * callback when a resource is found. This method calls getResponse with the correct code + */ + synchronized public void onResourceFound(OcResource ocResource) { + // eventHandler for onGetListener + resourceList.add(ocResource); + OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() { + @Override + public void onGetCompleted(List headerOptionList, OcRepresentation rep) { + logMessage(TAG + " Got a response from " + getClientDeviceName()); + getResponse(rep, getClientDeviceCode()); + } + + @Override + public void onGetFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + + if (ocResource.getUri().equals(StringConstants.RESOURCE_URI)) { + logMessage(TAG + "Discovered a device with \nHost: " + ocResource.getHost() + + ", Uri: " + ocResource.getUri()); + } + List lightTypes = new LinkedList<>(); + lightTypes.add("intel.fridge.light"); + try { + OcResource light = OcPlatform.constructResourceObject(ocResource.getHost(), + StringConstants.LIGHT, OcConnectivityType.WIFI, false, lightTypes, ifaces); + + List doorTypes = new LinkedList<>(); + doorTypes.add("intel.fridge.door"); + OcResource leftDoor = OcPlatform.constructResourceObject(ocResource.getHost(), + StringConstants.LEFT_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces); + + OcResource rightDoor = OcPlatform.constructResourceObject(ocResource.getHost(), + StringConstants.RIGHT_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces); + + OcResource randomDoor = OcPlatform.constructResourceObject(ocResource.getHost(), + StringConstants.RANDOM_DOOR, OcConnectivityType.WIFI, false, doorTypes, ifaces); + + List headerOptions = new LinkedList<>(); + OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY, + StringConstants.API_VERSION); + OcHeaderOption clientToken = new OcHeaderOption(StringConstants.CLIENT_VERSION_KEY, + StringConstants.CLIENT_TOKEN); + headerOptions.add(apiVersion); + headerOptions.add(clientToken); + ocResource.setHeaderOptions(headerOptions); + /** + * wait for 1 second before calling get on different resources. + * It is done for better readability. + * doWait() is called before each call to get + */ + doWait(); + + setupClientOptions("Device", 0); + ocResource.get(new HashMap(), onGetListener); + doWait(); + + setupClientOptions("Fridge Light", 1); + light.get(new HashMap(), onGetListener); + doWait(); + + setupClientOptions("Left Door", 2); + leftDoor.get(new HashMap(), onGetListener); + doWait(); + + setupClientOptions("Right Door", 3); + rightDoor.get(new HashMap(), onGetListener); + doWait(); + + setupClientOptions("Random Door", 4); + randomDoor.get(new HashMap(), onGetListener); + doWait(); + + resourceList.add(leftDoor); + leftDoor.deleteResource(new OcResource.OnDeleteListener() { + @Override + public void onDeleteCompleted(List ocHeaderOptions) { + logMessage(TAG + "Delete resource successful"); + } + + @Override + public void onDeleteFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }); + } catch (OcException e) { + logMessage(TAG + "onResourceFound Error. " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_fridge_client); + registerReceiver(mMessageReceiver, new IntentFilter(StringConstants.INTENT)); + + mEventsTextView = new TextView(this); + mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); + LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout); + layout.addView(mEventsTextView, new LinearLayout.LayoutParams + (LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)); + ifaces = new LinkedList<>(); + ifaces.add(StringConstants.RESOURCE_INTERFACE); + mDeviceCode = -1; + mDeviceName = ""; + + initOICStack(); + } + + public class MessageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String message = intent.getStringExtra(StringConstants.MESSAGE); + logMessage(message); + } + } + + @Override + public void logMessage(final String text) { + if (StringConstants.ENABLE_PRINTING) { + runOnUiThread(new Runnable() { + public void run() { + final Message msg = new Message(); + msg.obj = text; + mEventsTextView.append("\n"); + mEventsTextView.append(text); + } + }); + Log.i(TAG, text); + } + } + + + private void setupClientOptions(String name, int value) { + mDeviceName = name; + mDeviceCode = value; + } + + private String getClientDeviceName() { + return mDeviceName; + } + + private int getClientDeviceCode() { + return mDeviceCode; + } + + + //method to print the headerOptions received from the server + void printHeaderOptions(List headerOptions) { + for (OcHeaderOption headerOption : headerOptions) { + if (StringConstants.API_VERSION_KEY == headerOption.getOptionId()) { + logMessage(TAG + "Server API version in GET response: " + + headerOption.getOptionData()); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_fridge_client, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onDestroy() { + super.onDestroy(); + onStop(); + } + + @Override + protected void onStop() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); + super.onStop(); + } +} diff --git a/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/StringConstants.java b/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/StringConstants.java new file mode 100644 index 0000000..da88e4d --- /dev/null +++ b/android/examples/fridgeclient/src/main/java/org/iotivity/base/examples/fridgeclient/StringConstants.java @@ -0,0 +1,33 @@ +package org.iotivity.base.examples.fridgeclient; + +import org.iotivity.base.OcPlatform; + +/** + * StringConstant contains the fridgeclient specific constant values. To add another supported + * Resource or Interface type to this app, begin by adding the new strings here, and then + * find the places throughout the app where Resource-specific case switches occur, and add + * the newly-supported type there. + */ +public interface StringConstants { + public static final String RESOURCE_URI = "/device"; + public static final String DEVICE_NAME = "device_name"; + public static final String LIGHT = "/light"; + public static final String LEFT_DOOR = "/door/left"; + public static final String RIGHT_DOOR = "/door/right"; + public static final String RANDOM_DOOR = "/door/random"; + public static final String MESSAGE = "message"; + public static final String API_VERSION = "v.1.2"; + public static final String CLIENT_TOKEN = "AaBbYyZz"; + public static final String ON = "on"; + public static final String OPEN = "open"; + public static final String SIDE = "side"; + public static final String INTENT = "org.iotivity.base.examples.fridgeclient"; + public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE; + + public static final int WAIT_TIME = 1000; + public static final int API_VERSION_KEY = 2048; + public static final int CLIENT_VERSION_KEY = 3000; + + public static final boolean ENABLE_PRINTING = true; // change to false to disable printing + // of messages on the console and the screen +} diff --git a/android/SimpleClient/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/examples/fridgeclient/src/main/res/drawable-hdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/SimpleClient/app/src/main/res/drawable-hdpi/ic_launcher.png rename to android/examples/fridgeclient/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/android/SimpleClient/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/examples/fridgeclient/src/main/res/drawable-mdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/SimpleClient/app/src/main/res/drawable-mdpi/ic_launcher.png rename to android/examples/fridgeclient/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/android/SimpleClient/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/examples/fridgeclient/src/main/res/drawable-xhdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/SimpleClient/app/src/main/res/drawable-xhdpi/ic_launcher.png rename to android/examples/fridgeclient/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/android/SimpleClient/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/examples/fridgeclient/src/main/res/drawable-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/SimpleClient/app/src/main/res/drawable-xxhdpi/ic_launcher.png rename to android/examples/fridgeclient/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/android/examples/fridgeclient/src/main/res/layout/activity_fridge_client.xml b/android/examples/fridgeclient/src/main/res/layout/activity_fridge_client.xml new file mode 100755 index 0000000..d813c8a --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/layout/activity_fridge_client.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/android/examples/fridgeclient/src/main/res/menu/menu_fridge_client.xml b/android/examples/fridgeclient/src/main/res/menu/menu_fridge_client.xml new file mode 100755 index 0000000..f812805 --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/menu/menu_fridge_client.xml @@ -0,0 +1,6 @@ +

+ + diff --git a/android/examples/fridgeclient/src/main/res/values-w820dp/dimens.xml b/android/examples/fridgeclient/src/main/res/values-w820dp/dimens.xml new file mode 100755 index 0000000..62df187 --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/android/examples/fridgeclient/src/main/res/values/dimens.xml b/android/examples/fridgeclient/src/main/res/values/dimens.xml new file mode 100755 index 0000000..295b5a9 --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/android/examples/fridgeclient/src/main/res/values/strings.xml b/android/examples/fridgeclient/src/main/res/values/strings.xml new file mode 100755 index 0000000..152e2c9 --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + FridgeClient + Hello world! + Settings + + diff --git a/android/examples/fridgeclient/src/main/res/values/styles.xml b/android/examples/fridgeclient/src/main/res/values/styles.xml new file mode 100755 index 0000000..084b42b --- /dev/null +++ b/android/examples/fridgeclient/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/android/examples/fridgeserver/.gitignore b/android/examples/fridgeserver/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/android/examples/fridgeserver/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/examples/fridgeserver/build.gradle b/android/examples/fridgeserver/build.gradle new file mode 100755 index 0000000..b7327b6 --- /dev/null +++ b/android/examples/fridgeserver/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.iotivity.base.examples.fridgeserver" + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:21.0.3' + compile project(':message') +} diff --git a/android/examples/fridgeserver/fridgeserver.iml b/android/examples/fridgeserver/fridgeserver.iml new file mode 100755 index 0000000..65d2947 --- /dev/null +++ b/android/examples/fridgeserver/fridgeserver.iml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/examples/fridgeserver/src/main/AndroidManifest.xml b/android/examples/fridgeserver/src/main/AndroidManifest.xml new file mode 100755 index 0000000..cbcffd9 --- /dev/null +++ b/android/examples/fridgeserver/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DeviceResource.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DeviceResource.java new file mode 100644 index 0000000..fc33258 --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DeviceResource.java @@ -0,0 +1,189 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.OcException; +import org.iotivity.base.OcHeaderOption; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcResourceRequest; +import org.iotivity.base.OcResourceResponse; +import org.iotivity.base.RequestHandlerFlag; +import org.iotivity.base.ResourceProperty; + +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * DeviceResource + *

+ * Creates a device resource and performs action based on client requests + */ +public class DeviceResource extends Resource implements IMessageLogger { + private Context mContext; + + private static String TAG = "DeviceResource: "; + + /** + * constructor + * + * @param context to enable sending of broadcast messages to be displayed on the user screen + */ + DeviceResource(Context context) { + mContext = context; + + // eventHandler for register deviceResource + OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + // this is where the main logic of DeviceResource is handled + return entityHandler(ocResourceRequest); + } + }; + + try { + logMessage(TAG + "RegisterDeviceResource " + StringConstants.DEVICE_URI + " : " + + StringConstants.RESOURCE_TYPENAME + " : " + StringConstants.RESOURCE_INTERFACE); + mResourceHandle = OcPlatform.registerResource(StringConstants.DEVICE_URI, + StringConstants.RESOURCE_TYPENAME, StringConstants.RESOURCE_INTERFACE, + eh, EnumSet.of(ResourceProperty.DISCOVERABLE)); + } catch (OcException e) { + logMessage(TAG + "registerResource error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * update current state of device + * + * @return device representation + */ + private void updateRepresentationValues() { + try { + mRepresentation.setValue(StringConstants.DEVICE_NAME, + "Intel Powered 2 door, 1 light refrigerator"); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + } + + /** + * unregister the resource + */ + private void deleteDeviceResource() { + try { + OcPlatform.unregisterResource(mResourceHandle); + logMessage(TAG + "Unregister DeviceResource successful"); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * this is the main method which handles different incoming requests appropriately. + * + * @param request OcResourceRequest from the client + * @return EntityHandlerResult depending on whether the request was handled successfully or not + */ + private EntityHandlerResult entityHandler(OcResourceRequest request) { + EntityHandlerResult result = EntityHandlerResult.ERROR; + if (null != request) { + List headerOptions = request.getHeaderOptions(); + String clientAPIVersion = ""; + String clientToken = ""; + + // search for header options map and look for API version and client token + for (OcHeaderOption headerOption : headerOptions) { + int optionId = headerOption.getOptionId(); + if (StringConstants.API_VERSION_KEY == optionId) { + clientAPIVersion = headerOption.getOptionData(); + logMessage(TAG + " Client API Version: " + clientAPIVersion); + } else if (StringConstants.CLIENT_VERSION_KEY == optionId) { + clientToken = headerOption.getOptionData(); + logMessage(TAG + " Client Token: " + clientToken); + } + } + if (clientAPIVersion.equals(StringConstants.API_VERSION) && + clientToken.equals(StringConstants.CLIENT_TOKEN)) { + List serverHeaderOptions = new LinkedList<>(); + OcHeaderOption apiVersion = new OcHeaderOption(StringConstants.API_VERSION_KEY, + StringConstants.API_VERSION); + serverHeaderOptions.add(apiVersion); + try { + if (request.getRequestHandlerFlagSet().contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + response.setHeaderOptions(serverHeaderOptions); + + switch (request.getRequestType()) { + case GET: + response.setErrorCode(StringConstants.OK); + response.setResponseResult(EntityHandlerResult.OK); + updateRepresentationValues(); + response.setResourceRepresentation(mRepresentation); + OcPlatform.sendResponse(response); + break; + case DELETE: + deleteDeviceResource(); + response.setErrorCode(StringConstants.OK); + response.setResponseResult(EntityHandlerResult.OK); + break; + case POST: + response.setResponseResult(EntityHandlerResult.ERROR); + OcPlatform.sendResponse(response); + break; + } + result = EntityHandlerResult.OK; + } + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + } + return result; + } + + @Override + public void logMessage(String msg) { + logMsg(msg); + if (StringConstants.ENABLE_PRINTING) { + Log.i(TAG, msg); + } + } + + public void logMsg(final String text) { + Intent intent = new Intent(StringConstants.INTENT); + intent.putExtra("message", text); + mContext.sendBroadcast(intent); + } +} diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DoorResource.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DoorResource.java new file mode 100644 index 0000000..438022b --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/DoorResource.java @@ -0,0 +1,178 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResourceRequest; +import org.iotivity.base.OcResourceResponse; +import org.iotivity.base.RequestHandlerFlag; +import org.iotivity.base.ResourceProperty; + +import java.util.EnumSet; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * DoorResource + *

+ * Creates a door resource and performs action based on client requests + */ +public class DoorResource extends Resource implements IMessageLogger { + private Context mContext; + + private static String TAG = "DoorResource: "; + private String mSide = StringConstants.LEFT; + private boolean mOpen; + private String resourceURI; + + /** + * Constructor + * + * @param side left or right side of the door + * @param context to enable sending of broadcast messages to be displayed on the user screen + */ + DoorResource(String side, Context context) { + mContext = context; + mSide = side; + + resourceURI = StringConstants.DOOR_URI + mSide; + + // eventHandler for register doorResource + OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + // this is where the main logic of DoorResource is handled + return entityHandler(ocResourceRequest); + } + }; + try { + logMessage(TAG + "RegisterDoorResource " + resourceURI + " : " + + StringConstants.RESOURCE_TYPEDOOR + " : " + StringConstants.RESOURCE_INTERFACE); + mResourceHandle = OcPlatform.registerResource(resourceURI, + StringConstants.RESOURCE_TYPEDOOR, StringConstants.RESOURCE_INTERFACE, + eh, EnumSet.of(ResourceProperty.DISCOVERABLE)); + } catch (OcException e) { + logMessage(TAG + "DoorResource registerResource error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * updates the current value of the door resource + * + * @return door representation + */ + private void updateRepresentationValues() { + try { + mRepresentation.setValue(StringConstants.SIDE, mSide); + mRepresentation.setValue(StringConstants.OPEN, mOpen); + mRepresentation.setValue(StringConstants.DEVICE_NAME, + "Intel Powered 2 door, 1 light refrigerator"); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + } + + /** + * update the OPEN value of doorResource (door is open/ closed) + * + * @param representation get current state of door + */ + private void put(OcRepresentation representation) { + try { + mOpen = representation.getValue(StringConstants.OPEN); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + // Note, we won't let the user change the door side! + } + + /** + * this is the main method which handles different incoming requests appropriately. + * + * @param request OcResourceRequest from the client + * @return EntityHandlerResult depending on whether the request was handled successfully or not + */ + private EntityHandlerResult entityHandler(OcResourceRequest request) { + EntityHandlerResult result = EntityHandlerResult.ERROR; + if (null != request) { + try { + if (request.getRequestHandlerFlagSet().contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + + switch (request.getRequestType()) { + case GET: + response.setErrorCode(StringConstants.OK); + updateRepresentationValues(); + response.setResourceRepresentation(mRepresentation); + response.setResponseResult(EntityHandlerResult.OK); + OcPlatform.sendResponse(response); + break; + case PUT: + response.setErrorCode(StringConstants.OK); + put(request.getResourceRepresentation()); + updateRepresentationValues(); + response.setResourceRepresentation(mRepresentation); + response.setResponseResult(EntityHandlerResult.OK); + OcPlatform.sendResponse(response); + break; + case DELETE: + response.setResponseResult(EntityHandlerResult.RESOURCE_DELETED); + response.setErrorCode(204); + OcPlatform.sendResponse(response); + break; + } + result = EntityHandlerResult.OK; + } + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + return result; + } + + @Override + public void logMessage(String msg) { + logMsg(msg); + if (StringConstants.ENABLE_PRINTING) { + Log.i(TAG, msg); + } + } + + public void logMsg(final String text) { + Intent intent = new Intent(StringConstants.INTENT); + intent.putExtra(StringConstants.MESSAGE, text); + mContext.sendBroadcast(intent); + } +} diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/FridgeServer.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/FridgeServer.java new file mode 100644 index 0000000..45971f7 --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/FridgeServer.java @@ -0,0 +1,145 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Message; +import android.support.v4.content.LocalBroadcastManager; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.iotivity.base.ModeType; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.PlatformConfig; +import org.iotivity.base.QualityOfService; +import org.iotivity.base.ServiceType; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * FridgeServer + *

+ * This is the main fridgeServer class. This instantiates Refrigerator object + * which has different resources (DeviceResource, LightResource, DoorResource). + */ +public class FridgeServer extends Activity implements IMessageLogger { + private Context mContext; + private static String TAG = "FridgeServer: "; + private TextView mEventsTextView; + private MessageReceiver mMessageReceiver = new MessageReceiver(); + private Refrigerator refrigerator; + + /** + * configure OIC platform and call findResource + */ + private void initOICStack() { + //create platform config + PlatformConfig cfg = new PlatformConfig( + this, + ServiceType.IN_PROC, + ModeType.SERVER, + "0.0.0.0", // bind to all available interfaces + 0, + QualityOfService.LOW); + OcPlatform.Configure(cfg); + logMessage(TAG + "Creating refrigerator resources"); + + refrigerator = new Refrigerator(mContext); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_fridge_server); + registerReceiver(mMessageReceiver, new IntentFilter(StringConstants.INTENT)); + + mEventsTextView = new TextView(this); + mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); + LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout); + layout.addView(mEventsTextView, new LinearLayout.LayoutParams + (LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)); + mContext = this; + + initOICStack(); + } + + public class MessageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String message = intent.getStringExtra(StringConstants.MESSAGE); + logMessage(message); + } + } + + @Override + public void logMessage(final String text) { + if (StringConstants.ENABLE_PRINTING) { + runOnUiThread(new Runnable() { + public void run() { + final Message msg = new Message(); + msg.obj = text; + mEventsTextView.append("\n"); + mEventsTextView.append(text); + } + }); + Log.i(TAG, text); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_fridge_server, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onDestroy() { + super.onDestroy(); + onStop(); + } + + @Override + protected void onStop() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); + super.onStop(); + } +} diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/LightResource.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/LightResource.java new file mode 100644 index 0000000..09b7f43 --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/LightResource.java @@ -0,0 +1,164 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResourceRequest; +import org.iotivity.base.OcResourceResponse; +import org.iotivity.base.RequestHandlerFlag; +import org.iotivity.base.ResourceProperty; + +import java.util.EnumSet; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * LightResource + *

+ * Creates a light resource and performs action based on client requests + */ +public class LightResource extends Resource implements IMessageLogger { + private Context mContext; + + private static String TAG = "LightResource: "; + + private boolean mIsOn = false; + + /** + * constructor + * + * @param context to enable sending of broadcast messages to be displayed on the user screen + */ + LightResource(Context context) { + mContext = context; + //eventHandler for register lightResource + OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + // this is where the main logic of LightResource is handled + return entityHandler(ocResourceRequest); + } + }; + try { + logMessage(TAG + "RegisterLightResource " + StringConstants.LIGHT_URI + " : " + + StringConstants.RESOURCE_TYPELIGHT + " : " + StringConstants.RESOURCE_INTERFACE); + mResourceHandle = OcPlatform.registerResource(StringConstants.LIGHT_URI, + StringConstants.RESOURCE_TYPELIGHT, StringConstants.RESOURCE_INTERFACE, + eh, EnumSet.of(ResourceProperty.DISCOVERABLE)); + } catch (OcException e) { + logMessage(TAG + "LightResource registerResource error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * updates the current state of the light (on/ off) + * + * @return light is on or off + */ + private void updateRepresentationValues() { + try { + mRepresentation.setValue(StringConstants.ON, mIsOn); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + } + + /** + * update the value of mIsOn from the representation + * + * @param representation get current state of light + */ + private void put(OcRepresentation representation) { + try { + mIsOn = representation.getValue(StringConstants.ON); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + } + + /** + * this is the main method which handles different incoming requests appropriately. + * + * @param request OcResourceRequest from the client + * @return EntityHandlerResult depending on whether the request was handled successfully or not + */ + private EntityHandlerResult entityHandler(OcResourceRequest request) { + EntityHandlerResult result = EntityHandlerResult.ERROR; + if (null != request) { + try { + if (request.getRequestHandlerFlagSet().contains(RequestHandlerFlag.REQUEST)) { + OcResourceResponse response = new OcResourceResponse(); + response.setRequestHandle(request.getRequestHandle()); + response.setResourceHandle(request.getResourceHandle()); + + switch (request.getRequestType()) { + case GET: + response.setErrorCode(StringConstants.OK); + updateRepresentationValues(); + response.setResourceRepresentation(mRepresentation); + response.setResponseResult(EntityHandlerResult.OK); + OcPlatform.sendResponse(response); + result = EntityHandlerResult.OK; + break; + case PUT: + response.setErrorCode(StringConstants.OK); + put(request.getResourceRepresentation()); + updateRepresentationValues(); + response.setResourceRepresentation(mRepresentation); + response.setResponseResult(EntityHandlerResult.OK); + OcPlatform.sendResponse(response); + result = EntityHandlerResult.OK; + break; + } + } + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + return EntityHandlerResult.ERROR; + } + } + return result; + } + + @Override + public void logMessage(String msg) { + logMsg(msg); + if (StringConstants.ENABLE_PRINTING) { + Log.i(TAG, msg); + } + } + + public void logMsg(final String text) { + Intent intent = new Intent(StringConstants.INTENT); + intent.putExtra(StringConstants.MESSAGE, text); + mContext.sendBroadcast(intent); + } +} diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Refrigerator.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Refrigerator.java new file mode 100644 index 0000000..4432755 --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Refrigerator.java @@ -0,0 +1,57 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import android.content.Context; + +/** + * Refrigerator + *

+ * Refrigerator class has different objects (resources) which are instantiated when a + * Refrigerator object is created. Operations are performed on each of the individual resources. + */ +public class Refrigerator { + private Context mContext; + + private LightResource mLight; + private DeviceResource mDevice; + private DoorResource mLeftDoor; + private DoorResource mRightDoor; + private DoorResource mRandomDoor; + + /** + * constructor + * + * @param context needed by individual resources to be able to send broadcast + * messages to be displayed on the user screen + */ + Refrigerator(Context context) { + mContext = context; + mLight = new LightResource(context); + mDevice = new DeviceResource(context); + mLeftDoor = new DoorResource(StringConstants.LEFT, context); + mRightDoor = new DoorResource(StringConstants.RIGHT, context); + mRandomDoor = new DoorResource(StringConstants.RANDOM, context); + } + +} diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Resource.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Resource.java new file mode 100644 index 0000000..350cee0 --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/Resource.java @@ -0,0 +1,41 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.fridgeserver; + +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResourceHandle; + +/** + * Resource + *

+ * Each of the other resource classes (DeviceResource, DoorResource and LightResource extend Resource + */ +public class Resource { + protected OcResourceHandle mResourceHandle; + protected OcRepresentation mRepresentation; + + Resource() { + mResourceHandle = null; + mRepresentation = new OcRepresentation(); + } +} \ No newline at end of file diff --git a/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/StringConstants.java b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/StringConstants.java new file mode 100644 index 0000000..1afe25b --- /dev/null +++ b/android/examples/fridgeserver/src/main/java/org/iotivity/base/examples/fridgeserver/StringConstants.java @@ -0,0 +1,37 @@ +package org.iotivity.base.examples.fridgeserver; + +import org.iotivity.base.OcPlatform; + +/** + * StringConstant contains the fridgeserver specific constant values. To add another supported + * Resource or Interface type to this app, begin by adding the new strings here, and then + * find the places throughout the app where Resource-specific case switches occur, and add + * the newly-supported type there. + */ +public interface StringConstants { + public static final String DEVICE_URI = "/device"; + public static final String LIGHT_URI = "/light"; + public static final String DOOR_URI = "/door/"; + public static final String DEVICE_NAME = "device_name"; + public static final String RESOURCE_TYPENAME = "intel.fridge"; + public static final String RESOURCE_TYPEDOOR = "intel.fridge.door"; + public static final String RESOURCE_TYPELIGHT = "intel.fridge.light"; + public static final String API_VERSION = "v.1.2"; + public static final String CLIENT_TOKEN = "AaBbYyZz"; + public static final String SIDE = "side"; + public static final String OPEN = "open"; + public static final String MESSAGE = "message"; + public static final String LEFT = "left"; + public static final String RIGHT = "right"; + public static final String RANDOM = "random"; + public static final String ON = "on"; + public static final String INTENT = "org.iotivity.base.examples.fridgeserver"; + public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE; + + public static final int API_VERSION_KEY = 2048; + public static final int CLIENT_VERSION_KEY = 3000; + public static final int OK = 200; + + public static final boolean ENABLE_PRINTING = true; // change to false to disable printing + // of messages on the console and the screen +} diff --git a/android/Base/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/examples/fridgeserver/src/main/res/drawable-hdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/Base/app/src/main/res/drawable-hdpi/ic_launcher.png rename to android/examples/fridgeserver/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/android/Base/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/examples/fridgeserver/src/main/res/drawable-mdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/Base/app/src/main/res/drawable-mdpi/ic_launcher.png rename to android/examples/fridgeserver/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/android/Base/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/examples/fridgeserver/src/main/res/drawable-xhdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/Base/app/src/main/res/drawable-xhdpi/ic_launcher.png rename to android/examples/fridgeserver/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/android/Base/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/examples/fridgeserver/src/main/res/drawable-xxhdpi/ic_launcher.png old mode 100644 new mode 100755 similarity index 100% rename from android/Base/app/src/main/res/drawable-xxhdpi/ic_launcher.png rename to android/examples/fridgeserver/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/android/examples/fridgeserver/src/main/res/layout/activity_fridge_server.xml b/android/examples/fridgeserver/src/main/res/layout/activity_fridge_server.xml new file mode 100755 index 0000000..39362b3 --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/layout/activity_fridge_server.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/android/examples/fridgeserver/src/main/res/menu/menu_fridge_server.xml b/android/examples/fridgeserver/src/main/res/menu/menu_fridge_server.xml new file mode 100755 index 0000000..2895144 --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/menu/menu_fridge_server.xml @@ -0,0 +1,6 @@ +

+ + diff --git a/android/examples/fridgeserver/src/main/res/values-w820dp/dimens.xml b/android/examples/fridgeserver/src/main/res/values-w820dp/dimens.xml new file mode 100755 index 0000000..62df187 --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/android/examples/fridgeserver/src/main/res/values/dimens.xml b/android/examples/fridgeserver/src/main/res/values/dimens.xml new file mode 100755 index 0000000..295b5a9 --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/android/examples/fridgeserver/src/main/res/values/strings.xml b/android/examples/fridgeserver/src/main/res/values/strings.xml new file mode 100755 index 0000000..3e317da --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + FridgeServer + Hello world! + Settings + + diff --git a/android/examples/fridgeserver/src/main/res/values/styles.xml b/android/examples/fridgeserver/src/main/res/values/styles.xml new file mode 100755 index 0000000..084b42b --- /dev/null +++ b/android/examples/fridgeserver/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/android/examples/gradle/wrapper/gradle-wrapper.jar b/android/examples/gradle/wrapper/gradle-wrapper.jar new file mode 100755 index 0000000..8c0fb64 Binary files /dev/null and b/android/examples/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/examples/gradle/wrapper/gradle-wrapper.properties b/android/examples/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000..cdc433f --- /dev/null +++ b/android/examples/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/android/examples/gradlew b/android/examples/gradlew new file mode 100755 index 0000000..583ae08 --- /dev/null +++ b/android/examples/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/Base/gradlew.bat b/android/examples/gradlew.bat old mode 100644 new mode 100755 similarity index 100% rename from android/Base/gradlew.bat rename to android/examples/gradlew.bat diff --git a/android/examples/message/.gitignore b/android/examples/message/.gitignore new file mode 100644 index 0000000..1a94a02 --- /dev/null +++ b/android/examples/message/.gitignore @@ -0,0 +1,3 @@ +/build + +src/main/res \ No newline at end of file diff --git a/android/examples/message/build.gradle b/android/examples/message/build.gradle new file mode 100755 index 0000000..1ed1a39 --- /dev/null +++ b/android/examples/message/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:21.0.3' +} diff --git a/android/examples/message/message.iml b/android/examples/message/message.iml new file mode 100755 index 0000000..e9cabc1 --- /dev/null +++ b/android/examples/message/message.iml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/examples/message/src/main/AndroidManifest.xml b/android/examples/message/src/main/AndroidManifest.xml new file mode 100755 index 0000000..9922f58 --- /dev/null +++ b/android/examples/message/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/android/examples/message/src/main/java/base/iotivity/org/examples/message/IMessageLogger.java b/android/examples/message/src/main/java/base/iotivity/org/examples/message/IMessageLogger.java new file mode 100644 index 0000000..7ecd6b3 --- /dev/null +++ b/android/examples/message/src/main/java/base/iotivity/org/examples/message/IMessageLogger.java @@ -0,0 +1,27 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package base.iotivity.org.examples.message; + +public interface IMessageLogger { + public void logMessage(String msg); +} diff --git a/android/examples/settings.gradle b/android/examples/settings.gradle new file mode 100755 index 0000000..bf2b78b --- /dev/null +++ b/android/examples/settings.gradle @@ -0,0 +1 @@ +include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient' \ No newline at end of file diff --git a/android/examples/simpleclient/.gitignore b/android/examples/simpleclient/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/android/examples/simpleclient/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/examples/simpleclient/build.gradle b/android/examples/simpleclient/build.gradle new file mode 100755 index 0000000..07cc15b --- /dev/null +++ b/android/examples/simpleclient/build.gradle @@ -0,0 +1,25 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.iotivity.base.examples.simpleclient" + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile project(':message') + compile 'com.android.support:appcompat-v7:21.0.3' +} diff --git a/android/examples/simpleclient/simpleclient.iml b/android/examples/simpleclient/simpleclient.iml new file mode 100755 index 0000000..4ba5a36 --- /dev/null +++ b/android/examples/simpleclient/simpleclient.iml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/examples/simpleclient/src/main/AndroidManifest.xml b/android/examples/simpleclient/src/main/AndroidManifest.xml new file mode 100755 index 0000000..0345054 --- /dev/null +++ b/android/examples/simpleclient/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/Light.java b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/Light.java new file mode 100644 index 0000000..2f981b3 --- /dev/null +++ b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/Light.java @@ -0,0 +1,65 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.simpleclient; + +/** + * Light + * + * This class is used by simpleclient to create an object and update the values depending on the server response + */ +public class Light { + private boolean mState; + private int mPower; + private String mName; + + // constructor + Light() { + mState = false; + mPower = 0; + mName = ""; + } + + // accessor methods + public boolean getState() { + return mState; + } + void setState(boolean state) { + mState = state; + } + int getPower() { + return mPower; + } + void setPower(int power) { + mPower = power; + } + String getName() { + return mName; + } + void setName(String name) { + mName = name; + } +} + + + + diff --git a/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/SimpleClient.java b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/SimpleClient.java new file mode 100644 index 0000000..b747c5a --- /dev/null +++ b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/SimpleClient.java @@ -0,0 +1,443 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.simpleclient; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Message; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.iotivity.base.ErrorCode; +import org.iotivity.base.ModeType; +import org.iotivity.base.ObserveType; +import org.iotivity.base.OcConnectivityType; +import org.iotivity.base.OcException; +import org.iotivity.base.OcHeaderOption; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResource; +import org.iotivity.base.PlatformConfig; +import org.iotivity.base.QualityOfService; +import org.iotivity.base.ServiceType; + +import java.util.HashMap; +import java.util.List; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * SimpleClient + *

+ * SimpleClient is a sample client app which should be started after the simpleServer is started. + * It finds resources advertised by the server and calls different operations on it (GET, PUT, + * POST and OBSERVE). + * This implements IMessageLogger to display messages on the screen + */ +public class SimpleClient extends Activity implements OcPlatform.OnResourceFoundListener, + IMessageLogger { + private static final String TAG = "SimpleClient: "; + + private Light myLight; + private OcResource curResource; + + //for display + private TextView mEventsTextView; + private static boolean printOnce = true; + + /** + * configure OIC platform and call findResource + */ + private void initOICStack() { + //create platform config + PlatformConfig cfg = new PlatformConfig( + this, + ServiceType.IN_PROC, + ModeType.CLIENT, + "0.0.0.0", // bind to all available interfaces + 0, + QualityOfService.LOW); + OcPlatform.Configure(cfg); + try { + /** + * find all resources + */ + OcPlatform.findResource("", OcPlatform.WELL_KNOWN_QUERY + "?rt=" + "core.light", + OcConnectivityType.WIFI, this); + } catch (OcException e) { + logMessage(TAG + "findResource error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + @Override + /** + * callback when a resource is found. This method calls doGetLightRepresentation to get the + * current values of myLight + */ + synchronized public void onResourceFound(OcResource ocResource) { + /** + * this may potentially be called by multiple threads at the same time + */ + synchronized (this) { + String resourceUri; + String hostAddress; + resourceUri = ocResource.getUri(); + hostAddress = ocResource.getHost(); + logMessage(TAG + "Discovered Resource\nUri: " + resourceUri + " \n Host: " + hostAddress); + // get the resource types + if (resourceUri.equals(StringConstants.RESOURCE_URI0)) { + curResource = ocResource; + doGetLightRepresentation(); + } + } + } + + /** + * get myLight values after observe + */ + private void doObserveLightRepresentation() { + // eventhandler for observe() + OcResource.OnObserveListener onObserveListener = new OcResource.OnObserveListener() { + @Override + public void onObserveCompleted(List ocHeaderOptions, + OcRepresentation ocRepresentation, int seqNum) { + if (printOnce) { + logMessage(TAG + "OBSERVE request was successful"); + printOnce = false; + } + try { + boolean state = ocRepresentation.getValue(StringConstants.STATE); + int power = ocRepresentation.getValue(StringConstants.POWER); + String name = ocRepresentation.getValue(StringConstants.NAME); + myLight.setState(state); + myLight.setPower(power); + myLight.setName(name); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "onObserve: Power: " + myLight.getPower()); + if (seqNum > 20) { + try { + curResource.cancelObserve(); + logMessage(TAG + "Successfully cancelled observe"); + } catch (OcException e) { + logMessage(TAG + "cancelObserve error. " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + } + + @Override + public void onObserveFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + try { + curResource.observe(ObserveType.OBSERVE, new HashMap(), onObserveListener); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * get the current value of myLight after POST and call doObserveLightRepresentation + * + * @param ocRepresentation needed to invoke post() + */ + private void doOnPost2(OcRepresentation ocRepresentation) { + // eventhandler for post() + OcResource.OnPostListener onPostListener2 = new OcResource.OnPostListener() { + @Override + public void onPostCompleted(List ocHeaderOptions, OcRepresentation rep) { + logMessage(TAG + "POST request was successful"); + String createdUri = rep.getUri(); + if (createdUri.equals(StringConstants.RESOURCE_URI1)) { + logMessage(TAG + "Uri of the created resource: " + createdUri); + } else { + try { + boolean state = rep.getValue(StringConstants.STATE); + int power = rep.getValue(StringConstants.POWER); + String name = rep.getValue(StringConstants.NAME); + myLight.setState(state); + myLight.setPower(power); + myLight.setName(name); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "onPost\nState: " + myLight.getState() + "\nPower: " + + myLight.getPower() + "\nName: " + myLight.getName()); + } + doObserveLightRepresentation(); + } + + @Override + public void onPostFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + try { + curResource.post(ocRepresentation, new HashMap(), onPostListener2); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * create a new resource and update its value. + */ + private void doPostLightRepresentation() { + // eventhandler for post() + OcResource.OnPostListener onPostListener = new OcResource.OnPostListener() { + @Override + public void onPostCompleted(List ocHeaderOptions, + OcRepresentation ocRepresentation) { + String createdUri = ""; + try { + createdUri = ocRepresentation.getValue(StringConstants.CREATED_URI); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + if (createdUri.equals(StringConstants.RESOURCE_URI1)) { + logMessage(TAG + "Uri of the created resource: " + createdUri); + } else { + boolean state = false; + try { + state = ocRepresentation.getValue(StringConstants.STATE); + int power = ocRepresentation.getValue(StringConstants.POWER); + String name = ocRepresentation.getValue(StringConstants.NAME); + myLight.setState(state); + myLight.setPower(power); + myLight.setName(name); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + } + OcRepresentation rep = new OcRepresentation(); + myLight.setState(true); + myLight.setPower(55); + try { + rep.setValue(StringConstants.POWER, myLight.getPower()); + rep.setValue(StringConstants.STATE, myLight.getState()); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + doOnPost2(rep); + } + + @Override + public void onPostFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + + OcRepresentation rep = new OcRepresentation(); + myLight.setState(false); + myLight.setPower(105); + try { + rep.setValue(StringConstants.STATE, myLight.getState()); + rep.setValue(StringConstants.POWER, myLight.getPower()); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + try { + curResource.post(rep, new HashMap(), onPostListener); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * modify the current value of myLight and call doPostLightRepresentation + */ + private void doPutLightRepresentation() { + // eventhandler for put() + OcResource.OnPutListener onPutListener = new OcResource.OnPutListener() { + @Override + public void onPutCompleted(List ocHeaderOptions, + OcRepresentation ocRepresentation) { + logMessage(TAG + "PUT resource was successful"); + try { + boolean state = ocRepresentation.getValue(StringConstants.STATE); + int power = ocRepresentation.getValue(StringConstants.POWER); + String name = ocRepresentation.getValue(StringConstants.NAME); + myLight.setState(state); + myLight.setPower(power); + myLight.setName(name); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + + logMessage(TAG + "onPutCompleted:\nState:" + myLight.getState() + "\nPower: " + + myLight.getPower() + "\nName: " + myLight.getName()); + doPostLightRepresentation(); + } + + @Override + public void onPutFailed(Throwable throwable) { + + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + + OcRepresentation rep = new OcRepresentation(); + Log.d(TAG, "myLight settings: power = 15"); + myLight.setState(true); + myLight.setPower(15); + try { + rep.setValue(StringConstants.STATE, myLight.getState()); + rep.setValue(StringConstants.POWER, myLight.getPower()); + rep.setValue(StringConstants.NAME, myLight.getName()); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + try { + Log.d(TAG, "before calling put"); + curResource.put(rep, new HashMap(), onPutListener); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + Log.d(TAG, "end of put call"); + } + + /** + * get the existing value of myLight and call doPutLightRepresentation() to modify the current values + */ + private void doGetLightRepresentation() { + // eventhandler for get() + OcResource.OnGetListener onGetListener = new OcResource.OnGetListener() { + @Override + public void onGetCompleted(List headerOptionList, + OcRepresentation ocRepresentation) { + logMessage(TAG + "GET resource was successful " + StringConstants.STATE); + try { + boolean state = ocRepresentation.getValue(StringConstants.STATE); + int power = ocRepresentation.getValue(StringConstants.POWER); + String name = ocRepresentation.getValue(StringConstants.NAME); + myLight.setState(state); + myLight.setPower(power); + myLight.setName(name); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "onGetCompleted\nState: " + myLight.getState() + "\nPower: " + + myLight.getPower() + "\nName: " + myLight.getName()); + doPutLightRepresentation(); + } + + @Override + public void onGetFailed(Throwable throwable) { + if (throwable instanceof OcException) { + OcException ocEx = (OcException) throwable; + ErrorCode errCode = ocEx.getErrorCode(); + //do something based on errorCode + } + Log.e(TAG, throwable.toString()); + } + }; + + try { + curResource.get(new HashMap(), onGetListener); + } catch (OcException e) { + logMessage(TAG + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + + /** + * to display on SimpleClient screen + */ + public class MessageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String message = intent.getStringExtra(StringConstants.MESSAGE); + logMessage(message); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mEventsTextView = new TextView(this); + mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); + LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout); + layout.addView(mEventsTextView, new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f) + ); + myLight = new Light(); + + initOICStack(); + } + + @Override + public void logMessage(String text) { + logMsg(text); + } + + public void logMsg(final String text) { + runOnUiThread(new Runnable() { + public void run() { + Message msg = new Message(); + msg.obj = text; + mEventsTextView.append("\n"); + mEventsTextView.append(text); + } + }); + Log.i(TAG, text); + //to print on SimpleServer screen + Intent intent = new Intent("org.iotivity.base.examples.simpleclient"); + intent.putExtra(StringConstants.MESSAGE, text); + sendBroadcast(intent); + } +} diff --git a/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/StringConstants.java b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/StringConstants.java new file mode 100644 index 0000000..f87c387 --- /dev/null +++ b/android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/StringConstants.java @@ -0,0 +1,17 @@ +package org.iotivity.base.examples.simpleclient; + +/** + * StringConstant contains the simpleclient specific constant values. To add another supported + * Resource or Interface type to this app, begin by adding the new strings here, and then + * find the places throughout the app where Resource-specific case switches occur, and add + * the newly-supported type there. + */ +public interface StringConstants { + public static final String RESOURCE_URI0 = "/light0"; + public static final String RESOURCE_URI1 = "/light1"; + public static final String CREATED_URI = "createduri"; + public static final String STATE = "state"; + public static final String NAME = "name"; + public static final String POWER = "power"; + public static final String MESSAGE = "message"; +} diff --git a/android/examples/simpleclient/src/main/res/drawable-hdpi/ic_launcher.png b/android/examples/simpleclient/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100755 index 0000000..96a442e Binary files /dev/null and b/android/examples/simpleclient/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/android/examples/simpleclient/src/main/res/drawable-mdpi/ic_launcher.png b/android/examples/simpleclient/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100755 index 0000000..359047d Binary files /dev/null and b/android/examples/simpleclient/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/android/examples/simpleclient/src/main/res/drawable-xhdpi/ic_launcher.png b/android/examples/simpleclient/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100755 index 0000000..71c6d76 Binary files /dev/null and b/android/examples/simpleclient/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/android/examples/simpleclient/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/examples/simpleclient/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100755 index 0000000..4df1894 Binary files /dev/null and b/android/examples/simpleclient/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/android/examples/simpleclient/src/main/res/layout/activity_main.xml b/android/examples/simpleclient/src/main/res/layout/activity_main.xml new file mode 100755 index 0000000..9aecf74 --- /dev/null +++ b/android/examples/simpleclient/src/main/res/layout/activity_main.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/examples/simpleclient/src/main/res/menu/menu_main.xml b/android/examples/simpleclient/src/main/res/menu/menu_main.xml new file mode 100755 index 0000000..a1045e9 --- /dev/null +++ b/android/examples/simpleclient/src/main/res/menu/menu_main.xml @@ -0,0 +1,6 @@ +

+ + diff --git a/android/examples/simpleclient/src/main/res/values-w820dp/dimens.xml b/android/examples/simpleclient/src/main/res/values-w820dp/dimens.xml new file mode 100755 index 0000000..62df187 --- /dev/null +++ b/android/examples/simpleclient/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/android/examples/simpleclient/src/main/res/values/dimens.xml b/android/examples/simpleclient/src/main/res/values/dimens.xml new file mode 100755 index 0000000..295b5a9 --- /dev/null +++ b/android/examples/simpleclient/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/android/examples/simpleclient/src/main/res/values/strings.xml b/android/examples/simpleclient/src/main/res/values/strings.xml new file mode 100755 index 0000000..575b3e0 --- /dev/null +++ b/android/examples/simpleclient/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + Starting Simple Client + Hello world! + Settings + + diff --git a/android/examples/simpleclient/src/main/res/values/styles.xml b/android/examples/simpleclient/src/main/res/values/styles.xml new file mode 100755 index 0000000..084b42b --- /dev/null +++ b/android/examples/simpleclient/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/android/examples/simpleserver/.gitignore b/android/examples/simpleserver/.gitignore new file mode 100644 index 0000000..3543521 --- /dev/null +++ b/android/examples/simpleserver/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/examples/simpleserver/build.gradle b/android/examples/simpleserver/build.gradle new file mode 100755 index 0000000..3ecd031 --- /dev/null +++ b/android/examples/simpleserver/build.gradle @@ -0,0 +1,27 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.1.2" + + defaultConfig { + applicationId "org.iotivity.base.examples.simpleserver" + minSdkVersion 19 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + //compile fileTree(dir: 'libs', include: ['*.so']) + compile project(':message') + compile 'com.android.support:appcompat-v7:21.0.3' +} diff --git a/android/examples/simpleserver/simpleserver.iml b/android/examples/simpleserver/simpleserver.iml new file mode 100755 index 0000000..c668fa1 --- /dev/null +++ b/android/examples/simpleserver/simpleserver.iml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/examples/simpleserver/src/main/AndroidManifest.xml b/android/examples/simpleserver/src/main/AndroidManifest.xml new file mode 100755 index 0000000..43352f4 --- /dev/null +++ b/android/examples/simpleserver/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + diff --git a/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightRepThread.java b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightRepThread.java new file mode 100644 index 0000000..0993995 --- /dev/null +++ b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightRepThread.java @@ -0,0 +1,86 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +/* + * // Starts a new thread for OBSERVE. It increments the value of mPower by 10 every 3 seconds + */ +package org.iotivity.base.examples.simpleserver; + +import android.util.Log; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResourceResponse; + +import java.util.List; + +/** + * LightRepThread + * + * Spawn a thread for OBSERVE. This increments the resource's power value by 10 every 3 seconds. + * If there is an observationList, call notifyListOfObservers(). Otherwise, call notifyAllObservers() + */ +public class LightRepThread extends Thread { + private static String TAG = "LightRepThread: "; + + private LightResource mLightResource; + private List mObservationList; + private static int count = 0; + + LightRepThread(Object lr, List observationList) { + mLightResource = (LightResource)lr; + mObservationList = observationList; + } + + public void run() { + while(count < 20) { + try { + sleep(3000); + } catch (InterruptedException e) { + Log.e(TAG, e.getMessage()); + } + + // increment current power value by 10 every 3 seconds + mLightResource.setPower(mLightResource.getPower() + 10); + try { + // if observationList is not empty, call notifyListOfObservers + if (mObservationList.size() > 0) { + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setErrorCode(StringConstants.ERROR_CODE); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + OcRepresentation r = mLightResource.get(); + ocResourceResponse.setResourceRepresentation + (mLightResource.get(), OcPlatform.DEFAULT_INTERFACE); + OcPlatform.notifyListOfObservers(mLightResource.getHandle(), mObservationList, ocResourceResponse); + } else { + // notify all observers if mObservationList is empty + OcPlatform.notifyAllObservers(mLightResource.getHandle()); + } + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + ++count; + } + } +} diff --git a/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightResource.java b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightResource.java new file mode 100644 index 0000000..e8414a0 --- /dev/null +++ b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightResource.java @@ -0,0 +1,308 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.simpleserver; + +import android.content.Context; +import android.content.Intent; +import android.util.Log; + +import org.iotivity.base.EntityHandlerResult; +import org.iotivity.base.ObservationInfo; +import org.iotivity.base.OcException; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.OcResourceHandle; +import org.iotivity.base.OcResourceRequest; +import org.iotivity.base.OcResourceResponse; +import org.iotivity.base.RequestHandlerFlag; +import org.iotivity.base.RequestType; +import org.iotivity.base.ResourceProperty; + +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * LightResource + * + * class LightResource is the main class of the simpleServer. This creates resources and handles incoming requests from the client. + */ +public class LightResource implements IMessageLogger { + private Context mContext; + private static String TAG = "SimpleServer: "; + + private String mName; + private Boolean mState; + private Integer mPower; + private OcRepresentation mLightRep; + private OcResourceHandle mResourceHandle; + private List mObservationIds; + private static boolean doOnce; // used in POST + LightRepThread lightRepThread; + + // constructor + LightResource(Context context) { + mContext = context; + mName = "John's light"; + mState = false; + mPower = 0; + mObservationIds = new LinkedList<>(); + mLightRep = new OcRepresentation(); + try { + mLightRep.setValue(StringConstants.STATE, mState); + mLightRep.setValue(StringConstants.POWER, mPower); + mLightRep.setValue(StringConstants.NAME, mName); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + doOnce = true; // used in post + lightRepThread = null; + } + + //accessor methods + protected int getPower() { + return mPower; + } + protected void setPower(int power) { + mPower = power; + } + protected OcResourceHandle getHandle() { + return mResourceHandle; + } + + /** + * creates a resource. this method internally calls registerResource + * @return returns the OcResourceHandle after creating and registering the resource + */ + protected OcResourceHandle createResource0() { + // entityhandler for registerResource + OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + // this is where the main logic of simpleserver is handled as different requests (GET, PUT, POST, OBSERVE, DELETE) are handled + return entityHandler(ocResourceRequest); + } + }; + + try { + mResourceHandle = OcPlatform.registerResource(StringConstants.RESOURCE_URI0, StringConstants.RESOURCE_TYPENAME, + StringConstants.RESOURCE_INTERFACE, eh, + EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE)); + } catch (OcException e) { + logMessage(TAG + "RegisterResource error. " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "Successfully registered resource"); + return mResourceHandle; + } + + /** + * create another resource. this method internally calls registerResource + */ + private void createResource1() { + // entityhandler for registerResource + OcPlatform.EntityHandler eh = new OcPlatform.EntityHandler() { + @Override + public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest) { + // this is where the main logic of simpleserver is handled as different requests (GET, PUT, POST, OBSERVE, DELETE) are handled + return entityHandler(ocResourceRequest); + } + }; + + try { + OcPlatform.registerResource(StringConstants.RESOURCE_URI1, StringConstants.RESOURCE_TYPENAME, + StringConstants.RESOURCE_INTERFACE, eh, + EnumSet.of(ResourceProperty.DISCOVERABLE, ResourceProperty.OBSERVABLE)); + } catch (OcException e) { + logMessage(TAG + "RegisterResource1 error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "Successfully registered resource1"); + } + + /** + * post representation . Post can act like put or can create a new resource. + * Gets value from the representation and updates the internal state + * @param rep current OcRepresentation of the object + * @return updated OcRepresentation + */ + private OcRepresentation post(OcRepresentation rep) { + //create a resource the first time + if (true == doOnce) { + createResource1(); + OcRepresentation representation = rep; + try { + representation.setValue(StringConstants.CREATED_URI, StringConstants.RESOURCE_URI1); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + doOnce = false; + return representation; + } + // from second time onwards, put + put(rep); + return get(); + } + + /** + * puts representation . Gets value from the representation and updates the internal state + * @param rep current OcRepresentation of the object + */ + private void put(OcRepresentation rep) { + try { + mState = rep.getValue(StringConstants.STATE); + mPower = rep.getValue(StringConstants.POWER); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + logMessage(TAG + "Put State: " + mState + " Name: " + mName + " Power: " + mPower); + } + + /** + * gets the updated representation. Updates the representation with internal state before sending out + * @return OcRepresentation after updating the values of the lightRepresentation + */ + protected OcRepresentation get() { + try { + mLightRep.setValue(StringConstants.STATE, mState); + mLightRep.setValue(StringConstants.POWER, mPower); + mLightRep.setValue(StringConstants.NAME, mName); + } catch (OcException e) { + Log.e(TAG, e.getMessage()); + } + return mLightRep; + } + + /** + * this is the main method which handles different incoming requests appropriately. + * Init is not supported currently. + * @param request OcResourceRequest from the client + * @return EntityHandlerResult depending on whether the request was handled successfully or not + */ + private EntityHandlerResult entityHandler(OcResourceRequest request) { + EntityHandlerResult result = EntityHandlerResult.ERROR; + if (null != request) { + RequestType requestType = request.getRequestType(); + EnumSet requestFlag = request.getRequestHandlerFlagSet(); + + if (requestFlag.contains(RequestHandlerFlag.INIT)) { + logMessage(TAG + "Init"); + } + if (requestFlag.contains(RequestHandlerFlag.REQUEST)) { + try { + logMessage(TAG + "Request"); + OcResourceResponse ocResourceResponse = new OcResourceResponse(); + ocResourceResponse.setRequestHandle(request.getRequestHandle()); + ocResourceResponse.setResourceHandle(request.getResourceHandle()); + + switch (requestType) { + // handle GET request + case GET: + logMessage("GET"); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setErrorCode(StringConstants.ERROR_CODE); + ocResourceResponse.setResourceRepresentation(get()); + OcPlatform.sendResponse(ocResourceResponse); + break; + // handle PUT request + case PUT: + OcRepresentation rep = request.getResourceRepresentation(); + put(rep); + ocResourceResponse.setErrorCode(StringConstants.ERROR_CODE); + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + ocResourceResponse.setResourceRepresentation(get()); + OcPlatform.sendResponse(ocResourceResponse); + break; + // handle POST request + case POST: + rep = request.getResourceRepresentation(); + OcRepresentation rep_post = post(rep); + ocResourceResponse.setResourceRepresentation(rep_post); + ocResourceResponse.setErrorCode(StringConstants.ERROR_CODE); + if (rep_post.hasAttribute(StringConstants.CREATED_URI)) { + String createdUri = rep_post.getValue(StringConstants.CREATED_URI); + if (createdUri.equals(StringConstants.RESOURCE_URI1)) { + ocResourceResponse.setNewResourceUri(createdUri); + ocResourceResponse.setResponseResult + (EntityHandlerResult.RESOURCE_CREATED); + } else { + ocResourceResponse.setResponseResult(EntityHandlerResult.OK); + } + } + OcPlatform.sendResponse(ocResourceResponse); + break; + // handle DELETE request + case DELETE: + logMessage(TAG + "DELETE"); + OcPlatform.unregisterResource(getHandle()); + OcPlatform.unregisterResource(getHandle()); + break; + + } + + result = EntityHandlerResult.OK; + } catch(OcException e) { + logMessage(TAG + "Error in Request " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + // handle OBSERVER request + if (requestFlag.contains(RequestHandlerFlag.OBSERVER)) { + logMessage(TAG + "OBSERVER"); + ObservationInfo observationInfo = request.getObservationInfo(); + + switch (observationInfo.getObserveAction()) { + case REGISTER: + synchronized (mObservationIds) { + mObservationIds.add(observationInfo.getOcObservationId()); + } + break; + case UNREGISTER: + synchronized (mObservationIds) { + mObservationIds.remove(observationInfo.getOcObservationId()); + } + break; + } + if (null == lightRepThread) { + lightRepThread = new LightRepThread(this, mObservationIds); + lightRepThread.run(); + } + result = EntityHandlerResult.OK; + } + } + return result; + } + + @Override + public void logMessage(String msg) { + logMsg(msg); + } + + public void logMsg(final String text) { + Intent intent = new Intent("org.iotivity.base.examples.simpleserver"); + intent.putExtra(StringConstants.MESSAGE, text); + mContext.sendBroadcast(intent); + } +} \ No newline at end of file diff --git a/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/SimpleServer.java b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/SimpleServer.java new file mode 100644 index 0000000..31b5c6a --- /dev/null +++ b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/SimpleServer.java @@ -0,0 +1,145 @@ +/* + * //****************************************************************** + * // + * // Copyright 2015 Intel Corporation. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + * // + * // 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. + * // + * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + */ + +package org.iotivity.base.examples.simpleserver; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Message; +import android.support.v4.content.LocalBroadcastManager; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.iotivity.base.ModeType; +import org.iotivity.base.OcPlatform; +import org.iotivity.base.OcRepresentation; +import org.iotivity.base.PlatformConfig; +import org.iotivity.base.QualityOfService; +import org.iotivity.base.ServiceType; + +import base.iotivity.org.examples.message.IMessageLogger; + +/** + * SimpleServer + * + * SimpleServer instantiates a TextView and creates and configures OICPlatform. + * It also creates a LightResource and waits for the incoming client requests to handle specific scenarios. + * This implements IMessageLogger to display messages on the screen + */ + +public class SimpleServer extends Activity implements IMessageLogger { + private final static String TAG = "SimpleServer: "; + private TextView mEventsTextView; + private MessageReceiver mMessageReceiver = new MessageReceiver(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + registerReceiver(mMessageReceiver, new IntentFilter("org.iotivity.base.examples.simpleserver")); + + mEventsTextView = new TextView(this); + mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); + LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout); + layout.addView(mEventsTextView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)); + + OcRepresentation rep = new OcRepresentation(); + rep.setValueBool("test", false); + boolean result = rep.getValueBool("test"); + + initOICStack(); + } + + /** + * configure OIC platform and call findResource + */ + private void initOICStack() { + //create platform config + PlatformConfig cfg = new PlatformConfig( + this, + ServiceType.IN_PROC, + ModeType.SERVER, + "0.0.0.0", // bind to all available interfaces + 0, + QualityOfService.LOW); + OcPlatform.Configure(cfg); + // Create instance of lightResource + LightResource myLight = new LightResource(this); + // create and register a resource + myLight.createResource0(); + } + + public class MessageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + final String message = intent.getStringExtra(StringConstants.MESSAGE); + logMessage(message); + } + } + + public void logMessage(final String text) { + runOnUiThread(new Runnable() { + public void run() { + final Message msg = new Message(); + msg.obj = text; + mEventsTextView.append("\n"); + mEventsTextView.append(text); + } + }); + Log.i(TAG, text); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + int id = item.getItemId(); + if (id == R.id.action_settings) { + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onDestroy() { + super.onDestroy(); + onStop(); + } + + @Override + protected void onStop() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); + super.onStop(); + } +} \ No newline at end of file diff --git a/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/StringConstants.java b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/StringConstants.java new file mode 100644 index 0000000..98f33d0 --- /dev/null +++ b/android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/StringConstants.java @@ -0,0 +1,21 @@ +package org.iotivity.base.examples.simpleserver; + +import org.iotivity.base.OcPlatform; +/** + * StringConstants contains the simpleserver specific constant values. To add another supported + * Resource or Interface type to this app, begin by adding the new strings here, and then + * find the places throughout the app where Resource-specific case switches occur, and add + * the newly-supported type there. + */ +public interface StringConstants { + public static final String RESOURCE_URI0 = "/light0"; + public static final String RESOURCE_URI1 = "/light1"; + public static final String RESOURCE_TYPENAME = "core.light"; + public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE; //resource interface + public static final String CREATED_URI = "createduri"; + public static final String STATE = "state"; + public static final String NAME = "name"; + public static final String POWER = "power"; + public static final String MESSAGE = "message"; + public static final int ERROR_CODE = 200; +} diff --git a/android/examples/simpleserver/src/main/res/drawable-hdpi/ic_launcher.png b/android/examples/simpleserver/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100755 index 0000000..96a442e Binary files /dev/null and b/android/examples/simpleserver/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/android/examples/simpleserver/src/main/res/drawable-mdpi/ic_launcher.png b/android/examples/simpleserver/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100755 index 0000000..359047d Binary files /dev/null and b/android/examples/simpleserver/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/android/examples/simpleserver/src/main/res/drawable-xhdpi/ic_launcher.png b/android/examples/simpleserver/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100755 index 0000000..71c6d76 Binary files /dev/null and b/android/examples/simpleserver/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/android/examples/simpleserver/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/examples/simpleserver/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100755 index 0000000..4df1894 Binary files /dev/null and b/android/examples/simpleserver/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/android/examples/simpleserver/src/main/res/layout/activity_main.xml b/android/examples/simpleserver/src/main/res/layout/activity_main.xml new file mode 100755 index 0000000..ebe6ef7 --- /dev/null +++ b/android/examples/simpleserver/src/main/res/layout/activity_main.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/android/examples/simpleserver/src/main/res/menu/menu_main.xml b/android/examples/simpleserver/src/main/res/menu/menu_main.xml new file mode 100755 index 0000000..a1045e9 --- /dev/null +++ b/android/examples/simpleserver/src/main/res/menu/menu_main.xml @@ -0,0 +1,6 @@ + + + diff --git a/android/examples/simpleserver/src/main/res/values-w820dp/dimens.xml b/android/examples/simpleserver/src/main/res/values-w820dp/dimens.xml new file mode 100755 index 0000000..62df187 --- /dev/null +++ b/android/examples/simpleserver/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/android/examples/simpleserver/src/main/res/values/dimens.xml b/android/examples/simpleserver/src/main/res/values/dimens.xml new file mode 100755 index 0000000..295b5a9 --- /dev/null +++ b/android/examples/simpleserver/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/android/examples/simpleserver/src/main/res/values/strings.xml b/android/examples/simpleserver/src/main/res/values/strings.xml new file mode 100755 index 0000000..4414f1d --- /dev/null +++ b/android/examples/simpleserver/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + SimpleServer + Starting Simple Server... + Settings + + diff --git a/android/examples/simpleserver/src/main/res/values/styles.xml b/android/examples/simpleserver/src/main/res/values/styles.xml new file mode 100755 index 0000000..084b42b --- /dev/null +++ b/android/examples/simpleserver/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/arduino.scons b/arduino.scons index 4ab2aff..2f40e74 100644 --- a/arduino.scons +++ b/arduino.scons @@ -1,11 +1,49 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# ## # This script includes arduino specific config for oic-resource ## Import('env') -env.ImportLib('Time') -if env.get('NET') == 'Ethernet': +# Add 'SHIELD' build option, let user select board network connection type +vars = Variables() +if 'IP' in env.get('TARGET_TRANSPORT'): + vars.Add(EnumVariable('SHIELD', 'Network connection type', 'WIFI', ['ETH', 'WIFI'])) +elif 'BLE' in env.get('TARGET_TRANSPORT'): + vars.Add(EnumVariable('SHIELD', 'Network connection type', 'RBL_NRF8001', ['RBL_NRF8001'])) +vars.Update(env) +Help(vars.GenerateHelpText(env)) + +env.ImportLib('SPI') +if 'ETH' in env.get('SHIELD'): env.ImportLib('Ethernet') -else: +if 'WIFI' in env.get('SHIELD'): env.ImportLib('WiFi') -env.ImportLib('SPI') \ No newline at end of file + env.AppendUnique(CPPDEFINES = ['ARDUINOWIFI']) +if 'RBL_NRF8001' in env.get('SHIELD'): + env.ImportLib('BLE') + env.ImportLib('RBL_nRF8001') + +env.ImportLib('Time/Time') +# we have variety of macros for arduino!! +env.AppendUnique(CPPDEFINES = ['WITH_ARDUINO', '__ARDUINO__']) +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['TB_LOG']) diff --git a/auto_build.sh b/auto_build.sh index 536331c..19c3440 100755 --- a/auto_build.sh +++ b/auto_build.sh @@ -17,37 +17,35 @@ function build() then echo "*********** Build for linux *************" scons RELEASE=$3 + + echo "*********** Build for linux with Security*************" + scons RELEASE=$3 SECURED=1 fi # Note: for android, as oic-resource uses C++11 feature stoi and to_string, # it requires gcc-4.9, currently only android-ndk-r10(for linux) # and windows android-ndk-r10(64bit target version) support these features. - if [ "$BUILD_FOR_ANDROID" = "true" ] - then - - echo "*********** Build Boost for android ***********" - pushd extlibs - ./buildDependencies.sh - popd + echo "*********** Build Boost for android ***********" + # disable parallel build for android as gradle depends on scons to finish first + export SCONSFLAGS="-Q" - echo "*********** Build for android x86 *************" - scons TARGET_OS=android TARGET_ARCH=x86 ANDROID_NDK=$1 RELEASE=$3 + echo "*********** Build for android x86 *************" + scons TARGET_OS=android TARGET_ARCH=x86 RELEASE=$3 TARGET_TRANSPORT=IP - echo "*********** Build for android armeabi *************" - scons TARGET_OS=android TARGET_ARCH=armeabi ANDROID_NDK=$1 RELEASE=$3 + echo "*********** Build for android armeabi *************" + scons TARGET_OS=android TARGET_ARCH=armeabi RELEASE=$3 TARGET_TRANSPORT=IP - echo "*********** Build for android armeabi-v7a *************" - scons TARGET_OS=android TARGET_ARCH=armeabi-v7a ANDROID_NDK=$1 RELEASE=$3 + # enable parallel build + export SCONSFLAGS="-Q -j 4" - echo "*********** Build for android armeabi-v7a-hard *************" - scons TARGET_OS=android TARGET_ARCH=armeabi-v7a-hard ANDROID_NDK=$1 RELEASE=$3 - fi - echo "*********** Build for arduino avr *************" - scons TARGET_OS=arduino TARGET_ARCH=avr ARDUINO_HOME=$2 RELEASE=$3 + scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$3 + scons resource TARGET_OS=arduino UPLOAD=false BOARD=mega TARGET_ARCH=avr TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$3 echo "*********** Build for arduino arm *************" - scons TARGET_OS=arduino TARGET_ARCH=arm ARDUINO_HOME=$2 RELEASE=$3 + scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=ETH RELEASE=$3 + scons resource TARGET_OS=arduino UPLOAD=false BOARD=arduino_due_x TARGET_ARCH=arm TARGET_TRANSPORT=IP SHIELD=WIFI RELEASE=$3 + if [ $(uname -s) = "Darwin" ] then @@ -75,7 +73,7 @@ function help() { echo "Usage:" echo " build:" - echo " `basename $0` " + echo " `basename $0` " echo " clean:" echo " `basename $0` -c" } @@ -100,4 +98,9 @@ fi export SCONSFLAGS="-Q -j 4" build $1 $2 true build $1 $2 false +scons resource RELEASE=false -c +scons resource LOGGING=false RELEASE=false +scons resource TEST=1 RELEASE=false echo "===================== done =====================" + + diff --git a/build_common/SConscript b/build_common/SConscript index db23ac3..16a81f9 100644 --- a/build_common/SConscript +++ b/build_common/SConscript @@ -15,14 +15,14 @@ host_target_map = { # Map of os and allowed archs (os: allowed archs) os_arch_map = { 'linux': ['x86', 'x86_64', 'arm', 'arm64'], - 'tizen': ['x86', 'x86_64', 'arm', 'arm64'], + 'tizen': ['x86', 'x86_64', 'arm', 'arm64', 'armeabi-v7a'], 'android': ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'arm64-v8a'], 'windows': ['x86', 'amd64', 'arm'], 'winrt': ['arm'], 'darwin': ['i386', 'x86_64'], 'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'], 'arduino': ['avr', 'arm'], - 'yocto': ['x86', 'x86_64'], + 'yocto': ['i586', 'x86_64', 'arm', 'powerpc', 'powerpc64', 'mips', 'mipsel'], } host = platform.system().lower() @@ -46,18 +46,42 @@ if default_arch not in os_arch_map[target_os]: target_arch = ARGUMENTS.get('TARGET_ARCH', default_arch) # target arch +# True if binary needs to be installed on board. (Might need root permissions) +# set to 'no', 'false' or 0 for only compilation +require_upload = ARGUMENTS.get('UPLOAD', False) + +if ARGUMENTS.get('TEST'): + logging_default = False +else: + logging_default = (ARGUMENTS.get('RELEASE', True) == 'false') + + + ###################################################################### # Common build options (release, target os, target arch) ###################################################################### +targets_disallow_multitransport = ['arduino'] + help_vars = Variables() +help_vars.Add(BoolVariable('VERBOSE', 'Show compilation', False)) help_vars.Add(BoolVariable('RELEASE', 'Build for release?', True)) # set to 'no', 'false' or 0 for debug help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map[host])) -help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os])) +if target_os in targets_disallow_multitransport: + help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'IP', ['BT', 'BLE', 'IP'])) +else: + help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP'])) + +help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os])) +help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1'))) +help_vars.Add(EnumVariable('TEST', 'Run unit tests', '0', allowed_values=('0', '1'))) +help_vars.Add(BoolVariable('LOGGING', 'Enable stack logging', logging_default)) +help_vars.Add(BoolVariable('UPLOAD', 'Upload binary ? (For Arduino)', require_upload)) +help_vars.Add(EnumVariable('BUILD_SAMPLE', 'Build with sample', 'ON', allowed_values=('ON', 'OFF'))) ###################################################################### # Platform(build target) specific options: SDK/NDK & toolchain ###################################################################### -targets_support_cc = ['linux', 'arduino'] +targets_support_cc = ['linux', 'arduino', 'tizen'] if target_os in targets_support_cc: # Set cross compile toolchain @@ -82,6 +106,12 @@ tc_set_msg = ''' * cause inexplicable errors. * ******************************************************************************* ''' +if env.get('VERBOSE') == False: + env['CCCOMSTR'] = "Compiling $TARGET" + env['CXXCOMSTR'] = "Compiling $TARGET" + env['LINKCOMSTR'] = "Linking $TARGET" + env['ARCOMSTR'] = "Archiving $TARGET" + env['RANLIBCOMSTR'] = "Indexing Archive $TARGET" if target_os in targets_support_cc: prefix = env.get('TC_PREFIX') @@ -144,8 +174,10 @@ def __install(ienv, targets, name): Alias(name, i_n) env.AppendUnique(TS = [name]) -def __append_target(ienv, target): - env.AppendUnique(TS = [target]) +def __append_target(ienv, name, targets = None): + if targets: + env.Alias(name, targets) + env.AppendUnique(TS = [name]) def __print_targets(env): Help(''' @@ -166,6 +198,7 @@ env.AddMethod(__src_to_obj, 'SrcToObj') env.AddMethod(__append_target, 'AppendTarget') env.AddMethod(__install, 'InstallTarget') env.SetDir(env.GetLaunchDir()) +env['ROOT_DIR']=env.GetLaunchDir()+'/..' Export('env') @@ -174,8 +207,8 @@ Export('env') ###################################################################### if target_os == "yocto": ''' - This code injects Yocto cross-compilation tools+flags into scons' - build environment in order to invoke the relevant tools while + This code injects Yocto cross-compilation tools+flags into scons' + build environment in order to invoke the relevant tools while performing a build. ''' import os.path @@ -203,6 +236,7 @@ if target_os == "yocto": if os.path.isfile(os.path.join(path, tools[tool])): env[tool] = os.path.join(path, os.environ[tool]) break + env['CROSS_COMPILE'] = target_prefix[:len(target_prefix) - 1] except: print "ERROR in Yocto cross-toolchain environment" Exit(1) @@ -213,19 +247,27 @@ if target_os == "yocto": env['TARGET_OS'] = 'linux' ''' We want to preserve debug symbols to allow BitBake to generate both DEBUG and - RELEASE packages for OIC. + RELEASE packages for OIC. + ''' + env.AppendUnique(CCFLAGS = ['-g']) + ''' + Additional flags to pass to the Yocto toolchain. ''' - env['CCFLAGS'].append('-g') + if env.get('RELEASE'): + env.AppendUnique(CPPDEFINES = ['NDEBUG']) + if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['TB_LOG']) + env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__', '_GNU_SOURCE']) + env.AppendUnique(CFLAGS = ['-std=gnu99']) + env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) + env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) Export('env') else: ''' If target_os is not Yocto, continue with the regular build process ''' # Load config of target os - if target_os in ['linux', 'tizen']: - env.SConscript('linux/SConscript') - else: - env.SConscript(target_os + '/SConscript') + env.SConscript(target_os + '/SConscript') # Delete the temp files of configuration if env.GetOption('clean'): @@ -233,7 +275,30 @@ if env.GetOption('clean'): if os.path.exists(dir + '/config.log'): Execute(Delete(dir + '/config.log')) + if os.path.exists(dir + '/.sconsign.dblite'): Execute(Delete(dir + '/.sconsign.dblite')) + if os.path.exists(dir + '/.sconf_temp'): Execute(Delete(dir + '/.sconf_temp')) +###################################################################### +# Check for PThreads support +###################################################################### +import iotivityconfig +from iotivityconfig import * + +conf = Configure(env, + custom_tests = + { + 'CheckPThreadsSupport' : iotivityconfig.check_pthreads + } ) + +# Identify whether we have pthreads support, which is necessary for +# threading and mutexes. This will set the environment variable +# POSIX_SUPPORTED, 1 if it is supported, 0 otherwise +conf.CheckPThreadsSupport() + +env = conf.Finish() +###################################################################### + +env.SConscript('external_libs.scons') Return('env') diff --git a/build_common/android/SConscript b/build_common/android/SConscript index 4ae0fe4..b90beb0 100644 --- a/build_common/android/SConscript +++ b/build_common/android/SConscript @@ -6,22 +6,42 @@ import platform import subprocess Import('env') +SConscript('../external_libs.scons') +SConscript('../../extlibs/android/ndk/SConscript') +SConscript('../../extlibs/android/gradle/SConscript') +SConscript('../../extlibs/android/sdk/SConscript') help_vars = Variables() -help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK root directory', os.environ.get('ANDROID_NDK'))) -help_vars.Update(env) -Help(help_vars.GenerateHelpText(env)) +help_vars.Add(PathVariable('ANDROID_GRADLE', 'Android Gradle directory', os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'gradle', 'gradle-2.2.1/bin/gradle'))) +help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK root directory', os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d'))) -android_ndk = env.get('ANDROID_NDK') -if not android_ndk: +if env.get('ANDROID_NDK'): + android_ndk = env.get('ANDROID_NDK') +else: print ''' -*************************************** Error ********************************* -* Android NDK path isn't set, you can set enviornment variable ANDROID_NDK * -* or add it in command line as: * +*************************************** Info ********************************** +* Android NDK path isn't set, the default will be used. You can set * +* environment variable ANDROID_NDK or add it in command line as: * * # scons ANDROID_NDK= ... * ******************************************************************************* ''' - Exit(1) + android_ndk = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'ndk', 'android-ndk-r10d') + +if env.get('ANDROID_GRADLE'): + android_gradle = env.get('ANDROID_GRADLE') +else: + print ''' +*************************************** Info ********************************** +* Android Gradle path isn't set, the default will be used. You can set * +* environment variable ANDROID_GRADLE or add it in command line as: * +* # scons ANDROID_GRADLE= ... * +******************************************************************************* +''' + android_gradle = os.path.join(env.get('SRC_DIR'), 'extlibs', 'android', 'gradle', 'gradle-2.2.1', 'bin', 'gradle') + +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) +src_dir = env.get('SRC_DIR') # Overwrite suffixes and prefixes if env['HOST_OS'] == 'win32': @@ -45,6 +65,7 @@ elif platform.system().lower() == 'darwin': # Android build system default cofig env.AppendUnique(CPPDEFINES = ['ANDROID']) +env.AppendUnique(CFLAGS = ['-std=c99']) env.AppendUnique(SHCFLAGS = ['-Wa,--noexecstack']) env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections', '-Wl,-z,nocopyreloc']) @@ -65,15 +86,17 @@ if not os.path.isfile(ndk_build_cmd): ''' % android_ndk Exit(1) -ANDROID_HOME = os.environ.get('ANDROID_HOME') -if ANDROID_HOME is not None: - ANDROID_HOME = os.path.abspath(ANDROID_HOME) +# ANDROID_HOME build option +help_vars = Variables() +help_vars.Add(PathVariable('ANDROID_HOME', 'ANDROID SDK root directory', os.environ.get('ANDROID_HOME'))) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) -if ANDROID_HOME is None or not os.path.exists(ANDROID_HOME): - print ''' -*************************************** Warning ******************************* -* Enviornment variable ANDROID_HOME is not set properly. It should be the * -* root directory of android sdk. If you'd like build Java code, it's required.* +print ''' +*************************************** Info ********************************** +* Environment variable ANDROID_HOME will use default value. To override * +* root directory of android sdk, please specify ANDROID_HOME as follows: * +* scons ANDROID_HOME= * ******************************************************************************* ''' @@ -81,13 +104,14 @@ target_arch = env.get('TARGET_ARCH') # Android ndk early version doesn't support C++11. Detect the toolchain version # to make sure proper toolchain is used -for tc_ver in ['4.9', '4.8', '4.7', '']: +for tc_ver in ['4.7', '4.8', '4.9', '']: if os.path.exists(android_ndk + '/toolchains/x86-' + tc_ver): break cmd = [ndk_build_cmd] cmd.append('APP_ABI=' + target_arch) -cmd.append('APP_STL=gnustl_static') +cmd.append('APP_PLATFORM=android-21') +cmd.append('APP_STL=gnustl_shared') if env.get('RELEASE'): cmd.append('APP_OPTIM=release') else: @@ -126,27 +150,46 @@ for flags in p.stdout.readlines(): elif cmp(flags[0:8], 'SYSROOT=') == 0: sysroot = flags[8:].strip() env.AppendUnique(LINKFLAGS = ['--sysroot=' + sysroot]) - env.AppendUnique(LIBPATH = [sysroot + '/usr/lib']) elif cmp(flags[0:8], 'LDFLAGS=') == 0: env.AppendUnique(LINKFLAGS = Split(flags[8:])) elif cmp(flags[0:7], 'TC_VER=') == 0: # set gnustl library path ver = flags[7:].strip() - env.AppendUnique(LIBPATH = [android_ndk + '/sources/cxx-stl/gnu-libstdc++/' - + ver + '/libs/' + target_arch]) + stl_path = android_ndk + '/sources/cxx-stl/gnu-libstdc++/' + ver + '/libs/' + target_arch + if target_arch in ['armeabi', 'armeabi-v7a', 'armeabi-v7a-hard']: + stl_path = stl_path + '/thumb/' + + env.AppendUnique(LIBPATH = [stl_path]) + env.Install(env.get('BUILD_DIR'), stl_path + '/libgnustl_shared.so') elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x platform_ver = flags[9+8:].strip() if not platform_ver.isdigit(): platform_ver = '' + + elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x + platform_ver = flags[9+8:].strip() + if not platform_ver.isdigit(): + platform_ver = '' + + + elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x + platform_ver = flags[9+8:].strip() + if not platform_ver.isdigit(): + platform_ver = '' + +# Determine dependency faux SYS_ROOT +dep_sys_root = os.path.join(env.get('SRC_DIR'), 'dep', 'android', target_arch, 'usr') +dep_src_dir = os.path.join(dep_sys_root, 'include') +dep_lib_dir = os.path.join(dep_sys_root, 'lib') + +env['DEP_SYS_ROOT'] = dep_sys_root + # Add external libraries including boost -env.AppendUnique(CPPPATH = [env.get('SRC_DIR') + '/out/android/include' ]) -if target_arch == 'x86': - env.AppendUnique(LIBPATH = [env.get('SRC_DIR') + '/out/android/lib/x86']) -else: - env.AppendUnique(LIBPATH = [env.get('SRC_DIR') + '/out/android/lib/arm-linux-androideabi']) +env.AppendUnique(CPPPATH = [ dep_src_dir ]) +env.AppendUnique(LIBPATH = [ dep_lib_dir ]) ###################################################################### # Set release/debug flags @@ -158,6 +201,21 @@ if env.get('RELEASE'): else: env.AppendUnique(CCFLAGS = ['-g']) +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + + +env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__']) +env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) +#env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + +env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +env.AppendUnique(LIBPATH = [src_dir + '/resource/csdk/connectivity/lib/android']) +env.AppendUnique(LIBS = ['log', 'coap']) + +if env.get('SECURED') == '1': + env.AppendUnique(LIBS = ['tinydtls']) + # From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'. # Due to the limitation of Scons, it's required to added it into the command line # directly (otherwise, it will also be added when build share library) @@ -166,7 +224,11 @@ env.Replace(CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SO env.Replace(LINKCOM = '$LINK -o $TARGET -pie $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS') # Fix android-ndk compatibility issue, make applications build on new NDK can run on old platform -#if platform_ver == '' or int(platform_ver) > 20: -# SConscript('compatibility/c_compat.scons') -# -#SConscript('compatibility/cpp11_compat.scons') +if platform_ver == '' or int(platform_ver) > 20: + SConscript('compatibility/c_compat.scons') + +SConscript('compatibility/cpp11_compat.scons') + +# Make sure that boost for android is available +SConscript(env.get('SRC_DIR') + '/extlibs/boost/SConscript') +SConscript(env.get('SRC_DIR') + '/extlibs/expat/SConscript') diff --git a/build_common/android/compatibility/android_cpp11_compat.cpp b/build_common/android/compatibility/android_cpp11_compat.cpp index dedc927..3d27cf9 100644 --- a/build_common/android/compatibility/android_cpp11_compat.cpp +++ b/build_common/android/compatibility/android_cpp11_compat.cpp @@ -57,6 +57,12 @@ namespace std { return os.str(); } + std::string to_string(long t) { + std::ostringstream os; + os << t; + return os.str(); + } + std::string to_string(double t) { std::ostringstream os; os << t; diff --git a/build_common/android/compatibility/android_cpp11_compat.h b/build_common/android/compatibility/android_cpp11_compat.h index 78af522..adaa9fb 100644 --- a/build_common/android/compatibility/android_cpp11_compat.h +++ b/build_common/android/compatibility/android_cpp11_compat.h @@ -15,6 +15,7 @@ namespace std { long double stold(const string& s); std::string to_string(int i); + std::string to_string(long t); std::string to_string(uint32_t i); std::string to_string(double d); } diff --git a/build_common/arduino/SConscript b/build_common/arduino/SConscript index 4c3a01f..65c0a3b 100644 --- a/build_common/arduino/SConscript +++ b/build_common/arduino/SConscript @@ -113,12 +113,28 @@ def __import_lib(env, lib): lib_src.extend(__search_files(lib_path, '*.c')) lib_src.extend(__search_files(lib_path, '*.cpp')) + lib_obj = __src_to_obj(env, lib_src) build_dir = env.get('BUILD_DIR') if build_dir: - lib_a = env.StaticLibrary(build_dir + lib, __src_to_obj(env, lib_src)) + lib_a = env.StaticLibrary(build_dir + lib, lib_obj) else: - lib_a = env.StaticLibrary(lib, __src_to_obj(env, lib_src)) - env.AppendUnique(LIBS = [File(lib_a[0])]) + lib_a = env.StaticLibrary(lib, lib_obj) + + # If we link libSPI.a, the final binary is not getting launched + # on the board. Which is not the case if we directly use SPI.o. + + if env.get('TARGET_ARCH') == 'arm': + if lib == 'SPI': + for obj in lib_obj: + if obj.name.endswith('SPI.o'): + env.PrependUnique(LIBS = [File(obj)]) + else: + + env.AppendUnique(LIBS = [File(lib_a[0])]) + else: + env.PrependUnique(LIBS = [File(lib_a[0])]) + + #env.AppendUnique(LIBS = [File(lib_a[0])]) def __build_core(env): core_src = __search_files(core_folder, '*.S') @@ -130,11 +146,14 @@ def __build_core(env): core_src.extend(__search_files(variant_folder, '*.cpp')) core_obj = __src_to_obj(env, core_src) - build_dir = env.get('BUILD_DIR') - if build_dir: - s_core = env.StaticLibrary(build_dir + 'core', core_obj) - else: - s_core = env.StaticLibrary('core', core_obj) + + prefix = env.get('BOARD') + '_' + if env.get('CPU'): + prefix += env.get('CPU') + '_' + + core = env.get('BUILD_DIR', '.') + '/arduino/' + prefix + 'core' + s_core = env.StaticLibrary(core, core_obj) + env.AppendUnique(LIBS = [File(s_core[0])]) # To avoid compiler issue. Otherewise there may be warnings: @@ -153,6 +172,25 @@ def __create_bin(env, source): else: hex = env.Command(name + '.hex', source, 'arm-none-eabi-objcopy -O binary $SOURCE $TARGET') +#Currently supporting only mega (ie. Arduino ATMega2560) and arduino_due_x/arduino_due_x_dbg (i.e. Arduino Due) builds +def __upload(env, binary): + if target_arch == 'avr': + protocol = __get_board_info(board, '.upload.protocol') + speed = __get_board_info(board, '.upload.speed') + port = '/dev/ttyACM0' + upload_cmd = arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -p' \ + + mcu + ' -c' + protocol + ' -P' + port + ' -b' + speed + ' -D -Uflash:w:' + binary + ':i' + print "Upload command: %s" %upload_cmd + install_cmd = env.Command('install_cmd', None, upload_cmd) + env.Default('install_cmd') + elif target_arch == 'arm': + protocol = __get_board_info(board, '.upload.protocol') + speed = __get_board_info(board, '.upload.speed') + port = 'ttyACM0' + uu = __get_board_info(board, '.upload.native_usb') + os.system('stty -F /dev/' + port + ' speed 1200 cs8 -cstopb -parenb') + os.system(arduino_home + '/hardware/tools/bossac -i --port=' + port + ' -U false -e -w -b ' + binary + ' -R') + # Print the command line that to upload binary to the board def __upload_help(env): if target_arch == 'avr': @@ -182,16 +220,12 @@ help_vars.Update(env) Help(help_vars.GenerateHelpText(env)) target_arch = env.get('TARGET_ARCH') + +# Verify that the arduino, time, red bear, and nordic libraries are +# installed. If not, get them and install them. +SConscript(env.get('SRC_DIR') + '/extlibs/arduino/SConscript') arduino_home = env.get('ARDUINO_HOME') -if not arduino_home: - print ''' -************************************* Error *********************************** -* Arduino root directory isn't set, you can set enviornment variable * -* ARDUINO_HOME or add it in command line as: * -* # scons ARDUINO_HOME= ... * -******************************************************************************* -''' - Exit(1) +print 'ARDUINO_HOME = ' + env.get('ARDUINO_HOME') # Overwrite suffixes and prefixes if env['HOST_OS'] == 'win32': @@ -221,7 +255,7 @@ else: # Get IDE version if os.path.exists(arduino_home + '/lib/version.txt'): vf = open(arduino_home + '/lib/version.txt', 'r') - version = vf.readline().replace('.', '') + version = vf.readline().replace('.', '').strip() else: print ''' ************************************* Error *********************************** @@ -310,7 +344,7 @@ core_folder = core_base + 'cores/' + core + '/' env.AppendUnique(CPPPATH = [core_folder]) if is_1_0_x: - comm_flags = [] + comm_flags = ['-std=c99'] if mcu: comm_flags.extend(['-mmcu=' + mcu]) if f_cpu: @@ -344,9 +378,11 @@ else: comm_flag = [cpu_flag, '-DF_CPU=' + f_cpu, '-DARDUINO=' + version, '-DARDUINO_' + __get_board_info(board, '.build.board')] if target_arch == 'arm': - comm_flag.extend(['-DARDUINO_ARCH_SAM']) + # As of 1.5.8 the arduino headers for arm had _asm_ bugs with ARM and + # require gnu99 to be used + comm_flag.extend(['-std=gnu99', '-DARDUINO_ARCH_SAM']) else: - comm_flag.extend(['-DARDUINO_ARCH_AVR']) + comm_flag.extend(['-std=c99', '-DARDUINO_ARCH_AVR']) compiler_path = platform_info.get('compiler.path') compiler_path = compiler_path.replace('{runtime.ide.path}', arduino_home) @@ -374,9 +410,8 @@ else: if target_arch == 'arm': env.AppendUnique(LINKFLAGS = ['-Os', '-Wl,--gc-sections', cpu_flag, - '-T' + variant_folder + '/' + __get_board_info(board, '.build.ldscript'), - '-Wl,-Map,' + env.get('BUILD_DIR') + 'arduino_prj.map']) - env.AppendUnique(LINKFLAGS = Split('-lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group')) + '-T' + variant_folder + '/' + __get_board_info(board, '.build.ldscript')]) + env.AppendUnique(LINKFLAGS = Split('-lm -lgcc -mthumb -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group')) variant_system_lib = __get_board_info(board, '.build.variant_system_lib') if variant_system_lib: @@ -392,9 +427,11 @@ else: env.AppendUnique(LIBS = 'm') env.Replace(ARCOM = '$AR ' + platform_info.get('compiler.ar.flags') + ' $TARGET $SOURCES') + __build_core(env) env.AddMethod(__import_lib, "ImportLib") #import arduino library -#env.AddMethod(__build_core, "BuildCore") #build arduino core +env.AddMethod(__build_core, "BuildCore") #build arduino core env.AddMethod(__create_bin, "CreateBin") #create binary files(.eep and .hex) +env.AddMethod(__upload, "Upload") #Upload binary to board env.AddMethod(__upload_help, "UploadHelp") #print the command line that to upload binary to the boardf diff --git a/build_common/darwin/SConscript b/build_common/darwin/SConscript index 7d57774..2b0386a 100644 --- a/build_common/darwin/SConscript +++ b/build_common/darwin/SConscript @@ -19,10 +19,12 @@ if sys_version is None: print ''' *********************************** Error ************************************* * MAC OSX/IOS version isn't set, please set it in command line as : * -* # scons SYS_VERSION= ... * +* # scons TARGET_ARCH= TARGET_OS= SYS_VERSION= ... * * To get the version, please see: * * /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ * * /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ * +* is 'armv7','armv7s','arm64','i386', 'x86_64' +* is 'darwin','ios' ******************************************************************************* ''' Exit(1) @@ -35,6 +37,7 @@ if env.get('RELEASE'): env.AppendUnique(CPPDEFINES = ['NDEBUG']) else: env.AppendUnique(CCFLAGS = ['-g']) + env.AppendUnique(LINKFLAGS = ['-g']) if target_os == 'darwin': sys_root = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX' + sys_version + '.sdk/' @@ -51,4 +54,4 @@ env.AppendUnique(LINKFLAGS = ['-arch', target_arch, '-isysroot', sys_root]) if target_os == 'darwin': flag = '-mmacosx-version-min=' + sys_version env.AppendUnique(CCFLAGS = [flag]) - env.AppendUnique(LINKFLAGS = [flag]) \ No newline at end of file + env.AppendUnique(LINKFLAGS = [flag]) diff --git a/build_common/external_libs.scons b/build_common/external_libs.scons new file mode 100644 index 0000000..432bbe5 --- /dev/null +++ b/build_common/external_libs.scons @@ -0,0 +1,128 @@ +## +# This script manages external libraries +# +# Some methods are added to manage external packages: +# 'PrepareLib': Checks the existence of an external library, if it +# doesn't exist, calls the script user provided to download(if required) +# and build the source code of the external library or notify user to +# install the library. +# 'Download': Download package from specify URL +# 'UnpackAll': Unpack the package +# 'Configure': Execute specify script(configure, bootstrap etc) +# 'InstallHeadFile': Install head files +# 'InstallLib': Install library binaries(.so, .a etc) +# +# By default, assume the script for an exteranl library is: +# /extlibs//SConscript +# +# Note: After the external library is built: +# Head files should be installed to /deps//include +# lib(e.g .so, .a) should be installed to /deps//lib/ +# +## +import os, subprocess +import urllib2, urlparse +import SCons.Errors + +Import('env') + +target_os = env.get('TARGET_OS') +target_arch = env.get('TARGET_ARCH') + +# for android, doesn't distinguish 'armeabi-v7a-hard' and 'armeabi-v7a' library +if target_os == 'android': + if target_arch == 'armeabi-v7a-hard': + target_arch = 'armeabi-v7a' + +if target_os == 'darwin': + env.AppendUnique(CPPPATH = ['/usr/local/include']) + env.AppendUnique(LIBPATH = ['/usr/local/lib']) + +# External library include files are in /deps//include +# the library binaries are in /deps//lib/ +env.AppendUnique(CPPPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'include')]) +env.AppendUnique(LIBPATH = [os.path.join(env.get('SRC_DIR'), 'deps', target_os, 'lib', target_arch)]) + +# Check whether a library exists, if not, notify user to install it or try to +# download the source code and build it +# @param libname - the name of the library try to prepare +# @param lib - the lib(.so, .a etc) to check (a library may include more then +# one lib, e.g. boost, includes boost_thread, boost_system ... +# @param path - the directory of the library building script, if it's not set, +# by default, it's /extlibs// +# @param script - the building script, by default, it's 'SConscript' +# +def __prepare_lib(ienv, libname, lib = None, path = None, script = None): + p_env = ienv.Clone() + if p_env.GetOption('clean') or p_env.GetOption('help'): + return + + conf = Configure(p_env) + + if not lib: + lib = libname + if not conf.CheckLib(lib): + if path: + dir = path + else: + dir = os.path.join(env.get('SRC_DIR'), 'extlibs', libname) + + # Execute the script to download(if required) and build source code + if script: + st = os.path.join(dir, script) + else: + st = os.path.join(dir, 'SConscript') + + if os.path.exists(st): + SConscript(st) + else: + if target_os in ['linux', 'darwin', 'tizen']: + print 'Don\'t find library(%s), please intall it, exit ...' % libname + else: + print 'Don\'t find library(%s) and don\'t find the process script (%s), exit ...' % (libname, st) + Exit(1) + + conf.Finish() + +# Run configure command (usually it's done before build a library) +def __configure(env, cwd, cmd) : + print "Configuring using [%s/%s] ..." % (cwd, cmd) + # build it now (we need the shell, because some programs need it) + devnull = open(os.devnull, "wb") + handle = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=devnull) + + if handle.wait() <> 0 : + raise SCons.Errors.BuildError( "Run configuring script [%s]" % (cmd) ) + +# Download from URL 'url', will save as 'target' +def __download(ienv, target, url) : + if os.path.exists(target) : + return target + + try : + print "Download %s from %s" % (target, url) + print "Downloading ..." + stream = urllib2.urlopen(url) + file = open(target, 'wb') + file.write(stream.read()) + file.close() + print "Download %s from %s complete" % (target, url) + return target + except Exception, e : + raise SCons.Errors.StopError( '%s [%s]' % (e, url) ) + +# Install header file(s) to /deps//include +def __install_head_file(ienv, file): + return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'include'), file) + +# Install library binaries to /deps//lib/ +def __install_lib(ienv, lib): + return ienv.Install(os.path.join(env.get('SRC_DIR'), 'dep', target_os, target_arch, 'usr', 'lib'), lib) + +SConscript('tools/UnpackAll.py') + +env.AddMethod(__prepare_lib, "PrepareLib") +env.AddMethod(__configure, "Configure") +env.AddMethod(__download, "Download") +env.AddMethod(__install_head_file, "InstallHeadFile") +env.AddMethod(__install_lib, "InstallLib") diff --git a/build_common/iotivityconfig/__init__.py b/build_common/iotivityconfig/__init__.py new file mode 100644 index 0000000..3a2ef6a --- /dev/null +++ b/build_common/iotivityconfig/__init__.py @@ -0,0 +1,110 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +# This file contains compiler tests for use in scons 'Configure' +# tests. + +from compiler import factory + +def _check_for_broken_gcc_headers(context, flag): + # Check for issue in some older (pre-C++11) C library headers that + # causes functions like snprintf() to remain undeclared when + # -std=c++0x or -ansi, for example, is added to the g++ command + # line flags, and despite the fact the appropriate feature test + # macro to make the prototypes visible is defined. + # + # Returns 1 if the broken headers were detected, 0 otherwise. + # + # This should only be called if the compiler is g++ (which it + # should be if we are here) and a flag was automatically appended + # to CXXFLAGS. + + context.Message('Checking for broken GCC C headers when C++11 is enabled... ') + ret = '-std=gnu++' in flag + context.Result(ret) + + if ret: + print('Warning: detected pre-C++11 GCC C header bugs. See:') + print(' https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34032') + print(' for related details.') + +def _inform_user_of_broken_gcc_headers(context, flag): + # Informative tests used to inform the user of broken GCC headers. + # They are unnecessary for actual builds. + if flag is not 1 and flag is not 0: + # The flag is neither 1 nor 0, meaning it contains the + # automatically detected C++11 flag. + + # Now verify that the compiler is actually GCC. + is_gcc = factory.check_for_gcc_cxx(context) + if is_gcc: + # This should only be called if the compiler is g++ and a + # flag was automatically appended to CXXFLAGS. + # + # We do not care if the user added a flag that triggers + # the header bug. It's the user's responsibility to + # handle the issue in that case. + _check_for_broken_gcc_headers(context, flag) + +def check_c99_flags(context): + """ + Check if command line flag is required to enable C99 support. + + Returns 1 if no flag is required, 0 if no flag was found, or the + actual flag if one was found. + """ + + cc = context.env['CC'] + context.Message('Checking for C99 flag for ' + cc + '... ') + config = factory.make_c_compiler_config(context) + ret = config.check_c99_flags() + context.Result(ret) + + return ret + +def check_cxx11_flags(context): + """ + Check if command line flag is required to enable C++11 support. + + Returns 1 if no flag is required, 0 if no flag was found, or the + actual flag if one was found. + """ + + cxx = context.env['CXX'] + context.Message('Checking for C++11 flag for ' + cxx + '... ') + config = factory.make_cxx_compiler_config(context) + ret = config.check_cxx11_flags() + context.Result(ret) + + # Let the user know if a workaround was enabled for broken GCC C + # headers when C++11 is enabled. + _inform_user_of_broken_gcc_headers(context, ret) + + return ret + +def check_pthreads(context): + """ + Check if pthreads are supported for this platform. + + Sets POSIX_SUPPORTED based on the result. + """ + context.Message('Checking for POSIX Thread Support...') + config = factory.make_c_compiler_config(context) + + ret = config.has_pthreads_support() + context.env['POSIX_SUPPORTED'] = ret + context.Result(ret) + return ret diff --git a/build_common/iotivityconfig/compiler/__init__.py b/build_common/iotivityconfig/compiler/__init__.py new file mode 100644 index 0000000..9f01a42 --- /dev/null +++ b/build_common/iotivityconfig/compiler/__init__.py @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +__all__ = [ "factory" ] diff --git a/build_common/iotivityconfig/compiler/configuration.py b/build_common/iotivityconfig/compiler/configuration.py new file mode 100644 index 0000000..3dbf4e1 --- /dev/null +++ b/build_common/iotivityconfig/compiler/configuration.py @@ -0,0 +1,178 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +class Configuration: + """Compiler-specific configuration abstract base class""" + + def __init__(self, context): + """ + Initialize the Configuration object + + Arguments: + context -- the scons configure context + """ + + if type(self) is Configuration: + raise TypeError('abstract class cannot be instantiated') + + self._context = context # scons configure context + self._env = context.env # scons environment + + def check_c99_flags(self): + """ + Check if command line flag is required to enable C99 + support. + + Returns 1 if no flag is required, 0 if no flag was + found, and the actual flag if one was found. + + CFLAGS will be updated with appropriate C99 flag, + accordingly. + """ + + return self._check_flags(self._c99_flags(), + self._c99_test_program(), + '.c', + 'CFLAGS') + + def check_cxx11_flags(self): + """ + Check if command line flag is required to enable C++11 + support. + + Returns 1 if no flag is required, 0 if no flag was + found, and the actual flag if one was found. + + CXXFLAGS will be updated with appropriate C++11 flag, + accordingly. + """ + + return self._check_flags(self._cxx11_flags(), + self._cxx11_test_program(), + '.cpp', + 'CXXFLAGS') + + def has_pthreads_support(self): + """ + Check if PThreads are supported by this system + + Returns 1 if this system DOES support pthreads, 0 + otherwise + """ + + return self._context.TryCompile(self._pthreads_test_program(), '.c') + + # -------------------------------------------------------------- + # Check if flag is required to build the given test program. + # + # Arguments: + # test_flags -- list of flags that may be needed to build + # test_program + # test_program -- program used used to determine if one of the + # given flags is required to for a successful + # build + # test_extension -- file extension associated with the test + # program, e.g. '.cpp' for C++ and '.c' for C + # flags_key -- key used to retrieve compiler flags that may + # be updated by this check from the SCons + # environment + # -------------------------------------------------------------- + def _check_flags(self, + test_flags, + test_program, + test_extension, + flags_key): + # Check if no additional flags are required. + ret = self._context.TryCompile(test_program, + test_extension) + + if ret is 0: + # Try flags known to enable compiler features needed by + # the test program. + + last_flags = self._env[flags_key] + for flag in test_flags: + self._env.Append(**{flags_key : flag}) + ret = self._context.TryCompile(test_program, + test_extension) + + if ret: + # Found a flag! + return flag + else: + # Restore original compiler flags for next flag + # test. + self._env.Replace(**{flags_key : last_flags}) + + return ret + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C99 + # support. + # + # Subclasses should implement this template method or use the + # default test program found in the DefaultConfiguration class + # through composition. + # ------------------------------------------------------------ + def _c99_test_program(self): + raise NotImplementedError('unimplemented method') + + # -------------------------------------------------------------- + # Get list of flags that could potentially enable C99 support. + # + # Subclasses should implement this template method if flags are + # needed to enable C99 support. + # -------------------------------------------------------------- + def _c99_flags(self): + raise NotImplementedError('unimplemented method') + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C++11 + # support. + # + # Subclasses should implement this template method or use the + # default test program found in the DefaultConfiguration class + # through composition. + # ------------------------------------------------------------ + def _cxx11_test_program(self): + raise NotImplementedError('unimplemented method') + + # -------------------------------------------------------------- + # Get list of flags that could potentially enable C++11 support. + # + # Subclasses should implement this template method if flags are + # needed to enable C++11 support. + # -------------------------------------------------------------- + def _cxx11_flags(self): + raise NotImplementedError('unimplemented method') + + # -------------------------------------------------------------- + # Return a test program to be used when checking for PThreads + # support + # + # -------------------------------------------------------------- + def _pthreads_test_program(self): + return """ +#include +#include +int main() +{ + #ifndef _POSIX_THREADS + # error POSIX Threads support not available + #endif + return 0; +} +""" diff --git a/build_common/iotivityconfig/compiler/default_configuration.py b/build_common/iotivityconfig/compiler/default_configuration.py new file mode 100644 index 0000000..ed90f40 --- /dev/null +++ b/build_common/iotivityconfig/compiler/default_configuration.py @@ -0,0 +1,84 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +from configuration import Configuration + +# Default (very simple) compiler configuration +class DefaultConfiguration(Configuration): + def __init__(self, context): + Configuration.__init__(self, context) + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C++11 + # support. + # ------------------------------------------------------------ + def _c99_test_program(self): + return """ +// Some headers found in C99. +#include +#include + +int main() +{ + struct foo + { + bool b; // C99 type + int i; + uint64_t q; // C99 type + }; + + // Designated initializer. + struct foo bar = { .b = false, .q = UINT64_MAX }; + + // Implicitly initialized field. + return bar.i != 0; +} +""" + + # -------------------------------------------------------------- + # Get list of flags that could potentially enable C99 support. + # + # The default configuration assumes that no flag is needed to + # enable C99 support. + # -------------------------------------------------------------- + def _c99_flags(self): + return [] + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C++11 + # support. + # ------------------------------------------------------------ + def _cxx11_test_program(self): + return """ +int main() +{ + int x = 3210; + auto f = [x](){ + return x; + }; + + return f() != x; +} +""" + + # -------------------------------------------------------------- + # Get list of flags that could potentially enable C++11 support. + # + # The default configuration assumes that no flag is needed to + # enable C++11 support. + # -------------------------------------------------------------- + def _cxx11_flags(self): + return [] diff --git a/build_common/iotivityconfig/compiler/factory.py b/build_common/iotivityconfig/compiler/factory.py new file mode 100644 index 0000000..7b0bee7 --- /dev/null +++ b/build_common/iotivityconfig/compiler/factory.py @@ -0,0 +1,126 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +from default_configuration import * +from gcc_configuration import * + +# Canonicalize the C or C++ compiler name to "gcc" if gcc is being +# used to simplify mapping to the GCC compiler configuration since GCC +# may be installed under a different name. This will be used when +# mapping compiler name to configuration in the factory submodule. +_GCC = 'gcc' + +# Update this dictionary with new compiler configurations as needed. +_CONFIG_MAP = { _GCC : GccConfiguration } + +_c_compiler_config = None +_cxx_compiler_config = None + +def check_for_gcc_c(context): + """ + Check if the C compiler is GCC + + Returns 1 if gcc, 0 otherwise + """ + + test_program = """ +#if !defined(__GNUC__) +# error "Not the GCC C compiler." +#endif + +int foo(void) +{ + return 0; +} +""" + + return context.TryCompile(test_program, '.c') + +def check_for_gcc_cxx(context): + """ + Check if the C++ compiler is GCC + + Returns 1 if gcc, 0 otherwise + """ + + test_program = """ +#if !defined(__GNUC__) || !defined(__cplusplus) +# error "Not the GCC C++ compiler." +#endif + +class foo +{ +public: + foo() : x_() {} + int x() const { return x_; } +private: + int x_; +}; +""" + + return context.TryCompile(test_program, '.cpp') + +def make_c_compiler_config(context): + """ + Create C compiler-specific configuration object. + + Arguments: + context -- the scons configure context + + The 'CC' key in the SCons environment will be mapped to the + appropriate supported compiler configuration. If no match is + found compiler configuration operations will simply be no-ops. + """ + + global _c_compiler_config + + if _c_compiler_config is None: + cc = context.env['CC'] + + if check_for_gcc_c(context): + cc = _GCC + + config = _CONFIG_MAP.get(cc, DefaultConfiguration) + + _c_compiler_config = config(context) + + return _c_compiler_config + +def make_cxx_compiler_config(context): + """ + Create C++ compiler-specific configuration object. + + Arguments: + context -- the scons configure context + + The 'CXX' key in the SCons environment will be mapped to the + appropriate supported compiler configuration. If no match is + found compiler configuration operations will simply be no-ops. + """ + + global _cxx_compiler_config + + if _cxx_compiler_config is None: + cxx = context.env['CXX'] + + if check_for_gcc_cxx(context): + cxx = _GCC + + config = _CONFIG_MAP.get(cxx, DefaultConfiguration) + + _cxx_compiler_config = config(context) + + return _cxx_compiler_config diff --git a/build_common/iotivityconfig/compiler/gcc_configuration.py b/build_common/iotivityconfig/compiler/gcc_configuration.py new file mode 100644 index 0000000..fbc8f38 --- /dev/null +++ b/build_common/iotivityconfig/compiler/gcc_configuration.py @@ -0,0 +1,109 @@ +# ------------------------------------------------------------------------ +# Copyright 2015 Intel Corporation +# +# 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. +# ------------------------------------------------------------------------ + +from configuration import Configuration + +# GCC compiler-specific configuration +class GccConfiguration(Configuration): + def __init__(self, context): + Configuration.__init__(self, context) + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C99 + # support in GCC. + # ------------------------------------------------------------ + def _c99_test_program(self): + # Use the default C99 test program but enable pedantic + # diagnostics specific to GCC to force errors to occur if a + # flag is required to compile C99 code without warning or + # error. + + from default_configuration import DefaultConfiguration + def_config = DefaultConfiguration(self._context) + + return """ +#ifndef __clang__ +#pragma GCC diagnostic error "-Wall" +#pragma GCC diagnostic error "-Werror" +#pragma GCC diagnostic error "-pedantic" +#endif +""" + def_config._c99_test_program() + + # ------------------------------------------------------------- + # Get flags known to enable C99 support for GCC C compiler. + # ------------------------------------------------------------- + def _c99_flags(self): + # Favor flags that do not enable GNU extensions by default, + # e.g. '-std=c99'. + return [ '-std=c99', + '-std=iso9899:1999', + '-std=gnu99', + '-std=c9x', + '-std=iso9899:199x', + '-std=gnu9x' ] + + # ------------------------------------------------------------ + # Return test program to be used when checking for basic C++11 + # support in GCC. + # ------------------------------------------------------------ + def _cxx11_test_program(self): + # Besides checking for a basic C++11 feature, this contrived + # test program is designed to trigger an issue in some older + # (pre-C++11) C library headers that causes functions like + # snprintf() to remain undeclared when -std=c++0x or -ansi, + # for example, is added to the g++ command line flags, and + # despite the fact the appropriate feature test macro to make + # the prototypes visible is defined. + # + # The recommended workaround is to instead of -std=c++0x use + # -std=gnu++0x to explicitly enable GNU extensions. Failure + # will force the configuration test to attempt the build with + # -std=gnu++0x, for example. + # + # For a more complete description of this issue, see: + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34032 + # + # Other compilers should be able to compile this code without + # issue. + return """ +#define _POSIX_C_SOURCE 200112L +#include + +int main() +{ + int x = 3210; + auto f = [x](){ + char buf[15] = { 0 }; + snprintf(buf, sizeof(buf) / sizeof(buf[0]), "%d", x); + return buf[0]; + }; + + return f() != '3'; +} +""" + + # ------------------------------------------------------------- + # Get flags known to enable C++11 support for GCC C++ compiler. + # ------------------------------------------------------------- + def _cxx11_flags(self): + # Favor command line flags from more recent versions of the + # compiler over older/deprecated flags. Also, favor flags + # that do not enable GNU extensions by default, + # e.g. '-std=c++..'. + return [ '-std=c++11', + '-std=gnu++11', + '-std=c++0x', + '-std=gnu++0x' ] diff --git a/build_common/linux/SConscript b/build_common/linux/SConscript index bb939be..b1640e1 100644 --- a/build_common/linux/SConscript +++ b/build_common/linux/SConscript @@ -4,14 +4,24 @@ ## Import('env') +print "Reading linux configuration script" + # Set release/debug flags if env.get('RELEASE'): env.AppendUnique(CCFLAGS = ['-Os']) env.AppendUnique(CPPDEFINES = ['NDEBUG']) - env.AppendUnique(LINKFLAGS = ['-s']) else: env.AppendUnique(CCFLAGS = ['-g']) +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + +env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__']) +env.AppendUnique(CFLAGS = ['-std=gnu99']) +env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) +env.AppendUnique(LIBS = ['uuid']) +env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + # Set arch flags target_arch = env.get('TARGET_ARCH') if target_arch in ['x86']: @@ -27,7 +37,7 @@ elif target_arch.find('v7a-hard') > 0: env.AppendUnique(LINKFLAGS = ['-mfloat-abi=hard']) elif target_arch.find('v7a') > 0: env.AppendUnique(CPPFLAGS = ['-march=armv7-a']) -elif target_arch.find('arm64') > 0: +elif target_arch.find('arm64') >= 0: env.AppendUnique(CPPFLAGS = ['-march=armv8-a']) else: env.AppendUnique(CPPFLAGS = ['-march=armv5te']) diff --git a/build_common/tizen/SConscript b/build_common/tizen/SConscript new file mode 100644 index 0000000..81be23a --- /dev/null +++ b/build_common/tizen/SConscript @@ -0,0 +1,46 @@ +## +# This script set linux specific flags (GNU GCC) +# +## +Import('env') + +print "Reading linux configuration script" + +# Set release/debug flags +if env.get('RELEASE'): + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) +else: + env.AppendUnique(CCFLAGS = ['-g']) + +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + +env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__']) +env.AppendUnique(CFLAGS = ['-std=gnu99']) +env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) +env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + +if env.get('TARGET_OS') == 'tizen': + env.AppendUnique(CCFLAGS = ['-D__TIZEN__', '-DSLP_SDK_LOG', '-D_GNU_SOURCE', '-DTIZEN_DEBUG_ENABLE']) + env.ParseConfig("pkg-config dlog --cflags --libs") + +# Set arch flags +target_arch = env.get('TARGET_ARCH') +if target_arch in ['x86']: + env.AppendUnique(CCFLAGS = ['-m32']) + env.AppendUnique(LINKFLAGS = ['-m32']) +elif target_arch in ['x86_64']: + env.AppendUnique(CCFLAGS = ['-m64']) + env.AppendUnique(LINKFLAGS = ['-m64']) +elif target_arch.find('v7a-hard') > 0: + env.AppendUnique(CPPFLAGS = ['-march=armv7-a']) + env.AppendUnique(CPPFLAGS = ['-mfloat-abi=hard']) + env.AppendUnique(CCFLAGS = ['-mfloat-abi=hard']) + env.AppendUnique(LINKFLAGS = ['-mfloat-abi=hard']) +elif target_arch.find('v7a') > 0: + env.AppendUnique(CPPFLAGS = ['-march=armv7-a']) +elif target_arch.find('arm64') >= 0: + env.AppendUnique(CPPFLAGS = ['-march=armv8-a']) +else: + env.AppendUnique(CPPFLAGS = ['-march=armv5te']) diff --git a/build_common/tools/UnpackAll.py b/build_common/tools/UnpackAll.py new file mode 100644 index 0000000..0df17e4 --- /dev/null +++ b/build_common/tools/UnpackAll.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- + +############################################################################ +# GPL License # +# # +# This file is a SCons (http://www.scons.org/) builder # +# Copyright (c) 2012-14, Philipp Kraus, # +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as # +# published by the Free Software Foundation, either version 3 of the # +# License, or (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +############################################################################ + +# This builder originated from work by Philipp Kraus and flashpixx project +# (see https://github.com/flashpixx). Based on the Unpack.py, it only +# contains changes to allow a complete unpacking of the archive. +# It is assumed that the target represents a file in the archive after it +# is unpacked. + +# The Unpack Builder can be used for unpacking archives (eg Zip, TGZ, BZ, ... ). +# The emitter of the Builder reads the archive data and creates a returning +# file list the builder extract the archive. The environment variable +# stores a dictionary "UNPACK" for set different extractions (subdict "EXTRACTOR"): +# { +# PRIORITY => a value for setting the extractor order (lower numbers = extractor is used earlier) +# SUFFIX => defines a list with file suffixes, which should be handled with this extractor +# EXTRACTSUFFIX => suffix of the extract command +# EXTRACTFLAGS => a string parameter for the RUN command for extracting the data +# EXTRACTCMD => full extract command of the builder +# RUN => the main program which will be started (if the parameter is empty, the extractor will be ignored) +# LISTCMD => the listing command for the emitter +# LISTFLAGS => the string options for the RUN command for showing a list of files +# LISTSUFFIX => suffix of the list command +# LISTEXTRACTOR => a optional Python function, that is called on each output line of the +# LISTCMD for extracting file & dir names, the function need two parameters (first line number, +# second line content) and must return a string with the file / dir path (other value types +# will be ignored) +# } +# Other options in the UNPACK dictionary are: +# STOPONEMPTYFILE => bool variable for stoping if the file has empty size (default True) +# VIWEXTRACTOUTPUT => shows the output messages of the extraction command (default False) +# EXTRACTDIR => path in that the data will be extracted (default #) +# +# The file which is handled by the first suffix match of the extractor, the extractor list can be append for other files. +# The order of the extractor dictionary creates the listing & extractor command eg file extension .tar.gz should be +# before .gz, because the tar.gz is extract in one shoot. +# +# Under *nix system these tools are supported: tar, bzip2, gzip, unzip +# Under Windows only 7-Zip (http://www.7-zip.org/) is supported + + +import subprocess, os +import SCons.Errors, SCons.Warnings, SCons.Util + +# enables Scons warning for this builder +class UnpackWarning(SCons.Warnings.Warning) : + pass + +SCons.Warnings.enableWarningClass(UnpackWarning) + +# extractor function for Tar output +# @param env environment object +# @param count number of returning lines +# @param no number of the output line +# @param i line content +def __fileextractor_nix_tar( env, count, no, i ) : + return i.split()[-1] + +# extractor function for GZip output, +# ignore the first line +# @param env environment object +# @param count number of returning lines +# @param no number of the output line +# @param i line content +def __fileextractor_nix_gzip( env, count, no, i ) : + if no == 0 : + return None + return i.split()[-1] + +# extractor function for Unzip output, +# ignore the first & last two lines +# @param env environment object +# @param count number of returning lines +# @param no number of the output line +# @param i line content +def __fileextractor_nix_unzip( env, count, no, i ) : + if no < 3 or no >= count - 2 : + return None + return i.split()[-1] + +# extractor function for 7-Zip +# @param env environment object +# @param count number of returning lines +# @param no number of the output line +# @param i line content +def __fileextractor_win_7zip( env, count, no, i ) : + item = i.split() + if no > 8 and no < count - 2 : + return item[-1] + return None + + + +# returns the extractor item for handling the source file +# @param source input source file +# @param env environment object +# @return extractor entry or None on non existing +def __getExtractor( source, env ) : + # we check each unpacker and get the correct list command first, run the command and + # replace the target filelist with the list values, we sorte the extractors by their priority + for unpackername, extractor in sorted(env["UNPACK"]["EXTRACTOR"].iteritems(), key = lambda (k,v) : (v["PRIORITY"],k)): + + if not SCons.Util.is_String(extractor["RUN"]) : + raise SCons.Errors.StopError("list command of the unpack builder for [%s] archives is not a string" % (unpackername)) + if not len(extractor["RUN"]) : + raise SCons.Errors.StopError("run command of the unpack builder for [%s] archives is not set - can not extract files" % (unpackername)) + + + if not SCons.Util.is_String(extractor["LISTFLAGS"]) : + raise SCons.Errors.StopError("list flags of the unpack builder for [%s] archives is not a string" % (unpackername)) + if not SCons.Util.is_String(extractor["LISTCMD"]) : + raise SCons.Errors.StopError("list command of the unpack builder for [%s] archives is not a string" % (unpackername)) + + if not SCons.Util.is_String(extractor["EXTRACTFLAGS"]) : + raise SCons.Errors.StopError("extract flags of the unpack builder for [%s] archives is not a string" % (unpackername)) + if not SCons.Util.is_String(extractor["EXTRACTCMD"]) : + raise SCons.Errors.StopError("extract command of the unpack builder for [%s] archives is not a string" % (unpackername)) + + + # check the source file suffix and if the first is found, run the list command + if not SCons.Util.is_List(extractor["SUFFIX"]) : + raise SCons.Errors.StopError("suffix list of the unpack builder for [%s] archives is not a list" % (unpackername)) + + for suffix in extractor["SUFFIX"] : + if str(source[0]).lower()[-len(suffix):] == suffix.lower() : + return extractor + + return None + + +# creates the extracter output message +# @param s original message +# @param target target name +# @param source source name +# @param env environment object +def __message( s, target, source, env ) : + print "extract [%s] ..." % (source[0]) + + +# action function for extracting of the data +# @param target target packed file +# @param source extracted files +# @param env environment object +def __action( target, source, env ) : + cwd = os.path.realpath('.') + extractor = __getExtractor([File(source)], env) + if not extractor : + print '''******************************* Error ***************************************** +* +* Doesn't support auto extracting [%s], please extract it to [%s]. +* * +******************************************************************************* +''' % (source, cwd) + raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source) ) + + extractor_cmd = extractor["EXTRACTCMD"] + + # if the extract command is empty, we create an error + if len(extractor_cmd) == 0 : + raise SCons.Errors.StopError( "the extractor command for the source file [%s] is empty" % (source) ) + + # build it now (we need the shell, because some programs need it) + handle = None + + cmd = env.subst(extractor_cmd, source=source, target=target) + + if env["UNPACK"]["VIWEXTRACTOUTPUT"] : + handle = subprocess.Popen( cmd, shell=True ) + else : + devnull = open(os.devnull, "wb") + handle = subprocess.Popen(cmd, shell=True, stdout=devnull, cwd = cwd) + + if handle.wait() <> 0 : + print '''******************************* Error ***************************************** +* +* Fail to unpack [%s]. It should be due to it isn't downloaded completely. +* Please download it manually or delete it and let the script auto download it* +* again. * +* * +******************************************************************************* +''' % (source) + raise SCons.Errors.BuildError( "error running extractor [%s] on the source [%s]" % (cmd, source) ) + +# emitter function for getting the files +# within the archive +# @param target target packed file +# @param source extracted files +# @param env environment object +def __emitter( target, source, env ) : + return target, source + +def __unpack_all(env, target, source) : + if os.path.exists(target): + return + + print "Unpacking %s ..." % source + __action(target, source, env) + +# generate function, that adds the builder to the environment +# @param env environment object +def generate( env ) : + # setup environment variable + toolset = { + "STOPONEMPTYFILE" : True, + "VIWEXTRACTOUTPUT" : False, + "EXTRACTDIR" : os.curdir, + "EXTRACTOR" : { + "TARGZ" : { + "PRIORITY" : 0, + "SUFFIX" : [".tar.gz", ".tgz", ".tar.gzip"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['TARGZ']['RUN']} ${UNPACK['EXTRACTOR']['TARGZ']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARGZ']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['TARGZ']['RUN']} ${UNPACK['EXTRACTOR']['TARGZ']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARGZ']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + }, + + "TARBZ" : { + "PRIORITY" : 0, + "SUFFIX" : [".tar.bz", ".tbz", ".tar.bz2", ".tar.bzip2", ".tar.bzip"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['TARBZ']['RUN']} ${UNPACK['EXTRACTOR']['TARBZ']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARBZ']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['TARBZ']['RUN']} ${UNPACK['EXTRACTOR']['TARBZ']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARBZ']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + }, + + "BZIP" : { + "PRIORITY" : 1, + "SUFFIX" : [".bz", "bzip", ".bz2", ".bzip2"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['BZIP']['RUN']} ${UNPACK['EXTRACTOR']['BZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['BZIP']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['BZIP']['RUN']} ${UNPACK['EXTRACTOR']['BZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['BZIP']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + }, + + "GZIP" : { + "PRIORITY" : 1, + "SUFFIX" : [".gz", ".gzip"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['GZIP']['RUN']} ${UNPACK['EXTRACTOR']['GZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['GZIP']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['GZIP']['RUN']} ${UNPACK['EXTRACTOR']['GZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['GZIP']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + }, + + "TAR" : { + "PRIORITY" : 1, + "SUFFIX" : [".tar"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['TAR']['RUN']} ${UNPACK['EXTRACTOR']['TAR']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TAR']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['TAR']['RUN']} ${UNPACK['EXTRACTOR']['TAR']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TAR']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + }, + + "ZIP" : { + "PRIORITY" : 1, + "SUFFIX" : [".zip"], + "EXTRACTSUFFIX" : "", + "EXTRACTFLAGS" : "", + "EXTRACTCMD" : "${UNPACK['EXTRACTOR']['ZIP']['RUN']} ${UNPACK['EXTRACTOR']['ZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['ZIP']['EXTRACTSUFFIX']}", + "RUN" : "", + "LISTCMD" : "${UNPACK['EXTRACTOR']['ZIP']['RUN']} ${UNPACK['EXTRACTOR']['ZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['ZIP']['LISTSUFFIX']}", + "LISTSUFFIX" : "", + "LISTFLAGS" : "", + "LISTEXTRACTOR" : None + } + } + } + + # read tools for Windows system + if env["PLATFORM"] <> "darwin" and "win" in env["PLATFORM"] : + + if env.WhereIs("7z") : + toolset["EXTRACTOR"]["TARGZ"]["RUN"] = "7z" + toolset["EXTRACTOR"]["TARGZ"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["TARGZ"]["LISTFLAGS"] = "x" + toolset["EXTRACTOR"]["TARGZ"]["LISTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} l -sii -ttar -y -so" + toolset["EXTRACTOR"]["TARGZ"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["TARGZ"]["EXTRACTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} x -sii -ttar -y -oc:${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["TARBZ"]["RUN"] = "7z" + toolset["EXTRACTOR"]["TARBZ"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["TARBZ"]["LISTFLAGS"] = "x" + toolset["EXTRACTOR"]["TARBZ"]["LISTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} l -sii -ttar -y -so" + toolset["EXTRACTOR"]["TARBZ"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["TARBZ"]["EXTRACTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} x -sii -ttar -y -oc:${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["BZIP"]["RUN"] = "7z" + toolset["EXTRACTOR"]["BZIP"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["BZIP"]["LISTFLAGS"] = "l" + toolset["EXTRACTOR"]["BZIP"]["LISTSUFFIX"] = "-y -so" + toolset["EXTRACTOR"]["BZIP"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["BZIP"]["EXTRACTSUFFIX"] = "-y -oc:${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["GZIP"]["RUN"] = "7z" + toolset["EXTRACTOR"]["GZIP"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["GZIP"]["LISTFLAGS"] = "l" + toolset["EXTRACTOR"]["GZIP"]["LISTSUFFIX"] = "-y -so" + toolset["EXTRACTOR"]["GZIP"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["GZIP"]["EXTRACTSUFFIX"] = "-y -oc:${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["ZIP"]["RUN"] = "7z" + toolset["EXTRACTOR"]["ZIP"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["ZIP"]["LISTFLAGS"] = "l" + toolset["EXTRACTOR"]["ZIP"]["LISTSUFFIX"] = "-y -so" + toolset["EXTRACTOR"]["ZIP"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["ZIP"]["EXTRACTSUFFIX"] = "-y -oc:${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["TAR"]["RUN"] = "7z" + toolset["EXTRACTOR"]["TAR"]["LISTEXTRACTOR"] = __fileextractor_win_7zip + toolset["EXTRACTOR"]["TAR"]["LISTFLAGS"] = "l" + toolset["EXTRACTOR"]["TAR"]["LISTSUFFIX"] = "-y -ttar -so" + toolset["EXTRACTOR"]["TAR"]["EXTRACTFLAGS"] = "x" + toolset["EXTRACTOR"]["TAR"]["EXTRACTSUFFIX"] = "-y -ttar -oc:${UNPACK['EXTRACTDIR']}" + + # here can add some other Windows tools, that can handle the archive files + # but I don't know which ones can handle all file types + + + + # read the tools on *nix systems and sets the default parameters + elif env["PLATFORM"] in ["darwin", "linux", "posix"] : + + if env.WhereIs("unzip") : + toolset["EXTRACTOR"]["ZIP"]["RUN"] = "unzip" + toolset["EXTRACTOR"]["ZIP"]["LISTEXTRACTOR"] = __fileextractor_nix_unzip + toolset["EXTRACTOR"]["ZIP"]["LISTFLAGS"] = "-l" + toolset["EXTRACTOR"]["ZIP"]["EXTRACTFLAGS"] = "-oqq" + toolset["EXTRACTOR"]["ZIP"]["EXTRACTSUFFIX"] = "-d ${UNPACK['EXTRACTDIR']}" + + if env.WhereIs("tar") : + toolset["EXTRACTOR"]["TAR"]["RUN"] = "tar" + toolset["EXTRACTOR"]["TAR"]["LISTEXTRACTOR"] = __fileextractor_nix_tar + toolset["EXTRACTOR"]["TAR"]["LISTFLAGS"] = "tvf" + toolset["EXTRACTOR"]["TAR"]["EXTRACTFLAGS"] = "xf" + toolset["EXTRACTOR"]["TAR"]["EXTRACTSUFFIX"] = "-C ${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["TARGZ"]["RUN"] = "tar" + toolset["EXTRACTOR"]["TARGZ"]["LISTEXTRACTOR"] = __fileextractor_nix_tar + toolset["EXTRACTOR"]["TARGZ"]["EXTRACTFLAGS"] = "xfz" + toolset["EXTRACTOR"]["TARGZ"]["LISTFLAGS"] = "tvfz" + toolset["EXTRACTOR"]["TARGZ"]["EXTRACTSUFFIX"] = "-C ${UNPACK['EXTRACTDIR']}" + + toolset["EXTRACTOR"]["TARBZ"]["RUN"] = "tar" + toolset["EXTRACTOR"]["TARBZ"]["LISTEXTRACTOR"] = __fileextractor_nix_tar + toolset["EXTRACTOR"]["TARBZ"]["EXTRACTFLAGS"] = "xfj" + toolset["EXTRACTOR"]["TARBZ"]["LISTFLAGS"] = "tvfj" + toolset["EXTRACTOR"]["TARBZ"]["EXTRACTSUFFIX"] = "-C ${UNPACK['EXTRACTDIR']}" + + if env.WhereIs("bzip2") : + toolset["EXTRACTOR"]["BZIP"]["RUN"] = "bzip2" + toolset["EXTRACTOR"]["BZIP"]["EXTRACTFLAGS"] = "-df" + + if env.WhereIs("gzip") : + toolset["EXTRACTOR"]["GZIP"]["RUN"] = "gzip" + toolset["EXTRACTOR"]["GZIP"]["LISTEXTRACTOR"] = __fileextractor_nix_gzip + toolset["EXTRACTOR"]["GZIP"]["LISTFLAGS"] = "-l" + toolset["EXTRACTOR"]["GZIP"]["EXTRACTFLAGS"] = "-df" + + else : + raise SCons.Errors.StopError("Unpack tool detection on this platform [%s] unkown" % (env["PLATFORM"])) + + # the target_factory must be a "Entry", because the target list can be files and dirs, so we can not specified the targetfactory explicite + env.Replace(UNPACK = toolset) + env.AddMethod(__unpack_all, 'UnpackAll') + +# env["BUILDERS"]["UnpackAll"] = SCons.Builder.Builder( action = __action, emitter = __emitter, target_factory = SCons.Node.FS.Entry, source_factory = SCons.Node.FS.File, single_source = True, PRINT_CMD_LINE_FUNC = __message ) + + +# existing function of the builder +# @param env environment object +# @return true +def exists(env) : + return 1 + +Import('env') +generate(env) diff --git a/examples/OICMiddle/Client.cpp b/examples/OICMiddle/Client.cpp index 8d6e7d1..b753b94 100644 --- a/examples/OICMiddle/Client.cpp +++ b/examples/OICMiddle/Client.cpp @@ -1,6 +1,6 @@ //****************************************************************** // -// Copyright 2014 Intel Corporation. +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // @@ -19,6 +19,7 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include +#include #include "WrapResource.h" #include "Client.h" @@ -38,7 +39,7 @@ void MiddleClient::findResources() { m_resourceMap.clear(); - OC::OCPlatform::findResource("", OC_WELL_KNOWN_QUERY, m_findCB); + OC::OCPlatform::findResource("", OC_WELL_KNOWN_QUERY, OC_ALL, m_findCB); } void MiddleClient::foundOCResource(shared_ptr resource) @@ -66,14 +67,21 @@ void MiddleClient::foundOCResource(shared_ptr resource) */ string MiddleClient::formatResourceID(std::shared_ptr resource) { - string host = resource->host(); - if (host.compare(0, 7, "coap://") == 0) - host = host.erase(0, 7); - return host + resource->uri(); + if(!resource) + { + throw invalid_argument("Invalid resource object in formatResourceID"); + } + + return resource->sid() + resource->uri(); } void MiddleClient::addResource(WrapResource *wres) { + if(!wres) + { + throw invalid_argument("Invalid WrapResource object in addResource"); + } + string resourceID = wres->getResourceID(); try { m_resourceMap[resourceID]; diff --git a/examples/OICMiddle/LineInput.cpp b/examples/OICMiddle/LineInput.cpp index 52a8528..685d33a 100644 --- a/examples/OICMiddle/LineInput.cpp +++ b/examples/OICMiddle/LineInput.cpp @@ -52,9 +52,8 @@ int LineInput::run() while (true) { fputs(">", stdout); len = 0; - getline(&line, &len, stdin); - int n = strlen(line); - if (!n) + const ssize_t n = getline(&line, &len, stdin); + if (n <= 0) continue; if (m_observer) { m_observer->cancelObserve(); @@ -382,7 +381,7 @@ ParseState LineInput::putCharInElem(char c, char *& e, ParseState newState) LineResult LineInput::parseLine(string lineIn, elements_t& elems) { const char *d; - char c, *e, delim; + char c, *e, delim = 0; bool isSep1, isSep2; size_t len = lineIn.size(); ParseState state = PS_Between; diff --git a/examples/OICMiddle/SConscript b/examples/OICMiddle/SConscript new file mode 100644 index 0000000..6748493 --- /dev/null +++ b/examples/OICMiddle/SConscript @@ -0,0 +1,76 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +## +# Examples build script +## +Import('env') +# Add third party libraries +lib_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env') + +examples_env = lib_env.Clone() + +###################################################################### +# Build flags +###################################################################### +examples_env.AppendUnique(CPPPATH = [ + '../../resource/include/', + '../../resource/csdk/stack/include', + '../../resource/csdk/ocrandom/include', + '../../resource/csdk/logger/include', + '../../resource/oc_logger/include' + ]) + +target_os = env.get('TARGET_OS') +if target_os not in ['windows', 'winrt']: + examples_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread']) + + # Note: 'pthread' is in libc for android. On other platform, if use + # new gcc(>4.9?) it isn't required, otherwise, it's required + if target_os != 'android': + examples_env.AppendUnique(LIBS = ['-lpthread']) + +examples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +examples_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', + 'coap', 'rt']) +if env.get('SECURED') == '1': + examples_env.AppendUnique(LIBS = ['tinydtls']) + +if target_os == 'android': + examples_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions']) + examples_env.AppendUnique(LIBS = ['gnustl_static']) + + if not env.get('RELEASE'): + examples_env.AppendUnique(LIBS = ['log']) + +if target_os in ['darwin', 'ios']: + examples_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE']) + +###################################################################### +# Source files and Targets +###################################################################### +OICMiddle = examples_env.Program('OICMiddle', ['OICMiddle.cpp', 'Client.cpp', 'LineInput.cpp', 'RestInput.cpp', 'Server.cpp', 'WrapResource.cpp']) + +Alias("examples", [OICMiddle]) +env.AppendTarget('examples') + + + diff --git a/examples/OICMiddle/Server.cpp b/examples/OICMiddle/Server.cpp index b55e715..b729a48 100644 --- a/examples/OICMiddle/Server.cpp +++ b/examples/OICMiddle/Server.cpp @@ -45,10 +45,6 @@ OCEntityHandlerResult MiddleServer::entityHandler(const std::shared_ptrgetRequestHandlerFlag(); bool responseNeeded = false; - if (requestFlag && RequestHandlerFlag::InitFlag) { - return OC_EH_OK; - } - if (requestFlag && RequestHandlerFlag::RequestFlag) { if (requestType == "PUT") { responseNeeded = true; diff --git a/examples/OICMiddle/makefile b/examples/OICMiddle/makefile deleted file mode 100644 index 5279218..0000000 --- a/examples/OICMiddle/makefile +++ /dev/null @@ -1,87 +0,0 @@ -#//****************************************************************** -#// -#// Copyright 2014 Intel Corporation. -#// -#//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#// -#// 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. -#// -#//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -# override with `make BUILD=release` -# default to release build -BUILD := debug -PLATFORM := linux -CXX := g++ -#CXX := clang -OUT_DIR := $(BUILD) -OIC := ../.. -OIC_RES := $(OIC)/resource -OIC_LIB := $(OIC)/out/linux/x86_64/release -OBJS := OICMiddle.o \ - Client.o \ - Server.o \ - WrapResource.o \ - LineInput.o \ - RestInput.o - -CXX_FLAGS.debug := -O0 -g3 -std=c++0x -Wall -pthread - -CXX_FLAGS.release := -O3 -std=c++0x -Wall -pthread - -CXX_INC := -I$(OIC_RES)/include/ -CXX_INC += -I$(OIC_RES)/oc_logger/include -CXX_INC += -I$(OIC_RES)/csdk/stack/include -CXX_INC += -I$(OIC_RES)/csdk/ocsocket/include -CXX_INC += -I$(OIC_RES)/csdk/ocrandom/include -CXX_INC += -I$(OIC_RES)/csdk/logger/include -CXX_INC += -I$(OIC_RES)/csdk/libcoap -CXX_INC += -I$(OIC_RES)/../extlibs/cereal/include - -CXX_LIBS := $(OIC_LIB)/liboc.so -CXX_LIBS += $(OIC_LIB)/liboctbstack.so -CXX_LIBS += $(OIC_LIB)/liboc_logger.so -CXX_LIBS += $(OIC_LIB)/liboc_logger_core.so -CXX_LIBS += $(OIC_LIB)/libcoap.so - -all: prep_dirs OICMiddle - -prep_dirs: - -mkdir -p $(OUT_DIR) - -OICMiddle: $(OBJS) - $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(OUT_DIR)/$@ $(OBJS) $(CXX_LIBS) - -OICMiddle.o: OICMiddle.cpp OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) OICMiddle.cpp $(CXX_INC) - -Client.o: Client.cpp Client.h OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) Client.cpp $(CXX_INC) - -Server.o: Server.cpp Server.h OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) Server.cpp $(CXX_INC) - -WrapResource.o: WrapResource.cpp WrapResource.h OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) WrapResource.cpp $(CXX_INC) - -LineInput.o: LineInput.cpp LineInput.h OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) LineInput.cpp $(CXX_INC) - -RestInput.o: RestInput.cpp RestInput.h OICMiddle.h - $(CXX) -c $(CXX_FLAGS.$(BUILD)) RestInput.cpp $(CXX_INC) - -clean: - rm $(OBJS) - rm -rf debug - rm -rf release - diff --git a/examples/OICSensorBoard/SConstruct b/examples/OICSensorBoard/SConstruct index e9acb2d..2a468aa 100644 --- a/examples/OICSensorBoard/SConstruct +++ b/examples/OICSensorBoard/SConstruct @@ -1,9 +1,29 @@ -#This script builds edisonclient for Ubuntu and edisonserver for Yocto. +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#This script builds edisonclient for Ubuntu and edisonserver for Yocto. #Client build for Ubuntu #Set IOTIVITY_ROOT to the root of oic-resource on Ubuntu. -IOTIVITY_ROOT = '' -#Set IOTIVITY_LIBS_PATH to path on Ubuntu that contains liboc.so, liboctbstack.so, liboc_logger.so and libcoap.so. +IOTIVITY_ROOT = '' +#Set IOTIVITY_LIBS_PATH to path on Ubuntu that contains liboc.so, liboctbstack.so, liboc_logger.so and libcoap.so. IOTIVITY_LIBS_PATH = '' env = DefaultEnvironment() @@ -13,9 +33,8 @@ env.AppendUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'coap']) envClient = env.Clone() envClient.AppendUnique(CPPPATH = [ - IOTIVITY_ROOT + '/resource/include', + IOTIVITY_ROOT + '/resource/include', IOTIVITY_ROOT + '/resource/csdk/stack/include', - IOTIVITY_ROOT + '/resource/csdk/ocsocket/include', IOTIVITY_ROOT + '/resource/oc_logger/include', ]) envClient.AppendUnique(LIBPATH = [IOTIVITY_LIBS_PATH]) @@ -58,8 +77,8 @@ try: envServer.AppendUnique(CPPPATH = [ sdk_root + '/usr/include/iotivity/', sdk_root + '/usr/include/iotivity/stack/', - sdk_root + '/usr/include/iotivity/ocsocket/', sdk_root + '/usr/include/iotivity/oc_logger/', - ]) + ]) except: print "ERROR configuring Yocto cross-toolchain environment. This is required for building the server" + diff --git a/extlibs/android/gradle/SConscript b/extlibs/android/gradle/SConscript new file mode 100644 index 0000000..9cece4b --- /dev/null +++ b/extlibs/android/gradle/SConscript @@ -0,0 +1,29 @@ +import os, sys, platform, subprocess + +Import('env') + +env = env.Clone() +ndk_env = env.Clone() +SConscript('../../../build_common/external_libs.scons') + +target_os = env.get('TARGET_OS') +host_os = sys.platform +print host_os +SConscript('../../../build_common/external_libs.scons') +###################################################################### +# Build flags +###################################################################### +src_dir = env.get('SRC_DIR') + +path = os.path.join(src_dir, 'extlibs', 'android', 'gradle', 'gradle-2.2.1') + +# check 'gradle' library, if it doesn't exits, ask user to download it +if not os.path.exists(path): + gradle_zip = env.Download('gradle2.2.1.zip', 'https://services.gradle.org/distributions/gradle-2.2.1-all.zip') + gradle_dir = env.UnpackAll('gradle-2.2.1', gradle_zip) + print ''' +*********************************************************************** +* Downloading gradle: * +******************************************************************************* +''' + diff --git a/extlibs/android/ndk/SConscript b/extlibs/android/ndk/SConscript new file mode 100644 index 0000000..cc36c4e --- /dev/null +++ b/extlibs/android/ndk/SConscript @@ -0,0 +1,37 @@ +import os, string, sys, subprocess, struct + +Import('env') + +env = env.Clone() +ndk_env = env.Clone() + +target_os = env.get('TARGET_OS') +target_arch = env.get('TARGET_ARCH') + +host_os = sys.platform + +###################################################################### +# Build flags +###################################################################### +src_dir = env.get('SRC_DIR') +path = os.path.join(src_dir, 'extlibs', 'android', 'ndk', 'android-ndk-r10d') + +# check 'ndk' library, if it doesn't exits, ask user to download it +if not os.path.exists(path): + ndk_env = Environment(ENV = os.environ) + if host_os == 'linux2' : + archType = 8 * struct.calcsize("P") + if archType == 64: + env.Download('android-ndk-r10d.bin', 'http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin') + else: + env.Download('android-ndk-r10d.bin', 'http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86.bin') + + os.system("chmod a+x android-ndk-r10d.bin") + os.system("./android-ndk-r10d.bin") + else: + if target_arch in ['x86_64']: + env.Download('android-ndk-r10d', 'http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86_64.exe') + if target_arch in ['x86']: + env.Download('android-ndk-r10d', 'http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86.exe') + + diff --git a/extlibs/android/sdk/SConscript b/extlibs/android/sdk/SConscript new file mode 100644 index 0000000..aa268e6 --- /dev/null +++ b/extlibs/android/sdk/SConscript @@ -0,0 +1,58 @@ +## +# Script to install (if they do not exist) the Android SDK library (ie. Android JDK) +## + +import os, subprocess, struct +import urllib2, urlparse +import SCons.Errors +import shutil + +Import('env') + +target_os = env.get('TARGET_OS') +src_dir = env.get('SRC_DIR') + +SConscript(src_dir + '/build_common/tools/UnpackAll.py') +SConscript(src_dir + '/build_common/external_libs.scons') + +# Download +if target_os == 'android': + android_home = env.get('ANDROID_HOME') + if not android_home: + print 'Creating ANDROID_HOME for Android SDK' + + androidlib_dir = src_dir + '/extlibs/android/sdk/android-sdk_r24.2' + + if not os.path.exists(androidlib_dir): + from sys import platform as _platform + if _platform == "linux" or _platform == "linux2": + androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-linux.tgz' + androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-linux.tgz' + elif _platform == "darwin": + androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-macosx.zip' + androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-macosx.zip' + elif _platform == "win32": + androidlib_zip_file = src_dir + '/extlibs/android/android-sdk_r24.2-windows.zip' + androidlib_url = 'http://dl.google.com/android/android-sdk_r24.2-windows.zip' + + # If the zip file is not already present, download it + if not os.path.exists(androidlib_zip_file): + androidlib_zip = env.Download(androidlib_zip_file, androidlib_url) + else: + androidlib_zip = androidlib_zip_file + + # Unzip the lib + print 'Unzipping android lib...' + env.UnpackAll(androidlib_dir, androidlib_zip) + print 'Unzipping android lib complete' + + # Remove downloaded file +# os.remove(androidlib_zip_file) + else: + androidlib_dir = env.get('ANDROID_HOME') + +# Set the ANDROID_HOME +env.Replace(ANDROID_HOME = androidlib_dir) +print 'ANDROID_HOME = ' + env.get('ANDROID_HOME') + + diff --git a/extlibs/arduino/SConscript b/extlibs/arduino/SConscript new file mode 100644 index 0000000..268c061 --- /dev/null +++ b/extlibs/arduino/SConscript @@ -0,0 +1,154 @@ +## +# Script to install (if they do not exist) the Arduino library, Time library, +# Red Bear Library, and Nordic library. +## + +import os, subprocess, struct +import urllib2, urlparse +import SCons.Errors +import shutil + +Import('env') + +target_os = env.get('TARGET_OS') +src_dir = env.get('SRC_DIR') + +SConscript(src_dir + '/build_common/tools/UnpackAll.py') +SConscript(src_dir + '/build_common/external_libs.scons') + +# Download +if target_os == 'arduino': + arduino_home = env.get('ARDUINO_HOME') + if not arduino_home: + print 'Creating ARDUINO_HOME for Arduino lib' + print ''' + ******************************************************************************* + * Arduino root directory isn't set, you can set enviornment variable * + * ARDUINO_HOME or add it in command line as follows (Only set if your * + * version has fixes applied as depicted below. Press ctrl+c now if you * + * wish to manually set ARDUINO_HOME.): * + * # scons ARDUINO_HOME= ... * + ******************************************************************************* + ''' + arduinolib_dir = src_dir + '/extlibs/arduino/arduino-1.5.8' + + if not os.path.exists(arduinolib_dir): + from sys import platform as _platform + if _platform == "linux" or _platform == "linux2": + archType = 8 * struct.calcsize("P") + print 'On %s-bit machine.' % (archType) + if archType == 32: + arduinolib_zip_file = src_dir + '/extlibs/arduino/arduino-1.5.8-linux32.tgz' + arduinolib_url = 'http://arduino.cc/download.php?f=/arduino-1.5.8-linux32.tgz' + else: + arduinolib_zip_file = src_dir + '/extlibs/arduino/arduino-1.5.8-linux64.tgz' + arduinolib_url = 'http://arduino.cc/download.php?f=/arduino-1.5.8-linux64.tgz' + elif _platform == "darwin": + arduinolib_zip_file = src_dir + '/extlibs/arduino/arduino-1.5.8-macosx.zip' + arduinolib_url = 'http://arduino.cc/download.php?f=/arduino-1.5.8-macosx.zip' + elif _platform == "win32": + arduinolib_zip_file = src_dir + '/extlibs/arduino/arduino-1.5.8-windows.zip' + arduinolib_url = src_dir + 'http://arduino.cc/download.php?f=/arduino-1.5.8-windows.zip' + + # If the zip file is not already present, download it + if not os.path.exists(arduinolib_zip_file): + arduinolib_zip = env.Download(arduinolib_zip_file, arduinolib_url) + else: + arduinolib_zip = arduinolib_zip_file + + # Unzip the lib + print 'Unzipping arduino lib...' + env.UnpackAll(arduinolib_dir, arduinolib_zip) + print 'Unzipping arduino lib complete' + + # Remove downloaded file + os.remove(arduinolib_zip_file) + else: + arduinolib_dir = env.get('ARDUINO_HOME') + + timelib_dir = arduinolib_dir + '/libraries/Time' + + if not os.path.exists(timelib_dir): + timelib_zip_file = src_dir + '/extlibs/arduino/Time.zip' + timelib_url = 'http://playground.arduino.cc/uploads/Code/Time.zip' + # Install Arduino Time library + # If the zip file is not already present, download it + os.mkdir(timelib_dir) + os.chdir(timelib_dir) + if not os.path.exists(timelib_zip_file): + timelib_zip = env.Download(timelib_zip_file, timelib_url) + else: + timelib_zip = timelib_zip_file + + # Unzip the lib + print 'Unzipping Arduino Time lib...' + env.UnpackAll(timelib_dir + '/Time', timelib_zip) + + # Apply patches to ARDUINO_HOME directory. + os.chdir(arduinolib_dir) + print 'Patching Arduino libraries...' + os.system("find ./libraries/Time/Time/DateStrings.cpp -type f -exec dos2unix {} \;") + os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch --directory=" + arduinolib_dir) + + # Remove downloaded file + os.remove(timelib_zip_file) + + redbearlib_dir = arduinolib_dir + '/libraries/RBL_nRF8001' + + if not os.path.exists(redbearlib_dir): + redbearlib_zip_file = src_dir + '/extlibs/arduino/25643e7b1b7da3740406325a471e3faa4b948747.zip' + redbearlib_url = 'https://github.com/RedBearLab/nRF8001/archive/25643e7b1b7da3740406325a471e3faa4b948747.zip' + if not os.path.exists(redbearlib_zip_file): + redbearlib_zip = env.Download(redbearlib_zip_file, redbearlib_url) + else: + redbearlib_zip = redbearlib_zip_file + + # Unzip the lib + print 'Unzipping Red Bear lib...' + os.chdir(arduinolib_dir + '/libraries') + env.UnpackAll(redbearlib_dir, redbearlib_zip) + + # Because the way Red Bear lib is distributed... All Red Bear source files must be moved up a few directories. + shutil.move('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747/Arduino/libraries/RBL_nRF8001/', '.') + shutil.rmtree('nRF8001-25643e7b1b7da3740406325a471e3faa4b948747') + + # Apply Red Bear patches + print 'Patching Red Bear library...' + os.chdir(arduinolib_dir + '/libraries/RBL_nRF8001/') + os.system("find . -type f -exec dos2unix {} \;") + os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch") + + # Remove downloaded file + os.remove(redbearlib_zip_file) + + nordiclib_dir = arduinolib_dir + '/libraries/BLE' + + if not os.path.exists(nordiclib_dir): + nordiclib_zip_file = src_dir + '/extlibs/arduino/ble-sdk-arduino-0.9.5.beta.zip' + nordiclib_url = 'https://github.com/NordicSemiconductor/ble-sdk-arduino/archive/0.9.5.beta.zip' + if not os.path.exists(nordiclib_zip_file): + nordiclib_zip = env.Download(nordiclib_zip_file, nordiclib_url) + else: + nordiclib_zip = nordiclib_zip_file + + # Unzip the lib + print 'Unzipping Nordic lib...' + os.chdir(arduinolib_dir + '/libraries') + env.UnpackAll(nordiclib_dir, nordiclib_zip) + + # Because the way Nordic lib is distributed... All Nordic source files must be moved up a few directories. + shutil.move('ble-sdk-arduino-0.9.5.beta/libraries/BLE/', '.') + shutil.rmtree('ble-sdk-arduino-0.9.5.beta') + + # Apply Nordic lib patches + print 'Patching Nordic library...' + os.chdir(arduinolib_dir + '/libraries/BLE/') + os.system("find . -type f -exec dos2unix {} \;") + os.system("patch -p1 < " + src_dir + "/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch") + + # Remove downloaded file + os.remove(nordiclib_zip_file) + +# Set the ARDUINO_HOME +env.Replace(ARDUINO_HOME = arduinolib_dir) +print 'ARDUINO_HOME = ' + env.get('ARDUINO_HOME') diff --git a/extlibs/boost/SConscript b/extlibs/boost/SConscript new file mode 100644 index 0000000..0fe0662 --- /dev/null +++ b/extlibs/boost/SConscript @@ -0,0 +1,56 @@ +import os, string, sys, subprocess + +Import('env') + +boost_env = env.Clone() + +modules = ['thread','program_options'] + +target_os = env.get('TARGET_OS') +target_arch = env.get('TARGET_ARCH') + +if 'linux' == target_os : + # Check for Boost libraries in /usr/boost + print 'TODO: Perform platform check for linux' + raise SCons.Errors.EnvironmentError('Unsupported platform') + +if 'android' == target_os : + env.Tool('URLDownload', toolpath=['../../tools/scons']) + env.Tool('UnpackAll', toolpath=['../../tools/scons']) + env.Tool('BoostBootstrap', toolpath=['../../tools/scons']) + env.Tool('BoostBuild', toolpath=['../../tools/scons']) + + boost_version = '1.58.0' + boost_base_name = 'boost_'+string.replace(boost_version,'.','_') + boost_arch_name = boost_base_name+'.zip' + boost_url = 'http://downloads.sourceforge.net/project/boost/boost/'+boost_version+'/'+boost_arch_name+'?r=&ts=1421801329&use_mirror=iweb' + + host_os = sys.platform + + if host_os == 'linux2' : + boost_bootstrap = boost_base_name+os.sep+'bootstrap.sh' + boost_b2_name = boost_base_name+os.sep+'b2' + else : + msg="Host platform (%s) is currently not supported for boost builds" % host_os + raise SCons.Errors.EnvironmentError(msg) + + boost_zip = env.URLDownload(boost_arch_name, boost_url) + boost_dir = env.UnpackAll(boost_bootstrap, boost_zip) + boost_b2 = env.BoostBootstrap(boost_b2_name, boost_dir) + + dep_sys_root = env['DEP_SYS_ROOT'] + dep_src_dir = dep_sys_root + os.sep + 'include' + dep_lib_dir = dep_sys_root + os.sep + 'lib' + + boost_targets = [ + os.path.join(dep_src_dir, 'boost', 'config.hpp'), + os.path.join(dep_src_dir, 'boost', 'variant.hpp'), + os.path.join(dep_src_dir, 'boost', 'program_options.hpp'), + os.path.join(dep_src_dir, 'libboost_thread.a'), + os.path.join(dep_src_dir, 'libboost_atomic.a'), + os.path.join(dep_src_dir, 'libboost_system.a'), + os.path.join(dep_src_dir, 'libboost_program_options.a') + ] + + boost_build = env.BoostBuild(boost_targets, boost_b2, PREFIX=dep_sys_root, MODULES=modules) + diff --git a/extlibs/cereal/SConscript b/extlibs/cereal/SConscript new file mode 100644 index 0000000..946a483 --- /dev/null +++ b/extlibs/cereal/SConscript @@ -0,0 +1,41 @@ +###################################################################### +# Cereal library build script +# +# Only 'hpp' is used by Iotivity, it's unnecessary to build it +###################################################################### +import os + +Import('env') + +src_dir = env.get('SRC_DIR') + +# In the pass, cereal library is in extlibs/cereal, according to external +# library management rule, cereal should be put in extlibs/cereal/cereal. +# jenkins of gerrit server, still follow the old, to avoid jenkins fail +# both places are handled. +old = os.path.join(src_dir, 'extlibs', 'cereal', 'include') +cur = os.path.join(src_dir, 'extlibs', 'cereal', 'cereal', 'include') + +# check 'cereal' library, if it doesn't exits, ask user to download it +if not os.path.exists(old) and not os.path.exists(cur): + cereal_env = Environment(ENV = os.environ) + c = cereal_env.Action(['git clone https://github.com/USCiLab/cereal.git cereal', + 'cd cereal && git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 && git apply ../../../resource/patches/cereal_gcc46.patch', + ]) + + print 'Downloading cereal library ...' + if cereal_env.Execute(c): + print ''' +*********************************** Error: ************************************ +* Please download cereal and apply the patch as following: * +* $ git clone https://github.com/USCiLab/cereal.git extlibs/cereal/cereal * +* $ cd extlibs/cereal/cereal * +* $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 * +* $ git apply ../../../resource/patches/cereal_gcc46.patch * +******************************************************************************* +''' + Exit(1) + else: + print 'Download cereal library complete' + +env.AppendUnique(CPPPATH = [old, cur]) diff --git a/extlibs/expat/SConscript b/extlibs/expat/SConscript new file mode 100644 index 0000000..e6b929c --- /dev/null +++ b/extlibs/expat/SConscript @@ -0,0 +1,55 @@ +## +# build script for expat library +# +# Note: +# 1) Only a part of source code are required to be built. +# 2) Download code from https://android.googlesource.com/platform/external/expat.git +# otherwise, after code is downloaded, it's required to execute './configure' to +# generate expat_config.h +# +## + +import os + +Import('env') + +expat_env = env.Clone() +SConscript(env.get('SRC_DIR') + '/build_common/tools/UnpackAll.py') +###################################################################### +# Build flags +###################################################################### +src_dir = 'expat-2.1.0/' + +if not os.path.exists(src_dir): + # Prepare source code (download / unpack / run configure) + env.Download('expat.tar.gz', 'http://sourceforge.net/projects/expat/files/expat/2.1.0/expat-2.1.0.tar.gz/download') + expat_src = env.UnpackAll(src_dir + '/Makefile', 'expat.tar.gz') + env.Configure(src_dir, './configure') + +expat_env.AppendUnique(CPPPATH = [src_dir, src_dir + 'lib', src_dir + 'vms']) + +target_os = env.get('TARGET_OS') +if target_os not in ['windows', 'winrt']: + expat_env.AppendUnique(CCFLAGS = ['-g', '-O2', '-Wall', + '-Wmissing-prototypes', '-Wstrict-prototypes', + '-fexceptions', '-fno-common']) + expat_env.AppendUnique(CPPDEFINES = ['HAVE_EXPAT_CONFIG_H']) + +###################################################################### +# Source files and Targets +###################################################################### +expat_src = [ + src_dir + 'lib/xmlparse.c', + src_dir + 'lib/xmltok.c', + src_dir + 'lib/xmlrole.c', + ] + +libexpat = expat_env.SharedLibrary('expat', expat_src) + +###################################################################### +# Install header files and library binary +###################################################################### +h = expat_env.InstallHeadFile([src_dir + 'lib/expat.h', src_dir + 'lib/expat_external.h']) +lib = expat_env.InstallLib(libexpat) + +expat_env.AppendTarget('libexpat', [h, lib]) diff --git a/extlibs/gtest/SConscript b/extlibs/gtest/SConscript new file mode 100644 index 0000000..396e4f3 --- /dev/null +++ b/extlibs/gtest/SConscript @@ -0,0 +1,80 @@ +## +# 'googletest' script to check if Google Unit Test library is installed. If not, +# get it and install it +# +## + +import os + +Import('env') + +target_os = env.get('TARGET_OS') +src_dir = env.get('SRC_DIR') + +targets_need_gtest = ['darwin','linux'] +gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0' +gtest_zip_file = src_dir + '/extlibs/gtest/gtest-1.7.0.zip' +gtest_url = 'https://googletest.googlecode.com/files/gtest-1.7.0.zip' + +if target_os in targets_need_gtest: + print '*** Checking for installation of google unit test 1.7.0 ***' + + if not os.path.exists(gtest_dir): + # If the gtest zip file is not already present, download it + if not os.path.exists(gtest_zip_file): + gtest_zip = env.Download(gtest_zip_file, gtest_url) + else: + gtest_zip = gtest_zip_file + + # Unzip gtest + print 'Unzipping google unit test' + env.UnpackAll(gtest_dir, gtest_zip) + + +if target_os == 'darwin': + if os.path.exists(gtest_dir): + # Build gtest and store it at a temporary directory + gtest_lib_dir = gtest_dir + '/lib' + gtest_dotlib_dir = gtest_lib_dir + '/.libs' + + if not os.path.exists(gtest_lib_dir): + print 'Create a directory' + os.mkdir(gtest_lib_dir) + + print 'Change to a directory' + os.chdir(gtest_lib_dir) + + print 'Invoke cmake command to generate appropriate make files' + env.Configure(gtest_lib_dir, 'cmake -G"Unix Makefiles" ..') + + # Run make on gtest + print 'Making google unit test' + env.Configure(gtest_lib_dir, 'make') + + print 'Create a directory' + os.mkdir(gtest_dotlib_dir) + + print 'Change to a directory' + os.chdir(gtest_dotlib_dir) + + print 'Create hard links pointing to gtest libraries' + os.link('../' + 'libgtest.a', 'libgtest.a') + os.link('../' + 'libgtest_main.a', 'libgtest_main.a') + print 'Create hard links pointing to gtest libraries - DONE' + + +elif target_os == 'linux': + if os.path.exists(gtest_dir): + if not os.path.exists(gtest_dir + "/lib"): + # Run configure on gtest + print 'Configuring google unit test' + if env.get('CROSS_COMPILE'): + env.Configure(gtest_dir, './configure --host=' + env['CROSS_COMPILE']) + else: + env.Configure(gtest_dir, './configure') + + # Run make on gtest + print 'Making google unit test' + env.Configure(gtest_dir, 'make') + + diff --git a/extlibs/hippomocks.scons b/extlibs/hippomocks.scons new file mode 100644 index 0000000..6d5b5a4 --- /dev/null +++ b/extlibs/hippomocks.scons @@ -0,0 +1,58 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +## +# 'hippomocks' script to check if Hippo Mocks Unit Test library is installed. +# If not, get it and install it +# +## + +import os, sys + +Import('env') + +target_os = env.get('TARGET_OS') +src_dir = env.get('SRC_DIR') + +# Only verify/install on linux +if target_os == 'linux': + print '*** Checking for installation of hippomocks ***' + + hippomocks_sha = '2f40aa11e31499432283b67f9d3449a3cd7b9c4d' + hippomocks_dir_src = src_dir + '/extlibs/hippomocks-' + hippomocks_sha + hippomocks_dir_dest = src_dir + '/extlibs/hippomocks-master' + hippomocks_zip_file = src_dir + '/extlibs/hippomocks-' + hippomocks_sha + '.zip' + hippomocks_url = 'https://github.com/dascandy/hippomocks/archive/' + hippomocks_sha + '.zip' + + if not os.path.exists(hippomocks_dir_dest): + # If the hippomocks zip file is not already present, download it + if not os.path.exists(hippomocks_zip_file): + hippomocks_zip = env.Download(hippomocks_zip_file, hippomocks_url) + else: + hippomocks_zip = hippomocks_zip_file + + # Unzip hippomocks + print 'Unzipping hippomocks' + env.UnpackAll(hippomocks_dir_src, hippomocks_zip) + print 'Renaming hippomocks directory' + os.rename(hippomocks_dir_src, hippomocks_dir_dest) + + + diff --git a/extlibs/rapidxml/rapidxml.hpp b/extlibs/rapidxml/rapidxml.hpp new file mode 100644 index 0000000..0845cfb --- /dev/null +++ b/extlibs/rapidxml/rapidxml.hpp @@ -0,0 +1,2638 @@ +#ifndef RAPIDXML_HPP_INCLUDED +#define RAPIDXML_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation + +// If standard library is disabled, user must provide implementations of required functions and typedefs +#if !defined(RAPIDXML_NO_STDLIB) +#include // For std::size_t +#include // For assert +#include // For placement new +#endif + +// On MSVC, disable "conditional expression is constant" warning (level 4). +// This warning is almost impossible to avoid with certain types of templated code +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) // Conditional expression is constant +#endif + +/////////////////////////////////////////////////////////////////////////// +// RAPIDXML_PARSE_ERROR + +#if defined(RAPIDXML_NO_EXCEPTIONS) + +#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); } + +namespace rapidxml +{ + //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, + //! this function is called to notify user about the error. + //! It must be defined by the user. + //!

+ //! This function cannot return. If it does, the results are undefined. + //!

+ //! A very simple definition might look like that: + //!
+    //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+    //! {
+    //!     std::cout << "Parse error: " << what << "\n";
+    //!     std::abort();
+    //! }
+    //! 
+ //! \param what Human readable description of the error. + //! \param where Pointer to character data where error was detected. + void parse_error_handler(const char *what, void *where); +} + +#else + +#include // For std::exception + +#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where) + +namespace rapidxml +{ + + //! Parse error exception. + //! This exception is thrown by the parser when an error occurs. + //! Use what() function to get human-readable error message. + //! Use where() function to get a pointer to position within source text where error was detected. + //!

+ //! If throwing exceptions by the parser is undesirable, + //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included. + //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception. + //! This function must be defined by the user. + //!

+ //! This class derives from std::exception class. + class parse_error: public std::exception + { + + public: + + //! Constructs parse error + parse_error(const char *what, void *where) + : m_what(what) + , m_where(where) + { + } + + //! Gets human readable description of error. + //! \return Pointer to null terminated description of the error. + virtual const char *what() const throw() + { + return m_what; + } + + //! Gets pointer to character data where error happened. + //! Ch should be the same as char type of xml_document that produced the error. + //! \return Pointer to location within the parsed string where error occured. + template + Ch *where() const + { + return reinterpret_cast(m_where); + } + + private: + + const char *m_what; + void *m_where; + + }; +} + +#endif + +/////////////////////////////////////////////////////////////////////////// +// Pool sizes + +#ifndef RAPIDXML_STATIC_POOL_SIZE +// Size of static memory block of memory_pool. +// Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. +// No dynamic memory allocations are performed by memory_pool until static memory is exhausted. +#define RAPIDXML_STATIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_DYNAMIC_POOL_SIZE +// Size of dynamic memory block of memory_pool. +// Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value. +// After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool. +#define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024) +#endif + +#ifndef RAPIDXML_ALIGNMENT +// Memory allocation alignment. +// Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer. +// All memory allocations for nodes, attributes and strings will be aligned to this value. +// This must be a power of 2 and at least 1, otherwise memory_pool will not work. +#define RAPIDXML_ALIGNMENT sizeof(void *) +#endif + +namespace rapidxml +{ + // Forward declarations + template class xml_node; + template class xml_attribute; + template class xml_document; + + //! Enumeration listing all node types produced by the parser. + //! Use xml_node::type() function to query node type. + enum node_type + { + node_document, //!< A document node. Name and value are empty. + node_element, //!< An element node. Name contains element name. Value contains text of first data node. + node_data, //!< A data node. Name is empty. Value contains data text. + node_cdata, //!< A CDATA node. Name is empty. Value contains data text. + node_comment, //!< A comment node. Name is empty. Value contains comment text. + node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes. + node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text. + node_pi //!< A PI node. Name contains target. Value contains instructions. + }; + + /////////////////////////////////////////////////////////////////////// + // Parsing flags + + //! Parse flag instructing the parser to not create data nodes. + //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_data_nodes = 0x1; + + //! Parse flag instructing the parser to not use text of first data node as a value of parent element. + //! Can be combined with other flags by use of | operator. + //! Note that child data nodes of element node take precendence over its value when printing. + //! That is, if element has one or more child data nodes and a value, the value will be ignored. + //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements. + //!

+ //! See xml_document::parse() function. + const int parse_no_element_values = 0x2; + + //! Parse flag instructing the parser to not place zero terminators after strings in the source text. + //! By default zero terminators are placed, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_string_terminators = 0x4; + + //! Parse flag instructing the parser to not translate entities in the source text. + //! By default entities are translated, modifying source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_entity_translation = 0x8; + + //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters. + //! By default, UTF-8 handling is enabled. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_no_utf8 = 0x10; + + //! Parse flag instructing the parser to create XML declaration node. + //! By default, declaration node is not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_declaration_node = 0x20; + + //! Parse flag instructing the parser to create comments nodes. + //! By default, comment nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_comment_nodes = 0x40; + + //! Parse flag instructing the parser to create DOCTYPE node. + //! By default, doctype node is not created. + //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_doctype_node = 0x80; + + //! Parse flag instructing the parser to create PI nodes. + //! By default, PI nodes are not created. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_pi_nodes = 0x100; + + //! Parse flag instructing the parser to validate closing tag names. + //! If not set, name inside closing tag is irrelevant to the parser. + //! By default, closing tags are not validated. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_validate_closing_tags = 0x200; + + //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes. + //! By default, whitespace is not trimmed. + //! This flag does not cause the parser to modify source text. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_trim_whitespace = 0x400; + + //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character. + //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag. + //! By default, whitespace is not normalized. + //! If this flag is specified, source text will be modified. + //! Can be combined with other flags by use of | operator. + //!

+ //! See xml_document::parse() function. + const int parse_normalize_whitespace = 0x800; + + // Compound flags + + //! Parse flags which represent default behaviour of the parser. + //! This is always equal to 0, so that all other flags can be simply ored together. + //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values. + //! This also means that meaning of each flag is a negation of the default setting. + //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is enabled by default, + //! and using the flag will disable it. + //!

+ //! See xml_document::parse() function. + const int parse_default = 0; + + //! A combination of parse flags that forbids any modifications of the source text. + //! This also results in faster parsing. However, note that the following will occur: + //!
    + //!
  • names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends
  • + //!
  • entities will not be translated
  • + //!
  • whitespace will not be normalized
  • + //!
+ //! See xml_document::parse() function. + const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation; + + //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data. + //!

+ //! See xml_document::parse() function. + const int parse_fastest = parse_non_destructive | parse_no_data_nodes; + + //! A combination of parse flags resulting in largest amount of data being extracted. + //! This usually results in slowest parsing. + //!

+ //! See xml_document::parse() function. + const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | + parse_pi_nodes | parse_validate_closing_tags; + + /////////////////////////////////////////////////////////////////////// + // Internals + + //! \cond internal + namespace internal + { + + // Struct that contains lookup tables for the parser + // It must be a template to allow correct linking (because it has static data members, which are defined in a header file). + template + struct lookup_tables + { + static const unsigned char lookup_whitespace[256]; // Whitespace table + static const unsigned char lookup_node_name[256]; // Node name table + static const unsigned char lookup_text[256]; // Text table + static const unsigned char lookup_text_pure_no_ws[256]; // Text table + static const unsigned char lookup_text_pure_with_ws[256]; // Text table + static const unsigned char lookup_attribute_name[256]; // Attribute name table + static const unsigned char + lookup_attribute_data_1[256]; // Attribute data table with single quote + static const unsigned char + lookup_attribute_data_1_pure[256]; // Attribute data table with single quote + static const unsigned char + lookup_attribute_data_2[256]; // Attribute data table with double quotes + static const unsigned char + lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes + static const unsigned char lookup_digits[256]; // Digits + static const unsigned char + lookup_upcase[256]; // To uppercase conversion table for ASCII characters + }; + + // Find length of the string + template + inline std::size_t measure(const Ch *p) + { + const Ch *tmp = p; + while (*tmp) + ++tmp; + return tmp - p; + } + + // Compare strings for equality + template + inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, + bool case_sensitive) + { + if (size1 != size2) + return false; + if (case_sensitive) + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (*p1 != *p2) + return false; + } + else + { + for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2) + if (lookup_tables<0>::lookup_upcase[static_cast(*p1)] != + lookup_tables<0>::lookup_upcase[static_cast(*p2)]) + return false; + } + return true; + } + } + //! \endcond + + /////////////////////////////////////////////////////////////////////// + // Memory pool + + //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation. + //! In most cases, you will not need to use this class directly. + //! However, if you need to create nodes manually or modify names/values of nodes, + //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. + //! Not only is this faster than allocating them by using new operator, + //! but also their lifetime will be tied to the lifetime of document, + //! possibly simplyfing memory management. + //!

+ //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. + //! You can also call allocate_string() function to allocate strings. + //! Such strings can then be used as names or values of nodes without worrying about their lifetime. + //! Note that there is no free() function -- all allocations are freed at once when clear() function is called, + //! or when the pool is destroyed. + //!

+ //! It is also possible to create a standalone memory_pool, and use it + //! to allocate nodes, whose lifetime will not be tied to any document. + //!

+ //! Pool maintains RAPIDXML_STATIC_POOL_SIZE bytes of statically allocated memory. + //! Until static memory is exhausted, no dynamic memory allocations are done. + //! When static memory is exhausted, pool allocates additional blocks of memory of size RAPIDXML_DYNAMIC_POOL_SIZE each, + //! by using global new[] and delete[] operators. + //! This behaviour can be changed by setting custom allocation routines. + //! Use set_allocator() function to set them. + //!

+ //! Allocations for nodes, attributes and strings are aligned at RAPIDXML_ALIGNMENT bytes. + //! This value defaults to the size of pointer on target architecture. + //!

+ //! To obtain absolutely top performance from the parser, + //! it is important that all nodes are allocated from a single, contiguous block of memory. + //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably. + //! If required, you can tweak RAPIDXML_STATIC_POOL_SIZE, RAPIDXML_DYNAMIC_POOL_SIZE and RAPIDXML_ALIGNMENT + //! to obtain best wasted memory to performance compromise. + //! To do it, define their values before rapidxml.hpp file is included. + //! \param Ch Character type of created nodes. + template + class memory_pool + { + + public: + + //! \cond internal + typedef void *(alloc_func)( + std::size_t); // Type of user-defined function used to allocate memory + typedef void (free_func)(void *); // Type of user-defined function used to free memory + //! \endcond + + //! Constructs empty pool with default allocator functions. + memory_pool() + : m_alloc_func(0) + , m_free_func(0) + { + init(); + } + + //! Destroys pool and frees all the memory. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Nodes allocated from the pool are no longer valid. + ~memory_pool() + { + clear(); + } + + //! Allocates a new node from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param type Type of node to create. + //! \param name Name to assign to the node, or 0 to assign no name. + //! \param value Value to assign to the node, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated node. This pointer will never be NULL. + xml_node *allocate_node(node_type type, + const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_node)); + xml_node *node = new(memory) xml_node(type); + if (name) + { + if (name_size > 0) + node->name(name, name_size); + else + node->name(name); + } + if (value) + { + if (value_size > 0) + node->value(value, value_size); + else + node->value(value); + } + return node; + } + + //! Allocates a new attribute from the pool, and optionally assigns name and value to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param name Name to assign to the attribute, or 0 to assign no name. + //! \param value Value to assign to the attribute, or 0 to assign no value. + //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string. + //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string. + //! \return Pointer to allocated attribute. This pointer will never be NULL. + xml_attribute *allocate_attribute(const Ch *name = 0, const Ch *value = 0, + std::size_t name_size = 0, std::size_t value_size = 0) + { + void *memory = allocate_aligned(sizeof(xml_attribute)); + xml_attribute *attribute = new(memory) xml_attribute; + if (name) + { + if (name_size > 0) + attribute->name(name, name_size); + else + attribute->name(name); + } + if (value) + { + if (value_size > 0) + attribute->value(value, value_size); + else + attribute->value(value); + } + return attribute; + } + + //! Allocates a char array of given size from the pool, and optionally copies a given string to it. + //! If the allocation request cannot be accomodated, this function will throw std::bad_alloc. + //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function + //! will call rapidxml::parse_error_handler() function. + //! \param source String to initialize the allocated memory with, or 0 to not initialize it. + //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated. + //! \return Pointer to allocated char array. This pointer will never be NULL. + Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) + { + assert(source || size); // Either source or size (or both) must be specified + if (size == 0) + size = internal::measure(source) + 1; + Ch *result = static_cast(allocate_aligned(size * sizeof(Ch))); + if (source) + for (std::size_t i = 0; i < size; ++i) + result[i] = source[i]; + return result; + } + + //! Clones an xml_node and its hierarchy of child nodes and attributes. + //! Nodes and attributes are allocated from this memory pool. + //! Names and values are not cloned, they are shared between the clone and the source. + //! Result node can be optionally specified as a second parameter, + //! in which case its contents will be replaced with cloned source node. + //! This is useful when you want to clone entire document. + //! \param source Node to clone. + //! \param result Node to put results in, or 0 to automatically allocate result node + //! \return Pointer to cloned node. This pointer will never be NULL. + xml_node *clone_node(const xml_node *source, xml_node *result = 0) + { + // Prepare result node + if (result) + { + result->remove_all_attributes(); + result->remove_all_nodes(); + result->type(source->type()); + } + else + result = allocate_node(source->type()); + + // Clone name and value + result->name(source->name(), source->name_size()); + result->value(source->value(), source->value_size()); + + // Clone child nodes and attributes + for (xml_node *child = source->first_node(); child; child = child->next_sibling()) + result->append_node(clone_node(child)); + for (xml_attribute *attr = source->first_attribute(); attr; attr = attr->next_attribute()) + result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), + attr->value_size())); + + return result; + } + + //! Clears the pool. + //! This causes memory occupied by nodes allocated by the pool to be freed. + //! Any nodes or strings allocated from the pool will no longer be valid. + void clear() + { + while (m_begin != m_static_memory) + { + char *previous_begin = reinterpret_cast
(align(m_begin))->previous_begin; + if (m_free_func) + m_free_func(m_begin); + else + delete[] m_begin; + m_begin = previous_begin; + } + init(); + } + + //! Sets or resets the user-defined memory allocation functions for the pool. + //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined. + //! Allocation function must not return invalid pointer on failure. It should either throw, + //! stop the program, or use longjmp() function to pass control to other place of program. + //! If it returns invalid pointer, results are undefined. + //!

+ //! User defined allocation functions must have the following forms: + //!
+ //!
void *allocate(std::size_t size); + //!
void free(void *pointer); + //!

+ //! \param af Allocation function, or 0 to restore default function + //! \param ff Free function, or 0 to restore default function + void set_allocator(alloc_func *af, free_func *ff) + { + assert(m_begin == m_static_memory + && m_ptr == align(m_begin)); // Verify that no memory is allocated yet + m_alloc_func = af; + m_free_func = ff; + } + + private: + + struct header + { + char *previous_begin; + }; + + void init() + { + m_begin = m_static_memory; + m_ptr = align(m_begin); + m_end = m_static_memory + sizeof(m_static_memory); + } + + char *align(char *ptr) + { + std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & + (RAPIDXML_ALIGNMENT - 1)); + return ptr + alignment; + } + + char *allocate_raw(std::size_t size) + { + // Allocate + void *memory; + if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[] + { + memory = m_alloc_func(size); + assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp + } + else + { + memory = new char[size]; +#ifdef RAPIDXML_NO_EXCEPTIONS + if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc + RAPIDXML_PARSE_ERROR("out of memory", 0); +#endif + } + return static_cast(memory); + } + + void *allocate_aligned(std::size_t size) + { + // Calculate aligned pointer + char *result = align(m_ptr); + + // If not enough memory left in current pool, allocate a new pool + if (result + size > m_end) + { + // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE) + std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE; + if (pool_size < size) + pool_size = size; + + // Allocate + std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation + char *raw_memory = allocate_raw(alloc_size); + + // Setup new pool in allocated memory + char *pool = align(raw_memory); + header *new_header = reinterpret_cast
(pool); + new_header->previous_begin = m_begin; + m_begin = raw_memory; + m_ptr = pool + sizeof(header); + m_end = raw_memory + alloc_size; + + // Calculate aligned pointer again using new pool + result = align(m_ptr); + } + + // Update pool and return aligned pointer + m_ptr = result + size; + return result; + } + + char *m_begin; // Start of raw memory making up current pool + char *m_ptr; // First free byte in current pool + char *m_end; // One past last available byte in current pool + char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory + alloc_func + *m_alloc_func; // Allocator function, or 0 if default is to be used + free_func *m_free_func; // Free function, or 0 if default is to be used + }; + + /////////////////////////////////////////////////////////////////////////// + // XML base + + //! Base class for xml_node and xml_attribute implementing common functions: + //! name(), name_size(), value(), value_size() and parent(). + //! \param Ch Character type to use + template + class xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + // Construct a base with empty name, value and parent + xml_base() + : m_name(0) + , m_value(0) + , m_parent(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets name of the node. + //! Interpretation of name depends on type of node. + //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use name_size() function to determine length of the name. + //! \return Name of node, or empty string if node has no name. + Ch *name() const + { + return m_name ? m_name : nullstr(); + } + + //! Gets size of node name, not including terminator character. + //! This function works correctly irrespective of whether name is or is not zero terminated. + //! \return Size of node name, in characters. + std::size_t name_size() const + { + return m_name ? m_name_size : 0; + } + + //! Gets value of node. + //! Interpretation of value depends on type of node. + //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse. + //!

+ //! Use value_size() function to determine length of the value. + //! \return Value of node, or empty string if node has no value. + Ch *value() const + { + return m_value ? m_value : nullstr(); + } + + //! Gets size of node value, not including terminator character. + //! This function works correctly irrespective of whether value is or is not zero terminated. + //! \return Size of node value, in characters. + std::size_t value_size() const + { + return m_value ? m_value_size : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets name of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of name must be specified separately, because name does not have to be zero terminated. + //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //! \param name Name of node to set. Does not have to be zero terminated. + //! \param size Size of name, in characters. This does not include zero terminator, if one is present. + void name(const Ch *name, std::size_t size) + { + m_name = const_cast(name); + m_name_size = size; + } + + //! Sets name of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t). + //! \param name Name of node to set. Must be zero terminated. + void name(const Ch *name) + { + this->name(name, internal::measure(name)); + } + + //! Sets value of node to a non zero-terminated string. + //! See \ref ownership_of_strings. + //!

+ //! Note that node does not own its name or value, it only stores a pointer to it. + //! It will not delete or otherwise free the pointer on destruction. + //! It is reponsibility of the user to properly manage lifetime of the string. + //! The easiest way to achieve it is to use memory_pool of the document to allocate the string - + //! on destruction of the document the string will be automatically freed. + //!

+ //! Size of value must be specified separately, because it does not have to be zero terminated. + //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated). + //!

+ //! If an element has a child node of type node_data, it will take precedence over element value when printing. + //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser. + //! \param value value of node to set. Does not have to be zero terminated. + //! \param size Size of value, in characters. This does not include zero terminator, if one is present. + void value(const Ch *value, std::size_t size) + { + m_value = const_cast(value); + m_value_size = size; + } + + //! Sets value of node to a zero-terminated string. + //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t). + //! \param value Vame of node to set. Must be zero terminated. + void value(const Ch *value) + { + this->value(value, internal::measure(value)); + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets node parent. + //! \return Pointer to parent node, or 0 if there is no parent. + xml_node *parent() const + { + return m_parent; + } + + protected: + + // Return empty string + static Ch *nullstr() + { + static Ch zero = Ch('\0'); + return &zero; + } + + Ch *m_name; // Name of node, or 0 if no name + Ch *m_value; // Value of node, or 0 if no value + std::size_t m_name_size; // Length of node name, or undefined of no name + std::size_t m_value_size; // Length of node value, or undefined if no value + xml_node *m_parent; // Pointer to parent node, or 0 if none + + }; + + //! Class representing attribute node of XML document. + //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base). + //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. + //! Thus, this text must persist in memory for the lifetime of attribute. + //! \param Ch Character type to use. + template + class xml_attribute: public xml_base + { + + friend class xml_node; + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty attribute with the specified type. + //! Consider using memory_pool of appropriate xml_document if allocating attributes manually. + xml_attribute() + { + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which attribute is a child. + //! \return Pointer to document that contains this attribute, or 0 if there is no parent document. + xml_document *document() const + { + if (xml_node *node = this->parent()) + { + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + else + return 0; + } + + //! Gets previous attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_prev_attribute; attribute; + attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_prev_attribute : 0; + } + + //! Gets next attribute, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *next_attribute(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_next_attribute; attribute; + attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return this->m_parent ? m_next_attribute : 0; + } + + private: + + xml_attribute + *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero + xml_attribute + *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML node + + //! Class representing a node of XML document. + //! Each node may have associated name and value strings, which are available through name() and value() functions. + //! Interpretation of name and value depends on type of the node. + //! Type of node can be determined by using type() function. + //!

+ //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. + //! Thus, this text must persist in the memory for the lifetime of node. + //! \param Ch Character type to use. + template + class xml_node: public xml_base + { + + public: + + /////////////////////////////////////////////////////////////////////////// + // Construction & destruction + + //! Constructs an empty node with the specified type. + //! Consider using memory_pool of appropriate document to allocate nodes manually. + //! \param type Type of node to construct. + xml_node(node_type type) + : m_type(type) + , m_first_node(0) + , m_first_attribute(0) + { + } + + /////////////////////////////////////////////////////////////////////////// + // Node data access + + //! Gets type of node. + //! \return Type of node. + node_type type() const + { + return m_type; + } + + /////////////////////////////////////////////////////////////////////////// + // Related nodes access + + //! Gets document of which node is a child. + //! \return Pointer to document that contains this node, or 0 if there is no parent document. + xml_document *document() const + { + xml_node *node = const_cast *>(this); + while (node->parent()) + node = node->parent(); + return node->type() == node_document ? static_cast *>(node) : 0; + } + + //! Gets first child node, optionally matching node name. + //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *first_node(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_first_node; child; child = child->next_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_first_node; + } + + //! Gets last child node, optionally matching node name. + //! Behaviour is undefined if node has no children. + //! Use first_node() to test if node has children. + //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found child, or 0 if not found. + xml_node *last_node(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + assert(m_first_node); // Cannot query for last child if node has no children + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *child = m_last_node; child; child = child->previous_sibling()) + if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive)) + return child; + return 0; + } + else + return m_last_node; + } + + //! Gets previous sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_prev_sibling; + } + + //! Gets next sibling node, optionally matching node name. + //! Behaviour is undefined if node has no parent. + //! Use parent() to test if node has a parent. + //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found sibling, or 0 if not found. + xml_node *next_sibling(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + assert(this->m_parent); // Cannot query for siblings if node has no parent + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_node *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling) + if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive)) + return sibling; + return 0; + } + else + return m_next_sibling; + } + + //! Gets first attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *first_attribute(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_first_attribute; attribute; + attribute = attribute->m_next_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute; + } + + //! Gets last attribute of node, optionally matching attribute name. + //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero + //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string + //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters + //! \return Pointer to found attribute, or 0 if not found. + xml_attribute *last_attribute(const Ch *name = 0, std::size_t name_size = 0, + bool case_sensitive = true) const + { + if (name) + { + if (name_size == 0) + name_size = internal::measure(name); + for (xml_attribute *attribute = m_last_attribute; attribute; + attribute = attribute->m_prev_attribute) + if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive)) + return attribute; + return 0; + } + else + return m_first_attribute ? m_last_attribute : 0; + } + + /////////////////////////////////////////////////////////////////////////// + // Node modification + + //! Sets type of node. + //! \param type Type of node to set. + void type(node_type type) + { + m_type = type; + } + + /////////////////////////////////////////////////////////////////////////// + // Node manipulation + + //! Prepends a new child node. + //! The prepended child becomes the first child, and all existing children are moved one position back. + //! \param child Node to prepend. + void prepend_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_next_sibling = m_first_node; + m_first_node->m_prev_sibling = child; + } + else + { + child->m_next_sibling = 0; + m_last_node = child; + } + m_first_node = child; + child->m_parent = this; + child->m_prev_sibling = 0; + } + + //! Appends a new child node. + //! The appended child becomes the last child. + //! \param child Node to append. + void append_node(xml_node *child) + { + assert(child && !child->parent() && child->type() != node_document); + if (first_node()) + { + child->m_prev_sibling = m_last_node; + m_last_node->m_next_sibling = child; + } + else + { + child->m_prev_sibling = 0; + m_first_node = child; + } + m_last_node = child; + child->m_parent = this; + child->m_next_sibling = 0; + } + + //! Inserts a new child node at specified place inside the node. + //! All children after and including the specified node are moved one position back. + //! \param where Place where to insert the child, or 0 to insert at the back. + //! \param child Node to insert. + void insert_node(xml_node *where, xml_node *child) + { + assert(!where || where->parent() == this); + assert(child && !child->parent() && child->type() != node_document); + if (where == m_first_node) + prepend_node(child); + else if (where == 0) + append_node(child); + else + { + child->m_prev_sibling = where->m_prev_sibling; + child->m_next_sibling = where; + where->m_prev_sibling->m_next_sibling = child; + where->m_prev_sibling = child; + child->m_parent = this; + } + } + + //! Removes first child node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_first_node() + { + assert(first_node()); + xml_node *child = m_first_node; + m_first_node = child->m_next_sibling; + if (child->m_next_sibling) + child->m_next_sibling->m_prev_sibling = 0; + else + m_last_node = 0; + child->m_parent = 0; + } + + //! Removes last child of the node. + //! If node has no children, behaviour is undefined. + //! Use first_node() to test if node has children. + void remove_last_node() + { + assert(first_node()); + xml_node *child = m_last_node; + if (child->m_prev_sibling) + { + m_last_node = child->m_prev_sibling; + child->m_prev_sibling->m_next_sibling = 0; + } + else + m_first_node = 0; + child->m_parent = 0; + } + + //! Removes specified child from the node + // \param where Pointer to child to be removed. + void remove_node(xml_node *where) + { + assert(where && where->parent() == this); + assert(first_node()); + if (where == m_first_node) + remove_first_node(); + else if (where == m_last_node) + remove_last_node(); + else + { + where->m_prev_sibling->m_next_sibling = where->m_next_sibling; + where->m_next_sibling->m_prev_sibling = where->m_prev_sibling; + where->m_parent = 0; + } + } + + //! Removes all child nodes (but not attributes). + void remove_all_nodes() + { + for (xml_node *node = first_node(); node; node = node->m_next_sibling) + node->m_parent = 0; + m_first_node = 0; + } + + //! Prepends a new attribute to the node. + //! \param attribute Attribute to prepend. + void prepend_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_next_attribute = m_first_attribute; + m_first_attribute->m_prev_attribute = attribute; + } + else + { + attribute->m_next_attribute = 0; + m_last_attribute = attribute; + } + m_first_attribute = attribute; + attribute->m_parent = this; + attribute->m_prev_attribute = 0; + } + + //! Appends a new attribute to the node. + //! \param attribute Attribute to append. + void append_attribute(xml_attribute *attribute) + { + assert(attribute && !attribute->parent()); + if (first_attribute()) + { + attribute->m_prev_attribute = m_last_attribute; + m_last_attribute->m_next_attribute = attribute; + } + else + { + attribute->m_prev_attribute = 0; + m_first_attribute = attribute; + } + m_last_attribute = attribute; + attribute->m_parent = this; + attribute->m_next_attribute = 0; + } + + //! Inserts a new attribute at specified place inside the node. + //! All attributes after and including the specified attribute are moved one position back. + //! \param where Place where to insert the attribute, or 0 to insert at the back. + //! \param attribute Attribute to insert. + void insert_attribute(xml_attribute *where, xml_attribute *attribute) + { + assert(!where || where->parent() == this); + assert(attribute && !attribute->parent()); + if (where == m_first_attribute) + prepend_attribute(attribute); + else if (where == 0) + append_attribute(attribute); + else + { + attribute->m_prev_attribute = where->m_prev_attribute; + attribute->m_next_attribute = where; + where->m_prev_attribute->m_next_attribute = attribute; + where->m_prev_attribute = attribute; + attribute->m_parent = this; + } + } + + //! Removes first attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_first_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_first_attribute; + if (attribute->m_next_attribute) + { + attribute->m_next_attribute->m_prev_attribute = 0; + } + else + m_last_attribute = 0; + attribute->m_parent = 0; + m_first_attribute = attribute->m_next_attribute; + } + + //! Removes last attribute of the node. + //! If node has no attributes, behaviour is undefined. + //! Use first_attribute() to test if node has attributes. + void remove_last_attribute() + { + assert(first_attribute()); + xml_attribute *attribute = m_last_attribute; + if (attribute->m_prev_attribute) + { + attribute->m_prev_attribute->m_next_attribute = 0; + m_last_attribute = attribute->m_prev_attribute; + } + else + m_first_attribute = 0; + attribute->m_parent = 0; + } + + //! Removes specified attribute from node. + //! \param where Pointer to attribute to be removed. + void remove_attribute(xml_attribute *where) + { + assert(first_attribute() && where->parent() == this); + if (where == m_first_attribute) + remove_first_attribute(); + else if (where == m_last_attribute) + remove_last_attribute(); + else + { + where->m_prev_attribute->m_next_attribute = where->m_next_attribute; + where->m_next_attribute->m_prev_attribute = where->m_prev_attribute; + where->m_parent = 0; + } + } + + //! Removes all attributes of node. + void remove_all_attributes() + { + for (xml_attribute *attribute = first_attribute(); attribute; + attribute = attribute->m_next_attribute) + attribute->m_parent = 0; + m_first_attribute = 0; + } + + private: + + /////////////////////////////////////////////////////////////////////////// + // Restrictions + + // No copying + xml_node(const xml_node &); + void operator =(const xml_node &); + + /////////////////////////////////////////////////////////////////////////// + // Data members + + // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0. + // This is required for maximum performance, as it allows the parser to omit initialization of + // unneded/redundant values. + // + // The rules are as follows: + // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively + // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage + // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage + + node_type m_type; // Type of node; always valid + xml_node *m_first_node; // Pointer to first child node, or 0 if none; always valid + xml_node + *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero + xml_attribute + *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid + xml_attribute + *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero + xml_node + *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + xml_node + *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero + + }; + + /////////////////////////////////////////////////////////////////////////// + // XML document + + //! This class represents root of the DOM hierarchy. + //! It is also an xml_node and a memory_pool through public inheritance. + //! Use parse() function to build a DOM tree from a zero-terminated XML text string. + //! parse() function allocates memory for nodes and attributes by using functions of xml_document, + //! which are inherited from memory_pool. + //! To access root node of the document, use the document itself, as if it was an xml_node. + //! \param Ch Character type to use. + template + class xml_document: public xml_node, public memory_pool + { + + public: + + //! Constructs empty XML document + xml_document() + : xml_node(node_document) + { + } + + //! Parses zero-terminated XML string according to given flags. + //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used. + //! The string must persist for the lifetime of the document. + //! In case of error, rapidxml::parse_error exception will be thrown. + //!

+ //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning. + //! Make sure that data is zero-terminated. + //!

+ //! Document can be parsed into multiple times. + //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool. + //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser. + template + void parse(Ch *text) + { + assert(text); + + // Remove current contents + this->remove_all_nodes(); + this->remove_all_attributes(); + + // Parse BOM, if any + parse_bom(text); + + // Parse children + while (1) + { + // Skip whitespace before node + skip(text); + if (*text == 0) + break; + + // Parse and append new child + if (*text == Ch('<')) + { + ++text; // Skip '<' + if (xml_node *node = parse_node(text)) + this->append_node(node); + } + else + RAPIDXML_PARSE_ERROR("expected <", text); + } + + } + + //! Clears the document by deleting all nodes and clearing the memory pool. + //! All nodes owned by document pool are destroyed. + void clear() + { + this->remove_all_nodes(); + this->remove_all_attributes(); + memory_pool::clear(); + } + + private: + + /////////////////////////////////////////////////////////////////////// + // Internal character utility functions + + // Detect whitespace character + struct whitespace_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_whitespace[static_cast(ch)]; + } + }; + + // Detect node name character + struct node_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_node_name[static_cast(ch)]; + } + }; + + // Detect attribute name character + struct attribute_name_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_attribute_name[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) + struct text_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_no_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast(ch)]; + } + }; + + // Detect text character (PCDATA) that does not require processing + struct text_pure_with_ws_pred + { + static unsigned char test(Ch ch) + { + return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast(ch)]; + } + }; + + // Detect attribute value character + template + struct attribute_value_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Detect attribute value character + template + struct attribute_value_pure_pred + { + static unsigned char test(Ch ch) + { + if (Quote == Ch('\'')) + return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast(ch)]; + if (Quote == Ch('\"')) + return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast(ch)]; + return 0; // Should never be executed, to avoid warnings on Comeau + } + }; + + // Insert coded character, using UTF8 or 8-bit ASCII + template + static void insert_coded_character(Ch *&text, unsigned long code) + { + if (Flags & parse_no_utf8) + { + // Insert 8-bit ASCII character + // Todo: possibly verify that code is less than 256 and use replacement char otherwise? + text[0] = static_cast(code); + text += 1; + } + else + { + // Insert UTF8 sequence + if (code < 0x80) // 1 byte sequence + { + text[0] = static_cast(code); + text += 1; + } + else if (code < 0x800) // 2 byte sequence + { + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xC0); + text += 2; + } + else if (code < 0x10000) // 3 byte sequence + { + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xE0); + text += 3; + } + else if (code < 0x110000) // 4 byte sequence + { + text[3] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[2] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[1] = static_cast((code | 0x80) & 0xBF); code >>= 6; + text[0] = static_cast(code | 0xF0); + text += 4; + } + else // Invalid, only codes up to 0x10FFFF are allowed in Unicode + { + RAPIDXML_PARSE_ERROR("invalid numeric character entity", text); + } + } + } + + // Skip characters until predicate evaluates to true + template + static void skip(Ch *&text) + { + Ch *tmp = text; + while (StopPred::test(*tmp)) + ++tmp; + text = tmp; + } + + // Skip characters until predicate evaluates to true while doing the following: + // - replacing XML character entity references with proper characters (' & " < > &#...;) + // - condensing whitespace sequences to single space character + template + static Ch *skip_and_expand_character_refs(Ch *&text) + { + // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip + if (Flags & parse_no_entity_translation && + !(Flags & parse_normalize_whitespace) && + !(Flags & parse_trim_whitespace)) + { + skip(text); + return text; + } + + // Use simple skip until first modification is detected + skip(text); + + // Use translation skip + Ch *src = text; + Ch *dest = src; + while (StopPred::test(*src)) + { + // If entity translation is enabled + if (!(Flags & parse_no_entity_translation)) + { + // Test if replacement is needed + if (src[0] == Ch('&')) + { + switch (src[1]) + { + + // & ' + case Ch('a'): + if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) + { + *dest = Ch('&'); + ++dest; + src += 5; + continue; + } + if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';')) + { + *dest = Ch('\''); + ++dest; + src += 6; + continue; + } + break; + + // " + case Ch('q'): + if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';')) + { + *dest = Ch('"'); + ++dest; + src += 6; + continue; + } + break; + + // > + case Ch('g'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('>'); + ++dest; + src += 4; + continue; + } + break; + + // < + case Ch('l'): + if (src[2] == Ch('t') && src[3] == Ch(';')) + { + *dest = Ch('<'); + ++dest; + src += 4; + continue; + } + break; + + // &#...; - assumes ASCII + case Ch('#'): + if (src[2] == Ch('x')) + { + unsigned long code = 0; + src += 3; // Skip &#x + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 16 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + else + { + unsigned long code = 0; + src += 2; // Skip &# + while (1) + { + unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast(*src)]; + if (digit == 0xFF) + break; + code = code * 10 + digit; + ++src; + } + insert_coded_character(dest, code); // Put character in output + } + if (*src == Ch(';')) + ++src; + else + RAPIDXML_PARSE_ERROR("expected ;", src); + continue; + + // Something else + default: + // Ignore, just copy '&' verbatim + break; + + } + } + } + + // If whitespace condensing is enabled + if (Flags & parse_normalize_whitespace) + { + // Test if condensing is needed + if (whitespace_pred::test(*src)) + { + *dest = Ch(' '); ++dest; // Put single space in dest + ++src; // Skip first whitespace char + // Skip remaining whitespace chars + while (whitespace_pred::test(*src)) + ++src; + continue; + } + } + + // No replacement, only copy character + *dest++ = *src++; + + } + + // Return new end + text = src; + return dest; + + } + + /////////////////////////////////////////////////////////////////////// + // Internal parsing functions + + // Parse BOM, if any + template + void parse_bom(Ch *&text) + { + // UTF-8? + if (static_cast(text[0]) == 0xEF && + static_cast(text[1]) == 0xBB && + static_cast(text[2]) == 0xBF) + { + text += 3; // Skup utf-8 bom + } + } + + // Parse XML declaration ( + xml_node *parse_xml_declaration(Ch *&text) + { + // If parsing of declaration is disabled + if (!(Flags & parse_declaration_node)) + { + // Skip until end of declaration + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + + // Create declaration + xml_node *declaration = this->allocate_node(node_declaration); + + // Skip whitespace before attributes or ?> + skip(text); + + // Parse declaration attributes + parse_node_attributes(text, declaration); + + // Skip ?> + if (text[0] != Ch('?') || text[1] != Ch('>')) + RAPIDXML_PARSE_ERROR("expected ?>", text); + text += 2; + + return declaration; + } + + // Parse XML comment (' + return 0; // Do not produce comment node + } + + // Remember value start + Ch *value = text; + + // Skip until end of comment + while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create comment node + xml_node *comment = this->allocate_node(node_comment); + comment->value(value, text - value); + + // Place zero terminator after comment value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip '-->' + return comment; + } + + // Parse DOCTYPE + template + xml_node *parse_doctype(Ch *&text) + { + // Remember value start + Ch *value = text; + + // Skip to > + while (*text != Ch('>')) + { + // Determine character type + switch (*text) + { + + // If '[' encountered, scan for matching ending ']' using naive algorithm with depth + // This works for all W3C test files except for 2 most wicked + case Ch('['): + { + ++text; // Skip '[' + int depth = 1; + while (depth > 0) + { + switch (*text) + { + case Ch('['): ++depth; break; + case Ch(']'): --depth; break; + case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); + default: break; + } + ++text; + } + break; + } + + // Error on end of text + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Other character, skip it + default: + ++text; + + } + } + + // If DOCTYPE nodes enabled + if (Flags & parse_doctype_node) + { + // Create a new doctype node + xml_node *doctype = this->allocate_node(node_doctype); + doctype->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 1; // skip '>' + return doctype; + } + else + { + text += 1; // skip '>' + return 0; + } + + } + + // Parse PI + template + xml_node *parse_pi(Ch *&text) + { + // If creation of PI nodes is enabled + if (Flags & parse_pi_nodes) + { + // Create pi node + xml_node *pi = this->allocate_node(node_pi); + + // Extract PI target name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected PI target", text); + pi->name(name, text - name); + + // Skip whitespace between pi target and pi + skip(text); + + // Remember start of pi + Ch *value = text; + + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Set pi value (verbatim, no entity expansion or whitespace normalization) + pi->value(value, text - value); + + // Place zero terminator after name and value + if (!(Flags & parse_no_string_terminators)) + { + pi->name()[pi->name_size()] = Ch('\0'); + pi->value()[pi->value_size()] = Ch('\0'); + } + + text += 2; // Skip '?>' + return pi; + } + else + { + // Skip to '?>' + while (text[0] != Ch('?') || text[1] != Ch('>')) + { + if (*text == Ch('\0')) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 2; // Skip '?>' + return 0; + } + } + + // Parse and append data + // Return character that ends data. + // This is necessary because this character might have been overwritten by a terminating 0 + template + Ch parse_and_append_data(xml_node *node, Ch *&text, Ch *contents_start) + { + // Backup to contents start if whitespace trimming is disabled + if (!(Flags & parse_trim_whitespace)) + text = contents_start; + + // Skip until end of data + Ch *value = text, *end; + if (Flags & parse_normalize_whitespace) + end = skip_and_expand_character_refs(text); + else + end = skip_and_expand_character_refs(text); + + // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after > + if (Flags & parse_trim_whitespace) + { + if (Flags & parse_normalize_whitespace) + { + // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end + if (*(end - 1) == Ch(' ')) + --end; + } + else + { + // Backup until non-whitespace character is found + while (whitespace_pred::test(*(end - 1))) + --end; + } + } + + // If characters are still left between end and value (this test is only necessary if normalization is enabled) + // Create new data node + if (!(Flags & parse_no_data_nodes)) + { + xml_node *data = this->allocate_node(node_data); + data->value(value, end - value); + node->append_node(data); + } + + // Add data to parent node if no data exists yet + if (!(Flags & parse_no_element_values)) + if (*node->value() == Ch('\0')) + node->value(value, end - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + { + Ch ch = *text; + *end = Ch('\0'); + return ch; // Return character that ends data; this is required because zero terminator overwritten it + } + + // Return character that ends data + return *text; + } + + // Parse CDATA + template + xml_node *parse_cdata(Ch *&text) + { + // If CDATA is disabled + if (Flags & parse_no_data_nodes) + { + // Skip until end of cdata + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + text += 3; // Skip ]]> + return 0; // Do not produce CDATA node + } + + // Skip until end of cdata + Ch *value = text; + while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) + { + if (!text[0]) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + + // Create new cdata node + xml_node *cdata = this->allocate_node(node_cdata); + cdata->value(value, text - value); + + // Place zero terminator after value + if (!(Flags & parse_no_string_terminators)) + *text = Ch('\0'); + + text += 3; // Skip ]]> + return cdata; + } + + // Parse element node + template + xml_node *parse_element(Ch *&text) + { + // Create element node + xml_node *element = this->allocate_node(node_element); + + // Extract element name + Ch *name = text; + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected element name", text); + element->name(name, text - name); + + // Skip whitespace between element name and attributes or > + skip(text); + + // Parse attributes, if any + parse_node_attributes(text, element); + + // Determine ending type + if (*text == Ch('>')) + { + ++text; + parse_node_contents(text, element); + } + else if (*text == Ch('/')) + { + ++text; + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; + } + else + RAPIDXML_PARSE_ERROR("expected >", text); + + // Place zero terminator after name + if (!(Flags & parse_no_string_terminators)) + element->name()[element->name_size()] = Ch('\0'); + + // Return parsed element + return element; + } + + // Determine node type, and parse it + template + xml_node *parse_node(Ch *&text) + { + // Parse proper node type + switch (text[0]) + { + + // <... + default: + // Parse and append element node + return parse_element(text); + + // (text); + } + else + { + // Parse PI + return parse_pi(text); + } + + // (text); + } + break; + + // (text); + } + break; + + // (text); + } + break; + + default: + break; + + } // switch + + // Attempt to skip other, unrecognized node types starting with ')) + { + if (*text == 0) + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + ++text; + } + ++text; // Skip '>' + return 0; // No node recognized + + } + } + + // Parse contents of the node - children, data etc. + template + void parse_node_contents(Ch *&text, xml_node *node) + { + // For all children and text + while (1) + { + // Skip whitespace between > and node contents + Ch *contents_start = text; // Store start of node contents before whitespace is skipped + skip(text); + Ch next_char = *text; + + // After data nodes, instead of continuing the loop, control jumps here. + // This is because zero termination inside parse_and_append_data() function + // would wreak havoc with the above code. + // Also, skipping whitespace after data nodes is unnecessary. +after_data_node: + + // Determine what comes next: node closing, child node, data node, or 0? + switch (next_char) + { + + // Node closing or child node + case Ch('<'): + if (text[1] == Ch('/')) + { + // Node closing + text += 2; // Skip '(text); + if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true)) + RAPIDXML_PARSE_ERROR("invalid closing tag name", text); + } + else + { + // No validation, just skip name + skip(text); + } + // Skip remaining whitespace after node name + skip(text); + if (*text != Ch('>')) + RAPIDXML_PARSE_ERROR("expected >", text); + ++text; // Skip '>' + return; // Node closed, finished parsing contents + } + else + { + // Child node + ++text; // Skip '<' + if (xml_node *child = parse_node(text)) + node->append_node(child); + } + break; + + // End of data - error + case Ch('\0'): + RAPIDXML_PARSE_ERROR("unexpected end of data", text); + + // Data node + default: + next_char = parse_and_append_data(node, text, contents_start); + goto after_data_node; // Bypass regular processing after data nodes + + } + } + } + + // Parse XML attributes of the node + template + void parse_node_attributes(Ch *&text, xml_node *node) + { + // For all attributes + while (attribute_name_pred::test(*text)) + { + // Extract attribute name + Ch *name = text; + ++text; // Skip first character of attribute name + skip(text); + if (text == name) + RAPIDXML_PARSE_ERROR("expected attribute name", name); + + // Create new attribute + xml_attribute *attribute = this->allocate_attribute(); + attribute->name(name, text - name); + node->append_attribute(attribute); + + // Skip whitespace after attribute name + skip(text); + + // Skip = + if (*text != Ch('=')) + RAPIDXML_PARSE_ERROR("expected =", text); + ++text; + + // Add terminating zero after name + if (!(Flags & parse_no_string_terminators)) + attribute->name()[attribute->name_size()] = 0; + + // Skip whitespace after = + skip(text); + + // Skip quote and remember if it was ' or " + Ch quote = *text; + if (quote != Ch('\'') && quote != Ch('"')) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; + + // Extract attribute value and expand char refs in it + Ch *value = text, *end; + const int AttFlags = Flags & + ~parse_normalize_whitespace; // No whitespace normalization in attributes + if (quote == Ch('\'')) + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags> + (text); + else + end = skip_and_expand_character_refs, attribute_value_pure_pred, AttFlags> + (text); + + // Set attribute value + attribute->value(value, end - value); + + // Make sure that end quote is present + if (*text != quote) + RAPIDXML_PARSE_ERROR("expected ' or \"", text); + ++text; // Skip quote + + // Add terminating zero after value + if (!(Flags & parse_no_string_terminators)) + attribute->value()[attribute->value_size()] = 0; + + // Skip whitespace after attribute value + skip(text); + } + } + + }; + + //! \cond internal + namespace internal + { + + // Whitespace (space \n \r \t) + template + const unsigned char lookup_tables::lookup_whitespace[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F + }; + + // Node name (anything but space \n \r \t / > ? \0) + template + const unsigned char lookup_tables::lookup_node_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) (anything but < \0) + template + const unsigned char lookup_tables::lookup_text[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled + // (anything but < \0 &) + template + const unsigned char lookup_tables::lookup_text_pure_no_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled + // (anything but < \0 & space \n \r \t) + template + const unsigned char lookup_tables::lookup_text_pure_with_ws[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute name (anything but space \n \r \t / < > = ? ! \0) + template + const unsigned char lookup_tables::lookup_attribute_name[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote (anything but ' \0) + template + const unsigned char lookup_tables::lookup_attribute_data_1[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with single quote that does not require processing (anything but ' \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_1_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote (anything but " \0) + template + const unsigned char lookup_tables::lookup_attribute_data_2[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Attribute data with double quote that does not require processing (anything but " \0 &) + template + const unsigned char lookup_tables::lookup_attribute_data_2_pure[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1 + 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F + }; + + // Digits (dec and hex, 255 denotes end of numeric character reference) + template + const unsigned char lookup_tables::lookup_digits[256] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 1 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 2 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, // 3 + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 4 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 5 + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 6 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 7 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 8 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 9 + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // A + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // B + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // C + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // D + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // E + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 // F + }; + + // Upper case conversion + template + const unsigned char lookup_tables::lookup_upcase[256] = + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0 + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2 + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3 + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5 + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6 + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, // 7 + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, // 8 + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, // 9 + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, // A + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, // B + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, // C + 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, // D + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, // E + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 // F + }; + } + //! \endcond + +} + +// Undefine internal macros +#undef RAPIDXML_PARSE_ERROR + +// On MSVC, restore warnings state +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif diff --git a/extlibs/rapidxml/rapidxml_iterators.hpp b/extlibs/rapidxml/rapidxml_iterators.hpp new file mode 100644 index 0000000..2960a39 --- /dev/null +++ b/extlibs/rapidxml/rapidxml_iterators.hpp @@ -0,0 +1,174 @@ +#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED +#define RAPIDXML_ITERATORS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_iterators.hpp This file contains rapidxml iterators + +#include "rapidxml.hpp" + +namespace rapidxml +{ + + //! Iterator of child nodes of xml_node + template + class node_iterator + { + + public: + + typedef typename xml_node value_type; + typedef typename xml_node &reference; + typedef typename xml_node *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + node_iterator() + : m_node(0) + { + } + + node_iterator(xml_node *node) + : m_node(node->first_node()) + { + } + + reference operator *() const + { + assert(m_node); + return *m_node; + } + + pointer operator->() const + { + assert(m_node); + return m_node; + } + + node_iterator &operator++() + { + assert(m_node); + m_node = m_node->next_sibling(); + return *this; + } + + node_iterator operator++(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + node_iterator &operator--() + { + assert(m_node && m_node->previous_sibling()); + m_node = m_node->previous_sibling(); + return *this; + } + + node_iterator operator--(int) + { + node_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const node_iterator &rhs) + { + return m_node == rhs.m_node; + } + + bool operator !=(const node_iterator &rhs) + { + return m_node != rhs.m_node; + } + + private: + + xml_node *m_node; + + }; + + //! Iterator of child attributes of xml_node + template + class attribute_iterator + { + + public: + + typedef typename xml_attribute value_type; + typedef typename xml_attribute &reference; + typedef typename xml_attribute *pointer; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + attribute_iterator() + : m_attribute(0) + { + } + + attribute_iterator(xml_node *node) + : m_attribute(node->first_attribute()) + { + } + + reference operator *() const + { + assert(m_attribute); + return *m_attribute; + } + + pointer operator->() const + { + assert(m_attribute); + return m_attribute; + } + + attribute_iterator &operator++() + { + assert(m_attribute); + m_attribute = m_attribute->next_attribute(); + return *this; + } + + attribute_iterator operator++(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + attribute_iterator &operator--() + { + assert(m_attribute && m_attribute->previous_attribute()); + m_attribute = m_attribute->previous_attribute(); + return *this; + } + + attribute_iterator operator--(int) + { + attribute_iterator tmp = *this; + ++this; + return tmp; + } + + bool operator ==(const attribute_iterator &rhs) + { + return m_attribute == rhs.m_attribute; + } + + bool operator !=(const attribute_iterator &rhs) + { + return m_attribute != rhs.m_attribute; + } + + private: + + xml_attribute *m_attribute; + + }; + +} + +#endif diff --git a/extlibs/rapidxml/rapidxml_print.hpp b/extlibs/rapidxml/rapidxml_print.hpp new file mode 100644 index 0000000..422c3e7 --- /dev/null +++ b/extlibs/rapidxml/rapidxml_print.hpp @@ -0,0 +1,429 @@ +#ifndef RAPIDXML_PRINT_HPP_INCLUDED +#define RAPIDXML_PRINT_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_print.hpp This file contains rapidxml printer implementation + +#include "rapidxml.hpp" + +// Only include streams if not disabled +#ifndef RAPIDXML_NO_STREAMS +#include +#include +#endif + +namespace rapidxml +{ + + /////////////////////////////////////////////////////////////////////// + // Printing flags + + const int print_no_indenting = + 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function. + + /////////////////////////////////////////////////////////////////////// + // Internal + + //! \cond internal + namespace internal + { + + /////////////////////////////////////////////////////////////////////////// + // Internal character operations + + // Copy characters from given range to given output iterator + template + inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) + { + while (begin != end) + *out++ = *begin++; + return out; + } + + // Copy characters from given range to given output iterator and expand + // characters into references (< > ' " &) + template + inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out) + { + while (begin != end) + { + if (*begin == noexpand) + { + *out++ = *begin; // No expansion, copy character + } + else + { + switch (*begin) + { + case Ch('<'): + *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('>'): + *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';'); + break; + case Ch('\''): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); + *out++ = Ch(';'); + break; + case Ch('"'): + *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); + *out++ = Ch(';'); + break; + case Ch('&'): + *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';'); + break; + default: + *out++ = *begin; // No expansion, copy character + } + } + ++begin; // Step to next character + } + return out; + } + + // Fill given output iterator with repetitions of the same character + template + inline OutIt fill_chars(OutIt out, int n, Ch ch) + { + for (int i = 0; i < n; ++i) + *out++ = ch; + return out; + } + + // Find character + template + inline bool find_char(const Ch *begin, const Ch *end) + { + while (begin != end) + if (*begin++ == ch) + return true; + return false; + } + + template + inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent); + + // Print children of the node + template + inline OutIt print_children(OutIt out, const xml_node *node, int flags, int indent) + { + for (xml_node *child = node->first_node(); child; child = child->next_sibling()) + out = print_node(out, child, flags, indent); + return out; + } + + // Print attributes of the node + template + inline OutIt print_attributes(OutIt out, const xml_node *node, int flags) + { + for (xml_attribute *attribute = node->first_attribute(); attribute; + attribute = attribute->next_attribute()) + { + if (attribute->name() && attribute->value()) + { + // Print attribute name + *out = Ch(' '), ++out; + out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out); + *out = Ch('='), ++out; + // Print attribute value using appropriate quote type + if (find_char(attribute->value(), attribute->value() + attribute->value_size())) + { + *out = Ch('\''), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), + Ch('"'), out); + *out = Ch('\''), ++out; + } + else + { + *out = Ch('"'), ++out; + out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), + Ch('\''), out); + *out = Ch('"'), ++out; + } + } + } + return out; + } + + // Print data node + template + inline OutIt print_data_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_data); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + return out; + } + + // Print data node + template + inline OutIt print_cdata_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_cdata); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'); ++out; + *out = Ch('!'); ++out; + *out = Ch('['); ++out; + *out = Ch('C'); ++out; + *out = Ch('D'); ++out; + *out = Ch('A'); ++out; + *out = Ch('T'); ++out; + *out = Ch('A'); ++out; + *out = Ch('['); ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch(']'); ++out; + *out = Ch(']'); ++out; + *out = Ch('>'); ++out; + return out; + } + + // Print element node + template + inline OutIt print_element_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_element); + + // Print element name and attributes, if any + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + out = print_attributes(out, node, flags); + + // If node is childless + if (node->value_size() == 0 && !node->first_node()) + { + // Print childless node tag ending + *out = Ch('/'), ++out; + *out = Ch('>'), ++out; + } + else + { + // Print normal node tag ending + *out = Ch('>'), ++out; + + // Test if node contains a single data node only (and no other nodes) + xml_node *child = node->first_node(); + if (!child) + { + // If node has no children, only print its value without indenting + out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out); + } + else if (child->next_sibling() == 0 && child->type() == node_data) + { + // If node has a sole data child, only print its value without indenting + out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out); + } + else + { + // Print all children with full indenting + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + out = print_children(out, node, flags, indent + 1); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + } + + // Print node end + *out = Ch('<'), ++out; + *out = Ch('/'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch('>'), ++out; + } + return out; + } + + // Print declaration node + template + inline OutIt print_declaration_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print declaration start + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + *out = Ch('x'), ++out; + *out = Ch('m'), ++out; + *out = Ch('l'), ++out; + + // Print attributes + out = print_attributes(out, node, flags); + + // Print declaration end + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + + return out; + } + + // Print comment node + template + inline OutIt print_comment_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_comment); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('-'), ++out; + *out = Ch('-'), ++out; + *out = Ch('>'), ++out; + return out; + } + + // Print doctype node + template + inline OutIt print_doctype_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_doctype); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('!'), ++out; + *out = Ch('D'), ++out; + *out = Ch('O'), ++out; + *out = Ch('C'), ++out; + *out = Ch('T'), ++out; + *out = Ch('Y'), ++out; + *out = Ch('P'), ++out; + *out = Ch('E'), ++out; + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('>'), ++out; + return out; + } + + // Print pi node + template + inline OutIt print_pi_node(OutIt out, const xml_node *node, int flags, int indent) + { + assert(node->type() == node_pi); + if (!(flags & print_no_indenting)) + out = fill_chars(out, indent, Ch('\t')); + *out = Ch('<'), ++out; + *out = Ch('?'), ++out; + out = copy_chars(node->name(), node->name() + node->name_size(), out); + *out = Ch(' '), ++out; + out = copy_chars(node->value(), node->value() + node->value_size(), out); + *out = Ch('?'), ++out; + *out = Ch('>'), ++out; + return out; + } + /////////////////////////////////////////////////////////////////////////// + // Internal printing operations + + // Print node + template + inline OutIt print_node(OutIt out, const xml_node *node, int flags, int indent) + { + // Print proper node type + switch (node->type()) + { + + // Document + case node_document: + out = print_children(out, node, flags, indent); + break; + + // Element + case node_element: + out = print_element_node(out, node, flags, indent); + break; + + // Data + case node_data: + out = print_data_node(out, node, flags, indent); + break; + + // CDATA + case node_cdata: + out = print_cdata_node(out, node, flags, indent); + break; + + // Declaration + case node_declaration: + out = print_declaration_node(out, node, flags, indent); + break; + + // Comment + case node_comment: + out = print_comment_node(out, node, flags, indent); + break; + + // Doctype + case node_doctype: + out = print_doctype_node(out, node, flags, indent); + break; + + // Pi + case node_pi: + out = print_pi_node(out, node, flags, indent); + break; + + // Unknown + default: + assert(0); + break; + } + + // If indenting not disabled, add line break after node + if (!(flags & print_no_indenting)) + *out = Ch('\n'), ++out; + + // Return modified iterator + return out; + } + } + //! \endcond + + /////////////////////////////////////////////////////////////////////////// + // Printing + + //! Prints XML to given output iterator. + //! \param out Output iterator to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output iterator pointing to position immediately after last character of printed text. + template + inline OutIt print(OutIt out, const xml_node &node, int flags = 0) + { + return internal::print_node(out, &node, flags, 0); + } + +#ifndef RAPIDXML_NO_STREAMS + + //! Prints XML to given output stream. + //! \param out Output stream to print to. + //! \param node Node to be printed. Pass xml_document to print entire document. + //! \param flags Flags controlling how XML is printed. + //! \return Output stream. + template + inline std::basic_ostream &print(std::basic_ostream &out, const xml_node &node, + int flags = 0) + { + print(std::ostream_iterator(out), node, flags); + return out; + } + + //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process. + //! \param out Output stream to print to. + //! \param node Node to be printed. + //! \return Output stream. + template + inline std::basic_ostream &operator <<(std::basic_ostream &out, const xml_node &node) + { + return print(out, node); + } + +#endif + +} + +#endif diff --git a/extlibs/rapidxml/rapidxml_utils.hpp b/extlibs/rapidxml/rapidxml_utils.hpp new file mode 100644 index 0000000..30e7369 --- /dev/null +++ b/extlibs/rapidxml/rapidxml_utils.hpp @@ -0,0 +1,122 @@ +#ifndef RAPIDXML_UTILS_HPP_INCLUDED +#define RAPIDXML_UTILS_HPP_INCLUDED + +// Copyright (C) 2006, 2009 Marcin Kalicinski +// Version 1.13 +// Revision $DateTime: 2009/05/13 01:46:17 $ +//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful +//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective. + +#include "rapidxml.hpp" +#include +#include +#include +#include + +namespace rapidxml +{ + + //! Represents data loaded from a file + template + class file + { + + public: + + //! Loads file into the memory. Data will be automatically destroyed by the destructor. + //! \param filename Filename to load. + file(const char *filename) + { + using namespace std; + + // Open stream + basic_ifstream stream(filename, ios::binary); + if (!stream) + throw runtime_error(string("cannot open file ") + filename); + stream.unsetf(ios::skipws); + + // Determine stream size + stream.seekg(0, ios::end); + size_t size = stream.tellg(); + stream.seekg(0); + + // Load data and add terminating 0 + m_data.resize(size + 1); + stream.read(&m_data.front(), static_cast(size)); + m_data[size] = 0; + } + + //! Loads file into the memory. Data will be automatically destroyed by the destructor + //! \param stream Stream to load from + file(std::basic_istream &stream) + { + using namespace std; + + // Load data and add terminating 0 + stream.unsetf(ios::skipws); + m_data.assign(istreambuf_iterator(stream), istreambuf_iterator()); + if (stream.fail() || stream.bad()) + throw runtime_error("error reading stream"); + m_data.push_back(0); + } + + //! Gets file data. + //! \return Pointer to data of file. + Ch *data() + { + return &m_data.front(); + } + + //! Gets file data. + //! \return Pointer to data of file. + const Ch *data() const + { + return &m_data.front(); + } + + //! Gets file data size. + //! \return Size of file data, in characters. + std::size_t size() const + { + return m_data.size(); + } + + private: + + std::vector m_data; // File data + + }; + + //! Counts children of node. Time complexity is O(n). + //! \return Number of children of node + template + inline std::size_t count_children(xml_node *node) + { + xml_node *child = node->first_node(); + std::size_t count = 0; + while (child) + { + ++count; + child = child->next_sibling(); + } + return count; + } + + //! Counts attributes of node. Time complexity is O(n). + //! \return Number of attributes of node + template + inline std::size_t count_attributes(xml_node *node) + { + xml_attribute *attr = node->first_attribute(); + std::size_t count = 0; + while (attr) + { + ++count; + attr = attr->next_attribute(); + } + return count; + } + +} + +#endif diff --git a/extlibs/timer/timer.c b/extlibs/timer/timer.c new file mode 100644 index 0000000..0dccd4e --- /dev/null +++ b/extlibs/timer/timer.c @@ -0,0 +1,354 @@ +//****************************************************************** +// +// Copyright 2014 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + + +#define _BSD_SOURCE + +#ifndef WITH_ARDUINO +#include +#include +#include +#include +#endif + +#include +#include + +#include "timer.h" + +#define SECOND (1) + +#define TIMEOUTS 10 + +#define TIMEOUT_USED 1 +#define TIMEOUT_UNUSED 2 + +#ifndef WITH_ARDUINO +pthread_t thread_id = 0; // 0: initial thread id (meaningless) +#endif + +struct timelist_t +{ + int timeout_state; + time_t timeout_seconds; + time_t timeout_time; + void (*cb)(); +} timeout_list[TIMEOUTS]; + +/* + * Return the number of seconds between before and after, (after - before). + * This must be async-signal safe, so it cannot use difftime(). + */ +time_t timespec_diff(const time_t after, const time_t before) +{ + return after - before; +} + +/* + * Add positive seconds to a timespec, nothing if seconds is negative. + */ +void timespec_add(time_t * to, const time_t seconds) +{ + if (to && seconds > 0) + { + (*to) += seconds; + } +} + +#ifndef WITH_ARDUINO + +long int getSeconds(struct tm* tp) +{ + long int nInterval = 0; + + nInterval = (tp->tm_hour * SECS_PER_HOUR); + nInterval += (tp->tm_min * SECS_PER_MIN); + nInterval += (tp->tm_sec * SECOND); + + printf("%ld", nInterval); + + return nInterval; +} + +long int getRelativeSecondsOfDayofweek(int ia, int ib) +{ + if( ia > ib ) + return (((long int)(7 - (ib - ia))) * SECS_PER_DAY); + + return (((long int)((ib - ia))) * SECS_PER_DAY); +} + +long int getRelativeIntervalOfWeek(struct tm* tp) +{ + time_t current_time; + struct tm* current, *midnight; + time_t delayed_time = 0; + + time(¤t_time); + current = localtime(¤t_time); + midnight = (struct tm* )malloc(sizeof(struct tm)); + memcpy(midnight, current, sizeof(struct tm)); + + midnight->tm_hour = 0; + midnight->tm_min = 0; + midnight->tm_sec = 0; + + // Seconds. + // Seconds from midnight. + delayed_time = current_time - mktime(midnight); + delayed_time = getRelativeSecondsOfDayofweek(current->tm_wday, tp->tm_wday) - delayed_time; + delayed_time = delayed_time + getSeconds(tp); + + return delayed_time; +} + +long int getSecondsFromAbsTime(struct tm* tp) +{ + time_t current_time; + time_t delayed_time = 0; + + time(¤t_time); + localtime(¤t_time); + + delayed_time = mktime(tp) - current_time; + + return delayed_time; +} + +time_t registerTimer(const time_t seconds, int *id, void *cb) +{ + time_t now, then; + time_t next; + int i, idx; + + if (0 == thread_id) + { + initThread(); + } + + if (seconds <= 0) + return -1 ; + + // get the current time + time(&now); + + for (idx = 0; idx < TIMEOUTS; ++idx) + if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED)) + break; + + if (TIMEOUTS == idx) // reach to end of timer list + return -1; + + // idx th timeout will be used. + // Reset and set state of the timer + timeout_list[idx].timeout_state = 0; + timeout_list[idx].timeout_state |= TIMEOUT_USED; + + // calculate when the timeout should fire + then = now; + timespec_add(&then, seconds); + + timeout_list[idx].timeout_time = then; + timeout_list[idx].timeout_seconds = seconds; + + // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb); + timeout_list[idx].cb = cb; + // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb); + + // How long till the next timeout? + next = seconds; + for (i = 0; i < TIMEOUTS; i++) + { + if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED) + { + const time_t secs = timespec_diff(timeout_list[i].timeout_time, now); + + if (secs >= 0 && secs < next) + next = secs; + } + } + + *id = idx; + /* Return the timeout number. */ + return timeout_list[idx].timeout_time; +} + +void unregisterTimer(int idx) +{ + if( 0 <= idx && idx <= TIMEOUTS) + timeout_list[idx].timeout_state = TIMEOUT_UNUSED; +} + +void checkTimeout() +{ + time_t now; + int i; + + time(&now); + + /* Check all timeouts that are used and armed, but not passed yet. */ + for (i = 0; i < TIMEOUTS; i++) + { + if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) == TIMEOUT_USED) + { + const time_t seconds = timespec_diff(timeout_list[i].timeout_time, now); + + if (seconds <= 0) + { + /* timeout [i] fires! */ + timeout_list[i].timeout_state = TIMEOUT_UNUSED; + if (timeout_list[i].cb) + { + timeout_list[i].cb(); + } + } + } + } +} + +void *loop(void *threadid) +{ + while (1) + { + sleep(SECOND); + checkTimeout(); + } + + return NULL ; +} + +int initThread() +{ + int res; + long t = 0; + + res = pthread_create(&thread_id, NULL, loop, (void *) t); + + if (res) + { + printf("ERROR; return code from pthread_create() is %d\n", res); + return -1; + } + + return 0; +} +#else // WITH_ARDUINO +time_t timeToSecondsFromNow(tmElements_t *t_then) +{ + time_t t, then; + + t = now(); + then = makeTime((*t_then)); + + return (time_t) (then - t); +} + +time_t registerTimer(const time_t seconds, int *id, void (*cb)()) +{ + time_t t, then; + time_t next; + int i, idx; + + if (seconds <= 0) + return -1; + + // get the current time + t = now(); + + for (idx = 0; idx < TIMEOUTS; ++idx) + if (!((timeout_list[idx].timeout_state & TIMEOUT_USED) & TIMEOUT_USED)) + break; + + if (TIMEOUTS == idx)// reach to end of timer list + return -1; + + // idx th timeout will be used. + // Reset and set state of the timer + timeout_list[idx].timeout_state = 0; + timeout_list[idx].timeout_state |= TIMEOUT_USED; + + // calculate when the timeout should fire + then = t; + timespec_add(&then, seconds); + + timeout_list[idx].timeout_time = then; + timeout_list[idx].timeout_seconds = seconds; + + // printf( "\nbefore timeout_list[idx].cb = %X\n", timeout_list[idx].cb); + timeout_list[idx].cb = cb; + // printf( " after timeout_list[idx].cb = %X\n", timeout_list[idx].cb); + + // How long till the next timeout? + next = seconds; + for (i = 0; i < TIMEOUTS; i++) + { + if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) + == TIMEOUT_USED) + { + const time_t secs = timespec_diff(timeout_list[i].timeout_time, + t); + + if (secs >= 0 && secs < next) + next = secs; + } + } + + *id = idx; + /* Return the timeout number. */ + return timeout_list[idx].timeout_time; +} + +void unregisterTimer(int idx) +{ + if( 0 <= idx && idx <= TIMEOUTS) + timeout_list[idx].timeout_state = TIMEOUT_UNUSED; +} + +void checkTimeout() +{ + time_t t; + int i; + + t = now(); + + /* Check all timeouts that are used and armed, but not passed yet. */ + for (i = 0; i < TIMEOUTS; i++) + { + if ((timeout_list[i].timeout_state & (TIMEOUT_USED | TIMEOUT_UNUSED)) + == TIMEOUT_USED) + { + const time_t seconds = timespec_diff(timeout_list[i].timeout_time, + t); + + if (seconds <= 0) + { + /* timeout [i] fires! */ + timeout_list[i].timeout_state = TIMEOUT_UNUSED; + if (timeout_list[i].cb) + { + timeout_list[i].cb(); + } + } + } + } +} + +#endif diff --git a/extlibs/timer/timer.h b/extlibs/timer/timer.h new file mode 100644 index 0000000..3ecff36 --- /dev/null +++ b/extlibs/timer/timer.h @@ -0,0 +1,74 @@ +//****************************************************************** +// +// Copyright 2014 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef TIMER_H_ +#define TIMER_H_ + +#ifndef WITH_ARDUINO +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +#ifndef WITH_ARDUINO +#define SECS_PER_MIN (60L) +#define SECS_PER_HOUR (SECS_PER_MIN * 60L) +#define SECS_PER_DAY (SECS_PER_HOUR * 24L) +#define DAYS_PER_WEEK (7L) +#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK) +#define SECS_PER_YEAR (SECS_PER_WEEK * 52L) +#define SECS_YR_2000 (946684800L) +#endif + +time_t timespec_diff(const time_t after, const time_t before); +void timespec_add(time_t * to, const time_t seconds); +void checkTimeout(); + +#ifndef WITH_ARDUINO +long int getSeconds(struct tm* tp); +long int getRelativeIntervalOfWeek(struct tm* tp); +long int getSecondsFromAbsTime(struct tm* tp); + +int initThread(); +void *loop(void *threadid); +time_t registerTimer(const time_t seconds, int *id, void *cb); +void unregisterTimer(int id); + +#else + +time_t timeToSecondsFromNow(tmElements_t *t); +time_t registerTimer(const time_t seconds, int *id, void (*cb)()); +void unregisterTimer(int id); + + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* TIMER_H_ */ + diff --git a/extlibs/tinydtls/0001-Added-support-in-tinyDTLS-to-support-rehandshake.patch b/extlibs/tinydtls/0001-Added-support-in-tinyDTLS-to-support-rehandshake.patch new file mode 100644 index 0000000..fb9c71f --- /dev/null +++ b/extlibs/tinydtls/0001-Added-support-in-tinyDTLS-to-support-rehandshake.patch @@ -0,0 +1,172 @@ +From c78aa91005b7b9542d595dc32d8c8fe020d2257d Mon Sep 17 00:00:00 2001 +From: Sachin Agrawal +Date: Wed, 21 Jan 2015 08:55:00 -0800 +Subject: [PATCH 1/1] Added support in tinyDTLS to support rehandshake + +As per RFC 6347 section 4.2.8, DTLS Server should support requests +from clients who have silently abandoned the existing association +and initiated a new handshake request by sending a ClientHello. +Code is updated to detect this scenario and delete the old +association when client successfully responds to HelloVerifyRequest. + + +Change-Id: I6e256921215c1a22e9e5013499c4dfd98659f8cc +Signed-off-by: Sachin Agrawal +--- + extlibs/tinydtls/dtls.c | 74 +++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 68 insertions(+), 6 deletions(-) + +diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c +index 779e701..111a65d 100644 +--- a/extlibs/tinydtls/dtls.c ++++ b/extlibs/tinydtls/dtls.c +@@ -529,6 +529,37 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) { + (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)); + } + ++/** ++ * This method detects if we already have a established DTLS session with ++ * peer and the peer is attempting to perform a fresh handshake by sending ++ * messages with epoch = 0. This is to handle situations mentioned in ++ * RFC 6347 - section 4.2.8. ++ * ++ * @param msg The packet received from Client ++ * @param msglen Packet length ++ * @param peer peer who is the sender for this packet ++ * @return @c 1 if this is a rehandshake attempt by ++ * client ++ */ ++static int ++hs_attempt_with_existing_peer(uint8_t *msg, size_t msglen, ++ dtls_peer_t *peer) ++{ ++ if ((peer) && (peer->state == DTLS_STATE_CONNECTED)) { ++ if (msg[0] == DTLS_CT_HANDSHAKE) { ++ uint16_t msg_epoch = dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); ++ if (msg_epoch == 0) { ++ dtls_handshake_header_t * hs_header = DTLS_HANDSHAKE_HEADER(msg + DTLS_RH_LENGTH); ++ if (hs_header->msg_type == DTLS_HT_CLIENT_HELLO || ++ hs_header->msg_type == DTLS_HT_HELLO_REQUEST) { ++ return 1; ++ } ++ } ++ } ++ } ++ return 0; ++} ++ + /** Dump out the cipher keys and IVs used for the symetric cipher. */ + static void dtls_debug_keyblock(dtls_security_parameters_t *config) + { +@@ -1540,6 +1571,7 @@ static int + dtls_verify_peer(dtls_context_t *ctx, + dtls_peer_t *peer, + session_t *session, ++ const dtls_state_t state, + uint8 *data, size_t data_length) + { + uint8 buf[DTLS_HV_LENGTH + DTLS_COOKIE_LENGTH]; +@@ -1595,9 +1627,11 @@ dtls_verify_peer(dtls_context_t *ctx, + + /* TODO use the same record sequence number as in the ClientHello, + see 4.2.1. Denial-of-Service Countermeasures */ +- err = dtls_send_handshake_msg_hash(ctx, peer, session, +- DTLS_HT_HELLO_VERIFY_REQUEST, +- buf, p - buf, 0); ++ err = dtls_send_handshake_msg_hash(ctx, ++ state == DTLS_STATE_CONNECTED ? peer : NULL, ++ session, ++ DTLS_HT_HELLO_VERIFY_REQUEST, ++ buf, p - buf, 0); + if (err < 0) { + dtls_warn("cannot send HelloVerify request\n"); + } +@@ -3209,7 +3243,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, + + case DTLS_HT_CLIENT_HELLO: + +- if ((peer && state != DTLS_STATE_CONNECTED) || ++ if ((peer && state != DTLS_STATE_CONNECTED && state != DTLS_STATE_WAIT_CLIENTHELLO) || + (!peer && state != DTLS_STATE_WAIT_CLIENTHELLO)) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } +@@ -3223,7 +3257,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, + Anything else will be rejected. Fragementation is not allowed + here as it would require peer state as well. + */ +- err = dtls_verify_peer(ctx, peer, session, data, data_length); ++ err = dtls_verify_peer(ctx, peer, session, state, data, data_length); + if (err < 0) { + dtls_warn("error in dtls_verify_peer err: %i\n", err); + return err; +@@ -3236,7 +3270,23 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, + + /* At this point, we have a good relationship with this peer. This + * state is left for re-negotiation of key material. */ ++ /* As per RFC 6347 - section 4.2.8 if this is an attempt to ++ * rehandshake, we can delete the existing key material ++ * as the client has demonstrated reachibility by completing ++ * the cookie exchange */ ++ if (peer && state == DTLS_STATE_WAIT_CLIENTHELLO) { ++ dtls_debug("removing the peer\n"); ++#ifndef WITH_CONTIKI ++ HASH_DEL_PEER(ctx->peers, peer); ++#else /* WITH_CONTIKI */ ++ list_remove(ctx->peers, peer); ++#endif /* WITH_CONTIKI */ ++ ++ dtls_free_peer(peer); ++ peer = NULL; ++ } + if (!peer) { ++ dtls_debug("creating new peer\n"); + dtls_security_parameters_t *security; + + /* msg contains a Client Hello with a valid cookie, so we can +@@ -3594,6 +3644,7 @@ dtls_handle_message(dtls_context_t *ctx, + int data_length; /* length of decrypted payload + (without MAC and padding) */ + int err; ++ int bypass_epoch_check = 0; + + /* check if we have DTLS state for addr/port/ifindex */ + peer = dtls_get_peer(ctx, session); +@@ -3613,6 +3664,15 @@ dtls_handle_message(dtls_context_t *ctx, + if (peer) { + data_length = decrypt_verify(peer, msg, rlen, &data); + if (data_length < 0) { ++ if (hs_attempt_with_existing_peer(msg, rlen, peer)) { ++ data = msg + DTLS_RH_LENGTH; ++ data_length = rlen - DTLS_RH_LENGTH; ++ state = DTLS_STATE_WAIT_CLIENTHELLO; ++ role = DTLS_SERVER; ++ /* Bypass epoch check as the epoch for incoming msg is 0 ++ and expected epoch MAY be different */ ++ bypass_epoch_check = 1; ++ } else { + int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); + dtls_info("decrypt_verify() failed\n"); + if (peer->state < DTLS_STATE_CONNECTED) { +@@ -3623,8 +3683,10 @@ dtls_handle_message(dtls_context_t *ctx, + } + return err; + } ++ } else { + role = peer->role; + state = peer->state; ++ } + } else { + /* is_record() ensures that msg contains at least a record header */ + data = msg + DTLS_RH_LENGTH; +@@ -3677,7 +3739,7 @@ dtls_handle_message(dtls_context_t *ctx, + /* Handshake messages other than Finish must use the current + * epoch, Finish has epoch + 1. */ + +- if (peer) { ++ if (peer && !bypass_epoch_check) { + uint16_t expected_epoch = dtls_security_params(peer)->epoch; + uint16_t msg_epoch = + dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); +-- +1.7.9.5 + diff --git a/extlibs/tinydtls/0001-Adding-autoconf-generated-files-in-tinydtls-repo.patch b/extlibs/tinydtls/0001-Adding-autoconf-generated-files-in-tinydtls-repo.patch new file mode 100644 index 0000000..263ed58 --- /dev/null +++ b/extlibs/tinydtls/0001-Adding-autoconf-generated-files-in-tinydtls-repo.patch @@ -0,0 +1,256 @@ +From b44aa20e0ff2763468bf82ff4e996dec03e872bd Mon Sep 17 00:00:00 2001 +From: Sachin Agrawal +Date: Thu, 2 Apr 2015 15:21:40 -0700 +Subject: [PATCH 1/1] Adding autoconf generated files in tinydtls repo + +tinydtls build system uses autotools while Iotivity uses +scons build system. Since tinydtls contains few source files +and header files, it seems convenient for Iotivity to use +scons to build tinydtls library. +This patch is to add autoconf generated files so that tinydtls +can be build using scons script. + +Note: Since this change is a custom change and specifically +for Iotivity, I do not intend to submit this patch for +upstreaming. + +Change-Id: I4da593a8abccd731466a88d365dca536f608c94a +Signed-off-by: Sachin Agrawal +--- + extlibs/tinydtls/dtls_config.h | 171 ++++++++++++++++++++++++++++++++++++++++ + extlibs/tinydtls/tinydtls.h | 45 +++++++++++ + 2 files changed, 216 insertions(+) + create mode 100644 extlibs/tinydtls/dtls_config.h + create mode 100644 extlibs/tinydtls/tinydtls.h + +diff --git a/extlibs/tinydtls/dtls_config.h b/extlibs/tinydtls/dtls_config.h +new file mode 100644 +index 0000000..39df8c9 +--- /dev/null ++++ b/extlibs/tinydtls/dtls_config.h +@@ -0,0 +1,171 @@ ++/* dtls_config.h. Generated from dtls_config.h.in by configure. */ ++/* tinydtls -- a very basic DTLS implementation ++ * ++ * Copyright (C) 2011--2014 Olaf Bergmann ++ * Copyright (C) 2013 Hauke Mehrtens ++ * ++ * Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, ++ * modify, merge, publish, distribute, sublicense, and/or sell copies ++ * of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++/** ++ * @file dtls_config.h ++ * @brief internal configuration for tinydtls library ++ * ++ * This file has been generated by configure from dtls_config.h.in. ++ */ ++ ++/* dummy definitions for PACKAGE_NAME and PACKAGE_VERSION */ ++#define PACKAGE_NAME "tinydtls" ++#define PACKAGE_STRING "tinydtls 0.8.1" ++#define PACKAGE_VERSION "0.8.1" ++ ++#ifdef CONTIKI ++#include "contiki.h" ++#include "contiki-lib.h" ++#include "contiki-net.h" ++ ++#include "contiki-conf.h" ++ ++/* global constants for constrained devices running Contiki */ ++#ifndef DTLS_PEER_MAX ++/** The maximum number DTLS peers (i.e. sessions). */ ++# define DTLS_PEER_MAX 1 ++#endif ++ ++#ifndef DTLS_HANDSHAKE_MAX ++/** The maximum number of concurrent DTLS handshakes. */ ++# define DTLS_HANDSHAKE_MAX 1 ++#endif ++ ++#ifndef DTLS_SECURITY_MAX ++/** The maximum number of concurrently used cipher keys */ ++# define DTLS_SECURITY_MAX (DTLS_PEER_MAX + DTLS_HANDSHAKE_MAX) ++#endif ++ ++#ifndef DTLS_HASH_MAX ++/** The maximum number of hash functions that can be used in parallel. */ ++# define DTLS_HASH_MAX (3 * DTLS_PEER_MAX) ++#endif ++#endif /* CONTIKI */ ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_ASSERT_H 1 ++ ++/* Define to 1 if your system has a GNU libc compatible `malloc' function, and ++ to 0 otherwise. */ ++#define HAVE_MALLOC 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_MEMORY_H 1 ++ ++/* Define to 1 if you have the `memset' function. */ ++#define HAVE_MEMSET 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDDEF_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDINT_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STDLIB_H 1 ++ ++/* Define to 1 if you have the `strdup' function. */ ++#define HAVE_STRDUP 1 ++ ++/* Define to 1 if you have the `strerror' function. */ ++#define HAVE_STRERROR 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRINGS_H 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_STRING_H 1 ++ ++/* Define to 1 if you have the `strnlen' function. */ ++#define HAVE_STRNLEN 1 ++ ++/* Define to 1 if you have the header file. */ ++#define HAVE_TIME_H 1 ++ ++/* Define to 1 if you have the `vprintf' function. */ ++#define HAVE_VPRINTF 1 ++ ++/* Define to the address where bug reports for this package should be sent. */ ++#define PACKAGE_BUGREPORT "" ++ ++/* Define to the full name of this package. */ ++#define PACKAGE_NAME "tinydtls" ++ ++/* Define to the full name and version of this package. */ ++#define PACKAGE_STRING "tinydtls 0.8.1" ++ ++/* Define to the one symbol short name of this package. */ ++#define PACKAGE_TARNAME "tinydtls" ++ ++/* Define to the home page for this package. */ ++#define PACKAGE_URL "" ++ ++/* Define to the version of this package. */ ++#define PACKAGE_VERSION "0.8.1" ++ ++/* Define to 1 if you have the ANSI C header files. */ ++#define STDC_HEADERS 1 ++ ++/* Define to `__inline__' or `__inline' if that's what the C compiler ++ calls it, or to nothing if 'inline' is not supported under any name. */ ++#ifndef __cplusplus ++/* #undef inline */ ++#endif ++ ++/* Define to rpl_malloc if the replacement function should be used. */ ++/* #undef malloc */ ++/* Define to `unsigned int' if does not define. */ ++ ++/* #undef size_t */ ++ ++/************************************************************************/ ++/* Specific Contiki platforms */ ++/************************************************************************/ ++ ++#ifdef CONTIKI ++ ++#if CONTIKI_TARGET_ECONOTAG ++# include "platform-specific/config-econotag.h" ++#endif /* CONTIKI_TARGET_ECONOTAG */ ++ ++#ifdef CONTIKI_TARGET_CC2538DK ++# include "platform-specific/config-cc2538dk.h" ++#endif /* CONTIKI_TARGET_CC2538DK */ ++ ++#ifdef CONTIKI_TARGET_WISMOTE ++# include "platform-specific/config-wismote.h" ++#endif /* CONTIKI_TARGET_WISMOTE */ ++ ++#ifdef CONTIKI_TARGET_SKY ++# include "platform-specific/config-sky.h" ++#endif /* CONTIKI_TARGET_SKY */ ++ ++#ifdef CONTIKI_TARGET_MINIMAL_NET ++# include "platform-specific/config-minimal-net.h" ++#endif /* CONTIKI_TARGET_MINIMAL_NET */ ++ ++#endif /* CONTIKI */ +diff --git a/extlibs/tinydtls/tinydtls.h b/extlibs/tinydtls/tinydtls.h +new file mode 100644 +index 0000000..3fa228a +--- /dev/null ++++ b/extlibs/tinydtls/tinydtls.h +@@ -0,0 +1,45 @@ ++/* tinydtls.h. Generated from tinydtls.h.in by configure. */ ++/* tinydtls -- a very basic DTLS implementation ++ * ++ * Copyright (C) 2011--2014 Olaf Bergmann ++ * Copyright (C) 2013 Hauke Mehrtens ++ * ++ * Permission is hereby granted, free of charge, to any person ++ * obtaining a copy of this software and associated documentation ++ * files (the "Software"), to deal in the Software without ++ * restriction, including without limitation the rights to use, copy, ++ * modify, merge, publish, distribute, sublicense, and/or sell copies ++ * of the Software, and to permit persons to whom the Software is ++ * furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be ++ * included in all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS ++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ * SOFTWARE. ++ */ ++ ++/** ++ * @file tinydtls.h ++ * @brief public tinydtls API ++ */ ++ ++#ifndef _DTLS_TINYDTLS_H_ ++#define _DTLS_TINYDTLS_H_ ++ ++/** Defined to 1 if tinydtls is built with support for ECC */ ++/* #undef DTLS_ECC */ ++ ++/** Defined to 1 if tinydtls is built with support for PSK */ ++#define DTLS_PSK 1 ++ ++/** Defined to 1 if tinydtls is built for Contiki OS */ ++/* #undef WITH_CONTIKI */ ++ ++#endif /* _DTLS_TINYDTLS_H_ */ +-- +1.7.9.5 + diff --git a/extlibs/tinydtls/0001-Bug-Fix-in-earlier-rehandhsake-implementation.patch b/extlibs/tinydtls/0001-Bug-Fix-in-earlier-rehandhsake-implementation.patch new file mode 100644 index 0000000..c52b679 --- /dev/null +++ b/extlibs/tinydtls/0001-Bug-Fix-in-earlier-rehandhsake-implementation.patch @@ -0,0 +1,174 @@ +From e25d93dec6d2907430f3680ad5fbdfedc1ee94d8 Mon Sep 17 00:00:00 2001 +From: Sachin Agrawal +Date: Sun, 15 Feb 2015 22:16:43 -0800 +Subject: [PATCH 1/1] Bug Fix in earlier rehandhsake implementation + +Identified a corner case in earlier rehandshake implementation where if +no data transfer takes place between client and Server before re-handshake +is issued, re-handshake process was failing. DTLS state machine does not +update it's state at Server until the first data packet was received from +client. Updated logic to detect for 're-handshake' situation when epoch +mis-match happens. Also updated dtls-client test app to conveniently test +the feature. Use 'client:rehandshake' command for testing. + +Change-Id: Idfaad7d477508603c35ad7948ca7c8f05e3228d0 +Signed-off-by: Sachin Agrawal +--- + extlibs/tinydtls/dtls.c | 44 ++++++++++++++++++---------------- + extlibs/tinydtls/tests/dtls-client.c | 27 +++++++++++++++++++++ + 2 files changed, 50 insertions(+), 21 deletions(-) + +diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c +index a87d7f1..a923386 100644 +--- a/extlibs/tinydtls/dtls.c ++++ b/extlibs/tinydtls/dtls.c +@@ -1562,6 +1562,7 @@ static void dtls_destroy_peer(dtls_context_t *ctx, dtls_peer_t *peer, int unlink + * \param ctx The DTLS context. + * \param peer The remote party we are talking to, if any. + * \param session Transport address of the remote peer. ++ * \param state Current state of the connection. + * \param msg The received datagram. + * \param msglen Length of \p msg. + * \return \c 1 if msg is a Client Hello with a valid cookie, \c 0 or +@@ -3644,7 +3645,6 @@ dtls_handle_message(dtls_context_t *ctx, + int data_length; /* length of decrypted payload + (without MAC and padding) */ + int err; +- int bypass_epoch_check = 0; + + /* check if we have DTLS state for addr/port/ifindex */ + peer = dtls_get_peer(ctx, session); +@@ -3668,24 +3668,21 @@ dtls_handle_message(dtls_context_t *ctx, + data = msg + DTLS_RH_LENGTH; + data_length = rlen - DTLS_RH_LENGTH; + state = DTLS_STATE_WAIT_CLIENTHELLO; +- role = DTLS_SERVER; +- /* Bypass epoch check as the epoch for incoming msg is 0 +- and expected epoch MAY be different */ +- bypass_epoch_check = 1; ++ role = DTLS_SERVER; + } else { +- int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); +- dtls_info("decrypt_verify() failed\n"); +- if (peer->state < DTLS_STATE_CONNECTED) { +- dtls_alert_send_from_err(ctx, peer, &peer->session, err); +- peer->state = DTLS_STATE_CLOSED; +- /* dtls_stop_retransmission(ctx, peer); */ +- dtls_destroy_peer(ctx, peer, 1); +- } +- return err; +- } +- } else { +- role = peer->role; +- state = peer->state; ++ int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); ++ dtls_info("decrypt_verify() failed\n"); ++ if (peer->state < DTLS_STATE_CONNECTED) { ++ dtls_alert_send_from_err(ctx, peer, &peer->session, err); ++ peer->state = DTLS_STATE_CLOSED; ++ /* dtls_stop_retransmission(ctx, peer); */ ++ dtls_destroy_peer(ctx, peer, 1); ++ } ++ return err; ++ } ++ } else { ++ role = peer->role; ++ state = peer->state; + } + } else { + /* is_record() ensures that msg contains at least a record header */ +@@ -3739,7 +3736,7 @@ dtls_handle_message(dtls_context_t *ctx, + /* Handshake messages other than Finish must use the current + * epoch, Finish has epoch + 1. */ + +- if (peer && !bypass_epoch_check) { ++ if (peer) { + uint16_t expected_epoch = dtls_security_params(peer)->epoch; + uint16_t msg_epoch = + dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); +@@ -3754,9 +3751,14 @@ dtls_handle_message(dtls_context_t *ctx, + } + + if (expected_epoch != msg_epoch) { +- dtls_warn("Wrong epoch, expected %i, got: %i\n", ++ if (hs_attempt_with_existing_peer(msg, rlen, peer)) { ++ state = DTLS_STATE_WAIT_CLIENTHELLO; ++ role = DTLS_SERVER; ++ } else { ++ dtls_warn("Wrong epoch, expected %i, got: %i\n", + expected_epoch, msg_epoch); +- break; ++ break; ++ } + } + } + +diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c +index 306a380..05cb98f 100644 +--- a/extlibs/tinydtls/tests/dtls-client.c ++++ b/extlibs/tinydtls/tests/dtls-client.c +@@ -44,6 +44,7 @@ typedef struct { + static dtls_str output_file = { 0, NULL }; /* output file name */ + + static dtls_context_t *dtls_context = NULL; ++static dtls_context_t *orig_dtls_context = NULL; + + + static const unsigned char ecdsa_priv_key[] = { +@@ -235,6 +236,7 @@ dtls_handle_read(struct dtls_context_t *ctx) { + static void dtls_handle_signal(int sig) + { + dtls_free_context(dtls_context); ++ dtls_free_context(orig_dtls_context); + signal(sig, SIG_DFL); + kill(getpid(), sig); + } +@@ -324,6 +326,12 @@ static dtls_handler_t cb = { + #define DTLS_CLIENT_CMD_CLOSE "client:close" + #define DTLS_CLIENT_CMD_RENEGOTIATE "client:renegotiate" + ++/* As per RFC 6347 section 4.2.8, DTLS Server should support requests ++ * from clients who have silently abandoned the existing association ++ * and initiated a new handshake request by sending a ClientHello. ++ * Below command tests this feature. ++ */ ++#define DTLS_CLIENT_CMD_REHANDSHAKE "client:rehandshake" + int + main(int argc, char **argv) { + fd_set rfds, wfds; +@@ -504,6 +512,24 @@ main(int argc, char **argv) { + printf("client: renegotiate connection\n"); + dtls_renegotiate(dtls_context, &dst); + len = 0; ++ } else if (len >= strlen(DTLS_CLIENT_CMD_REHANDSHAKE) && ++ !memcmp(buf, DTLS_CLIENT_CMD_REHANDSHAKE, strlen(DTLS_CLIENT_CMD_REHANDSHAKE))) { ++ printf("client: rehandshake connection\n"); ++ if (orig_dtls_context == NULL) { ++ /* Cache the current context. We cannot free the current context as it will notify ++ * the Server to close the connection (which we do not want). ++ */ ++ orig_dtls_context = dtls_context; ++ /* Now, Create a new context and attempt to initiate a handshake. */ ++ dtls_context = dtls_new_context(&fd); ++ if (!dtls_context) { ++ dtls_emerg("cannot create context\n"); ++ exit(-1); ++ } ++ dtls_set_handler(dtls_context, &cb); ++ dtls_connect(dtls_context, &dst); ++ } ++ len = 0; + } else { + try_send(dtls_context, &dst); + } +@@ -511,6 +537,7 @@ main(int argc, char **argv) { + } + + dtls_free_context(dtls_context); ++ dtls_free_context(orig_dtls_context); + exit(0); + } + +-- +1.7.9.5 + diff --git a/extlibs/tinydtls/0001-Fixed-issue-to-pass-PSK-identity-hint-to-application.patch b/extlibs/tinydtls/0001-Fixed-issue-to-pass-PSK-identity-hint-to-application.patch new file mode 100644 index 0000000..343c891 --- /dev/null +++ b/extlibs/tinydtls/0001-Fixed-issue-to-pass-PSK-identity-hint-to-application.patch @@ -0,0 +1,73 @@ +From 116451f8fab0df90e87d394d1fa1ac9e739c7dbe Mon Sep 17 00:00:00 2001 +From: Sachin Agrawal +Date: Tue, 20 Jan 2015 15:57:40 -0800 +Subject: [PATCH 1/1] Fixed issue to pass PSK identity hint to application in + callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In cases (with PSK ciphersuite) where Server is sending +'PSK Identity Hint’ inside ServerKeyExchange message, DTLS library +is not passing the ‘identity hint’ inside ‘desc’ argument in +get_psk_info(DTLS_PSK_KEY, desc) callback. Instead, ‘desc’ contains +the identity of the client itself. The reason for this is that the +code inside dtls_send_client_key_exchange() method +overwrites the ‘identity hint’ received earlier. + +Change-Id: Ibf447e3a6b33284118908a52aed4cf636038ab23 +Signed-off-by: Sachin Agrawal +--- + extlibs/tinydtls/dtls.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c +index 92222eb..9090f22 100644 +--- a/extlibs/tinydtls/dtls.c ++++ b/extlibs/tinydtls/dtls.c +@@ -2164,6 +2164,7 @@ static int + dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer) + { + uint8 buf[DTLS_CKXEC_LENGTH]; ++ uint8 client_id[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; + uint8 *p; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + +@@ -2175,28 +2176,24 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer) + int len; + + len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY, +- handshake->keyx.psk.identity, handshake->keyx.psk.id_length, +- buf + sizeof(uint16), +- min(sizeof(buf) - sizeof(uint16), +- sizeof(handshake->keyx.psk.identity))); ++ NULL, 0, ++ client_id, ++ sizeof(client_id)); + if (len < 0) { + dtls_crit("no psk identity set in kx\n"); + return len; + } + + if (len + sizeof(uint16) > DTLS_CKXEC_LENGTH) { +- memset(&handshake->keyx.psk, 0, sizeof(dtls_handshake_parameters_psk_t)); + dtls_warn("the psk identity is too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } +- handshake->keyx.psk.id_length = (unsigned int)len; +- memcpy(handshake->keyx.psk.identity, p + sizeof(uint16), len); + +- dtls_int_to_uint16(p, handshake->keyx.psk.id_length); ++ dtls_int_to_uint16(p, len); + p += sizeof(uint16); + +- memcpy(p, handshake->keyx.psk.identity, handshake->keyx.psk.id_length); +- p += handshake->keyx.psk.id_length; ++ memcpy(p, client_id, len); ++ p += len; + + break; + } +-- +1.7.9.5 + diff --git a/extlibs/tinydtls/0001-Updated-tinyDTLS-test-apps-to-use-identity-hint.patch b/extlibs/tinydtls/0001-Updated-tinyDTLS-test-apps-to-use-identity-hint.patch new file mode 100644 index 0000000..4470e1a --- /dev/null +++ b/extlibs/tinydtls/0001-Updated-tinyDTLS-test-apps-to-use-identity-hint.patch @@ -0,0 +1,188 @@ +From 6b26519bea04167b9cf68069bf641af4651c87e0 Mon Sep 17 00:00:00 2001 +From: Sachin Agrawal +Date: Thu, 26 Feb 2015 09:28:06 -0800 +Subject: [PATCH 1/1] Updated tinyDTLS test apps to use identity hint + +dtls-server test is updated to pass 'psk hint' to tinyDTLS library so that +it can send ServerKeyExchange packet. Similarly, dtls-client test +is updated to retrieve PSK specific for the server whose identity was +received via 'psk hint' packet. + +Change-Id: Ifba720f1505ed6afbf56dfc179d98790176ce0b0 +Signed-off-by: Sachin Agrawal +--- + extlibs/tinydtls/tests/dtls-client.c | 45 ++++++++++++++++++++++------------ + extlibs/tinydtls/tests/dtls-server.c | 43 +++++++++++++++++++++----------- + 2 files changed, 59 insertions(+), 29 deletions(-) + +diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c +index 96ed0fa..65b0275 100644 +--- a/extlibs/tinydtls/tests/dtls-client.c ++++ b/extlibs/tinydtls/tests/dtls-client.c +@@ -22,9 +22,10 @@ + + #define DEFAULT_PORT 20220 + +-#define PSK_DEFAULT_IDENTITY "Client_identity" ++#define PSK_CLIENT_IDENTITY "Client_identity" ++#define PSK_SERVER_IDENTITY "Server_identity" + #define PSK_DEFAULT_KEY "secretPSK" +-#define PSK_OPTIONS "i:k:" ++#define PSK_OPTIONS "i:s:k:" + + #ifdef __GNUC__ + #define UNUSED_PARAM __attribute__((unused)) +@@ -93,8 +94,10 @@ read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) { + /* The PSK information for DTLS */ + #define PSK_ID_MAXLEN 256 + #define PSK_MAXLEN 256 +-static unsigned char psk_id[PSK_ID_MAXLEN]; +-static size_t psk_id_length = 0; ++static unsigned char psk_client_id[PSK_ID_MAXLEN]; ++static size_t psk_client_id_length = 0; ++static unsigned char psk_server_id[PSK_ID_MAXLEN]; ++static size_t psk_server_id_length = 0; + static unsigned char psk_key[PSK_MAXLEN]; + static size_t psk_key_length = 0; + +@@ -114,15 +117,15 @@ get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, + dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id); + } + +- if (result_length < psk_id_length) { ++ if (result_length < psk_client_id_length) { + dtls_warn("cannot set psk_identity -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + +- memcpy(result, psk_id, psk_id_length); +- return psk_id_length; ++ memcpy(result, psk_client_id, psk_client_id_length); ++ return psk_client_id_length; + case DTLS_PSK_KEY: +- if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { ++ if (id_len != psk_server_id_length || memcmp(psk_server_id, id, id_len) != 0) { + dtls_warn("PSK for unknown id requested, exiting\n"); + return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); + } else if (result_length < psk_key_length) { +@@ -291,12 +294,13 @@ usage( const char *program, const char *version) { + fprintf(stderr, "%s v%s -- DTLS client implementation\n" + "(c) 2011-2014 Olaf Bergmann \n\n" + #ifdef DTLS_PSK +- "usage: %s [-i file] [-k file] [-o file] [-p port] [-v num] addr [port]\n" ++ "usage: %s [-i file] [-s file] [-k file] [-o file] [-p port] [-v num] addr [port]\n" + #else /* DTLS_PSK */ + "usage: %s [-o file] [-p port] [-v num] addr [port]\n" + #endif /* DTLS_PSK */ + #ifdef DTLS_PSK +- "\t-i file\t\tread PSK identity from file\n" ++ "\t-i file\t\tread PSK Client identity from file\n" ++ "\t-s file\t\tread PSK Server identity from file\n" + "\t-k file\t\tread pre-shared key from file\n" + #endif /* DTLS_PSK */ + "\t-o file\t\toutput received data to this file (use '-' for STDOUT)\n" +@@ -337,9 +341,11 @@ main(int argc, char **argv) { + snprintf(port_str, sizeof(port_str), "%d", port); + + #ifdef DTLS_PSK +- psk_id_length = strlen(PSK_DEFAULT_IDENTITY); ++ psk_client_id_length = strlen(PSK_CLIENT_IDENTITY); ++ psk_server_id_length = strlen(PSK_SERVER_IDENTITY); + psk_key_length = strlen(PSK_DEFAULT_KEY); +- memcpy(psk_id, PSK_DEFAULT_IDENTITY, psk_id_length); ++ memcpy(psk_client_id, PSK_CLIENT_IDENTITY, psk_client_id_length); ++ memcpy(psk_server_id, PSK_SERVER_IDENTITY, psk_server_id_length); + memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length); + #endif /* DTLS_PSK */ + +@@ -347,11 +353,20 @@ main(int argc, char **argv) { + switch (opt) { + #ifdef DTLS_PSK + case 'i' : { +- ssize_t result = read_from_file(optarg, psk_id, PSK_ID_MAXLEN); ++ ssize_t result = read_from_file(optarg, psk_client_id, PSK_ID_MAXLEN); + if (result < 0) { +- dtls_warn("cannot read PSK identity\n"); ++ dtls_warn("cannot read Client PSK identity\n"); + } else { +- psk_id_length = result; ++ psk_client_id_length = result; ++ } ++ break; ++ } ++ case 's' : { ++ ssize_t result = read_from_file(optarg, psk_server_id, PSK_ID_MAXLEN); ++ if (result < 0) { ++ dtls_warn("cannot read Server PSK identity\n"); ++ } else { ++ psk_server_id_length = result; + } + break; + } +diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c +index 3f030b1..ae1283e 100644 +--- a/extlibs/tinydtls/tests/dtls-server.c ++++ b/extlibs/tinydtls/tests/dtls-server.c +@@ -47,6 +47,9 @@ handle_sigint(int signum) { + #endif + + #ifdef DTLS_PSK ++ ++#define PSK_SERVER_HINT "Server_identity" ++ + /* This function is the "key store" for tinyDTLS. It is called to + * retrieve a key for the given identity within this particular + * session. */ +@@ -70,23 +73,35 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session, + (unsigned char *)"", 1 } + }; + +- if (type != DTLS_PSK_KEY) { +- return 0; +- } ++ switch (type) { ++ case DTLS_PSK_HINT: ++ if (result_length < strlen(PSK_SERVER_HINT)) { ++ dtls_warn("cannot set psk_hint -- buffer too small\n"); ++ return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); ++ } + +- if (id) { +- int i; +- for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { +- if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { +- if (result_length < psk[i].key_length) { +- dtls_warn("buffer too small for PSK"); +- return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); +- } +- +- memcpy(result, psk[i].key, psk[i].key_length); +- return psk[i].key_length; ++ memcpy(result, PSK_SERVER_HINT, strlen(PSK_SERVER_HINT)); ++ return strlen(PSK_SERVER_HINT); ++ ++ case DTLS_PSK_KEY: ++ if (id) { ++ int i; ++ for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { ++ if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { ++ if (result_length < psk[i].key_length) { ++ dtls_warn("buffer too small for PSK"); ++ return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); ++ } ++ ++ memcpy(result, psk[i].key, psk[i].key_length); ++ return psk[i].key_length; ++ } + } + } ++ break; ++ ++ default: ++ dtls_warn("unsupported request type: %d\n", type); + } + + return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); +-- +1.7.9.5 + diff --git a/extlibs/tinydtls/Android.mk b/extlibs/tinydtls/Android.mk new file mode 100644 index 0000000..d21965c --- /dev/null +++ b/extlibs/tinydtls/Android.mk @@ -0,0 +1,17 @@ +APP_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_PATH = $(APP_PATH) +LOCAL_MODULE := TinyDtls +LOCAL_SRC_FILES := dtls.c crypto.c ccm.c hmac.c netq.c peer.c dtls_time.c session.c +#LOCAL_SRC_FILES += debug.c +LOCAL_SRC_FILES += aes/rijndael.c +LOCAL_SRC_FILES += ecc/ecc.c +LOCAL_SRC_FILES += sha2/sha2.c + +LOCAL_C_INCLUDES := $(APP_PATH) $(APP_PATH)/aes $(APP_PATH)/ecc $(APP_PATH)/sha2 + +#LOCAL_CFLAGS := -DWITH_OICSTACK -fPIC +LOCAL_CFLAGS += -DDTLSv12 -DWITH_SHA256 -DDTLS_CHECK_CONTENTTYPE -DHAVE_SYS_TIME_H + +include $(BUILD_SHARED_LIBRARY) diff --git a/extlibs/tinydtls/LICENSE b/extlibs/tinydtls/LICENSE new file mode 100644 index 0000000..2588fe2 --- /dev/null +++ b/extlibs/tinydtls/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2011--2012 Olaf Bergmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/extlibs/tinydtls/Makefile.in b/extlibs/tinydtls/Makefile.in new file mode 100644 index 0000000..9a52e4c --- /dev/null +++ b/extlibs/tinydtls/Makefile.in @@ -0,0 +1,142 @@ +# Makefile for tinydtls +# +# Copyright (C) 2011--2014 Olaf Bergmann +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir +ETAGS = @ETAGS@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +libdir = @libdir@ +includedir = @includedir@/@PACKAGE_NAME@ +package = @PACKAGE_TARNAME@-@PACKAGE_VERSION@ + +install := cp + +# files and flags +SOURCES:= dtls.c crypto.c ccm.c hmac.c netq.c peer.c dtls_time.c session.c +ifneq ("@NDEBUG@", "1") +SOURCES += debug.c +endif +SUB_OBJECTS:=aes/rijndael.o @OPT_OBJS@ +OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) $(SUB_OBJECTS) +HEADERS:=dtls.h hmac.h debug.h dtls_config.h uthash.h numeric.h crypto.h global.h ccm.h \ + netq.h t_list.h alert.h utlist.h prng.h peer.h state.h dtls_time.h session.h \ + tinydtls.h +CFLAGS:=-Wall -pedantic -std=c99 @CFLAGS@ +CPPFLAGS:=@CPPFLAGS@ -DDTLS_CHECK_CONTENTTYPE +SUBDIRS:=tests doc platform-specific sha2 aes ecc +DISTSUBDIRS:=$(SUBDIRS) examples/contiki +DISTDIR=$(top_builddir)/$(package) +FILES:=Makefile.in configure configure.in dtls_config.h.in tinydtls.h.in \ + Makefile.tinydtls $(SOURCES) $(HEADERS) +LIB:=libtinydtls.a +LDFLAGS:=@LIBS@ +ARFLAGS:=cru +doc:=doc + +.PHONY: all dirs clean install dist distclean .gitignore doc TAGS + +ifneq ("@WITH_CONTIKI@", "1") +.SUFFIXES: +.SUFFIXES: .c .o + +all: $(LIB) dirs + +check: + echo DISTDIR: $(DISTDIR) + echo top_builddir: $(top_builddir) + $(MAKE) -C tests check + +dirs: $(SUBDIRS) + for dir in $^; do \ + $(MAKE) -C $$dir ; \ + done + +$(SUB_OBJECTS):: + $(MAKE) -C $(@D) $(@F) + +$(LIB): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $^ + ranlib $@ + +clean: + @rm -f $(PROGRAM) main.o $(LIB) $(OBJECTS) + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean ; \ + done +else # WITH_CONTIKI +all: + $(MAKE) -C examples/contiki $@ +endif # WITH_CONTIKI + +doc: + $(MAKE) -C doc + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ $(DISTDIR).tar.gz + +dist: $(FILES) $(DISTSUBDIRS) + test -d $(DISTDIR) || mkdir $(DISTDIR) + cp $(FILES) $(DISTDIR) + for dir in $(DISTSUBDIRS); do \ + $(MAKE) -C $$dir dist; \ + done + tar czf $(package).tar.gz $(DISTDIR) + +install: $(LIB) $(HEADERS) $(SUBDIRS) + test -d $(libdir) || mkdir -p $(libdir) + test -d $(includedir) || mkdir -p $(includedir) + $(install) $(LIB) $(libdir)/ + $(install) $(HEADERS) $(includedir)/ + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir install="$(install)" includedir=$(includedir) install; \ + done + +TAGS: + $(ETAGS) -o $@.new $(SOURCES) + $(ETAGS) -a -o $@.new $(HEADERS) + mv $@.new $@ + +# files that should be ignored by git +GITIGNOREDS:= core \*~ \*.[oa] \*.gz \*.cap \*.pcap Makefile \ + autom4te.cache/ config.h config.log config.status configure \ + doc/Doxyfile doc/doxygen.out doc/html/ $(LIB) tests/ccm-test \ + tests/dtls-client tests/dtls-server tests/prf-test $(package) \ + $(DISTDIR)/ TAGS \*.patch .gitignore ecc/testecc ecc/testfield \ + \*.d \*.hex \*.elf \*.map obj_\* tinydtls.h dtls_config.h \ + $(addprefix \*., $(notdir $(wildcard ../../platform/*))) \ + .project + +.gitignore: + echo $(GITIGNOREDS) | sed 's/ /\n/g' > $@ + diff --git a/extlibs/tinydtls/Makefile.tinydtls b/extlibs/tinydtls/Makefile.tinydtls new file mode 100644 index 0000000..88affc4 --- /dev/null +++ b/extlibs/tinydtls/Makefile.tinydtls @@ -0,0 +1,36 @@ +# This is a -*- Makefile -*- + +ifeq ($(TARGET), redbee-econotag) +CFLAGS += -DSHA2_USE_INTTYPES_H=1 -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN +endif + +ifeq ($(TARGET), wismote) +CFLAGS += -DSHA2_USE_INTTYPES_H=1 -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN +endif + +ifeq ($(TARGET), exp5438) +CFLAGS += -DSHA2_USE_INTTYPES_H=1 -DLITTLE_ENDIAN=3412 -DBYTE_ORDER=LITTLE_ENDIAN +endif + +ifeq ($(TARGET), native) +CFLAGS += -DSHA2_USE_INTTYPES_H=1 +endif + +ifeq ($(TARGET), minimal-net) +CFLAGS += -DSHA2_USE_INTTYPES_H=1 +endif + +CFLAGS += -DDTLSv12 -DWITH_SHA256 +tinydtls_src = dtls.c crypto.c hmac.c rijndael.c sha2.c ccm.c netq.c ecc.c dtls_time.c peer.c session.c + +# This adds support for TLS_PSK_WITH_AES_128_CCM_8 +CFLAGS += -DDTLS_PSK + +# This adds support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 +CFLAGS += -DDTLS_ECC +tinydtls_src += ecc.c + +# This activates debugging support +# CFLAGS += -DNDEBUG +tinydtls_src += debug.c + diff --git a/extlibs/tinydtls/README b/extlibs/tinydtls/README new file mode 100644 index 0000000..a7b6093 --- /dev/null +++ b/extlibs/tinydtls/README @@ -0,0 +1,26 @@ +CONTENTS + +This library contains functions and structures that can help +constructing a single-threaded UDP server with DTLS support in +C99. The following components are available: + +* dtls + Basic support for DTLS with pre-shared key mode. + +* tests + The subdirectory tests contains test programs that show how each + component is used. + +BUILDING + +When using the code from the git repository at sourceforge, invoke +'autoreconf' to re-create the configure script. To build for Contiki, +place tinydtls into Contiki's apps directory and call + ./configure --with-contiki. + +After configuration, invoke make to build the library and associated +test programs. To add tinydtls as Contiki application, drop it into +the apps directory and add the following line to your Makefile: + + APPS += tinydtls/aes tinydtls/sha2 tinydtls/ecc tinydtls + diff --git a/extlibs/tinydtls/SConscript b/extlibs/tinydtls/SConscript new file mode 100644 index 0000000..e547991 --- /dev/null +++ b/extlibs/tinydtls/SConscript @@ -0,0 +1,98 @@ +# ***************************************************************** +# +# Copyright 2015 Samsung Electronics All Rights Reserved. +# +# +# +# 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. +# +# *****************************************************************/ +## +# Tinydtls build script +## + +Import('env') + +print "Reading Tinydtls folder script" + +target_os = env.get('TARGET_OS') + +if(target_os) == 'arduino': + env.Replace(CFLAGS = env.get('CXXFLAGS')) + +root_dir = './' + +tinydtls_src_path = root_dir + +env.AppendUnique(CPPPATH = [root_dir]) +env.AppendUnique(CPPPATH = [root_dir+'aes/']) +env.AppendUnique(CPPPATH = [root_dir+'ecc/']) +env.AppendUnique(CPPPATH = [root_dir+'sha2/']) + +if target_os not in ['arduino', 'windows', 'winrt']: + env.AppendUnique(CPPDEFINES = ['HAVE_SYS_TIME_H']) + +###################################################################### +# Source files and Target(s) +###################################################################### +tinydtls_src = [ + 'dtls.c', + 'crypto.c', + 'ccm.c', + 'hmac.c', + 'netq.c', + 'peer.c', + 'dtls_time.c', + 'session.c', + 'aes/rijndael.c', + 'ecc/ecc.c', + 'sha2/sha2.c', + ] + +env.AppendUnique(TINYDTLS_SRC = tinydtls_src) + +if not env.get('RELEASE'): + if(target_os) not in ['android', 'arduino']: + env.AppendUnique(TINYDTLS_SRC = ['debug.c']) +else: + env.AppendUnique(CPPDEFINES = ['NDEBUG']) + +env.AppendUnique(CPPDEFINES = ['DTLSV12', 'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE']) + +libtinydtls = env.StaticLibrary('libtinydtls', env.get('TINYDTLS_SRC'), OBJPREFIX='libtinydtls_') + +###################################################################### +# Generate tinydtls samples +# +# Note: +# Currently there is a bug in debug.h/debug.c which fails compilation +# of tinydtls samples in release mode. This bug is being tracked in +# IOT-395 +###################################################################### +if not env.get('RELEASE'): + samples_env = env.Clone() + + if target_os not in ['arduino', 'windows', 'winrt']: + samples_env.AppendUnique(CPPDEFINES = ['_GNU_SOURCE']) + + dtlsserver = samples_env.Program('dtls-server', ['tests/dtls-server.c']) + dtlsclient = samples_env.Program('dtls-client', ['tests/dtls-client.c']) + + samples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) + samples_env.PrependUnique(LIBS = ['tinydtls']) + + Alias("samples", [dtlsserver, dtlsclient]) + samples_env.AppendTarget('samples') + +env.InstallTarget(libtinydtls, 'libtinydtls'); + diff --git a/extlibs/tinydtls/aes/Makefile.in b/extlibs/tinydtls/aes/Makefile.in new file mode 100644 index 0000000..4cf29d4 --- /dev/null +++ b/extlibs/tinydtls/aes/Makefile.in @@ -0,0 +1,76 @@ +# Makefile for tinydtls +# +# Copyright (C) 2011 Olaf Bergmann +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_srcdir:= @top_srcdir@ + +SOURCES:= rijndael.c +HEADERS:= rijndael.h +OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) +CPPFLAGS=@CPPFLAGS@ +CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@ +LDLIBS=@LIBS@ +FILES:=Makefile.in $(SOURCES) $(HEADERS) +DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ + +.PHONY: all dirs clean install dist distclean .gitignore doc + +.SUFFIXES: +.SUFFIXES: .c .o + +all: + +check: + echo DISTDIR: $(DISTDIR) + echo top_builddir: $(top_builddir) + +clean: + @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean ; \ + done + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ $(DISTDIR).tar.gz + +dist: $(FILES) + test -d $(DISTDIR)/aes || mkdir $(DISTDIR)/aes + cp -p $(FILES) $(DISTDIR)/aes + +install: $(HEADERS) + test -d $(includedir)/aes || mkdir -p $(includedir)/aes + $(install) $(HEADERS) $(includedir)/aes + +.gitignore: + echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/extlibs/tinydtls/aes/rijndael.c b/extlibs/tinydtls/aes/rijndael.c new file mode 100644 index 0000000..33001a8 --- /dev/null +++ b/extlibs/tinydtls/aes/rijndael.c @@ -0,0 +1,1287 @@ +/* $OpenBSD: rijndael.c,v 1.19 2008/06/09 07:49:45 djm Exp $ */ + +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + */ + +/* #include */ +/* #include */ + +#include "rijndael.h" + +#ifdef ARDUINO_AVR_MEGA2560 + #include +#else + #define PROGMEM + #define pgm_read_dword * +#endif + +#undef FULL_UNROLL + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +PROGMEM static const aes_u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +PROGMEM static const aes_u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +PROGMEM static const aes_u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +PROGMEM static const aes_u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; +PROGMEM static const aes_u32 Te4[256] = { + 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, + 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, + 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, + 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, + 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, + 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, + 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, + 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, + 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, + 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, + 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, + 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, + 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, + 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, + 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, + 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, + 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, + 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, + 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, + 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, + 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, + 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, + 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, + 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, + 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, + 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, + 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, + 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, + 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, + 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, + 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, + 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, + 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, + 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, + 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, + 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, + 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, + 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, + 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, + 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, + 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, + 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, + 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, + 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, + 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, + 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, + 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, + 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, + 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, + 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, + 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, + 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, + 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, + 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, + 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, + 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, + 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, + 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, + 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, + 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, + 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, + 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, + 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, + 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, +}; + +#ifdef WITH_AES_DECRYPT + +PROGMEM static const aes_u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +PROGMEM static const aes_u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +PROGMEM static const aes_u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +PROGMEM static const aes_u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +PROGMEM static const aes_u32 Td4[256] = { + 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, + 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, + 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, + 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, + 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, + 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, + 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, + 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, + 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, + 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, + 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, + 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, + 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, + 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, + 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, + 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, + 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, + 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, + 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, + 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, + 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, + 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, + 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, + 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, + 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, + 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, + 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, + 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, + 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, + 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, + 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, + 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, + 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, + 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, + 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, + 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, + 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, + 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, + 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, + 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, + 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, + 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, + 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, + 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, + 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, + 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, + 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, + 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, + 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, + 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, + 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, + 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, + 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, + 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, + 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, + 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, + 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, + 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, + 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, + 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, + 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, + 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, + 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, + 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +}; + +#endif /* WITH_AES_DECRYPT */ + +PROGMEM static const aes_u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#define GETU32(pt) (((aes_u32)(pt)[0] << 24) ^ ((aes_u32)(pt)[1] << 16) ^ ((aes_u32)(pt)[2] << 8) ^ ((aes_u32)(pt)[3])) +#define PUTU32(ct, st) { (ct)[0] = (aes_u8)((st) >> 24); (ct)[1] = (aes_u8)((st) >> 16); (ct)[2] = (aes_u8)((st) >> 8); (ct)[3] = (aes_u8)(st); } + +/** + * Expand the cipher key into the encryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits) +{ + int i = 0; + aes_u32 temp; + + rk[0] = GETU32(cipherKey ); + rk[1] = GETU32(cipherKey + 4); + rk[2] = GETU32(cipherKey + 8); + rk[3] = GETU32(cipherKey + 12); + if (keyBits == 128) { + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (pgm_read_dword(&Te4[(temp >> 16) &0xff ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(temp >> 8) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(temp ) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(temp >> 24) ]) & 0x000000ff) ^ + (pgm_read_dword(&rcon[i])); + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 10; + } + rk += 4; + } + } + rk[4] = GETU32(cipherKey + 16); + rk[5] = GETU32(cipherKey + 20); + if (keyBits == 192) { + for (;;) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(temp >> 8) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(temp ) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(temp >> 24) ]) & 0x000000ff) ^ + (pgm_read_dword(&rcon[i])); + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 12; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(cipherKey + 24); + rk[7] = GETU32(cipherKey + 28); + if (keyBits == 256) { + for (;;) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(temp >> 8) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(temp ) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(temp >> 24) ]) & 0x000000ff) ^ + (pgm_read_dword(&rcon[i])); + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 14; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (pgm_read_dword(&Te4[(temp >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(temp >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(temp ) & 0xff]) & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } + return 0; +} + +#ifdef WITH_AES_DECRYPT +/** + * Expand the cipher key into the decryption key schedule. + * + * @return the number of rounds for the given cipher key size. + */ +int +rijndaelKeySetupDec(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits) +{ + int Nr, i, j; + aes_u32 temp; + + /* expand the cipher key: */ + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); + + /* invert the order of the round keys: */ + for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < Nr; i++) { + rk += 4; + rk[0] = + pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[0] >> 24) ]) & 0xff]) ^ + pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[0] >> 16) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[0] >> 8) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[0] ) & 0xff]) & 0xff]); + rk[1] = + pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[1] >> 24) ]) & 0xff]) ^ + pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[1] >> 16) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[1] >> 8) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[1] ) & 0xff]) & 0xff]); + rk[2] = + pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[2] >> 24) ]) & 0xff]) ^ + pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[2] >> 16) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[2] >> 8) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[2] ) & 0xff]) & 0xff]); + rk[3] = + pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[3] >> 24) ]) & 0xff]) ^ + pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[3] >> 16) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[3] >> 8) & 0xff]) & 0xff]) ^ + pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[3] ) & 0xff]) & 0xff]); + } + return Nr; +} +#endif + +void +rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16], + aes_u8 ct[16]) +{ + aes_u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(pt ) ^ rk[0]; + s1 = GETU32(pt + 4) ^ rk[1]; + s2 = GETU32(pt + 8) ^ rk[2]; + s3 = GETU32(pt + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[ 4]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[ 5]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[ 6]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[ 7]; + /* round 2: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[ 8]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[ 9]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[10]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[11]; + /* round 3: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[12]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[13]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[14]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[15]; + /* round 4: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[16]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[17]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[18]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[19]; + /* round 5: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[20]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[21]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[22]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[23]; + /* round 6: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[24]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[25]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[26]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[27]; + /* round 7: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[28]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[29]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[30]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[31]; + /* round 8: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[32]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[33]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[34]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[35]; + /* round 9: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[36]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[37]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[38]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[40]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[41]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[42]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[43]; + /* round 11: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[44]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[45]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[46]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[48]; + s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[49]; + s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[50]; + s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[51]; + /* round 13: */ + t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[52]; + t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[53]; + t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[54]; + t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + pgm_read_dword(&Te0[(s0 >> 24) ]) ^ + pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(s2 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(s3 ) & 0xff]) ^ + rk[4]; + t1 = + pgm_read_dword(&Te0[(s1 >> 24) ]) ^ + pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(s3 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(s0 ) & 0xff]) ^ + rk[5]; + t2 = + pgm_read_dword(&Te0[(s2 >> 24) ]) ^ + pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(s0 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(s1 ) & 0xff]) ^ + rk[6]; + t3 = + pgm_read_dword(&Te0[(s3 >> 24) ]) ^ + pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(s1 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(s2 ) & 0xff]) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + pgm_read_dword(&Te0[(t0 >> 24) ]) ^ + pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(t2 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(t3 ) & 0xff]) ^ + rk[0]; + s1 = + pgm_read_dword(&Te0[(t1 >> 24) ]) ^ + pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(t3 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(t0 ) & 0xff]) ^ + rk[1]; + s2 = + pgm_read_dword(&Te0[(t2 >> 24) ]) ^ + pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(t0 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(t1 ) & 0xff]) ^ + rk[2]; + s3 = + pgm_read_dword(&Te0[(t3 >> 24) ]) ^ + pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ + pgm_read_dword(&Te2[(t1 >> 8) & 0xff]) ^ + pgm_read_dword(&Te3[(t2 ) & 0xff]) ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (pgm_read_dword(&Te4[(t0 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(t1 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(t2 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(t3 ) & 0xff]) & 0x000000ff) ^ + rk[0]; + PUTU32(ct , s0); + s1 = + (pgm_read_dword(&Te4[(t1 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(t2 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(t3 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(t0 ) & 0xff]) & 0x000000ff) ^ + rk[1]; + PUTU32(ct + 4, s1); + s2 = + (pgm_read_dword(&Te4[(t2 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(t3 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(t0 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(t1 ) & 0xff]) & 0x000000ff) ^ + rk[2]; + PUTU32(ct + 8, s2); + s3 = + (pgm_read_dword(&Te4[(t3 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Te4[(t0 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Te4[(t1 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Te4[(t2 ) & 0xff]) & 0x000000ff) ^ + rk[3]; + PUTU32(ct + 12, s3); +} + +#ifdef WITH_AES_DECRYPT +static void +rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16], + aes_u8 pt[16]) +{ + aes_u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(ct ) ^ rk[0]; + s1 = GETU32(ct + 4) ^ rk[1]; + s2 = GETU32(ct + 8) ^ rk[2]; + s3 = GETU32(ct + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[ 4]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[ 5]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[ 6]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[ 7]; + /* round 2: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[ 8]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[ 9]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[10]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[11]; + /* round 3: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[12]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[13]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[14]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[15]; + /* round 4: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[16]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[17]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[18]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[19]; + /* round 5: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[20]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[21]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[22]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[23]; + /* round 6: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[24]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[25]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[26]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[27]; + /* round 7: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[28]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[29]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[30]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[31]; + /* round 8: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[32]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[33]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[34]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[35]; + /* round 9: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[36]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[37]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[38]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[39]; + if (Nr > 10) { + /* round 10: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[40]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[41]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[42]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[43]; + /* round 11: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[44]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[45]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[46]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[47]; + if (Nr > 12) { + /* round 12: */ + s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[48]; + s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[49]; + s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[50]; + s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[51]; + /* round 13: */ + t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[52]; + t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[53]; + t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[54]; + t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[55]; + } + } + rk += Nr << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + pgm_read_dword(&Td0[(s0 >> 24) ]) ^ + pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(s2 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(s1 ) & 0xff]) ^ + rk[4]; + t1 = + pgm_read_dword(&Td0[(s1 >> 24) ]) ^ + pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(s3 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(s2 ) & 0xff]) ^ + rk[5]; + t2 = + pgm_read_dword(&Td0[(s2 >> 24) ]) ^ + pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(s0 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(s3 ) & 0xff]) ^ + rk[6]; + t3 = + pgm_read_dword(&Td0[(s3 >> 24) ]) ^ + pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(s1 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(s0 ) & 0xff]) ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + pgm_read_dword(&Td0[(t0 >> 24) ]) ^ + pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(t2 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(t1 ) & 0xff]) ^ + rk[0]; + s1 = + pgm_read_dword(&Td0[(t1 >> 24) ]) ^ + pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(t3 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(t2 ) & 0xff]) ^ + rk[1]; + s2 = + pgm_read_dword(&Td0[(t2 >> 24) ]) ^ + pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(t0 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(t3 ) & 0xff]) ^ + rk[2]; + s3 = + pgm_read_dword(&Td0[(t3 >> 24) ]) ^ + pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ + pgm_read_dword(&Td2[(t1 >> 8) & 0xff]) ^ + pgm_read_dword(&Td3[(t0 ) & 0xff]) ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (pgm_read_dword(&Td4[(t0 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Td4[(t3 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Td4[(t2 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Td4[(t1 ) & 0xff]) & 0x000000ff) ^ + rk[0]; + PUTU32(pt , s0); + s1 = + (pgm_read_dword(&Td4[(t1 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Td4[(t0 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Td4[(t3 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Td4[(t2 ) & 0xff]) & 0x000000ff) ^ + rk[1]; + PUTU32(pt + 4, s1); + s2 = + (pgm_read_dword(&Td4[(t2 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Td4[(t1 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Td4[(t0 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Td4[(t3 ) & 0xff]) & 0x000000ff) ^ + rk[2]; + PUTU32(pt + 8, s2); + s3 = + (pgm_read_dword(&Td4[(t3 >> 24) ]) & 0xff000000) ^ + (pgm_read_dword(&Td4[(t2 >> 16) & 0xff]) & 0x00ff0000) ^ + (pgm_read_dword(&Td4[(t1 >> 8) & 0xff]) & 0x0000ff00) ^ + (pgm_read_dword(&Td4[(t0 ) & 0xff]) & 0x000000ff) ^ + rk[3]; + PUTU32(pt + 12, s3); +} +#endif + +/* setup key context for encryption only */ +int +rijndael_set_key_enc_only(rijndael_ctx *ctx, const u_char *key, int bits) +{ + int rounds; + + rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); + if (rounds == 0) + return -1; + + ctx->Nr = rounds; +#ifdef WITH_AES_DECRYPT + ctx->enc_only = 1; +#endif + + return 0; +} + +#ifdef WITH_AES_DECRYPT +/* setup key context for both encryption and decryption */ +int +rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits) +{ + int rounds; + + rounds = rijndaelKeySetupEnc(ctx->ek, key, bits); + if (rounds == 0) + return -1; + if (rijndaelKeySetupDec(ctx->dk, key, bits) != rounds) + return -1; + + ctx->Nr = rounds; + ctx->enc_only = 0; + + return 0; +} + +void +rijndael_decrypt(rijndael_ctx *ctx, const u_char *src, u_char *dst) +{ + rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst); +} +#endif + +void +rijndael_encrypt(rijndael_ctx *ctx, const u_char *src, u_char *dst) +{ + rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst); +} diff --git a/extlibs/tinydtls/aes/rijndael.h b/extlibs/tinydtls/aes/rijndael.h new file mode 100644 index 0000000..60e9bef --- /dev/null +++ b/extlibs/tinydtls/aes/rijndael.h @@ -0,0 +1,66 @@ +/* $OpenBSD: rijndael.h,v 1.13 2008/06/09 07:49:45 djm Exp $ */ + +/** + * rijndael-alg-fst.h + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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. + */ +#ifndef __RIJNDAEL_H +#define __RIJNDAEL_H + +#include + +#define AES_MAXKEYBITS (256) +#define AES_MAXKEYBYTES (AES_MAXKEYBITS>>3) +/* for 256-bit keys we need 14 rounds for a 128 we only need 10 round */ +#define AES_MAXROUNDS 14 + +/* bergmann: to avoid conflicts with typedefs from certain Contiki platforms, + * the following type names have been prefixed with "aes_": */ +typedef unsigned char u_char; +typedef uint8_t aes_u8; +typedef uint16_t aes_u16; +typedef uint32_t aes_u32; + +/* The structure for key information */ +typedef struct { +#ifdef WITH_AES_DECRYPT + int enc_only; /* context contains only encrypt schedule */ +#endif + int Nr; /* key-length-dependent number of rounds */ + aes_u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */ +#ifdef WITH_AES_DECRYPT + aes_u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */ +#endif +} rijndael_ctx; + +int rijndael_set_key(rijndael_ctx *, const u_char *, int); +int rijndael_set_key_enc_only(rijndael_ctx *, const u_char *, int); +void rijndael_decrypt(rijndael_ctx *, const u_char *, u_char *); +void rijndael_encrypt(rijndael_ctx *, const u_char *, u_char *); + +int rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits); +int rijndaelKeySetupDec(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int keyBits); +void rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16], aes_u8 ct[16]); + +#endif /* __RIJNDAEL_H */ diff --git a/extlibs/tinydtls/alert.h b/extlibs/tinydtls/alert.h new file mode 100644 index 0000000..5a27faa --- /dev/null +++ b/extlibs/tinydtls/alert.h @@ -0,0 +1,81 @@ +/* alert.h -- DTLS alert protocol + * + * Copyright (C) 2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file alert.h + * @brief DTLS alert protocol + */ + +#ifndef _DTLS_ALERT_H_ +#define _DTLS_ALERT_H_ + +typedef enum { + DTLS_ALERT_LEVEL_WARNING=1, + DTLS_ALERT_LEVEL_FATAL=2 +} dtls_alert_level_t; + +typedef enum { + DTLS_ALERT_CLOSE_NOTIFY = 0, /* close_notify */ + DTLS_ALERT_UNEXPECTED_MESSAGE = 10, /* unexpected_message */ + DTLS_ALERT_BAD_RECORD_MAC = 20, /* bad_record_mac */ + DTLS_ALERT_RECORD_OVERFLOW = 22, /* record_overflow */ + DTLS_ALERT_DECOMPRESSION_FAILURE = 30, /* decompression_failure */ + DTLS_ALERT_HANDSHAKE_FAILURE = 40, /* handshake_failure */ + DTLS_ALERT_BAD_CERTIFICATE = 42, /* bad_certificate */ + DTLS_ALERT_UNSUPPORTED_CERTIFICATE = 43, /* unsupported_certificate */ + DTLS_ALERT_CERTIFICATE_REVOKED = 44, /* certificate_revoked */ + DTLS_ALERT_CERTIFICATE_EXPIRED = 45, /* certificate_expired */ + DTLS_ALERT_CERTIFICATE_UNKNOWN = 46, /* certificate_unknown */ + DTLS_ALERT_ILLEGAL_PARAMETER = 47, /* illegal_parameter */ + DTLS_ALERT_UNKNOWN_CA = 48, /* unknown_ca */ + DTLS_ALERT_ACCESS_DENIED = 49, /* access_denied */ + DTLS_ALERT_DECODE_ERROR = 50, /* decode_error */ + DTLS_ALERT_DECRYPT_ERROR = 51, /* decrypt_error */ + DTLS_ALERT_PROTOCOL_VERSION = 70, /* protocol_version */ + DTLS_ALERT_INSUFFICIENT_SECURITY = 71, /* insufficient_security */ + DTLS_ALERT_INTERNAL_ERROR = 80, /* internal_error */ + DTLS_ALERT_USER_CANCELED = 90, /* user_canceled */ + DTLS_ALERT_NO_RENEGOTIATION = 100, /* no_renegotiation */ + DTLS_ALERT_UNSUPPORTED_EXTENSION = 110 /* unsupported_extension */ +} dtls_alert_t; + +#define DTLS_EVENT_CONNECT 0x01DC /**< initiated handshake */ +#define DTLS_EVENT_CONNECTED 0x01DE /**< handshake or re-negotiation + * has finished */ +#define DTLS_EVENT_RENEGOTIATE 0x01DF /**< re-negotiation has started */ + +static inline int +dtls_alert_create(dtls_alert_level_t level, dtls_alert_t desc) +{ + return -((level << 8) | desc); +} + +static inline int +dtls_alert_fatal_create(dtls_alert_t desc) +{ + return dtls_alert_create(DTLS_ALERT_LEVEL_FATAL, desc); +} + +#endif /* _DTLS_ALERT_H_ */ diff --git a/extlibs/tinydtls/ccm.c b/extlibs/tinydtls/ccm.c new file mode 100644 index 0000000..7563db8 --- /dev/null +++ b/extlibs/tinydtls/ccm.c @@ -0,0 +1,311 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "dtls_config.h" +#include "global.h" +#include "numeric.h" +#include "ccm.h" + +#ifdef HAVE_ASSERT_H +# include +#endif + +#define CCM_FLAGS(A,M,L) (((A > 0) << 6) | (((M - 2)/2) << 3) | (L - 1)) + +#define MASK_L(_L) ((1 << 8 * _L) - 1) + +#define SET_COUNTER(A,L,cnt,C) { \ + int i; \ + memset((A) + DTLS_CCM_BLOCKSIZE - (L), 0, (L)); \ + (C) = (cnt) & MASK_L(L); \ + for (i = DTLS_CCM_BLOCKSIZE - 1; (C) && (i > (L)); --i, (C) >>= 8) \ + (A)[i] |= (C) & 0xFF; \ + } + +static inline void +block0(size_t M, /* number of auth bytes */ + size_t L, /* number of bytes to encode message length */ + size_t la, /* l(a) octets additional authenticated data */ + size_t lm, /* l(m) message length */ + unsigned char nonce[DTLS_CCM_BLOCKSIZE], + unsigned char *result) { + int i; + + result[0] = CCM_FLAGS(la, M, L); + + /* copy the nonce */ + memcpy(result + 1, nonce, DTLS_CCM_BLOCKSIZE - L); + + for (i=0; i < L; i++) { + result[15-i] = lm & 0xff; + lm >>= 8; + } +} + +/** + * Creates the CBC-MAC for the additional authentication data that + * is sent in cleartext. + * + * \param ctx The crypto context for the AES encryption. + * \param msg The message starting with the additional authentication data. + * \param la The number of additional authentication bytes in \p msg. + * \param B The input buffer for crypto operations. When this function + * is called, \p B must be initialized with \c B0 (the first + * authentication block. + * \param X The output buffer where the result of the CBC calculation + * is placed. + * \return The result is written to \p X. + */ +static void +add_auth_data(rijndael_ctx *ctx, const unsigned char *msg, size_t la, + unsigned char B[DTLS_CCM_BLOCKSIZE], + unsigned char X[DTLS_CCM_BLOCKSIZE]) { + size_t i,j; + + rijndael_encrypt(ctx, B, X); + + memset(B, 0, DTLS_CCM_BLOCKSIZE); + + if (!la) + return; + +#ifndef WITH_CONTIKI + if (la < 0xFF00) { /* 2^16 - 2^8 */ + j = 2; + dtls_int_to_uint16(B, la); + } else if (la <= UINT32_MAX) { + j = 6; + dtls_int_to_uint16(B, 0xFFFE); + dtls_int_to_uint32(B+2, la); + } else { + j = 10; + dtls_int_to_uint16(B, 0xFFFF); + dtls_int_to_uint64(B+2, la); + } +#else /* WITH_CONTIKI */ + /* With Contiki, we are building for small devices and thus + * anticipate that the number of additional authentication bytes + * will not exceed 65280 bytes (0xFF00) and we can skip the + * workarounds required for j=6 and j=10 on devices with a word size + * of 32 bits or 64 bits, respectively. + */ + + assert(la < 0xFF00); + j = 2; + dtls_int_to_uint16(B, la); +#endif /* WITH_CONTIKI */ + + i = min(DTLS_CCM_BLOCKSIZE - j, la); + memcpy(B + j, msg, i); + la -= i; + msg += i; + + memxor(B, X, DTLS_CCM_BLOCKSIZE); + + rijndael_encrypt(ctx, B, X); + + while (la > DTLS_CCM_BLOCKSIZE) { + for (i = 0; i < DTLS_CCM_BLOCKSIZE; ++i) + B[i] = X[i] ^ *msg++; + la -= DTLS_CCM_BLOCKSIZE; + + rijndael_encrypt(ctx, B, X); + } + + if (la) { + memset(B, 0, DTLS_CCM_BLOCKSIZE); + memcpy(B, msg, la); + memxor(B, X, DTLS_CCM_BLOCKSIZE); + + rijndael_encrypt(ctx, B, X); + } +} + +static inline void +encrypt(rijndael_ctx *ctx, size_t L, unsigned long counter, + unsigned char *msg, size_t len, + unsigned char A[DTLS_CCM_BLOCKSIZE], + unsigned char S[DTLS_CCM_BLOCKSIZE]) { + + static unsigned long counter_tmp; + + SET_COUNTER(A, L, counter, counter_tmp); + rijndael_encrypt(ctx, A, S); + memxor(msg, S, len); +} + +static inline void +mac(rijndael_ctx *ctx, + unsigned char *msg, size_t len, + unsigned char B[DTLS_CCM_BLOCKSIZE], + unsigned char X[DTLS_CCM_BLOCKSIZE]) { + size_t i; + + for (i = 0; i < len; ++i) + B[i] = X[i] ^ msg[i]; + + rijndael_encrypt(ctx, B, X); + +} + +long int +dtls_ccm_encrypt_message(rijndael_ctx *ctx, size_t M, size_t L, + unsigned char nonce[DTLS_CCM_BLOCKSIZE], + unsigned char *msg, size_t lm, + const unsigned char *aad, size_t la) { + size_t i, len; + unsigned long counter_tmp; + unsigned long counter = 1; /* \bug does not work correctly on ia32 when + lm >= 2^16 */ + unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */ + unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */ + unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */ + unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */ + + len = lm; /* save original length */ + /* create the initial authentication block B0 */ + block0(M, L, la, lm, nonce, B); + add_auth_data(ctx, aad, la, B, X); + + /* initialize block template */ + A[0] = L-1; + + /* copy the nonce */ + memcpy(A + 1, nonce, DTLS_CCM_BLOCKSIZE - L); + + while (lm >= DTLS_CCM_BLOCKSIZE) { + /* calculate MAC */ + mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X); + + /* encrypt */ + encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S); + + /* update local pointers */ + lm -= DTLS_CCM_BLOCKSIZE; + msg += DTLS_CCM_BLOCKSIZE; + counter++; + } + + if (lm) { + /* Calculate MAC. The remainder of B must be padded with zeroes, so + * B is constructed to contain X ^ msg for the first lm bytes (done in + * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes + * (i.e., we can use memcpy() here). + */ + memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm); + mac(ctx, msg, lm, B, X); + + /* encrypt */ + encrypt(ctx, L, counter, msg, lm, A, S); + + /* update local pointers */ + msg += lm; + } + + /* calculate S_0 */ + SET_COUNTER(A, L, 0, counter_tmp); + rijndael_encrypt(ctx, A, S); + + for (i = 0; i < M; ++i) + *msg++ = X[i] ^ S[i]; + + return len + M; +} + +long int +dtls_ccm_decrypt_message(rijndael_ctx *ctx, size_t M, size_t L, + unsigned char nonce[DTLS_CCM_BLOCKSIZE], + unsigned char *msg, size_t lm, + const unsigned char *aad, size_t la) { + + size_t len; + unsigned long counter_tmp; + unsigned long counter = 1; /* \bug does not work correctly on ia32 when + lm >= 2^16 */ + unsigned char A[DTLS_CCM_BLOCKSIZE]; /* A_i blocks for encryption input */ + unsigned char B[DTLS_CCM_BLOCKSIZE]; /* B_i blocks for CBC-MAC input */ + unsigned char S[DTLS_CCM_BLOCKSIZE]; /* S_i = encrypted A_i blocks */ + unsigned char X[DTLS_CCM_BLOCKSIZE]; /* X_i = encrypted B_i blocks */ + + if (lm < M) + goto error; + + len = lm; /* save original length */ + lm -= M; /* detract MAC size*/ + + /* create the initial authentication block B0 */ + block0(M, L, la, lm, nonce, B); + add_auth_data(ctx, aad, la, B, X); + + /* initialize block template */ + A[0] = L-1; + + /* copy the nonce */ + memcpy(A + 1, nonce, DTLS_CCM_BLOCKSIZE - L); + + while (lm >= DTLS_CCM_BLOCKSIZE) { + /* decrypt */ + encrypt(ctx, L, counter, msg, DTLS_CCM_BLOCKSIZE, A, S); + + /* calculate MAC */ + mac(ctx, msg, DTLS_CCM_BLOCKSIZE, B, X); + + /* update local pointers */ + lm -= DTLS_CCM_BLOCKSIZE; + msg += DTLS_CCM_BLOCKSIZE; + counter++; + } + + if (lm) { + /* decrypt */ + encrypt(ctx, L, counter, msg, lm, A, S); + + /* Calculate MAC. Note that msg ends in the MAC so we must + * construct B to contain X ^ msg for the first lm bytes (done in + * mac() and X ^ 0 for the remaining DTLS_CCM_BLOCKSIZE - lm bytes + * (i.e., we can use memcpy() here). + */ + memcpy(B + lm, X + lm, DTLS_CCM_BLOCKSIZE - lm); + mac(ctx, msg, lm, B, X); + + /* update local pointers */ + msg += lm; + } + + /* calculate S_0 */ + SET_COUNTER(A, L, 0, counter_tmp); + rijndael_encrypt(ctx, A, S); + + memxor(msg, S, M); + + /* return length if MAC is valid, otherwise continue with error handling */ + if (equals(X, msg, M)) + return len - M; + + error: + return -1; +} diff --git a/extlibs/tinydtls/ccm.h b/extlibs/tinydtls/ccm.h new file mode 100644 index 0000000..c3949d2 --- /dev/null +++ b/extlibs/tinydtls/ccm.h @@ -0,0 +1,69 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_CCM_H_ +#define _DTLS_CCM_H_ + +#include "aes/rijndael.h" + +/* implementation of Counter Mode CBC-MAC, RFC 3610 */ + +#define DTLS_CCM_BLOCKSIZE 16 /**< size of hmac blocks */ +#define DTLS_CCM_MAX 16 /**< max number of bytes in digest */ +#define DTLS_CCM_NONCE_SIZE 12 /**< size of nonce */ + +/** + * Authenticates and encrypts a message using AES in CCM mode. Please + * see also RFC 3610 for the meaning of \p M, \p L, \p lm and \p la. + * + * \param ctx The initialized rijndael_ctx object to be used for AES operations. + * \param M The number of authentication octets. + * \param L The number of bytes used to encode the message length. + * \param N The nonce value to use. You must provide \c DTLS_CCM_BLOCKSIZE + * nonce octets, although only the first \c 16 - \p L are used. + * \param msg The message to encrypt. The first \p la octets are additional + * authentication data that will be cleartext. Note that the + * encryption operation modifies the contents of \p msg and adds + * \p M bytes MAC. Therefore, the buffer must be at least + * \p lm + \p M bytes large. + * \param lm The actual length of \p msg. + * \param aad A pointer to the additional authentication data (can be \c NULL if + * \p la is zero). + * \param la The number of additional authentication octets (may be zero). + * \return FIXME + */ +long int +dtls_ccm_encrypt_message(rijndael_ctx *ctx, size_t M, size_t L, + unsigned char nonce[DTLS_CCM_BLOCKSIZE], + unsigned char *msg, size_t lm, + const unsigned char *aad, size_t la); + +long int +dtls_ccm_decrypt_message(rijndael_ctx *ctx, size_t M, size_t L, + unsigned char nonce[DTLS_CCM_BLOCKSIZE], + unsigned char *msg, size_t lm, + const unsigned char *aad, size_t la); + +#endif /* _DTLS_CCM_H_ */ diff --git a/extlibs/tinydtls/configure.in b/extlibs/tinydtls/configure.in new file mode 100644 index 0000000..70b9a54 --- /dev/null +++ b/extlibs/tinydtls/configure.in @@ -0,0 +1,115 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. +# +# Copyright (C) 2011--2014 Olaf Bergmann +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +AC_PREREQ([2.65]) +AC_INIT([tinydtls], [0.8.1]) +AC_CONFIG_SRCDIR([dtls.c]) +dnl AC_CONFIG_HEADERS([config.h]) + +AC_ARG_WITH(contiki, + [AS_HELP_STRING([--with-contiki],[build libtinydtls for the Contiki OS])], + [AC_DEFINE(WITH_CONTIKI,1,[Define to 1 if building for Contiki.]) + WITH_CONTIKI=1], + []) + +AC_PATH_PROG(DOXYGEN, doxygen, [:]) +AC_PATH_PROG(ETAGS, etags, [/bin/false]) + +if test "${with_contiki}" != "yes" ; then +# Checks for programs. +AC_PROG_MAKE_SET +AC_PROG_CC +AC_PROG_RANLIB + +AC_C_BIGENDIAN + +# Checks for libraries. +AC_SEARCH_LIBS([gethostbyname], [nsl]) +AC_SEARCH_LIBS([socket], [socket]) +fi + +AC_ARG_WITH(debug, + [AS_HELP_STRING([--without-debug],[disable all debug output and assertions])], + [CPPFLAGS="${CPPFLAGS} -DNDEBUG" + NDEBUG=1], + []) + +AC_ARG_WITH(ecc, + [AS_HELP_STRING([--without-ecc],[disable support for TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8])], + [], + [AC_DEFINE(DTLS_ECC, 1, [Define to 1 if building with ECC support.]) + OPT_OBJS="${OPT_OBJS} ecc/ecc.o" + DTLS_ECC=1]) + +AC_ARG_WITH(psk, + [AS_HELP_STRING([--without-psk],[disable support for TLS_PSK_WITH_AES_128_CCM_8])], + [], + [AC_DEFINE(DTLS_PSK, 1, [Define to 1 if building with PSK support]) + DTLS_PSK=1]) + +CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256" +OPT_OBJS="${OPT_OBJS} sha2/sha2.o" + +AC_SUBST(OPT_OBJS) +AC_SUBST(NDEBUG) +AC_SUBST(WITH_CONTIKI) +AC_SUBST(DTLS_ECC) +AC_SUBST(DTLS_PSK) + +if test "${with_contiki}" = "yes" ; then + AC_MSG_NOTICE([skipping header checks for Contiki]) +else + # Checks for header files. + AC_CHECK_HEADERS([assert.h arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/param.h sys/socket.h unistd.h]) + + AC_CHECK_HEADERS([sys/time.h time.h]) + AC_CHECK_HEADERS([sys/types.h sys/stat.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_INLINE +AC_TYPE_SIZE_T + +AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len], + [AC_DEFINE(HAVE_SOCKADDR_IN6_SIN6_LEN, [1], + [Define to 1 if struct sockaddr_in6 has a member sin6_len.])], [], + [#include ]) + +# Checks for library functions. +AC_FUNC_MALLOC +AC_CHECK_FUNCS([memset select socket strdup strerror strnlen fls vprintf]) +fi + +AC_CONFIG_HEADERS([dtls_config.h tinydtls.h]) + +AC_CONFIG_FILES([Makefile + doc/Makefile + doc/Doxyfile + tests/Makefile + examples/contiki/Makefile + platform-specific/Makefile + sha2/Makefile + aes/Makefile + ecc/Makefile]) +AC_OUTPUT diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c new file mode 100644 index 0000000..0113342 --- /dev/null +++ b/extlibs/tinydtls/crypto.c @@ -0,0 +1,554 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * + * Modified source code for micro-ecc porting, + * + * Following functions are removed: + * - dtls_ec_key_to_uint32 + * - dtls_ec_key_from_uint32 + * Following functions are modified: + * - dtls_ecdh_pre_master_secret + * - dtls_ecdsa_generate_key + * - dtls_ecdsa_create_sig_hash + * - dtls_ecdsa_verify_sig_hash + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include "tinydtls.h" +#include "dtls_config.h" + +#ifdef HAVE_ASSERT_H +#include +#else +#define assert(x) +#endif + +#include "global.h" +#include "debug.h" +#include "numeric.h" +#include "dtls.h" +#include "crypto.h" +#include "ccm.h" +#include "ecc/ecc.h" +#include "prng.h" +#include "netq.h" + +#ifndef WITH_CONTIKI +#include +#endif + +#define HMAC_UPDATE_SEED(Context,Seed,Length) \ + if (Seed) dtls_hmac_update(Context, (Seed), (Length)) + +static struct dtls_cipher_context_t cipher_context; +#ifndef WITH_CONTIKI +static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +static struct dtls_cipher_context_t *dtls_cipher_context_get(void) +{ +#ifndef WITH_CONTIKI + pthread_mutex_lock(&cipher_context_mutex); +#endif + return &cipher_context; +} + +static void dtls_cipher_context_release(void) +{ +#ifndef WITH_CONTIKI + pthread_mutex_unlock(&cipher_context_mutex); +#endif +} + +#ifndef WITH_CONTIKI +void crypto_init() +{ +} + +static dtls_handshake_parameters_t *dtls_handshake_malloc() { + return malloc(sizeof(dtls_handshake_parameters_t)); +} + +static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) { + free(handshake); +} + +static dtls_security_parameters_t *dtls_security_malloc() { + return malloc(sizeof(dtls_security_parameters_t)); +} + +static void dtls_security_dealloc(dtls_security_parameters_t *security) { + free(security); +} +#else /* WITH_CONTIKI */ + +#include "memb.h" +MEMB(handshake_storage, dtls_handshake_parameters_t, DTLS_HANDSHAKE_MAX); +MEMB(security_storage, dtls_security_parameters_t, DTLS_SECURITY_MAX); + +void crypto_init() { + memb_init(&handshake_storage); + memb_init(&security_storage); +} + +static dtls_handshake_parameters_t *dtls_handshake_malloc() { + return memb_alloc(&handshake_storage); +} + +static void dtls_handshake_dealloc(dtls_handshake_parameters_t *handshake) { + memb_free(&handshake_storage, handshake); +} + +static dtls_security_parameters_t *dtls_security_malloc() { + return memb_alloc(&security_storage); +} + +static void dtls_security_dealloc(dtls_security_parameters_t *security) { + memb_free(&security_storage, security); +} +#endif /* WITH_CONTIKI */ + +dtls_handshake_parameters_t *dtls_handshake_new() +{ + dtls_handshake_parameters_t *handshake; + + handshake = dtls_handshake_malloc(); + if (!handshake) { + dtls_crit("can not allocate a handshake struct\n"); + return NULL; + } + + memset(handshake, 0, sizeof(*handshake)); + + if (handshake) { + /* initialize the handshake hash wrt. the hard-coded DTLS version */ + dtls_debug("DTLSv12: initialize HASH_SHA256\n"); + /* TLS 1.2: PRF(secret, label, seed) = P_(secret, label + seed) */ + /* FIXME: we use the default SHA256 here, might need to support other + hash functions as well */ + dtls_hash_init(&handshake->hs_state.hs_hash); + } + return handshake; +} + +void dtls_handshake_free(dtls_handshake_parameters_t *handshake) +{ + if (!handshake) + return; + + netq_delete_all(handshake->reorder_queue); + dtls_handshake_dealloc(handshake); +} + +dtls_security_parameters_t *dtls_security_new() +{ + dtls_security_parameters_t *security; + + security = dtls_security_malloc(); + if (!security) { + dtls_crit("can not allocate a security struct\n"); + return NULL; + } + + memset(security, 0, sizeof(*security)); + + if (security) { + security->cipher = TLS_NULL_WITH_NULL_NULL; + security->compression = TLS_COMPRESSION_NULL; + } + return security; +} + +void dtls_security_free(dtls_security_parameters_t *security) +{ + if (!security) + return; + + dtls_security_dealloc(security); +} + +size_t +dtls_p_hash(dtls_hashfunc_t h, + const unsigned char *key, size_t keylen, + const unsigned char *label, size_t labellen, + const unsigned char *random1, size_t random1len, + const unsigned char *random2, size_t random2len, + unsigned char *buf, size_t buflen) { + dtls_hmac_context_t *hmac_a, *hmac_p; + + unsigned char A[DTLS_HMAC_DIGEST_SIZE]; + unsigned char tmp[DTLS_HMAC_DIGEST_SIZE]; + size_t dlen; /* digest length */ + size_t len = 0; /* result length */ + + hmac_a = dtls_hmac_new(key, keylen); + if (!hmac_a) + return 0; + + /* calculate A(1) from A(0) == seed */ + HMAC_UPDATE_SEED(hmac_a, label, labellen); + HMAC_UPDATE_SEED(hmac_a, random1, random1len); + HMAC_UPDATE_SEED(hmac_a, random2, random2len); + + dlen = dtls_hmac_finalize(hmac_a, A); + + hmac_p = dtls_hmac_new(key, keylen); + if (!hmac_p) + goto error; + + while (len + dlen < buflen) { + + /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */ + dtls_hmac_init(hmac_p, key, keylen); + dtls_hmac_update(hmac_p, A, dlen); + + HMAC_UPDATE_SEED(hmac_p, label, labellen); + HMAC_UPDATE_SEED(hmac_p, random1, random1len); + HMAC_UPDATE_SEED(hmac_p, random2, random2len); + + len += dtls_hmac_finalize(hmac_p, tmp); + memcpy(buf, tmp, dlen); + buf += dlen; + + /* calculate A(i+1) */ + dtls_hmac_init(hmac_a, key, keylen); + dtls_hmac_update(hmac_a, A, dlen); + dtls_hmac_finalize(hmac_a, A); + } + + dtls_hmac_init(hmac_p, key, keylen); + dtls_hmac_update(hmac_p, A, dlen); + + HMAC_UPDATE_SEED(hmac_p, label, labellen); + HMAC_UPDATE_SEED(hmac_p, random1, random1len); + HMAC_UPDATE_SEED(hmac_p, random2, random2len); + + dtls_hmac_finalize(hmac_p, tmp); + memcpy(buf, tmp, buflen - len); + + error: + dtls_hmac_free(hmac_a); + dtls_hmac_free(hmac_p); + + return buflen; +} + +size_t +dtls_prf(const unsigned char *key, size_t keylen, + const unsigned char *label, size_t labellen, + const unsigned char *random1, size_t random1len, + const unsigned char *random2, size_t random2len, + unsigned char *buf, size_t buflen) { + + /* Clear the result buffer */ + memset(buf, 0, buflen); + return dtls_p_hash(HASH_SHA256, + key, keylen, + label, labellen, + random1, random1len, + random2, random2len, + buf, buflen); +} + +void +dtls_mac(dtls_hmac_context_t *hmac_ctx, + const unsigned char *record, + const unsigned char *packet, size_t length, + unsigned char *buf) { + uint16 L; + dtls_int_to_uint16(L, length); + + assert(hmac_ctx); + dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48)); + dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16)); + dtls_hmac_update(hmac_ctx, L, sizeof(uint16)); + dtls_hmac_update(hmac_ctx, packet, length); + + dtls_hmac_finalize(hmac_ctx, buf); +} + +static size_t +dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen, + unsigned char *buf, + unsigned char *nounce, + const unsigned char *aad, size_t la) { + long int len; + + assert(ccm_ctx); + + len = dtls_ccm_encrypt_message(&ccm_ctx->ctx, 8 /* M */, + max(2, 15 - DTLS_CCM_NONCE_SIZE), + nounce, + buf, srclen, + aad, la); + return len; +} + +static size_t +dtls_ccm_decrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, + size_t srclen, unsigned char *buf, + unsigned char *nounce, + const unsigned char *aad, size_t la) { + long int len; + + assert(ccm_ctx); + + len = dtls_ccm_decrypt_message(&ccm_ctx->ctx, 8 /* M */, + max(2, 15 - DTLS_CCM_NONCE_SIZE), + nounce, + buf, srclen, + aad, la); + return len; +} + +#ifdef DTLS_PSK +int +dtls_psk_pre_master_secret(unsigned char *key, size_t keylen, + unsigned char *result, size_t result_len) { + unsigned char *p = result; + + if (result_len < (2 * (sizeof(uint16) + keylen))) { + return -1; + } + + dtls_int_to_uint16(p, keylen); + p += sizeof(uint16); + + memset(p, 0, keylen); + p += keylen; + + memcpy(p, result, sizeof(uint16)); + p += sizeof(uint16); + + memcpy(p, key, keylen); + + return 2 * (sizeof(uint16) + keylen); +} +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC + +int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size, + unsigned char *buf) { + int i; + unsigned char *buf_orig = buf; + int first = 1; + + for (i = (key_size / sizeof(uint32_t)) - 1; i >= 0 ; i--) { + if (key[i] == 0) + continue; + /* the first bit has to be set to zero, to indicate a poritive integer */ + if (first && key[i] & 0x80000000) { + *buf = 0; + buf++; + dtls_int_to_uint32(buf, key[i]); + buf += 4; + } else if (first && !(key[i] & 0xFF800000)) { + buf[0] = (key[i] >> 16) & 0xff; + buf[1] = (key[i] >> 8) & 0xff; + buf[2] = key[i] & 0xff; + buf += 3; + } else if (first && !(key[i] & 0xFFFF8000)) { + buf[0] = (key[i] >> 8) & 0xff; + buf[1] = key[i] & 0xff; + buf += 2; + } else if (first && !(key[i] & 0xFFFFFF80)) { + buf[0] = key[i] & 0xff; + buf += 1; + } else { + dtls_int_to_uint32(buf, key[i]); + buf += 4; + } + first = 0; + } + return buf - buf_orig; +} + +int dtls_ecdh_pre_master_secret(unsigned char *priv_key, + unsigned char *pub_key_x, + unsigned char *pub_key_y, + size_t key_size, + unsigned char *result, + size_t result_len) { + + uint8_t publicKey[64]; + uint8_t privateKey[32]; + + if (result_len < key_size) { + return -1; + } + + + memcpy(publicKey, pub_key_x, 32); + memcpy(publicKey + 32, pub_key_y, 32); + memcpy(privateKey, priv_key, 32); + uECC_shared_secret(publicKey, privateKey, result); + + return key_size; +} + +void +dtls_ecdsa_generate_key(unsigned char *priv_key, + unsigned char *pub_key_x, + unsigned char *pub_key_y, + size_t key_size) { + + uint8_t publicKey[64]; + uint8_t privateKey[32]; + + uECC_make_key(publicKey, privateKey); + memcpy(pub_key_x, publicKey, 32); + memcpy(pub_key_y, publicKey + 32, 32); + memcpy(priv_key, privateKey, 32); + +} + +/* rfc4492#section-5.4 */ +void +dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size, + const unsigned char *sign_hash, size_t sign_hash_size, + uint32_t point_r[9], uint32_t point_s[9]) { + int ret; + + uint8_t privateKey[32]; + uint8_t hashValue[32]; + uint8_t sign[64]; + + + uECC_sign(privateKey, hashValue, sign); + memcpy(point_r, sign, 32); + memcpy(point_s, sign + 32, 32); +} + +void +dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size, + const unsigned char *client_random, size_t client_random_size, + const unsigned char *server_random, size_t server_random_size, + const unsigned char *keyx_params, size_t keyx_params_size, + uint32_t point_r[9], uint32_t point_s[9]) { + dtls_hash_ctx data; + unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; + + dtls_hash_init(&data); + dtls_hash_update(&data, client_random, client_random_size); + dtls_hash_update(&data, server_random, server_random_size); + dtls_hash_update(&data, keyx_params, keyx_params_size); + dtls_hash_finalize(sha256hash, &data); + + dtls_ecdsa_create_sig_hash(priv_key, key_size, sha256hash, + sizeof(sha256hash), point_r, point_s); +} + +/* rfc4492#section-5.4 */ +int +dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x, + const unsigned char *pub_key_y, size_t key_size, + const unsigned char *sign_hash, size_t sign_hash_size, + unsigned char *result_r, unsigned char *result_s) { + + uint8_t publicKey[64]; + uint8_t hashValue[32]; + uint8_t sign[64]; + + memcpy(publicKey, pub_key_x, 32); + memcpy(publicKey + 32, pub_key_y, 32); + return uECC_verify(publicKey, hashValue, sign); +} + +int +dtls_ecdsa_verify_sig(const unsigned char *pub_key_x, + const unsigned char *pub_key_y, size_t key_size, + const unsigned char *client_random, size_t client_random_size, + const unsigned char *server_random, size_t server_random_size, + const unsigned char *keyx_params, size_t keyx_params_size, + unsigned char *result_r, unsigned char *result_s) { + dtls_hash_ctx data; + unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; + + dtls_hash_init(&data); + dtls_hash_update(&data, client_random, client_random_size); + dtls_hash_update(&data, server_random, server_random_size); + dtls_hash_update(&data, keyx_params, keyx_params_size); + dtls_hash_finalize(sha256hash, &data); + + return dtls_ecdsa_verify_sig_hash(pub_key_x, pub_key_y, key_size, sha256hash, + sizeof(sha256hash), result_r, result_s); +} +#endif /* DTLS_ECC */ + +int +dtls_encrypt(const unsigned char *src, size_t length, + unsigned char *buf, + unsigned char *nounce, + unsigned char *key, size_t keylen, + const unsigned char *aad, size_t la) +{ + int ret; + struct dtls_cipher_context_t *ctx = dtls_cipher_context_get(); + + ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen); + if (ret < 0) { + /* cleanup everything in case the key has the wrong size */ + dtls_warn("cannot set rijndael key\n"); + goto error; + } + + if (src != buf) + memmove(buf, src, length); + ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la); + +error: + dtls_cipher_context_release(); + return ret; +} + +int +dtls_decrypt(const unsigned char *src, size_t length, + unsigned char *buf, + unsigned char *nounce, + unsigned char *key, size_t keylen, + const unsigned char *aad, size_t la) +{ + int ret; + struct dtls_cipher_context_t *ctx = dtls_cipher_context_get(); + + ret = rijndael_set_key_enc_only(&ctx->data.ctx, key, 8 * keylen); + if (ret < 0) { + /* cleanup everything in case the key has the wrong size */ + dtls_warn("cannot set rijndael key\n"); + goto error; + } + + if (src != buf) + memmove(buf, src, length); + ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la); + +error: + dtls_cipher_context_release(); + return ret; +} + diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h new file mode 100644 index 0000000..972a174 --- /dev/null +++ b/extlibs/tinydtls/crypto.h @@ -0,0 +1,359 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_CRYPTO_H_ +#define _DTLS_CRYPTO_H_ + +#include /* for rand() and srand() */ +#include + +#include "t_list.h" + +#include "aes/rijndael.h" + +#include "global.h" +#include "state.h" +#include "numeric.h" +#include "hmac.h" +#include "ccm.h" + +/* TLS_PSK_WITH_AES_128_CCM_8 */ +#define DTLS_MAC_KEY_LENGTH 0 +#define DTLS_KEY_LENGTH 16 /* AES-128 */ +#define DTLS_BLK_LENGTH 16 /* AES-128 */ +#define DTLS_MAC_LENGTH DTLS_HMAC_DIGEST_SIZE +#define DTLS_IV_LENGTH 4 /* length of nonce_explicit */ + +/** + * Maximum size of the generated keyblock. Note that MAX_KEYBLOCK_LENGTH must + * be large enough to hold the pre_master_secret, i.e. twice the length of the + * pre-shared key + 1. + */ +#define MAX_KEYBLOCK_LENGTH \ + (2 * DTLS_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH + 2 * DTLS_IV_LENGTH) + +/** Length of DTLS master_secret */ +#define DTLS_MASTER_SECRET_LENGTH 48 +#define DTLS_RANDOM_LENGTH 32 + +typedef enum { AES128=0 +} dtls_crypto_alg; + +typedef enum { + DTLS_ECDH_CURVE_SECP256R1 +} dtls_ecdh_curve; + +/** Crypto context for TLS_PSK_WITH_AES_128_CCM_8 cipher suite. */ +typedef struct { + rijndael_ctx ctx; /**< AES-128 encryption context */ +} aes128_ccm_t; + +typedef struct dtls_cipher_context_t { + /** numeric identifier of this cipher suite in host byte order. */ + aes128_ccm_t data; /**< The crypto context */ +} dtls_cipher_context_t; + +typedef struct { + uint8 own_eph_priv[32]; + uint8 other_eph_pub_x[32]; + uint8 other_eph_pub_y[32]; + uint8 other_pub_x[32]; + uint8 other_pub_y[32]; +} dtls_handshake_parameters_ecdsa_t; + +/* This is the maximal supported length of the psk client identity and psk + * server identity hint */ +#define DTLS_PSK_MAX_CLIENT_IDENTITY_LEN 32 + +/* This is the maximal supported length of the pre-shared key. */ +#define DTLS_PSK_MAX_KEY_LEN 32 + +typedef struct { + uint16_t id_length; + unsigned char identity[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; +} dtls_handshake_parameters_psk_t; + +typedef struct { + dtls_compression_t compression; /**< compression method */ + + dtls_cipher_t cipher; /**< cipher type */ + uint16_t epoch; /**< counter for cipher state changes*/ + uint64_t rseq; /**< sequence number of last record sent */ + + /** + * The key block generated from PRF applied to client and server + * random bytes. The actual size is given by the selected cipher and + * can be calculated using dtls_kb_size(). Use \c dtls_kb_ macros to + * access the components of the key block. + */ + uint8 key_block[MAX_KEYBLOCK_LENGTH]; +} dtls_security_parameters_t; + +typedef struct { + union { + struct random_t { + uint8 client[DTLS_RANDOM_LENGTH]; /**< client random gmt and bytes */ + uint8 server[DTLS_RANDOM_LENGTH]; /**< server random gmt and bytes */ + } random; + /** the session's master secret */ + uint8 master_secret[DTLS_MASTER_SECRET_LENGTH]; + } tmp; + LIST_STRUCT(reorder_queue); /**< the packets to reorder */ + dtls_hs_state_t hs_state; /**< handshake protocol status */ + + dtls_compression_t compression; /**< compression method */ + dtls_cipher_t cipher; /**< cipher type */ + unsigned int do_client_auth:1; + union { +#ifdef DTLS_ECC + dtls_handshake_parameters_ecdsa_t ecdsa; +#endif /* DTLS_ECC */ +#ifdef DTLS_PSK + dtls_handshake_parameters_psk_t psk; +#endif /* DTLS_PSK */ + } keyx; +} dtls_handshake_parameters_t; + +/* The following macros provide access to the components of the + * key_block in the security parameters. */ + +#define dtls_kb_client_mac_secret(Param, Role) ((Param)->key_block) +#define dtls_kb_server_mac_secret(Param, Role) \ + (dtls_kb_client_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH) +#define dtls_kb_remote_mac_secret(Param, Role) \ + ((Role) == DTLS_SERVER \ + ? dtls_kb_client_mac_secret(Param, Role) \ + : dtls_kb_server_mac_secret(Param, Role)) +#define dtls_kb_local_mac_secret(Param, Role) \ + ((Role) == DTLS_CLIENT \ + ? dtls_kb_client_mac_secret(Param, Role) \ + : dtls_kb_server_mac_secret(Param, Role)) +#define dtls_kb_mac_secret_size(Param, Role) DTLS_MAC_KEY_LENGTH +#define dtls_kb_client_write_key(Param, Role) \ + (dtls_kb_server_mac_secret(Param, Role) + DTLS_MAC_KEY_LENGTH) +#define dtls_kb_server_write_key(Param, Role) \ + (dtls_kb_client_write_key(Param, Role) + DTLS_KEY_LENGTH) +#define dtls_kb_remote_write_key(Param, Role) \ + ((Role) == DTLS_SERVER \ + ? dtls_kb_client_write_key(Param, Role) \ + : dtls_kb_server_write_key(Param, Role)) +#define dtls_kb_local_write_key(Param, Role) \ + ((Role) == DTLS_CLIENT \ + ? dtls_kb_client_write_key(Param, Role) \ + : dtls_kb_server_write_key(Param, Role)) +#define dtls_kb_key_size(Param, Role) DTLS_KEY_LENGTH +#define dtls_kb_client_iv(Param, Role) \ + (dtls_kb_server_write_key(Param, Role) + DTLS_KEY_LENGTH) +#define dtls_kb_server_iv(Param, Role) \ + (dtls_kb_client_iv(Param, Role) + DTLS_IV_LENGTH) +#define dtls_kb_remote_iv(Param, Role) \ + ((Role) == DTLS_SERVER \ + ? dtls_kb_client_iv(Param, Role) \ + : dtls_kb_server_iv(Param, Role)) +#define dtls_kb_local_iv(Param, Role) \ + ((Role) == DTLS_CLIENT \ + ? dtls_kb_client_iv(Param, Role) \ + : dtls_kb_server_iv(Param, Role)) +#define dtls_kb_iv_size(Param, Role) DTLS_IV_LENGTH + +#define dtls_kb_size(Param, Role) \ + (2 * (dtls_kb_mac_secret_size(Param, Role) + \ + dtls_kb_key_size(Param, Role) + dtls_kb_iv_size(Param, Role))) + +/* just for consistency */ +#define dtls_kb_digest_size(Param, Role) DTLS_MAC_LENGTH + +/** + * Expands the secret and key to a block of DTLS_HMAC_MAX + * size according to the algorithm specified in section 5 of + * RFC 4346. + * + * \param h Identifier of the hash function to use. + * \param key The secret. + * \param keylen Length of \p key. + * \param seed The seed. + * \param seedlen Length of \p seed. + * \param buf Output buffer where the result is XORed into + * The buffe must be capable to hold at least + * \p buflen bytes. + * \return The actual number of bytes written to \p buf or 0 + * on error. + */ +size_t dtls_p_hash(dtls_hashfunc_t h, + const unsigned char *key, size_t keylen, + const unsigned char *label, size_t labellen, + const unsigned char *random1, size_t random1len, + const unsigned char *random2, size_t random2len, + unsigned char *buf, size_t buflen); + +/** + * This function implements the TLS PRF for DTLS_VERSION. For version + * 1.0, the PRF is P_MD5 ^ P_SHA1 while version 1.2 uses + * P_SHA256. Currently, the actual PRF is selected at compile time. + */ +size_t dtls_prf(const unsigned char *key, size_t keylen, + const unsigned char *label, size_t labellen, + const unsigned char *random1, size_t random1len, + const unsigned char *random2, size_t random2len, + unsigned char *buf, size_t buflen); + +/** + * Calculates MAC for record + cleartext packet and places the result + * in \p buf. The given \p hmac_ctx must be initialized with the HMAC + * function to use and the proper secret. As the DTLS mac calculation + * requires data from the record header, \p record must point to a + * buffer of at least \c sizeof(dtls_record_header_t) bytes. Usually, + * the remaining packet will be encrypted, therefore, the cleartext + * is passed separately in \p packet. + * + * \param hmac_ctx The HMAC context to use for MAC calculation. + * \param record The record header. + * \param packet Cleartext payload to apply the MAC to. + * \param length Size of \p packet. + * \param buf A result buffer that is large enough to hold + * the generated digest. + */ +void dtls_mac(dtls_hmac_context_t *hmac_ctx, + const unsigned char *record, + const unsigned char *packet, size_t length, + unsigned char *buf); + +/** + * Encrypts the specified \p src of given \p length, writing the + * result to \p buf. The cipher implementation may add more data to + * the result buffer such as an initialization vector or padding + * (e.g. for block cipers in CBC mode). The caller therefore must + * ensure that \p buf provides sufficient storage to hold the result. + * Usually this means ( 2 + \p length / blocksize ) * blocksize. The + * function returns a value less than zero on error or otherwise the + * number of bytes written. + * + * \param ctx The cipher context to use. + * \param src The data to encrypt. + * \param length The actual size of of \p src. + * \param buf The result buffer. \p src and \p buf must not + * overlap. + * \param aad additional data for AEAD ciphers + * \param aad_length actual size of @p aad + * \return The number of encrypted bytes on success, less than zero + * otherwise. + */ +int dtls_encrypt(const unsigned char *src, size_t length, + unsigned char *buf, + unsigned char *nounce, + unsigned char *key, size_t keylen, + const unsigned char *aad, size_t aad_length); + +/** + * Decrypts the given buffer \p src of given \p length, writing the + * result to \p buf. The function returns \c -1 in case of an error, + * or the number of bytes written. Note that for block ciphers, \p + * length must be a multiple of the cipher's block size. A return + * value between \c 0 and the actual length indicates that only \c n-1 + * block have been processed. Unlike dtls_encrypt(), the source + * and destination of dtls_decrypt() may overlap. + * + * \param ctx The cipher context to use. + * \param src The buffer to decrypt. + * \param length The length of the input buffer. + * \param buf The result buffer. + * \param aad additional authentication data for AEAD ciphers + * \param aad_length actual size of @p aad + * \return Less than zero on error, the number of decrypted bytes + * otherwise. + */ +int dtls_decrypt(const unsigned char *src, size_t length, + unsigned char *buf, + unsigned char *nounce, + unsigned char *key, size_t keylen, + const unsigned char *a_data, size_t a_data_length); + +/* helper functions */ + +/** + * Generates pre_master_sercet from given PSK and fills the result + * according to the "plain PSK" case in section 2 of RFC 4279. + * Diffie-Hellman and RSA key exchange are currently not supported. + * + * @param key The shared key. + * @param keylen Length of @p key in bytes. + * @param result The derived pre master secret. + * @return The actual length of @p result. + */ +int dtls_psk_pre_master_secret(unsigned char *key, size_t keylen, + unsigned char *result, size_t result_len); + +#define DTLS_EC_KEY_SIZE 32 + +int dtls_ecdh_pre_master_secret(unsigned char *priv_key, + unsigned char *pub_key_x, + unsigned char *pub_key_y, + size_t key_size, + unsigned char *result, + size_t result_len); + +void dtls_ecdsa_generate_key(unsigned char *priv_key, + unsigned char *pub_key_x, + unsigned char *pub_key_y, + size_t key_size); + +void dtls_ecdsa_create_sig_hash(const unsigned char *priv_key, size_t key_size, + const unsigned char *sign_hash, size_t sign_hash_size, + uint32_t point_r[9], uint32_t point_s[9]); + +void dtls_ecdsa_create_sig(const unsigned char *priv_key, size_t key_size, + const unsigned char *client_random, size_t client_random_size, + const unsigned char *server_random, size_t server_random_size, + const unsigned char *keyx_params, size_t keyx_params_size, + uint32_t point_r[9], uint32_t point_s[9]); + +int dtls_ecdsa_verify_sig_hash(const unsigned char *pub_key_x, + const unsigned char *pub_key_y, size_t key_size, + const unsigned char *sign_hash, size_t sign_hash_size, + unsigned char *result_r, unsigned char *result_s); + +int dtls_ecdsa_verify_sig(const unsigned char *pub_key_x, + const unsigned char *pub_key_y, size_t key_size, + const unsigned char *client_random, size_t client_random_size, + const unsigned char *server_random, size_t server_random_size, + const unsigned char *keyx_params, size_t keyx_params_size, + unsigned char *result_r, unsigned char *result_s); + +int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size, + unsigned char *buf); + + +dtls_handshake_parameters_t *dtls_handshake_new(); + +void dtls_handshake_free(dtls_handshake_parameters_t *handshake); + +dtls_security_parameters_t *dtls_security_new(); + +void dtls_security_free(dtls_security_parameters_t *security); +void crypto_init(); + +#endif /* _DTLS_CRYPTO_H_ */ + diff --git a/extlibs/tinydtls/debug.c b/extlibs/tinydtls/debug.c new file mode 100644 index 0000000..49a93eb --- /dev/null +++ b/extlibs/tinydtls/debug.c @@ -0,0 +1,373 @@ +/* debug.c -- debug utilities + * + * Copyright (C) 2011--2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tinydtls.h" +#include "dtls_config.h" + +#if defined(HAVE_ASSERT_H) && !defined(assert) +#include +#endif + +#include +#include + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#include "global.h" +#include "debug.h" + +static int maxlog = DTLS_LOG_WARN; /* default maximum log level */ + +const char *dtls_package_name() { + return PACKAGE_NAME; +} + +const char *dtls_package_version() { + return PACKAGE_VERSION; +} + +log_t +dtls_get_log_level() { + return maxlog; +} + +void +dtls_set_log_level(log_t level) { + maxlog = level; +} + +/* this array has the same order as the type log_t */ +static char *loglevels[] = { + "EMRG", "ALRT", "CRIT", "WARN", "NOTE", "INFO", "DEBG" +}; + +#ifdef HAVE_TIME_H + +static inline size_t +print_timestamp(char *s, size_t len, time_t t) { + struct tm *tmp; + tmp = localtime(&t); + return strftime(s, len, "%b %d %H:%M:%S", tmp); +} + +#else /* alternative implementation: just print the timestamp */ + +static inline size_t +print_timestamp(char *s, size_t len, clock_time_t t) { +#ifdef HAVE_SNPRINTF + return snprintf(s, len, "%u.%03u", + (unsigned int)(t / CLOCK_SECOND), + (unsigned int)(t % CLOCK_SECOND)); +#else /* HAVE_SNPRINTF */ + /* @todo do manual conversion of timestamp */ + return 0; +#endif /* HAVE_SNPRINTF */ +} + +#endif /* HAVE_TIME_H */ + +/** + * A length-safe strlen() fake. + * + * @param s The string to count characters != 0. + * @param maxlen The maximum length of @p s. + * + * @return The length of @p s. + */ +static inline size_t +dtls_strnlen(const char *s, size_t maxlen) { + size_t n = 0; + while(*s++ && n < maxlen) + ++n; + return n; +} + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +static size_t +dsrv_print_addr(const session_t *addr, char *buf, size_t len) { +#ifdef HAVE_ARPA_INET_H + const void *addrptr = NULL; + in_port_t port; + char *p = buf; + + switch (addr->addr.sa.sa_family) { + case AF_INET: + if (len < INET_ADDRSTRLEN) + return 0; + + addrptr = &addr->addr.sin.sin_addr; + port = ntohs(addr->addr.sin.sin_port); + break; + case AF_INET6: + if (len < INET6_ADDRSTRLEN + 2) + return 0; + + *p++ = '['; + + addrptr = &addr->addr.sin6.sin6_addr; + port = ntohs(addr->addr.sin6.sin6_port); + + break; + default: + memcpy(buf, "(unknown address type)", min(22, len)); + return min(22, len); + } + + if (inet_ntop(addr->addr.sa.sa_family, addrptr, p, len) == 0) { + perror("dsrv_print_addr"); + return 0; + } + + p += dtls_strnlen(p, len); + + if (addr->addr.sa.sa_family == AF_INET6) { + if (p < buf + len) { + *p++ = ']'; + } else + return 0; + } + + p += snprintf(p, buf + len - p + 1, ":%d", port); + + return p - buf; +#else /* HAVE_ARPA_INET_H */ +# if WITH_CONTIKI + char *p = buf; +# ifdef UIP_CONF_IPV6 + uint8_t i; + const char hex[] = "0123456789ABCDEF"; + + if (len < 41) + return 0; + + *p++ = '['; + + for (i=0; i < 16; i += 2) { + if (i) { + *p++ = ':'; + } + *p++ = hex[(addr->addr.u8[i] & 0xf0) >> 4]; + *p++ = hex[(addr->addr.u8[i] & 0x0f)]; + *p++ = hex[(addr->addr.u8[i+1] & 0xf0) >> 4]; + *p++ = hex[(addr->addr.u8[i+1] & 0x0f)]; + } + *p++ = ']'; +# else /* UIP_CONF_IPV6 */ +# warning "IPv4 network addresses will not be included in debug output" + + if (len < 21) + return 0; +# endif /* UIP_CONF_IPV6 */ + if (buf + len - p < 6) + return 0; + + p += sprintf(p, ":%d", uip_htons(addr->port)); + + return p - buf; +# else /* WITH_CONTIKI */ + /* TODO: output addresses manually */ +# warning "inet_ntop() not available, network addresses will not be included in debug output" +# endif /* WITH_CONTIKI */ + return 0; +#endif +} + +#ifndef WITH_CONTIKI +void +dsrv_log(log_t level, char *format, ...) { + static char timebuf[32]; + va_list ap; + FILE *log_fd; + + if (maxlog < level) + return; + + log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout; + + if (print_timestamp(timebuf,sizeof(timebuf), time(NULL))) + fprintf(log_fd, "%s ", timebuf); + + if (level <= DTLS_LOG_DEBUG) + fprintf(log_fd, "%s ", loglevels[level]); + + va_start(ap, format); + vfprintf(log_fd, format, ap); + va_end(ap); + fflush(log_fd); +} +#elif defined (HAVE_VPRINTF) /* WITH_CONTIKI */ +void +dsrv_log(log_t level, char *format, ...) { + static char timebuf[32]; + va_list ap; + + if (maxlog < level) + return; + + if (print_timestamp(timebuf,sizeof(timebuf), clock_time())) + PRINTF("%s ", timebuf); + + if (level <= DTLS_LOG_DEBUG) + PRINTF("%s ", loglevels[level]); + + va_start(ap, format); + vprintf(format, ap); + va_end(ap); +} +#endif /* WITH_CONTIKI */ + +#ifndef NDEBUG +/** dumps packets in usual hexdump format */ +void hexdump(const unsigned char *packet, int length) { + int n = 0; + + while (length--) { + if (n % 16 == 0) + printf("%08X ",n); + + printf("%02X ", *packet++); + + n++; + if (n % 8 == 0) { + if (n % 16 == 0) + printf("\n"); + else + printf(" "); + } + } +} + +/** dump as narrow string of hex digits */ +void dump(unsigned char *buf, size_t len) { + while (len--) + printf("%02x", *buf++); +} + +void dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr) +{ + char addrbuf[73]; + int len; + + len = dsrv_print_addr(addr, addrbuf, sizeof(addrbuf)); + if (!len) + return; + dsrv_log(level, "%s: %s\n", name, addrbuf); +} + +#ifndef WITH_CONTIKI +void +dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) { + static char timebuf[32]; + FILE *log_fd; + int n = 0; + + if (maxlog < level) + return; + + log_fd = level <= DTLS_LOG_CRIT ? stderr : stdout; + + if (print_timestamp(timebuf, sizeof(timebuf), time(NULL))) + fprintf(log_fd, "%s ", timebuf); + + if (level <= DTLS_LOG_DEBUG) + fprintf(log_fd, "%s ", loglevels[level]); + + if (extend) { + fprintf(log_fd, "%s: (%zu bytes):\n", name, length); + + while (length--) { + if (n % 16 == 0) + fprintf(log_fd, "%08X ", n); + + fprintf(log_fd, "%02X ", *buf++); + + n++; + if (n % 8 == 0) { + if (n % 16 == 0) + fprintf(log_fd, "\n"); + else + fprintf(log_fd, " "); + } + } + } else { + fprintf(log_fd, "%s: (%zu bytes): ", name, length); + while (length--) + fprintf(log_fd, "%02X", *buf++); + } + fprintf(log_fd, "\n"); + + fflush(log_fd); +} +#else /* WITH_CONTIKI */ +void +dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) { + static char timebuf[32]; + int n = 0; + + if (maxlog < level) + return; + + if (print_timestamp(timebuf,sizeof(timebuf), clock_time())) + PRINTF("%s ", timebuf); + + if (level >= 0 && level <= DTLS_LOG_DEBUG) + PRINTF("%s ", loglevels[level]); + + if (extend) { + PRINTF("%s: (%zu bytes):\n", name, length); + + while (length--) { + if (n % 16 == 0) + PRINTF("%08X ", n); + + PRINTF("%02X ", *buf++); + + n++; + if (n % 8 == 0) { + if (n % 16 == 0) + PRINTF("\n"); + else + PRINTF(" "); + } + } + } else { + PRINTF("%s: (%zu bytes): ", name, length); + while (length--) + PRINTF("%02X", *buf++); + } + PRINTF("\n"); +} +#endif /* WITH_CONTIKI */ + +#endif /* NDEBUG */ diff --git a/extlibs/tinydtls/debug.h b/extlibs/tinydtls/debug.h new file mode 100644 index 0000000..95286f8 --- /dev/null +++ b/extlibs/tinydtls/debug.h @@ -0,0 +1,143 @@ +/* debug.h -- debug utilities + * + * Copyright (C) 2011--2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_DEBUG_H_ +#define _DTLS_DEBUG_H_ + +#include + +#include "dtls_config.h" +#include "global.h" +#include "session.h" + +#ifdef WITH_CONTIKI +# ifndef DEBUG +# define DEBUG DEBUG_PRINT +# endif /* DEBUG */ +#include "net/ip/uip-debug.h" + +#ifdef CONTIKI_TARGET_MBXXX +extern char __Stack_Init, _estack; + +static inline void check_stack() { + const char *p = &__Stack_Init; + while (p < &_estack && *p == 0x38) { + p++; + } + + PRINTF("Stack: %d bytes used (%d free)\n", &_estack - p, p - &__Stack_Init); +} +#else /* CONTIKI_TARGET_MBXXX */ +static inline void check_stack() { +} +#endif /* CONTIKI_TARGET_MBXXX */ +#else /* WITH_CONTKI */ +#define PRINTF(...) + +static inline void check_stack() { +} +#endif + +struct __session_t; + +/** Pre-defined log levels akin to what is used in \b syslog. */ +typedef enum { DTLS_LOG_EMERG=0, DTLS_LOG_ALERT, DTLS_LOG_CRIT, DTLS_LOG_WARN, + DTLS_LOG_NOTICE, DTLS_LOG_INFO, DTLS_LOG_DEBUG +} log_t; + +/** Returns a zero-terminated string with the name of this library. */ +const char *dtls_package_name(); + +/** Returns a zero-terminated string with the library version. */ +const char *dtls_package_version(); + +#ifndef NDEBUG +/** Returns the current log level. */ +log_t dtls_get_log_level(); + +/** Sets the log level to the specified value. */ +void dtls_set_log_level(log_t level); + +/** + * Writes the given text to \c stdout. The text is output only when \p + * level is below or equal to the log level that set by + * set_log_level(). */ +#ifdef HAVE_VPRINTF +void dsrv_log(log_t level, char *format, ...); +#else +#define dsrv_log(level, format, ...) PRINTF(format, ##__VA_ARGS__) +#endif + +/** dumps packets in usual hexdump format */ +void hexdump(const unsigned char *packet, int length); + +/** dump as narrow string of hex digits */ +void dump(unsigned char *buf, size_t len); + +void dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend); + +void dtls_dsrv_log_addr(log_t level, const char *name, const session_t *addr); + +#else /* NDEBUG */ + +static inline log_t dtls_get_log_level() +{ + return DTLS_LOG_EMERG; +} + +static inline void dtls_set_log_level(log_t level) +{} + +static inline void dsrv_log(log_t level, char *format, ...) +{} + +static inline void hexdump(const unsigned char *packet, int length) +{} + +static inline void dump(unsigned char *buf, size_t len) +{} + +static inline void +dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) +{} + +static inline void +dtls_dsrv_log_addr(log_t level, const char *name, const struct __session_t *addr) +{} + +#endif /* NDEBUG */ + +/* A set of convenience macros for common log levels. */ +#define dtls_emerg(...) dsrv_log(DTLS_LOG_EMERG, __VA_ARGS__) +#define dtls_alert(...) dsrv_log(DTLS_LOG_ALERT, __VA_ARGS__) +#define dtls_crit(...) dsrv_log(DTLS_LOG_CRIT, __VA_ARGS__) +#define dtls_warn(...) dsrv_log(DTLS_LOG_WARN, __VA_ARGS__) +#define dtls_notice(...) dsrv_log(DTLS_LOG_NOTICE, __VA_ARGS__) +#define dtls_info(...) dsrv_log(DTLS_LOG_INFO, __VA_ARGS__) +#define dtls_debug(...) dsrv_log(DTLS_LOG_DEBUG, __VA_ARGS__) +#define dtls_debug_hexdump(name, buf, length) dtls_dsrv_hexdump_log(DTLS_LOG_DEBUG, name, buf, length, 1) +#define dtls_debug_dump(name, buf, length) dtls_dsrv_hexdump_log(DTLS_LOG_DEBUG, name, buf, length, 0) + +#endif /* _DTLS_DEBUG_H_ */ diff --git a/extlibs/tinydtls/doc/Doxyfile.in b/extlibs/tinydtls/doc/Doxyfile.in new file mode 100644 index 0000000..9f7ffdf --- /dev/null +++ b/extlibs/tinydtls/doc/Doxyfile.in @@ -0,0 +1,1551 @@ +# Doxyfile 1.6.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = @PACKAGE_NAME@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @PACKAGE_VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = .. + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = DSRV_NO_DTLS DSRV_NO_PROTOCOL_DEMUX + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/extlibs/tinydtls/doc/DoxygenLayout.xml b/extlibs/tinydtls/doc/DoxygenLayout.xml new file mode 100644 index 0000000..1c8525c --- /dev/null +++ b/extlibs/tinydtls/doc/DoxygenLayout.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extlibs/tinydtls/doc/Makefile.in b/extlibs/tinydtls/doc/Makefile.in new file mode 100644 index 0000000..a07101e --- /dev/null +++ b/extlibs/tinydtls/doc/Makefile.in @@ -0,0 +1,36 @@ +# the library's version +VERSION:=@PACKAGE_VERSION@ +PACKAGE_TARNAME:=@PACKAGE_TARNAME@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir +DOXYGEN= @DOXYGEN@ + +top_builddir = @top_builddir@ +prefix = @prefix@ +datarootdir = @datarootdir@ +docdir = @docdir@ +htmldir = @htmldir@ + +DISTDIR?=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ +FILES:=Makefile.in Doxyfile.in html + +doc: Doxyfile + $(DOXYGEN) $< >./doxygen.out 2>&1 + +clean: + @rm -rf html + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ + +dist: doc + test -d $(DISTDIR)/doc || mkdir $(DISTDIR)/doc + cp -r $(FILES) $(DISTDIR)/doc + +install: $(doc) html + test -d $(htmldir) || mkdir -p $(htmldir) + cp -r html/* $(htmldir) diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c new file mode 100644 index 0000000..a923386 --- /dev/null +++ b/extlibs/tinydtls/dtls.c @@ -0,0 +1,4072 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012,2014 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "tinydtls.h" +#include "dtls_config.h" +#include "dtls_time.h" + +#include +#include +#ifdef HAVE_ASSERT_H +#include +#endif +#ifndef WITH_CONTIKI +#include +#include "uthash.h" +#endif /* WITH_CONTIKI */ + +#include "debug.h" +#include "numeric.h" +#include "netq.h" +#include "dtls.h" + +#include "alert.h" +#include "session.h" +#include "prng.h" + +#ifdef WITH_SHA256 +# include "sha2/sha2.h" +#endif + +#define dtls_set_version(H,V) dtls_int_to_uint16((H)->version, (V)) +#define dtls_set_content_type(H,V) ((H)->content_type = (V) & 0xff) +#define dtls_set_length(H,V) ((H)->length = (V)) + +#define dtls_get_content_type(H) ((H)->content_type & 0xff) +#define dtls_get_version(H) dtls_uint16_to_int((H)->version) +#define dtls_get_epoch(H) dtls_uint16_to_int((H)->epoch) +#define dtls_get_sequence_number(H) dtls_uint48_to_ulong((H)->sequence_number) +#define dtls_get_fragment_length(H) dtls_uint24_to_int((H)->fragment_length) + +#ifndef WITH_CONTIKI +#define HASH_FIND_PEER(head,sess,out) \ + HASH_FIND(hh,head,sess,sizeof(session_t),out) +#define HASH_ADD_PEER(head,sess,add) \ + HASH_ADD(hh,head,sess,sizeof(session_t),add) +#define HASH_DEL_PEER(head,delptr) \ + HASH_DELETE(hh,head,delptr) +#endif /* WITH_CONTIKI */ + +#define DTLS_RH_LENGTH sizeof(dtls_record_header_t) +#define DTLS_HS_LENGTH sizeof(dtls_handshake_header_t) +#define DTLS_CH_LENGTH sizeof(dtls_client_hello_t) /* no variable length fields! */ +#define DTLS_COOKIE_LENGTH_MAX 32 +#define DTLS_CH_LENGTH_MAX sizeof(dtls_client_hello_t) + DTLS_COOKIE_LENGTH_MAX + 12 + 26 +#define DTLS_HV_LENGTH sizeof(dtls_hello_verify_t) +#define DTLS_SH_LENGTH (2 + DTLS_RANDOM_LENGTH + 1 + 2 + 1) +#define DTLS_CE_LENGTH (3 + 3 + 27 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE) +#define DTLS_SKEXEC_LENGTH (1 + 2 + 1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE + 1 + 1 + 2 + 70) +#define DTLS_SKEXECPSK_LENGTH_MIN 2 +#define DTLS_SKEXECPSK_LENGTH_MAX 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN +#define DTLS_CKXPSK_LENGTH_MIN 2 +#define DTLS_CKXEC_LENGTH (1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE) +#define DTLS_CV_LENGTH (1 + 1 + 2 + 1 + 1 + 1 + 1 + DTLS_EC_KEY_SIZE + 1 + 1 + DTLS_EC_KEY_SIZE) +#define DTLS_FIN_LENGTH 12 + +#define HS_HDR_LENGTH DTLS_RH_LENGTH + DTLS_HS_LENGTH +#define HV_HDR_LENGTH HS_HDR_LENGTH + DTLS_HV_LENGTH + +#define HIGH(V) (((V) >> 8) & 0xff) +#define LOW(V) ((V) & 0xff) + +#define DTLS_RECORD_HEADER(M) ((dtls_record_header_t *)(M)) +#define DTLS_HANDSHAKE_HEADER(M) ((dtls_handshake_header_t *)(M)) + +#define HANDSHAKE(M) ((dtls_handshake_header_t *)((M) + DTLS_RH_LENGTH)) +#define CLIENTHELLO(M) ((dtls_client_hello_t *)((M) + HS_HDR_LENGTH)) + +/* The length check here should work because dtls_*_to_int() works on + * unsigned char. Otherwise, broken messages could cause severe + * trouble. Note that this macro jumps out of the current program flow + * when the message is too short. Beware! + */ +#define SKIP_VAR_FIELD(P,L,T) { \ + if (L < dtls_ ## T ## _to_int(P) + sizeof(T)) \ + goto error; \ + L -= dtls_ ## T ## _to_int(P) + sizeof(T); \ + P += dtls_ ## T ## _to_int(P) + sizeof(T); \ + } + +/* some constants for the PRF */ +#define PRF_LABEL(Label) prf_label_##Label +#define PRF_LABEL_SIZE(Label) (sizeof(PRF_LABEL(Label)) - 1) + +static const unsigned char prf_label_master[] = "master secret"; +static const unsigned char prf_label_key[] = "key expansion"; +static const unsigned char prf_label_client[] = "client"; +static const unsigned char prf_label_server[] = "server"; +static const unsigned char prf_label_finished[] = " finished"; + +/* first part of Raw public key, the is the start of the Subject Public Key */ +static const unsigned char cert_asn1_header[] = { + 0x30, 0x59, /* SEQUENCE, length 89 bytes */ + 0x30, 0x13, /* SEQUENCE, length 19 bytes */ + 0x06, 0x07, /* OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) */ + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, + 0x06, 0x08, /* OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) */ + 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, + 0x03, 0x42, 0x00, /* BIT STRING, length 66 bytes, 0 bits unused */ + 0x04 /* uncompressed, followed by the r und s values of the public key */ +}; + +#ifdef WITH_CONTIKI +PROCESS(dtls_retransmit_process, "DTLS retransmit process"); + +static dtls_context_t the_dtls_context; + +static inline dtls_context_t * +malloc_context() { + return &the_dtls_context; +} + +static inline void +free_context(dtls_context_t *context) { +} + +#else /* WITH_CONTIKI */ + +static inline dtls_context_t * +malloc_context() { + return (dtls_context_t *)malloc(sizeof(dtls_context_t)); +} + +static inline void +free_context(dtls_context_t *context) { + free(context); +} +#endif + +void +dtls_init() { + dtls_clock_init(); + crypto_init(); + netq_init(); + peer_init(); +} + +/* Calls cb_alert() with given arguments if defined, otherwise an + * error message is logged and the result is -1. This is just an + * internal helper. + */ +#define CALL(Context, which, ...) \ + ((Context)->h && (Context)->h->which \ + ? (Context)->h->which((Context), ##__VA_ARGS__) \ + : -1) + +static int +dtls_send_multi(dtls_context_t *ctx, dtls_peer_t *peer, + dtls_security_parameters_t *security , session_t *session, + unsigned char type, uint8 *buf_array[], + size_t buf_len_array[], size_t buf_array_len); + +/** + * Sends the fragment of length \p buflen given in \p buf to the + * specified \p peer. The data will be MAC-protected and encrypted + * according to the selected cipher and split into one or more DTLS + * records of the specified \p type. This function returns the number + * of bytes that were sent, or \c -1 if an error occurred. + * + * \param ctx The DTLS context to use. + * \param peer The remote peer. + * \param type The content type of the record. + * \param buf The data to send. + * \param buflen The actual length of \p buf. + * \return Less than zero on error, the number of bytes written otherwise. + */ +static int +dtls_send(dtls_context_t *ctx, dtls_peer_t *peer, unsigned char type, + uint8 *buf, size_t buflen) { + return dtls_send_multi(ctx, peer, dtls_security_params(peer), &peer->session, + type, &buf, &buflen, 1); +} + +/** + * Stops ongoing retransmissions of handshake messages for @p peer. + */ +static void dtls_stop_retransmission(dtls_context_t *context, dtls_peer_t *peer); + +dtls_peer_t * +dtls_get_peer(const dtls_context_t *ctx, const session_t *session) { + dtls_peer_t *p = NULL; + +#ifndef WITH_CONTIKI + HASH_FIND_PEER(ctx->peers, session, p); +#else /* WITH_CONTIKI */ + for (p = list_head(ctx->peers); p; p = list_item_next(p)) + if (dtls_session_equals(&p->session, session)) + return p; +#endif /* WITH_CONTIKI */ + + return p; +} + +static void +dtls_add_peer(dtls_context_t *ctx, dtls_peer_t *peer) { +#ifndef WITH_CONTIKI + HASH_ADD_PEER(ctx->peers, session, peer); +#else /* WITH_CONTIKI */ + list_add(ctx->peers, peer); +#endif /* WITH_CONTIKI */ +} + +int +dtls_write(struct dtls_context_t *ctx, + session_t *dst, uint8 *buf, size_t len) { + + dtls_peer_t *peer = dtls_get_peer(ctx, dst); + + /* Check if peer connection already exists */ + if (!peer) { /* no ==> create one */ + int res; + + /* dtls_connect() returns a value greater than zero if a new + * connection attempt is made, 0 for session reuse. */ + res = dtls_connect(ctx, dst); + + return (res >= 0) ? 0 : res; + } else { /* a session exists, check if it is in state connected */ + + if (peer->state != DTLS_STATE_CONNECTED) { + return 0; + } else { + return dtls_send(ctx, peer, DTLS_CT_APPLICATION_DATA, buf, len); + } + } +} + +static int +dtls_get_cookie(uint8 *msg, size_t msglen, uint8 **cookie) { + /* To access the cookie, we have to determine the session id's + * length and skip the whole thing. */ + if (msglen < DTLS_HS_LENGTH + DTLS_CH_LENGTH + sizeof(uint8)) + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + + if (dtls_uint16_to_int(msg + DTLS_HS_LENGTH) != DTLS_VERSION) + return dtls_alert_fatal_create(DTLS_ALERT_PROTOCOL_VERSION); + + msglen -= DTLS_HS_LENGTH + DTLS_CH_LENGTH; + msg += DTLS_HS_LENGTH + DTLS_CH_LENGTH; + + SKIP_VAR_FIELD(msg, msglen, uint8); /* skip session id */ + + if (msglen < (*msg & 0xff) + sizeof(uint8)) + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + + *cookie = msg + sizeof(uint8); + return dtls_uint8_to_int(msg); + + error: + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); +} + +static int +dtls_create_cookie(dtls_context_t *ctx, + session_t *session, + uint8 *msg, size_t msglen, + uint8 *cookie, int *clen) { + unsigned char buf[DTLS_HMAC_MAX]; + size_t len, e; + + /* create cookie with HMAC-SHA256 over: + * - SECRET + * - session parameters (only IP address?) + * - client version + * - random gmt and bytes + * - session id + * - cipher_suites + * - compression method + */ + + /* We use our own buffer as hmac_context instead of a dynamic buffer + * created by dtls_hmac_new() to separate storage space for cookie + * creation from storage that is used in real sessions. Note that + * the buffer size must fit with the default hash algorithm (see + * implementation of dtls_hmac_context_new()). */ + + dtls_hmac_context_t hmac_context; + dtls_hmac_init(&hmac_context, ctx->cookie_secret, DTLS_COOKIE_SECRET_LENGTH); + + dtls_hmac_update(&hmac_context, + (unsigned char *)&session->addr, session->size); + + /* feed in the beginning of the Client Hello up to and including the + session id */ + e = sizeof(dtls_client_hello_t); + e += (*(msg + DTLS_HS_LENGTH + e) & 0xff) + sizeof(uint8); + if (e + DTLS_HS_LENGTH > msglen) + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + + dtls_hmac_update(&hmac_context, msg + DTLS_HS_LENGTH, e); + + /* skip cookie bytes and length byte */ + e += *(uint8 *)(msg + DTLS_HS_LENGTH + e) & 0xff; + e += sizeof(uint8); + if (e + DTLS_HS_LENGTH > msglen) + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + + dtls_hmac_update(&hmac_context, + msg + DTLS_HS_LENGTH + e, + dtls_get_fragment_length(DTLS_HANDSHAKE_HEADER(msg)) - e); + + len = dtls_hmac_finalize(&hmac_context, buf); + + if (len < *clen) { + memset(cookie + len, 0, *clen - len); + *clen = len; + } + + memcpy(cookie, buf, *clen); + return 0; +} + +#ifdef DTLS_CHECK_CONTENTTYPE +/* used to check if a received datagram contains a DTLS message */ +static char const content_types[] = { + DTLS_CT_CHANGE_CIPHER_SPEC, + DTLS_CT_ALERT, + DTLS_CT_HANDSHAKE, + DTLS_CT_APPLICATION_DATA, + 0 /* end marker */ +}; +#endif + +/** + * Checks if \p msg points to a valid DTLS record. If + * + */ +static unsigned int +is_record(uint8 *msg, size_t msglen) { + unsigned int rlen = 0; + + if (msglen >= DTLS_RH_LENGTH /* FIXME allow empty records? */ +#ifdef DTLS_CHECK_CONTENTTYPE + && strchr(content_types, msg[0]) +#endif + && msg[1] == HIGH(DTLS_VERSION) + && msg[2] == LOW(DTLS_VERSION)) + { + rlen = DTLS_RH_LENGTH + + dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->length); + + /* we do not accept wrong length field in record header */ + if (rlen > msglen) + rlen = 0; + } + + return rlen; +} + +/** + * Initializes \p buf as record header. The caller must ensure that \p + * buf is capable of holding at least \c sizeof(dtls_record_header_t) + * bytes. Increments sequence number counter of \p security. + * \return pointer to the next byte after the written header. + * The length will be set to 0 and has to be changed before sending. + */ +static inline uint8 * +dtls_set_record_header(uint8 type, dtls_security_parameters_t *security, + uint8 *buf) { + + dtls_int_to_uint8(buf, type); + buf += sizeof(uint8); + + dtls_int_to_uint16(buf, DTLS_VERSION); + buf += sizeof(uint16); + + if (security) { + dtls_int_to_uint16(buf, security->epoch); + buf += sizeof(uint16); + + dtls_int_to_uint48(buf, security->rseq); + buf += sizeof(uint48); + + /* increment record sequence counter by 1 */ + security->rseq++; + } else { + memset(buf, 0, sizeof(uint16) + sizeof(uint48)); + buf += sizeof(uint16) + sizeof(uint48); + } + + memset(buf, 0, sizeof(uint16)); + return buf + sizeof(uint16); +} + +/** + * Initializes \p buf as handshake header. The caller must ensure that \p + * buf is capable of holding at least \c sizeof(dtls_handshake_header_t) + * bytes. Increments message sequence number counter of \p peer. + * \return pointer to the next byte after \p buf + */ +static inline uint8 * +dtls_set_handshake_header(uint8 type, dtls_peer_t *peer, + int length, + int frag_offset, int frag_length, + uint8 *buf) { + + dtls_int_to_uint8(buf, type); + buf += sizeof(uint8); + + dtls_int_to_uint24(buf, length); + buf += sizeof(uint24); + + if (peer && peer->handshake_params) { + /* and copy the result to buf */ + dtls_int_to_uint16(buf, peer->handshake_params->hs_state.mseq_s); + + /* increment handshake message sequence counter by 1 */ + peer->handshake_params->hs_state.mseq_s++; + } else { + memset(buf, 0, sizeof(uint16)); + } + buf += sizeof(uint16); + + dtls_int_to_uint24(buf, frag_offset); + buf += sizeof(uint24); + + dtls_int_to_uint24(buf, frag_length); + buf += sizeof(uint24); + + return buf; +} + +/** only one compression method is currently defined */ +static uint8 compression_methods[] = { + TLS_COMPRESSION_NULL +}; + +/** returns true if the cipher matches TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ +static inline int is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(dtls_cipher_t cipher) +{ +#ifdef DTLS_ECC + return cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; +#else + return 0; +#endif /* DTLS_ECC */ +} + +/** returns true if the cipher matches TLS_PSK_WITH_AES_128_CCM_8 */ +static inline int is_tls_psk_with_aes_128_ccm_8(dtls_cipher_t cipher) +{ +#ifdef DTLS_PSK + return cipher == TLS_PSK_WITH_AES_128_CCM_8; +#else + return 0; +#endif /* DTLS_PSK */ +} + +/** returns true if the application is configured for psk */ +static inline int is_psk_supported(dtls_context_t *ctx) +{ +#ifdef DTLS_PSK + return ctx && ctx->h && ctx->h->get_psk_info; +#else + return 0; +#endif /* DTLS_PSK */ +} + +/** returns true if the application is configured for ecdhe_ecdsa */ +static inline int is_ecdsa_supported(dtls_context_t *ctx, int is_client) +{ +#ifdef DTLS_ECC + return ctx && ctx->h && ((!is_client && ctx->h->get_ecdsa_key) || + (is_client && ctx->h->verify_ecdsa_key)); +#else + return 0; +#endif /* DTLS_ECC */ +} + +/** Returns true if the application is configured for ecdhe_ecdsa with + * client authentication */ +static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx) +{ +#ifdef DTLS_ECC + return ctx && ctx->h && ctx->h->get_ecdsa_key && ctx->h->verify_ecdsa_key; +#else + return 0; +#endif /* DTLS_ECC */ +} + +/** + * Returns @c 1 if @p code is a cipher suite other than @c + * TLS_NULL_WITH_NULL_NULL that we recognize. + * + * @param ctx The current DTLS context + * @param code The cipher suite identifier to check + * @param is_client 1 for a dtls client, 0 for server + * @return @c 1 iff @p code is recognized, + */ +static int +known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) { + int psk; + int ecdsa; + + psk = is_psk_supported(ctx); + ecdsa = is_ecdsa_supported(ctx, is_client); + return (psk && is_tls_psk_with_aes_128_ccm_8(code)) || + (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)); +} + +/** + * This method detects if we already have a established DTLS session with + * peer and the peer is attempting to perform a fresh handshake by sending + * messages with epoch = 0. This is to handle situations mentioned in + * RFC 6347 - section 4.2.8. + * + * @param msg The packet received from Client + * @param msglen Packet length + * @param peer peer who is the sender for this packet + * @return @c 1 if this is a rehandshake attempt by + * client + */ +static int +hs_attempt_with_existing_peer(uint8_t *msg, size_t msglen, + dtls_peer_t *peer) +{ + if ((peer) && (peer->state == DTLS_STATE_CONNECTED)) { + if (msg[0] == DTLS_CT_HANDSHAKE) { + uint16_t msg_epoch = dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); + if (msg_epoch == 0) { + dtls_handshake_header_t * hs_header = DTLS_HANDSHAKE_HEADER(msg + DTLS_RH_LENGTH); + if (hs_header->msg_type == DTLS_HT_CLIENT_HELLO || + hs_header->msg_type == DTLS_HT_HELLO_REQUEST) { + return 1; + } + } + } + } + return 0; +} + +/** Dump out the cipher keys and IVs used for the symetric cipher. */ +static void dtls_debug_keyblock(dtls_security_parameters_t *config) +{ + dtls_debug("key_block (%d bytes):\n", dtls_kb_size(config, peer->role)); + dtls_debug_dump(" client_MAC_secret", + dtls_kb_client_mac_secret(config, peer->role), + dtls_kb_mac_secret_size(config, peer->role)); + + dtls_debug_dump(" server_MAC_secret", + dtls_kb_server_mac_secret(config, peer->role), + dtls_kb_mac_secret_size(config, peer->role)); + + dtls_debug_dump(" client_write_key", + dtls_kb_client_write_key(config, peer->role), + dtls_kb_key_size(config, peer->role)); + + dtls_debug_dump(" server_write_key", + dtls_kb_server_write_key(config, peer->role), + dtls_kb_key_size(config, peer->role)); + + dtls_debug_dump(" client_IV", + dtls_kb_client_iv(config, peer->role), + dtls_kb_iv_size(config, peer->role)); + + dtls_debug_dump(" server_IV", + dtls_kb_server_iv(config, peer->role), + dtls_kb_iv_size(config, peer->role)); +} + +/** returns the name of the goven handshake type number. + * see IANA for a full list of types: + * https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-7 + */ +static char *dtls_handshake_type_to_name(int type) +{ + switch (type) { + case DTLS_HT_HELLO_REQUEST: + return "hello_request"; + case DTLS_HT_CLIENT_HELLO: + return "client_hello"; + case DTLS_HT_SERVER_HELLO: + return "server_hello"; + case DTLS_HT_HELLO_VERIFY_REQUEST: + return "hello_verify_request"; + case DTLS_HT_CERTIFICATE: + return "certificate"; + case DTLS_HT_SERVER_KEY_EXCHANGE: + return "server_key_exchange"; + case DTLS_HT_CERTIFICATE_REQUEST: + return "certificate_request"; + case DTLS_HT_SERVER_HELLO_DONE: + return "server_hello_done"; + case DTLS_HT_CERTIFICATE_VERIFY: + return "certificate_verify"; + case DTLS_HT_CLIENT_KEY_EXCHANGE: + return "client_key_exchange"; + case DTLS_HT_FINISHED: + return "finished"; + default: + return "unknown"; + } +} + +/** + * Calculate the pre master secret and after that calculate the master-secret. + */ +static int +calculate_key_block(dtls_context_t *ctx, + dtls_handshake_parameters_t *handshake, + dtls_peer_t *peer, + session_t *session, + dtls_peer_type role) { + unsigned char *pre_master_secret; + int pre_master_len = 0; + dtls_security_parameters_t *security = dtls_security_params_next(peer); + uint8 master_secret[DTLS_MASTER_SECRET_LENGTH]; + + if (!security) { + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + pre_master_secret = security->key_block; + + switch (handshake->cipher) { +#ifdef DTLS_PSK + case TLS_PSK_WITH_AES_128_CCM_8: { + unsigned char psk[DTLS_PSK_MAX_KEY_LEN]; + int len; + + len = CALL(ctx, get_psk_info, session, DTLS_PSK_KEY, + handshake->keyx.psk.identity, + handshake->keyx.psk.id_length, + psk, DTLS_PSK_MAX_KEY_LEN); + if (len < 0) { + dtls_crit("no psk key for session available\n"); + return len; + } + /* Temporarily use the key_block storage space for the pre master secret. */ + pre_master_len = dtls_psk_pre_master_secret(psk, len, + pre_master_secret, + MAX_KEYBLOCK_LENGTH); + + dtls_debug_hexdump("psk", psk, len); + + memset(psk, 0, DTLS_PSK_MAX_KEY_LEN); + if (pre_master_len < 0) { + dtls_crit("the psk was too long, for the pre master secret\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + break; + } +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: { + pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecdsa.own_eph_priv, + handshake->keyx.ecdsa.other_eph_pub_x, + handshake->keyx.ecdsa.other_eph_pub_y, + sizeof(handshake->keyx.ecdsa.own_eph_priv), + pre_master_secret, + MAX_KEYBLOCK_LENGTH); + if (pre_master_len < 0) { + dtls_crit("the curve was too long, for the pre master secret\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + break; + } +#endif /* DTLS_ECC */ + default: + dtls_crit("calculate_key_block: unknown cipher\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + dtls_debug_dump("client_random", handshake->tmp.random.client, DTLS_RANDOM_LENGTH); + dtls_debug_dump("server_random", handshake->tmp.random.server, DTLS_RANDOM_LENGTH); + dtls_debug_dump("pre_master_secret", pre_master_secret, pre_master_len); + + dtls_prf(pre_master_secret, pre_master_len, + PRF_LABEL(master), PRF_LABEL_SIZE(master), + handshake->tmp.random.client, DTLS_RANDOM_LENGTH, + handshake->tmp.random.server, DTLS_RANDOM_LENGTH, + master_secret, + DTLS_MASTER_SECRET_LENGTH); + + dtls_debug_dump("master_secret", master_secret, DTLS_MASTER_SECRET_LENGTH); + + /* create key_block from master_secret + * key_block = PRF(master_secret, + "key expansion" + tmp.random.server + tmp.random.client) */ + + dtls_prf(master_secret, + DTLS_MASTER_SECRET_LENGTH, + PRF_LABEL(key), PRF_LABEL_SIZE(key), + handshake->tmp.random.server, DTLS_RANDOM_LENGTH, + handshake->tmp.random.client, DTLS_RANDOM_LENGTH, + security->key_block, + dtls_kb_size(security, role)); + + memcpy(handshake->tmp.master_secret, master_secret, DTLS_MASTER_SECRET_LENGTH); + dtls_debug_keyblock(security); + + security->cipher = handshake->cipher; + security->compression = handshake->compression; + security->rseq = 0; + + return 0; +} + +/* TODO: add a generic method which iterates over a list and searches for a specific key */ +static int verify_ext_eliptic_curves(uint8 *data, size_t data_length) { + int i, curve_name; + + /* length of curve list */ + i = dtls_uint16_to_int(data); + data += sizeof(uint16); + if (i + sizeof(uint16) != data_length) { + dtls_warn("the list of the supported elliptic curves should be tls extension length - 2\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + for (i = data_length - sizeof(uint16); i > 0; i -= sizeof(uint16)) { + /* check if this curve is supported */ + curve_name = dtls_uint16_to_int(data); + data += sizeof(uint16); + + if (curve_name == TLS_EXT_ELLIPTIC_CURVES_SECP256R1) + return 0; + } + + dtls_warn("no supported elliptic curve found\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); +} + +static int verify_ext_cert_type(uint8 *data, size_t data_length) { + int i, cert_type; + + /* length of cert type list */ + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + if (i + sizeof(uint8) != data_length) { + dtls_warn("the list of the supported certificate types should be tls extension length - 1\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + for (i = data_length - sizeof(uint8); i > 0; i -= sizeof(uint8)) { + /* check if this cert type is supported */ + cert_type = dtls_uint8_to_int(data); + data += sizeof(uint8); + + if (cert_type == TLS_CERT_TYPE_RAW_PUBLIC_KEY) + return 0; + } + + dtls_warn("no supported certificate type found\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); +} + +static int verify_ext_ec_point_formats(uint8 *data, size_t data_length) { + int i, cert_type; + + /* length of ec_point_formats list */ + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + if (i + sizeof(uint8) != data_length) { + dtls_warn("the list of the supported ec_point_formats should be tls extension length - 1\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + for (i = data_length - sizeof(uint8); i > 0; i -= sizeof(uint8)) { + /* check if this ec_point_format is supported */ + cert_type = dtls_uint8_to_int(data); + data += sizeof(uint8); + + if (cert_type == TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED) + return 0; + } + + dtls_warn("no supported ec_point_format found\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); +} + +/* + * Check for some TLS Extensions used by the ECDHE_ECDSA cipher. + */ +static int +dtls_check_tls_extension(dtls_peer_t *peer, + uint8 *data, size_t data_length, int client_hello) +{ + uint16_t i, j; + int ext_elliptic_curve = 0; + int ext_client_cert_type = 0; + int ext_server_cert_type = 0; + int ext_ec_point_formats = 0; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + + if (data_length < sizeof(uint16)) { + /* no tls extensions specified */ + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher)) { + goto error; + } + return 0; + } + + /* get the length of the tls extension list */ + j = dtls_uint16_to_int(data); + data += sizeof(uint16); + data_length -= sizeof(uint16); + + if (data_length < j) + goto error; + + /* check for TLS extensions needed for this cipher */ + while (data_length) { + if (data_length < sizeof(uint16) * 2) + goto error; + + /* get the tls extension type */ + i = dtls_uint16_to_int(data); + data += sizeof(uint16); + data_length -= sizeof(uint16); + + /* get the length of the tls extension */ + j = dtls_uint16_to_int(data); + data += sizeof(uint16); + data_length -= sizeof(uint16); + + if (data_length < j) + goto error; + + switch (i) { + case TLS_EXT_ELLIPTIC_CURVES: + ext_elliptic_curve = 1; + if (verify_ext_eliptic_curves(data, j)) + goto error; + break; + case TLS_EXT_CLIENT_CERTIFICATE_TYPE: + ext_client_cert_type = 1; + if (client_hello) { + if (verify_ext_cert_type(data, j)) + goto error; + } else { + if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) + goto error; + } + break; + case TLS_EXT_SERVER_CERTIFICATE_TYPE: + ext_server_cert_type = 1; + if (client_hello) { + if (verify_ext_cert_type(data, j)) + goto error; + } else { + if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) + goto error; + } + break; + case TLS_EXT_EC_POINT_FORMATS: + ext_ec_point_formats = 1; + if (verify_ext_ec_point_formats(data, j)) + goto error; + break; + case TLS_EXT_ENCRYPT_THEN_MAC: + /* As only AEAD cipher suites are currently available, this + * extension can be skipped. + */ + dtls_info("skipped encrypt-then-mac extension\n"); + break; + default: + dtls_warn("unsupported tls extension: %i\n", i); + break; + } + data += j; + data_length -= j; + } + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && client_hello) { + if (!ext_elliptic_curve || !ext_client_cert_type || !ext_server_cert_type + || !ext_ec_point_formats) { + dtls_warn("not all required tls extensions found in client hello\n"); + goto error; + } + } else if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && !client_hello) { + if (!ext_client_cert_type || !ext_server_cert_type) { + dtls_warn("not all required tls extensions found in server hello\n"); + goto error; + } + } + return 0; + +error: + if (client_hello && peer->state == DTLS_STATE_CONNECTED) { + return dtls_alert_create(DTLS_ALERT_LEVEL_WARNING, DTLS_ALERT_NO_RENEGOTIATION); + } else { + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } +} + +/** + * Parses the ClientHello from the client and updates the internal handshake + * parameters with the new data for the given \p peer. When the ClientHello + * handshake message in \p data does not contain a cipher suite or + * compression method, it is copied from the the current security parameters. + * + * \param ctx The current DTLS context. + * \param peer The remote peer whose security parameters are about to change. + * \param data The handshake message with a ClientHello. + * \param data_length The actual size of \p data. + * \return \c -Something if an error occurred, \c 0 on success. + */ +static int +dtls_update_parameters(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) { + int i, j; + int ok; + dtls_handshake_parameters_t *config = peer->handshake_params; + dtls_security_parameters_t *security = dtls_security_params(peer); + + assert(config); + assert(data_length > DTLS_HS_LENGTH + DTLS_CH_LENGTH); + + /* skip the handshake header and client version information */ + data += DTLS_HS_LENGTH + sizeof(uint16); + data_length -= DTLS_HS_LENGTH + sizeof(uint16); + + /* store client random in config */ + memcpy(config->tmp.random.client, data, DTLS_RANDOM_LENGTH); + data += DTLS_RANDOM_LENGTH; + data_length -= DTLS_RANDOM_LENGTH; + + /* Caution: SKIP_VAR_FIELD may jump to error: */ + SKIP_VAR_FIELD(data, data_length, uint8); /* skip session id */ + SKIP_VAR_FIELD(data, data_length, uint8); /* skip cookie */ + + i = dtls_uint16_to_int(data); + if (data_length < i + sizeof(uint16)) { + /* Looks like we do not have a cipher nor compression. This is ok + * for renegotiation, but not for the initial handshake. */ + + if (!security || security->cipher == TLS_NULL_WITH_NULL_NULL) + goto error; + + config->cipher = security->cipher; + config->compression = security->compression; + + return 0; + } + + data += sizeof(uint16); + data_length -= sizeof(uint16) + i; + + ok = 0; + while (i && !ok) { + config->cipher = dtls_uint16_to_int(data); + ok = known_cipher(ctx, config->cipher, 0); + i -= sizeof(uint16); + data += sizeof(uint16); + } + + /* skip remaining ciphers */ + data += i; + + if (!ok) { + /* reset config cipher to a well-defined value */ + config->cipher = TLS_NULL_WITH_NULL_NULL; + dtls_warn("No matching cipher found\n"); + goto error; + } + + if (data_length < sizeof(uint8)) { + /* no compression specified, take the current compression method */ + if (security) + config->compression = security->compression; + else + config->compression = TLS_COMPRESSION_NULL; + return 0; + } + + i = dtls_uint8_to_int(data); + if (data_length < i + sizeof(uint8)) + goto error; + + data += sizeof(uint8); + data_length -= sizeof(uint8) + i; + + ok = 0; + while (i && !ok) { + for (j = 0; j < sizeof(compression_methods) / sizeof(uint8); ++j) + if (dtls_uint8_to_int(data) == compression_methods[j]) { + config->compression = compression_methods[j]; + ok = 1; + } + i -= sizeof(uint8); + data += sizeof(uint8); + } + + if (!ok) { + /* reset config cipher to a well-defined value */ + goto error; + } + + return dtls_check_tls_extension(peer, data, data_length, 1); +error: + if (peer->state == DTLS_STATE_CONNECTED) { + return dtls_alert_create(DTLS_ALERT_LEVEL_WARNING, DTLS_ALERT_NO_RENEGOTIATION); + } else { + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } +} + +/** + * Parse the ClientKeyExchange and update the internal handshake state with + * the new data. + */ +static inline int +check_client_keyexchange(dtls_context_t *ctx, + dtls_handshake_parameters_t *handshake, + uint8 *data, size_t length) { + +#ifdef DTLS_ECC + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher)) { + + if (length < DTLS_HS_LENGTH + DTLS_CKXEC_LENGTH) { + dtls_debug("The client key exchange is too short\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += DTLS_HS_LENGTH; + + if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) { + dtls_alert("expected 65 bytes long public point\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + + if (dtls_uint8_to_int(data) != 4) { + dtls_alert("expected uncompressed public point\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + + memcpy(handshake->keyx.ecdsa.other_eph_pub_x, data, + sizeof(handshake->keyx.ecdsa.other_eph_pub_x)); + data += sizeof(handshake->keyx.ecdsa.other_eph_pub_x); + + memcpy(handshake->keyx.ecdsa.other_eph_pub_y, data, + sizeof(handshake->keyx.ecdsa.other_eph_pub_y)); + data += sizeof(handshake->keyx.ecdsa.other_eph_pub_y); + } +#endif /* DTLS_ECC */ +#ifdef DTLS_PSK + if (is_tls_psk_with_aes_128_ccm_8(handshake->cipher)) { + int id_length; + + if (length < DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN) { + dtls_debug("The client key exchange is too short\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += DTLS_HS_LENGTH; + + id_length = dtls_uint16_to_int(data); + data += sizeof(uint16); + + if (DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN + id_length != length) { + dtls_debug("The identity has a wrong length\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + if (id_length > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { + dtls_warn("please use a smaller client identity\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + handshake->keyx.psk.id_length = id_length; + memcpy(handshake->keyx.psk.identity, data, id_length); + } +#endif /* DTLS_PSK */ + return 0; +} + +static inline void +update_hs_hash(dtls_peer_t *peer, uint8 *data, size_t length) { + dtls_debug_dump("add MAC data", data, length); + dtls_hash_update(&peer->handshake_params->hs_state.hs_hash, data, length); +} + +static void +copy_hs_hash(dtls_peer_t *peer, dtls_hash_ctx *hs_hash) { + memcpy(hs_hash, &peer->handshake_params->hs_state.hs_hash, + sizeof(peer->handshake_params->hs_state.hs_hash)); +} + +static inline size_t +finalize_hs_hash(dtls_peer_t *peer, uint8 *buf) { + return dtls_hash_finalize(buf, &peer->handshake_params->hs_state.hs_hash); +} + +static inline void +clear_hs_hash(dtls_peer_t *peer) { + assert(peer); + dtls_debug("clear MAC\n"); + dtls_hash_init(&peer->handshake_params->hs_state.hs_hash); +} + +/** + * Checks if \p record + \p data contain a Finished message with valid + * verify_data. + * + * \param ctx The current DTLS context. + * \param peer The remote peer of the security association. + * \param data The cleartext payload of the message. + * \param data_length Actual length of \p data. + * \return \c 0 if the Finished message is valid, \c negative number otherwise. + */ +static int +check_finished(dtls_context_t *ctx, dtls_peer_t *peer, + uint8 *data, size_t data_length) { + size_t digest_length, label_size; + const unsigned char *label; + unsigned char buf[DTLS_HMAC_MAX]; + + if (data_length < DTLS_HS_LENGTH + DTLS_FIN_LENGTH) + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + + /* Use a union here to ensure that sufficient stack space is + * reserved. As statebuf and verify_data are not used at the same + * time, we can re-use the storage safely. + */ + union { + unsigned char statebuf[DTLS_HASH_CTX_SIZE]; + unsigned char verify_data[DTLS_FIN_LENGTH]; + } b; + + /* temporarily store hash status for roll-back after finalize */ + memcpy(b.statebuf, &peer->handshake_params->hs_state.hs_hash, DTLS_HASH_CTX_SIZE); + + digest_length = finalize_hs_hash(peer, buf); + /* clear_hash(); */ + + /* restore hash status */ + memcpy(&peer->handshake_params->hs_state.hs_hash, b.statebuf, DTLS_HASH_CTX_SIZE); + + if (peer->role == DTLS_CLIENT) { + label = PRF_LABEL(server); + label_size = PRF_LABEL_SIZE(server); + } else { /* server */ + label = PRF_LABEL(client); + label_size = PRF_LABEL_SIZE(client); + } + + dtls_prf(peer->handshake_params->tmp.master_secret, + DTLS_MASTER_SECRET_LENGTH, + label, label_size, + PRF_LABEL(finished), PRF_LABEL_SIZE(finished), + buf, digest_length, + b.verify_data, sizeof(b.verify_data)); + + dtls_debug_dump("d:", data + DTLS_HS_LENGTH, sizeof(b.verify_data)); + dtls_debug_dump("v:", b.verify_data, sizeof(b.verify_data)); + + /* compare verify data and create DTLS alert code when they differ */ + return equals(data + DTLS_HS_LENGTH, b.verify_data, sizeof(b.verify_data)) + ? 0 + : dtls_alert_create(DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE); +} + +/** + * Prepares the payload given in \p data for sending with + * dtls_send(). The \p data is encrypted and compressed according to + * the current security parameters of \p peer. The result of this + * operation is put into \p sendbuf with a prepended record header of + * type \p type ready for sending. As some cipher suites add a MAC + * before encryption, \p data must be large enough to hold this data + * as well (usually \c dtls_kb_digest_size(CURRENT_CONFIG(peer)). + * + * \param peer The remote peer the packet will be sent to. + * \param security The encryption paramater used to encrypt + * \param type The content type of this record. + * \param data_array Array with payloads in correct order. + * \param data_len_array sizes of the payloads in correct order. + * \param data_array_len The number of payloads given. + * \param sendbuf The output buffer where the encrypted record + * will be placed. + * \param rlen This parameter must be initialized with the + * maximum size of \p sendbuf and will be updated + * to hold the actual size of the stored packet + * on success. On error, the value of \p rlen is + * undefined. + * \return Less than zero on error, or greater than zero success. + */ +static int +dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security, + unsigned char type, + uint8 *data_array[], size_t data_len_array[], + size_t data_array_len, + uint8 *sendbuf, size_t *rlen) { + uint8 *p, *start; + int res; + unsigned int i; + + if (*rlen < DTLS_RH_LENGTH) { + dtls_alert("The sendbuf (%zu bytes) is too small\n", *rlen); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + p = dtls_set_record_header(type, security, sendbuf); + start = p; + + if (!security || security->cipher == TLS_NULL_WITH_NULL_NULL) { + /* no cipher suite */ + + res = 0; + for (i = 0; i < data_array_len; i++) { + /* check the minimum that we need for packets that are not encrypted */ + if (*rlen < res + DTLS_RH_LENGTH + data_len_array[i]) { + dtls_debug("dtls_prepare_record: send buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(p, data_array[i], data_len_array[i]); + p += data_len_array[i]; + res += data_len_array[i]; + } + } else { /* TLS_PSK_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ + /** + * length of additional_data for the AEAD cipher which consists of + * seq_num(2+6) + type(1) + version(2) + length(2) + */ +#define A_DATA_LEN 13 + unsigned char nonce[DTLS_CCM_BLOCKSIZE]; + unsigned char A_DATA[A_DATA_LEN]; + + if (is_tls_psk_with_aes_128_ccm_8(security->cipher)) { + dtls_debug("dtls_prepare_record(): encrypt using TLS_PSK_WITH_AES_128_CCM_8\n"); + } else if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(security->cipher)) { + dtls_debug("dtls_prepare_record(): encrypt using TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n"); + } else { + dtls_debug("dtls_prepare_record(): encrypt using unknown cipher\n"); + } + + /* set nonce + from RFC 6655: + The "nonce" input to the AEAD algorithm is exactly that of [RFC5288]: + the "nonce" SHALL be 12 bytes long and is constructed as follows: + (this is an example of a "partially explicit" nonce; see Section + 3.2.1 in [RFC5116]). + + struct { + opaque salt[4]; + opaque nonce_explicit[8]; + } CCMNonce; + + [...] + + In DTLS, the 64-bit seq_num is the 16-bit epoch concatenated with the + 48-bit seq_num. + + When the nonce_explicit is equal to the sequence number, the CCMNonce + will have the structure of the CCMNonceExample given below. + + struct { + uint32 client_write_IV; // low order 32-bits + uint64 seq_num; // TLS sequence number + } CCMClientNonce. + + + struct { + uint32 server_write_IV; // low order 32-bits + uint64 seq_num; // TLS sequence number + } CCMServerNonce. + + + struct { + case client: + CCMClientNonce; + case server: + CCMServerNonce: + } CCMNonceExample; + */ + + memcpy(p, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); + p += 8; + res = 8; + + for (i = 0; i < data_array_len; i++) { + /* check the minimum that we need for packets that are not encrypted */ + if (*rlen < res + DTLS_RH_LENGTH + data_len_array[i]) { + dtls_debug("dtls_prepare_record: send buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(p, data_array[i], data_len_array[i]); + p += data_len_array[i]; + res += data_len_array[i]; + } + + memset(nonce, 0, DTLS_CCM_BLOCKSIZE); + memcpy(nonce, dtls_kb_local_iv(security, peer->role), + dtls_kb_iv_size(security, peer->role)); + memcpy(nonce + dtls_kb_iv_size(security, peer->role), start, 8); /* epoch + seq_num */ + + dtls_debug_dump("nonce:", nonce, DTLS_CCM_BLOCKSIZE); + dtls_debug_dump("key:", dtls_kb_local_write_key(security, peer->role), + dtls_kb_key_size(security, peer->role)); + + /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: + * + * additional_data = seq_num + TLSCompressed.type + + * TLSCompressed.version + TLSCompressed.length; + */ + memcpy(A_DATA, &DTLS_RECORD_HEADER(sendbuf)->epoch, 8); /* epoch and seq_num */ + memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(sendbuf)->content_type, 3); /* type and version */ + dtls_int_to_uint16(A_DATA + 11, res - 8); /* length */ + + res = dtls_encrypt(start + 8, res - 8, start + 8, nonce, + dtls_kb_local_write_key(security, peer->role), + dtls_kb_key_size(security, peer->role), + A_DATA, A_DATA_LEN); + + if (res < 0) + return res; + + res += 8; /* increment res by size of nonce_explicit */ + dtls_debug_dump("message:", start, res); + } + + /* fix length of fragment in sendbuf */ + dtls_int_to_uint16(sendbuf + 11, res); + + *rlen = DTLS_RH_LENGTH + res; + return 0; +} + +static int +dtls_send_handshake_msg_hash(dtls_context_t *ctx, + dtls_peer_t *peer, + session_t *session, + uint8 header_type, + uint8 *data, size_t data_length, + int add_hash) +{ + uint8 buf[DTLS_HS_LENGTH]; + uint8 *data_array[2]; + size_t data_len_array[2]; + int i = 0; + dtls_security_parameters_t *security = peer ? dtls_security_params(peer) : NULL; + + dtls_set_handshake_header(header_type, peer, data_length, 0, + data_length, buf); + + if (add_hash) { + update_hs_hash(peer, buf, sizeof(buf)); + } + data_array[i] = buf; + data_len_array[i] = sizeof(buf); + i++; + + if (data != NULL) { + if (add_hash) { + update_hs_hash(peer, data, data_length); + } + data_array[i] = data; + data_len_array[i] = data_length; + i++; + } + dtls_debug("send handshake packet of type: %s (%i)\n", + dtls_handshake_type_to_name(header_type), header_type); + return dtls_send_multi(ctx, peer, security, session, DTLS_CT_HANDSHAKE, + data_array, data_len_array, i); +} + +static int +dtls_send_handshake_msg(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 header_type, + uint8 *data, size_t data_length) +{ + return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, + header_type, data, data_length, 1); +} + +/** + * Returns true if the message @p Data is a handshake message that + * must be included in the calculation of verify_data in the Finished + * message. + * + * @param Type The message type. Only handshake messages but the initial + * Client Hello and Hello Verify Request are included in the hash, + * @param Data The PDU to examine. + * @param Length The length of @p Data. + * + * @return @c 1 if @p Data must be included in hash, @c 0 otherwise. + * + * @hideinitializer + */ +#define MUST_HASH(Type, Data, Length) \ + ((Type) == DTLS_CT_HANDSHAKE && \ + ((Data) != NULL) && ((Length) > 0) && \ + ((Data)[0] != DTLS_HT_HELLO_VERIFY_REQUEST) && \ + ((Data)[0] != DTLS_HT_CLIENT_HELLO || \ + ((Length) >= HS_HDR_LENGTH && \ + (dtls_uint16_to_int(DTLS_RECORD_HEADER(Data)->epoch > 0) || \ + (dtls_uint16_to_int(HANDSHAKE(Data)->message_seq) > 0))))) + +/** + * Sends the data passed in @p buf as a DTLS record of type @p type to + * the given peer. The data will be encrypted and compressed according + * to the security parameters for @p peer. + * + * @param ctx The DTLS context in effect. + * @param peer The remote party where the packet is sent. + * @param type The content type of this record. + * @param buf The data to send. + * @param buflen The number of bytes to send from @p buf. + * @return Less than zero in case of an error or the number of + * bytes that have been sent otherwise. + */ +static int +dtls_send_multi(dtls_context_t *ctx, dtls_peer_t *peer, + dtls_security_parameters_t *security , session_t *session, + unsigned char type, uint8 *buf_array[], + size_t buf_len_array[], size_t buf_array_len) +{ + /* We cannot use ctx->sendbuf here as it is reserved for collecting + * the input for this function, i.e. buf == ctx->sendbuf. + * + * TODO: check if we can use the receive buf here. This would mean + * that we might not be able to handle multiple records stuffed in + * one UDP datagram */ + unsigned char sendbuf[DTLS_MAX_BUF]; + size_t len = sizeof(sendbuf); + int res; + unsigned int i; + size_t overall_len = 0; + + res = dtls_prepare_record(peer, security, type, buf_array, buf_len_array, buf_array_len, sendbuf, &len); + + if (res < 0) + return res; + + /* if (peer && MUST_HASH(peer, type, buf, buflen)) */ + /* update_hs_hash(peer, buf, buflen); */ + + dtls_debug_hexdump("send header", sendbuf, sizeof(dtls_record_header_t)); + for (i = 0; i < buf_array_len; i++) { + dtls_debug_hexdump("send unencrypted", buf_array[i], buf_len_array[i]); + overall_len += buf_len_array[i]; + } + + if ((type == DTLS_CT_HANDSHAKE && buf_array[0][0] != DTLS_HT_HELLO_VERIFY_REQUEST) || + type == DTLS_CT_CHANGE_CIPHER_SPEC) { + /* copy handshake messages other than HelloVerify into retransmit buffer */ + netq_t *n = netq_node_new(overall_len); + if (n) { + dtls_tick_t now; + dtls_ticks(&now); + n->t = now + 2 * CLOCK_SECOND; + n->retransmit_cnt = 0; + n->timeout = 2 * CLOCK_SECOND; + n->peer = peer; + n->epoch = (security) ? security->epoch : 0; + n->type = type; + n->length = 0; + for (i = 0; i < buf_array_len; i++) { + memcpy(n->data + n->length, buf_array[i], buf_len_array[i]); + n->length += buf_len_array[i]; + } + + if (!netq_insert_node(ctx->sendqueue, n)) { + dtls_warn("cannot add packet to retransmit buffer\n"); + netq_node_free(n); +#ifdef WITH_CONTIKI + } else { + /* must set timer within the context of the retransmit process */ + PROCESS_CONTEXT_BEGIN(&dtls_retransmit_process); + etimer_set(&ctx->retransmit_timer, n->timeout); + PROCESS_CONTEXT_END(&dtls_retransmit_process); +#else /* WITH_CONTIKI */ + dtls_debug("copied to sendqueue\n"); +#endif /* WITH_CONTIKI */ + } + } else + dtls_warn("retransmit buffer full\n"); + } + + /* FIXME: copy to peer's sendqueue (after fragmentation if + * necessary) and initialize retransmit timer */ + res = CALL(ctx, write, session, sendbuf, len); + + /* Guess number of bytes application data actually sent: + * dtls_prepare_record() tells us in len the number of bytes to + * send, res will contain the bytes actually sent. */ + return res <= 0 ? res : overall_len - (len - res); +} + +static inline int +dtls_send_alert(dtls_context_t *ctx, dtls_peer_t *peer, dtls_alert_level_t level, + dtls_alert_t description) { + uint8_t msg[] = { level, description }; + + dtls_send(ctx, peer, DTLS_CT_ALERT, msg, sizeof(msg)); + return 0; +} + +int +dtls_close(dtls_context_t *ctx, const session_t *remote) { + int res = -1; + dtls_peer_t *peer; + + peer = dtls_get_peer(ctx, remote); + + if (peer) { + res = dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_CLOSE_NOTIFY); + /* indicate tear down */ + peer->state = DTLS_STATE_CLOSING; + } + return res; +} + +static void dtls_destroy_peer(dtls_context_t *ctx, dtls_peer_t *peer, int unlink) +{ + if (peer->state != DTLS_STATE_CLOSED && peer->state != DTLS_STATE_CLOSING) + dtls_close(ctx, &peer->session); + if (unlink) { +#ifndef WITH_CONTIKI + HASH_DEL_PEER(ctx->peers, peer); +#else /* WITH_CONTIKI */ + list_remove(ctx->peers, peer); +#endif /* WITH_CONTIKI */ + + dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "removed peer", &peer->session); + } + dtls_free_peer(peer); +} + +/** + * Checks a received Client Hello message for a valid cookie. When the + * Client Hello contains no cookie, the function fails and a Hello + * Verify Request is sent to the peer (using the write callback function + * registered with \p ctx). The return value is \c -1 on error, \c 0 when + * undecided, and \c 1 if the Client Hello was good. + * + * \param ctx The DTLS context. + * \param peer The remote party we are talking to, if any. + * \param session Transport address of the remote peer. + * \param state Current state of the connection. + * \param msg The received datagram. + * \param msglen Length of \p msg. + * \return \c 1 if msg is a Client Hello with a valid cookie, \c 0 or + * \c -1 otherwise. + */ +static int +dtls_verify_peer(dtls_context_t *ctx, + dtls_peer_t *peer, + session_t *session, + const dtls_state_t state, + uint8 *data, size_t data_length) +{ + uint8 buf[DTLS_HV_LENGTH + DTLS_COOKIE_LENGTH]; + uint8 *p = buf; + int len = DTLS_COOKIE_LENGTH; + uint8 *cookie = NULL; + int err; +#undef mycookie +#define mycookie (buf + DTLS_HV_LENGTH) + + /* Store cookie where we can reuse it for the HelloVerify request. */ + err = dtls_create_cookie(ctx, session, data, data_length, mycookie, &len); + if (err < 0) + return err; + + dtls_debug_dump("create cookie", mycookie, len); + + assert(len == DTLS_COOKIE_LENGTH); + + /* Perform cookie check. */ + len = dtls_get_cookie(data, data_length, &cookie); + if (len < 0) { + dtls_warn("error while fetching the cookie, err: %i\n", err); + return err; + } + + dtls_debug_dump("compare with cookie", cookie, len); + + /* check if cookies match */ + if (len == DTLS_COOKIE_LENGTH && memcmp(cookie, mycookie, len) == 0) { + dtls_debug("found matching cookie\n"); + return 0; + } + + if (len > 0) { + dtls_debug_dump("invalid cookie", cookie, len); + } else { + dtls_debug("cookie len is 0!\n"); + } + + /* ClientHello did not contain any valid cookie, hence we send a + * HelloVerify request. */ + + dtls_int_to_uint16(p, DTLS_VERSION); + p += sizeof(uint16); + + dtls_int_to_uint8(p, DTLS_COOKIE_LENGTH); + p += sizeof(uint8); + + assert(p == mycookie); + + p += DTLS_COOKIE_LENGTH; + + /* TODO use the same record sequence number as in the ClientHello, + see 4.2.1. Denial-of-Service Countermeasures */ + err = dtls_send_handshake_msg_hash(ctx, + state == DTLS_STATE_CONNECTED ? peer : NULL, + session, + DTLS_HT_HELLO_VERIFY_REQUEST, + buf, p - buf, 0); + if (err < 0) { + dtls_warn("cannot send HelloVerify request\n"); + } + return err; /* HelloVerify is sent, now we cannot do anything but wait */ + +#undef mycookie +} + +#ifdef DTLS_ECC +static int +dtls_check_ecdsa_signature_elem(uint8 *data, size_t data_length, + unsigned char **result_r, + unsigned char **result_s) +{ + int i; + uint8 *data_orig = data; + + if (dtls_uint8_to_int(data) != TLS_EXT_SIG_HASH_ALGO_SHA256) { + dtls_alert("only sha256 is supported in certificate verify\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (dtls_uint8_to_int(data) != TLS_EXT_SIG_HASH_ALGO_ECDSA) { + dtls_alert("only ecdsa signature is supported in client verify\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (data_length < dtls_uint16_to_int(data)) { + dtls_alert("signature length wrong\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint16); + data_length -= sizeof(uint16); + + if (dtls_uint8_to_int(data) != 0x30) { + dtls_alert("wrong ASN.1 struct, expected SEQUENCE\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (data_length < dtls_uint8_to_int(data)) { + dtls_alert("signature length wrong\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (dtls_uint8_to_int(data) != 0x02) { + dtls_alert("wrong ASN.1 struct, expected Integer\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + data_length -= sizeof(uint8); + + /* Sometimes these values have a leeding 0 byte */ + *result_r = data + i - DTLS_EC_KEY_SIZE; + + data += i; + data_length -= i; + + if (dtls_uint8_to_int(data) != 0x02) { + dtls_alert("wrong ASN.1 struct, expected Integer\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + data_length -= sizeof(uint8); + + /* Sometimes these values have a leeding 0 byte */ + *result_s = data + i - DTLS_EC_KEY_SIZE; + + data += i; + data_length -= i; + + return data - data_orig; +} + +static int +check_client_certificate_verify(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + dtls_handshake_parameters_t *config = peer->handshake_params; + int ret; + unsigned char *result_r; + unsigned char *result_s; + dtls_hash_ctx hs_hash; + unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; + + assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); + + data += DTLS_HS_LENGTH; + + if (data_length < DTLS_HS_LENGTH + DTLS_CV_LENGTH) { + dtls_alert("the packet length does not match the expected\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + ret = dtls_check_ecdsa_signature_elem(data, data_length, &result_r, &result_s); + if (ret < 0) { + return ret; + } + data += ret; + data_length -= ret; + + copy_hs_hash(peer, &hs_hash); + + dtls_hash_finalize(sha256hash, &hs_hash); + + ret = dtls_ecdsa_verify_sig_hash(config->keyx.ecdsa.other_pub_x, config->keyx.ecdsa.other_pub_y, + sizeof(config->keyx.ecdsa.other_pub_x), + sha256hash, sizeof(sha256hash), + result_r, result_s); + + if (ret < 0) { + dtls_alert("wrong signature err: %i\n", ret); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + return 0; +} +#endif /* DTLS_ECC */ + +static int +dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer) +{ + /* Ensure that the largest message to create fits in our source + * buffer. (The size of the destination buffer is checked by the + * encoding function, so we do not need to guess.) */ + uint8 buf[DTLS_SH_LENGTH + 2 + 5 + 5 + 8 + 6]; + uint8 *p; + int ecdsa; + uint8 extension_size; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + dtls_tick_t now; + + ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher); + + extension_size = (ecdsa) ? 2 + 5 + 5 + 6 : 0; + + /* Handshake header */ + p = buf; + + /* ServerHello */ + dtls_int_to_uint16(p, DTLS_VERSION); + p += sizeof(uint16); + + /* Set server random: First 4 bytes are the server's Unix timestamp, + * followed by 28 bytes of generate random data. */ + dtls_ticks(&now); + dtls_int_to_uint32(handshake->tmp.random.server, now / CLOCK_SECOND); + dtls_prng(handshake->tmp.random.server + 4, 28); + + memcpy(p, handshake->tmp.random.server, DTLS_RANDOM_LENGTH); + p += DTLS_RANDOM_LENGTH; + + *p++ = 0; /* no session id */ + + if (handshake->cipher != TLS_NULL_WITH_NULL_NULL) { + /* selected cipher suite */ + dtls_int_to_uint16(p, handshake->cipher); + p += sizeof(uint16); + + /* selected compression method */ + *p++ = compression_methods[handshake->compression]; + } + + if (extension_size) { + /* length of the extensions */ + dtls_int_to_uint16(p, extension_size - 2); + p += sizeof(uint16); + } + + if (ecdsa) { + /* client certificate type extension */ + dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 1); + p += sizeof(uint16); + + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); + p += sizeof(uint8); + + /* client certificate type extension */ + dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 1); + p += sizeof(uint16); + + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); + p += sizeof(uint8); + + /* ec_point_formats */ + dtls_int_to_uint16(p, TLS_EXT_EC_POINT_FORMATS); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + /* number of supported formats */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + dtls_int_to_uint8(p, TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED); + p += sizeof(uint8); + } + + assert(p - buf <= sizeof(buf)); + + /* TODO use the same record sequence number as in the ClientHello, + see 4.2.1. Denial-of-Service Countermeasures */ + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_HELLO, + buf, p - buf); +} + +#ifdef DTLS_ECC +static int +dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer, + const dtls_ecdsa_key_t *key) +{ + uint8 buf[DTLS_CE_LENGTH]; + uint8 *p; + + /* Certificate + * + * Start message construction at beginning of buffer. */ + p = buf; + + dtls_int_to_uint24(p, 94); /* certificates length */ + p += sizeof(uint24); + + dtls_int_to_uint24(p, 91); /* length of this certificate */ + p += sizeof(uint24); + + memcpy(p, &cert_asn1_header, sizeof(cert_asn1_header)); + p += sizeof(cert_asn1_header); + + memcpy(p, key->pub_key_x, DTLS_EC_KEY_SIZE); + p += DTLS_EC_KEY_SIZE; + + memcpy(p, key->pub_key_y, DTLS_EC_KEY_SIZE); + p += DTLS_EC_KEY_SIZE; + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE, + buf, p - buf); +} + +static uint8 * +dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s) +{ + int len_r; + int len_s; + +#define R_KEY_OFFSET (1 + 1 + 2 + 1 + 1 + 1 + 1) +#define S_KEY_OFFSET(len_s) (R_KEY_OFFSET + (len_s) + 1 + 1) + /* store the pointer to the r component of the signature and make space */ + len_r = dtls_ec_key_from_uint32_asn1(point_r, DTLS_EC_KEY_SIZE, p + R_KEY_OFFSET); + len_s = dtls_ec_key_from_uint32_asn1(point_s, DTLS_EC_KEY_SIZE, p + S_KEY_OFFSET(len_r)); + +#undef R_KEY_OFFSET +#undef S_KEY_OFFSET + + /* sha256 */ + dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_SHA256); + p += sizeof(uint8); + + /* ecdsa */ + dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_ECDSA); + p += sizeof(uint8); + + /* length of signature */ + dtls_int_to_uint16(p, len_r + len_s + 2 + 2 + 2); + p += sizeof(uint16); + + /* ASN.1 SEQUENCE */ + dtls_int_to_uint8(p, 0x30); + p += sizeof(uint8); + + dtls_int_to_uint8(p, len_r + len_s + 2 + 2); + p += sizeof(uint8); + + /* ASN.1 Integer r */ + dtls_int_to_uint8(p, 0x02); + p += sizeof(uint8); + + dtls_int_to_uint8(p, len_r); + p += sizeof(uint8); + + /* the pint r was added here */ + p += len_r; + + /* ASN.1 Integer s */ + dtls_int_to_uint8(p, 0x02); + p += sizeof(uint8); + + dtls_int_to_uint8(p, len_s); + p += sizeof(uint8); + + /* the pint s was added here */ + p += len_s; + + return p; +} + +static int +dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer, + const dtls_ecdsa_key_t *key) +{ + /* The ASN.1 Integer representation of an 32 byte unsigned int could be + * 33 bytes long add space for that */ + uint8 buf[DTLS_SKEXEC_LENGTH + 2]; + uint8 *p; + uint8 *key_params; + uint8 *ephemeral_pub_x; + uint8 *ephemeral_pub_y; + uint32_t point_r[9]; + uint32_t point_s[9]; + dtls_handshake_parameters_t *config = peer->handshake_params; + + /* ServerKeyExchange + * + * Start message construction at beginning of buffer. */ + p = buf; + + key_params = p; + /* ECCurveType curve_type: named_curve */ + dtls_int_to_uint8(p, 3); + p += sizeof(uint8); + + /* NamedCurve namedcurve: secp256r1 */ + dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1); + p += sizeof(uint16); + + dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE); + p += sizeof(uint8); + + /* This should be an uncompressed point, but I do not have access to the spec. */ + dtls_int_to_uint8(p, 4); + p += sizeof(uint8); + + /* store the pointer to the x component of the pub key and make space */ + ephemeral_pub_x = p; + p += DTLS_EC_KEY_SIZE; + + /* store the pointer to the y component of the pub key and make space */ + ephemeral_pub_y = p; + p += DTLS_EC_KEY_SIZE; + + dtls_ecdsa_generate_key(config->keyx.ecdsa.own_eph_priv, + ephemeral_pub_x, ephemeral_pub_y, + DTLS_EC_KEY_SIZE); + + /* sign the ephemeral and its paramaters */ + dtls_ecdsa_create_sig(key->priv_key, DTLS_EC_KEY_SIZE, + config->tmp.random.client, DTLS_RANDOM_LENGTH, + config->tmp.random.server, DTLS_RANDOM_LENGTH, + key_params, p - key_params, + point_r, point_s); + + p = dtls_add_ecdsa_signature_elem(p, point_r, point_s); + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE, + buf, p - buf); +} +#endif /* DTLS_ECC */ + +#ifdef DTLS_PSK +static int +dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer, + const unsigned char *psk_hint, size_t len) +{ + uint8 buf[DTLS_SKEXECPSK_LENGTH_MAX]; + uint8 *p; + + p = buf; + + assert(len <= DTLS_PSK_MAX_CLIENT_IDENTITY_LEN); + if (len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { + /* should never happen */ + dtls_warn("psk identity hint is too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + dtls_int_to_uint16(p, len); + p += sizeof(uint16); + + memcpy(p, psk_hint, len); + p += len; + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE, + buf, p - buf); +} +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC +static int +dtls_send_server_certificate_request(dtls_context_t *ctx, dtls_peer_t *peer) +{ + uint8 buf[8]; + uint8 *p; + + /* ServerHelloDone + * + * Start message construction at beginning of buffer. */ + p = buf; + + /* certificate_types */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + /* ecdsa_sign */ + dtls_int_to_uint8(p, TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN); + p += sizeof(uint8); + + /* supported_signature_algorithms */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + /* sha256 */ + dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_SHA256); + p += sizeof(uint8); + + /* ecdsa */ + dtls_int_to_uint8(p, TLS_EXT_SIG_HASH_ALGO_ECDSA); + p += sizeof(uint8); + + /* certificate_authoritiess */ + dtls_int_to_uint16(p, 0); + p += sizeof(uint16); + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE_REQUEST, + buf, p - buf); +} +#endif /* DTLS_ECC */ + +static int +dtls_send_server_hello_done(dtls_context_t *ctx, dtls_peer_t *peer) +{ + + /* ServerHelloDone + * + * Start message construction at beginning of buffer. */ + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_HELLO_DONE, + NULL, 0); +} + +static int +dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer) +{ + int res; + + res = dtls_send_server_hello(ctx, peer); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare ServerHello record\n"); + return res; + } + +#ifdef DTLS_ECC + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) { + const dtls_ecdsa_key_t *ecdsa_key; + + res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key); + if (res < 0) { + dtls_crit("no ecdsa certificate to send in certificate\n"); + return res; + } + + res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); + return res; + } + + res = dtls_send_server_key_exchange_ecdh(ctx, peer, ecdsa_key); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare Server Key Exchange record\n"); + return res; + } + + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && + is_ecdsa_client_auth_supported(ctx)) { + res = dtls_send_server_certificate_request(ctx, peer); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare certificate Request record\n"); + return res; + } + } + } +#endif /* DTLS_ECC */ + +#ifdef DTLS_PSK + if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) { + unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; + int len; + + /* The identity hint is optional, therefore we ignore the result + * and check psk only. */ + len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_HINT, + NULL, 0, psk_hint, DTLS_PSK_MAX_CLIENT_IDENTITY_LEN); + + if (len < 0) { + dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n"); + return len; + } + + if (len > 0) { + res = dtls_send_server_key_exchange_psk(ctx, peer, psk_hint, (size_t)len); + + if (res < 0) { + dtls_debug("dtls_server_key_exchange_psk: cannot send server key exchange record\n"); + return res; + } + } + } +#endif /* DTLS_PSK */ + + res = dtls_send_server_hello_done(ctx, peer); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare ServerHelloDone record\n"); + return res; + } + return 0; +} + +static inline int +dtls_send_ccs(dtls_context_t *ctx, dtls_peer_t *peer) { + uint8 buf[1] = {1}; + + return dtls_send(ctx, peer, DTLS_CT_CHANGE_CIPHER_SPEC, buf, 1); +} + + +static int +dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer) +{ + uint8 buf[DTLS_CKXEC_LENGTH]; + uint8 client_id[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN]; + uint8 *p; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + + p = buf; + + switch (handshake->cipher) { +#ifdef DTLS_PSK + case TLS_PSK_WITH_AES_128_CCM_8: { + int len; + + len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY, + NULL, 0, + client_id, + sizeof(client_id)); + if (len < 0) { + dtls_crit("no psk identity set in kx\n"); + return len; + } + + if (len + sizeof(uint16) > DTLS_CKXEC_LENGTH) { + dtls_warn("the psk identity is too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + dtls_int_to_uint16(p, len); + p += sizeof(uint16); + + memcpy(p, client_id, len); + p += len; + + break; + } +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: { + uint8 *ephemeral_pub_x; + uint8 *ephemeral_pub_y; + + dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE); + p += sizeof(uint8); + + /* This should be an uncompressed point, but I do not have access to the spec. */ + dtls_int_to_uint8(p, 4); + p += sizeof(uint8); + + ephemeral_pub_x = p; + p += DTLS_EC_KEY_SIZE; + ephemeral_pub_y = p; + p += DTLS_EC_KEY_SIZE; + + dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecdsa.own_eph_priv, + ephemeral_pub_x, ephemeral_pub_y, + DTLS_EC_KEY_SIZE); + + break; + } +#endif /* DTLS_ECC */ + default: + dtls_crit("cipher not supported\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CLIENT_KEY_EXCHANGE, + buf, p - buf); +} + +#ifdef DTLS_ECC +static int +dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer, + const dtls_ecdsa_key_t *key) +{ + /* The ASN.1 Integer representation of an 32 byte unsigned int could be + * 33 bytes long add space for that */ + uint8 buf[DTLS_CV_LENGTH + 2]; + uint8 *p; + uint32_t point_r[9]; + uint32_t point_s[9]; + dtls_hash_ctx hs_hash; + unsigned char sha256hash[DTLS_HMAC_DIGEST_SIZE]; + + /* ServerKeyExchange + * + * Start message construction at beginning of buffer. */ + p = buf; + + copy_hs_hash(peer, &hs_hash); + + dtls_hash_finalize(sha256hash, &hs_hash); + + /* sign the ephemeral and its paramaters */ + dtls_ecdsa_create_sig_hash(key->priv_key, DTLS_EC_KEY_SIZE, + sha256hash, sizeof(sha256hash), + point_r, point_s); + + p = dtls_add_ecdsa_signature_elem(p, point_r, point_s); + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE_VERIFY, + buf, p - buf); +} +#endif /* DTLS_ECC */ + +static int +dtls_send_finished(dtls_context_t *ctx, dtls_peer_t *peer, + const unsigned char *label, size_t labellen) +{ + int length; + uint8 hash[DTLS_HMAC_MAX]; + uint8 buf[DTLS_FIN_LENGTH]; + dtls_hash_ctx hs_hash; + uint8 *p = buf; + + copy_hs_hash(peer, &hs_hash); + + length = dtls_hash_finalize(hash, &hs_hash); + + dtls_prf(peer->handshake_params->tmp.master_secret, + DTLS_MASTER_SECRET_LENGTH, + label, labellen, + PRF_LABEL(finished), PRF_LABEL_SIZE(finished), + hash, length, + p, DTLS_FIN_LENGTH); + + dtls_debug_dump("server finished MAC", p, DTLS_FIN_LENGTH); + + p += DTLS_FIN_LENGTH; + + assert(p - buf <= sizeof(buf)); + + return dtls_send_handshake_msg(ctx, peer, DTLS_HT_FINISHED, + buf, p - buf); +} + +static int +dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer, + uint8 cookie[], size_t cookie_length) { + uint8 buf[DTLS_CH_LENGTH_MAX]; + uint8 *p = buf; + uint8_t cipher_size; + uint8_t extension_size; + int psk; + int ecdsa; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + dtls_tick_t now; + + psk = is_psk_supported(ctx); + ecdsa = is_ecdsa_supported(ctx, 1); + + cipher_size = 2 + ((ecdsa) ? 2 : 0) + ((psk) ? 2 : 0); + extension_size = (ecdsa) ? 2 + 6 + 6 + 8 + 6: 0; + + if (cipher_size == 0) { + dtls_crit("no cipher callbacks implemented\n"); + } + + dtls_int_to_uint16(p, DTLS_VERSION); + p += sizeof(uint16); + + if (cookie_length > DTLS_COOKIE_LENGTH_MAX) { + dtls_warn("the cookie is too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + if (cookie_length == 0) { + /* Set client random: First 4 bytes are the client's Unix timestamp, + * followed by 28 bytes of generate random data. */ + dtls_ticks(&now); + dtls_int_to_uint32(handshake->tmp.random.client, now / CLOCK_SECOND); + dtls_prng(handshake->tmp.random.client + sizeof(uint32), + DTLS_RANDOM_LENGTH - sizeof(uint32)); + } + /* we must use the same Client Random as for the previous request */ + memcpy(p, handshake->tmp.random.client, DTLS_RANDOM_LENGTH); + p += DTLS_RANDOM_LENGTH; + + /* session id (length 0) */ + dtls_int_to_uint8(p, 0); + p += sizeof(uint8); + + /* cookie */ + dtls_int_to_uint8(p, cookie_length); + p += sizeof(uint8); + if (cookie_length != 0) { + memcpy(p, cookie, cookie_length); + p += cookie_length; + } + + /* add known cipher(s) */ + dtls_int_to_uint16(p, cipher_size - 2); + p += sizeof(uint16); + + if (ecdsa) { + dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); + p += sizeof(uint16); + } + if (psk) { + dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8); + p += sizeof(uint16); + } + + /* compression method */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + dtls_int_to_uint8(p, TLS_COMPRESSION_NULL); + p += sizeof(uint8); + + if (extension_size) { + /* length of the extensions */ + dtls_int_to_uint16(p, extension_size - 2); + p += sizeof(uint16); + } + + if (ecdsa) { + /* client certificate type extension */ + dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + /* length of the list */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); + p += sizeof(uint8); + + /* client certificate type extension */ + dtls_int_to_uint16(p, TLS_EXT_SERVER_CERTIFICATE_TYPE); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + /* length of the list */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY); + p += sizeof(uint8); + + /* elliptic_curves */ + dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 4); + p += sizeof(uint16); + + /* length of the list */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + dtls_int_to_uint16(p, TLS_EXT_ELLIPTIC_CURVES_SECP256R1); + p += sizeof(uint16); + + /* ec_point_formats */ + dtls_int_to_uint16(p, TLS_EXT_EC_POINT_FORMATS); + p += sizeof(uint16); + + /* length of this extension type */ + dtls_int_to_uint16(p, 2); + p += sizeof(uint16); + + /* number of supported formats */ + dtls_int_to_uint8(p, 1); + p += sizeof(uint8); + + dtls_int_to_uint8(p, TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED); + p += sizeof(uint8); + } + + assert(p - buf <= sizeof(buf)); + + if (cookie_length != 0) + clear_hs_hash(peer); + + return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, + DTLS_HT_CLIENT_HELLO, + buf, p - buf, cookie_length != 0); +} + +static int +check_server_hello(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + dtls_handshake_parameters_t *handshake = peer->handshake_params; + + /* This function is called when we expect a ServerHello (i.e. we + * have sent a ClientHello). We might instead receive a HelloVerify + * request containing a cookie. If so, we must repeat the + * ClientHello with the given Cookie. + */ + if (data_length < DTLS_HS_LENGTH + DTLS_HS_LENGTH) + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + + update_hs_hash(peer, data, data_length); + + /* FIXME: check data_length before accessing fields */ + + /* Get the server's random data and store selected cipher suite + * and compression method (like dtls_update_parameters(). + * Then calculate master secret and wait for ServerHelloDone. When received, + * send ClientKeyExchange (?) and ChangeCipherSpec + ClientFinished. */ + + /* check server version */ + data += DTLS_HS_LENGTH; + data_length -= DTLS_HS_LENGTH; + + if (dtls_uint16_to_int(data) != DTLS_VERSION) { + dtls_alert("unknown DTLS version\n"); + return dtls_alert_fatal_create(DTLS_ALERT_PROTOCOL_VERSION); + } + + data += sizeof(uint16); /* skip version field */ + data_length -= sizeof(uint16); + + /* store server random data */ + memcpy(handshake->tmp.random.server, data, DTLS_RANDOM_LENGTH); + /* skip server random */ + data += DTLS_RANDOM_LENGTH; + data_length -= DTLS_RANDOM_LENGTH; + + SKIP_VAR_FIELD(data, data_length, uint8); /* skip session id */ + + /* Check cipher suite. As we offer all we have, it is sufficient + * to check if the cipher suite selected by the server is in our + * list of known cipher suites. Subsets are not supported. */ + handshake->cipher = dtls_uint16_to_int(data); + if (!known_cipher(ctx, handshake->cipher, 1)) { + dtls_alert("unsupported cipher 0x%02x 0x%02x\n", + data[0], data[1]); + return dtls_alert_fatal_create(DTLS_ALERT_INSUFFICIENT_SECURITY); + } + data += sizeof(uint16); + data_length -= sizeof(uint16); + + /* Check if NULL compression was selected. We do not know any other. */ + if (dtls_uint8_to_int(data) != TLS_COMPRESSION_NULL) { + dtls_alert("unsupported compression method 0x%02x\n", data[0]); + return dtls_alert_fatal_create(DTLS_ALERT_INSUFFICIENT_SECURITY); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + return dtls_check_tls_extension(peer, data, data_length, 0); + +error: + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); +} + +static int +check_server_hello_verify_request(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + dtls_hello_verify_t *hv; + int res; + + if (data_length < DTLS_HS_LENGTH + DTLS_HV_LENGTH) + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + + hv = (dtls_hello_verify_t *)(data + DTLS_HS_LENGTH); + + res = dtls_send_client_hello(ctx, peer, hv->cookie, hv->cookie_length); + + if (res < 0) + dtls_warn("cannot send ClientHello\n"); + + return res; +} + +#ifdef DTLS_ECC +static int +check_server_certificate(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + int err; + dtls_handshake_parameters_t *config = peer->handshake_params; + + update_hs_hash(peer, data, data_length); + + assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); + + data += DTLS_HS_LENGTH; + + if (dtls_uint24_to_int(data) != 94) { + dtls_alert("expect length of 94 bytes for server certificate message\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint24); + + if (dtls_uint24_to_int(data) != 91) { + dtls_alert("expect length of 91 bytes for certificate\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint24); + + if (memcmp(data, cert_asn1_header, sizeof(cert_asn1_header))) { + dtls_alert("got an unexpected Subject public key format\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(cert_asn1_header); + + memcpy(config->keyx.ecdsa.other_pub_x, data, + sizeof(config->keyx.ecdsa.other_pub_x)); + data += sizeof(config->keyx.ecdsa.other_pub_x); + + memcpy(config->keyx.ecdsa.other_pub_y, data, + sizeof(config->keyx.ecdsa.other_pub_y)); + data += sizeof(config->keyx.ecdsa.other_pub_y); + + err = CALL(ctx, verify_ecdsa_key, &peer->session, + config->keyx.ecdsa.other_pub_x, + config->keyx.ecdsa.other_pub_y, + sizeof(config->keyx.ecdsa.other_pub_x)); + if (err < 0) { + dtls_warn("The certificate was not accepted\n"); + return err; + } + + return 0; +} + +static int +check_server_key_exchange_ecdsa(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + dtls_handshake_parameters_t *config = peer->handshake_params; + int ret; + unsigned char *result_r; + unsigned char *result_s; + unsigned char *key_params; + + update_hs_hash(peer, data, data_length); + + assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher)); + + data += DTLS_HS_LENGTH; + + if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_LENGTH) { + dtls_alert("the packet length does not match the expected\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + key_params = data; + + if (dtls_uint8_to_int(data) != TLS_EC_CURVE_TYPE_NAMED_CURVE) { + dtls_alert("Only named curves supported\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (dtls_uint16_to_int(data) != TLS_EXT_ELLIPTIC_CURVES_SECP256R1) { + dtls_alert("secp256r1 supported\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint16); + data_length -= sizeof(uint16); + + if (dtls_uint8_to_int(data) != 1 + 2 * DTLS_EC_KEY_SIZE) { + dtls_alert("expected 65 bytes long public point\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + if (dtls_uint8_to_int(data) != 4) { + dtls_alert("expected uncompressed public point\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + data += sizeof(uint8); + data_length -= sizeof(uint8); + + memcpy(config->keyx.ecdsa.other_eph_pub_x, data, sizeof(config->keyx.ecdsa.other_eph_pub_y)); + data += sizeof(config->keyx.ecdsa.other_eph_pub_y); + data_length -= sizeof(config->keyx.ecdsa.other_eph_pub_y); + + memcpy(config->keyx.ecdsa.other_eph_pub_y, data, sizeof(config->keyx.ecdsa.other_eph_pub_y)); + data += sizeof(config->keyx.ecdsa.other_eph_pub_y); + data_length -= sizeof(config->keyx.ecdsa.other_eph_pub_y); + + ret = dtls_check_ecdsa_signature_elem(data, data_length, &result_r, &result_s); + if (ret < 0) { + return ret; + } + data += ret; + data_length -= ret; + + ret = dtls_ecdsa_verify_sig(config->keyx.ecdsa.other_pub_x, config->keyx.ecdsa.other_pub_y, + sizeof(config->keyx.ecdsa.other_pub_x), + config->tmp.random.client, DTLS_RANDOM_LENGTH, + config->tmp.random.server, DTLS_RANDOM_LENGTH, + key_params, + 1 + 2 + 1 + 1 + (2 * DTLS_EC_KEY_SIZE), + result_r, result_s); + + if (ret < 0) { + dtls_alert("wrong signature\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + return 0; +} +#endif /* DTLS_ECC */ + +#ifdef DTLS_PSK +static int +check_server_key_exchange_psk(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + dtls_handshake_parameters_t *config = peer->handshake_params; + uint16_t len; + + update_hs_hash(peer, data, data_length); + + assert(is_tls_psk_with_aes_128_ccm_8(config->cipher)); + + data += DTLS_HS_LENGTH; + + if (data_length < DTLS_HS_LENGTH + DTLS_SKEXECPSK_LENGTH_MIN) { + dtls_alert("the packet length does not match the expected\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + len = dtls_uint16_to_int(data); + data += sizeof(uint16); + + if (len != data_length - DTLS_HS_LENGTH - sizeof(uint16)) { + dtls_warn("the length of the server identity hint is worng\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + if (len > DTLS_PSK_MAX_CLIENT_IDENTITY_LEN) { + dtls_warn("please use a smaller server identity hint\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + /* store the psk_identity_hint in config->keyx.psk for later use */ + config->keyx.psk.id_length = len; + memcpy(config->keyx.psk.identity, data, len); + return 0; +} +#endif /* DTLS_PSK */ + +static int +check_certificate_request(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + unsigned int i; + int auth_alg; + int sig_alg; + int hash_alg; + + update_hs_hash(peer, data, data_length); + + assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)); + + data += DTLS_HS_LENGTH; + + if (data_length < DTLS_HS_LENGTH + 5) { + dtls_alert("the packet length does not match the expected\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + i = dtls_uint8_to_int(data); + data += sizeof(uint8); + if (i + 1 > data_length) { + dtls_alert("the cerfificate types are too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + auth_alg = 0; + for (; i > 0 ; i -= sizeof(uint8)) { + if (dtls_uint8_to_int(data) == TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN + && auth_alg == 0) + auth_alg = dtls_uint8_to_int(data); + data += sizeof(uint8); + } + + if (auth_alg != TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN) { + dtls_alert("the request authentication algorithm is not supproted\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + i = dtls_uint16_to_int(data); + data += sizeof(uint16); + if (i + 1 > data_length) { + dtls_alert("the signature and hash algorithm list is too long\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + + hash_alg = 0; + sig_alg = 0; + for (; i > 0 ; i -= sizeof(uint16)) { + int current_hash_alg; + int current_sig_alg; + + current_hash_alg = dtls_uint8_to_int(data); + data += sizeof(uint8); + current_sig_alg = dtls_uint8_to_int(data); + data += sizeof(uint8); + + if (current_hash_alg == TLS_EXT_SIG_HASH_ALGO_SHA256 && hash_alg == 0 && + current_sig_alg == TLS_EXT_SIG_HASH_ALGO_ECDSA && sig_alg == 0) { + hash_alg = current_hash_alg; + sig_alg = current_sig_alg; + } + } + + if (hash_alg != TLS_EXT_SIG_HASH_ALGO_SHA256 || + sig_alg != TLS_EXT_SIG_HASH_ALGO_ECDSA) { + dtls_alert("no supported hash and signature algorithem\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + /* common names are ignored */ + + peer->handshake_params->do_client_auth = 1; + return 0; +} + +static int +check_server_hellodone(dtls_context_t *ctx, + dtls_peer_t *peer, + uint8 *data, size_t data_length) +{ + int res; +#ifdef DTLS_ECC + const dtls_ecdsa_key_t *ecdsa_key; +#endif /* DTLS_ECC */ + + dtls_handshake_parameters_t *handshake = peer->handshake_params; + + /* calculate master key, send CCS */ + + update_hs_hash(peer, data, data_length); + +#ifdef DTLS_ECC + if (handshake->do_client_auth) { + + res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key); + if (res < 0) { + dtls_crit("no ecdsa certificate to send in certificate\n"); + return res; + } + + res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); + return res; + } + } +#endif /* DTLS_ECC */ + + /* send ClientKeyExchange */ + res = dtls_send_client_key_exchange(ctx, peer); + + if (res < 0) { + dtls_debug("cannot send KeyExchange message\n"); + return res; + } + +#ifdef DTLS_ECC + if (handshake->do_client_auth) { + + res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key); + + if (res < 0) { + dtls_debug("dtls_server_hello: cannot prepare Certificate record\n"); + return res; + } + } +#endif /* DTLS_ECC */ + + res = calculate_key_block(ctx, handshake, peer, + &peer->session, peer->role); + if (res < 0) { + return res; + } + + res = dtls_send_ccs(ctx, peer); + if (res < 0) { + dtls_debug("cannot send CCS message\n"); + return res; + } + + /* and switch cipher suite */ + dtls_security_params_switch(peer); + + /* Client Finished */ + return dtls_send_finished(ctx, peer, PRF_LABEL(client), PRF_LABEL_SIZE(client)); +} + +static int +decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length, + uint8 **cleartext) +{ + dtls_record_header_t *header = DTLS_RECORD_HEADER(packet); + dtls_security_parameters_t *security = dtls_security_params_epoch(peer, dtls_get_epoch(header)); + int clen; + + *cleartext = (uint8 *)packet + sizeof(dtls_record_header_t); + clen = length - sizeof(dtls_record_header_t); + + if (!security) { + dtls_alert("No security context for epoch: %i\n", dtls_get_epoch(header)); + return -1; + } + + if (security->cipher == TLS_NULL_WITH_NULL_NULL) { + /* no cipher suite selected */ + return clen; + } else { /* TLS_PSK_WITH_AES_128_CCM_8 or TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 */ + /** + * length of additional_data for the AEAD cipher which consists of + * seq_num(2+6) + type(1) + version(2) + length(2) + */ +#define A_DATA_LEN 13 + unsigned char nonce[DTLS_CCM_BLOCKSIZE]; + unsigned char A_DATA[A_DATA_LEN]; + + if (clen < 16) /* need at least IV and MAC */ + return -1; + + memset(nonce, 0, DTLS_CCM_BLOCKSIZE); + memcpy(nonce, dtls_kb_remote_iv(security, peer->role), + dtls_kb_iv_size(security, peer->role)); + + /* read epoch and seq_num from message */ + memcpy(nonce + dtls_kb_iv_size(security, peer->role), *cleartext, 8); + *cleartext += 8; + clen -= 8; + + dtls_debug_dump("nonce", nonce, DTLS_CCM_BLOCKSIZE); + dtls_debug_dump("key", dtls_kb_remote_write_key(security, peer->role), + dtls_kb_key_size(security, peer->role)); + dtls_debug_dump("ciphertext", *cleartext, clen); + + /* re-use N to create additional data according to RFC 5246, Section 6.2.3.3: + * + * additional_data = seq_num + TLSCompressed.type + + * TLSCompressed.version + TLSCompressed.length; + */ + memcpy(A_DATA, &DTLS_RECORD_HEADER(packet)->epoch, 8); /* epoch and seq_num */ + memcpy(A_DATA + 8, &DTLS_RECORD_HEADER(packet)->content_type, 3); /* type and version */ + dtls_int_to_uint16(A_DATA + 11, clen - 8); /* length without nonce_explicit */ + + clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce, + dtls_kb_remote_write_key(security, peer->role), + dtls_kb_key_size(security, peer->role), + A_DATA, A_DATA_LEN); + if (clen < 0) + dtls_warn("decryption failed\n"); + else { +#ifndef NDEBUG + printf("decrypt_verify(): found %i bytes cleartext\n", clen); +#endif + dtls_security_params_free_other(peer); + dtls_debug_dump("cleartext", *cleartext, clen); + } + } + return clen; +} + +static int +dtls_send_hello_request(dtls_context_t *ctx, dtls_peer_t *peer) +{ + return dtls_send_handshake_msg_hash(ctx, peer, &peer->session, + DTLS_HT_HELLO_REQUEST, + NULL, 0, 0); +} + +int +dtls_renegotiate(dtls_context_t *ctx, const session_t *dst) +{ + dtls_peer_t *peer = NULL; + int err; + + peer = dtls_get_peer(ctx, dst); + + if (!peer) { + return -1; + } + if (peer->state != DTLS_STATE_CONNECTED) + return -1; + + peer->handshake_params = dtls_handshake_new(); + if (!peer->handshake_params) + return -1; + + peer->handshake_params->hs_state.mseq_r = 0; + peer->handshake_params->hs_state.mseq_s = 0; + + if (peer->role == DTLS_CLIENT) { + /* send ClientHello with empty Cookie */ + err = dtls_send_client_hello(ctx, peer, NULL, 0); + if (err < 0) + dtls_warn("cannot send ClientHello\n"); + else + peer->state = DTLS_STATE_CLIENTHELLO; + return err; + } else if (peer->role == DTLS_SERVER) { + return dtls_send_hello_request(ctx, peer); + } + + return -1; +} + +static int +handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, + const dtls_peer_type role, const dtls_state_t state, + uint8 *data, size_t data_length) { + + int err = 0; + + /* This will clear the retransmission buffer if we get an expected + * handshake message. We have to make sure that no handshake message + * should get expected when we still should retransmit something, when + * we do everything accordingly to the DTLS 1.2 standard this should + * not be a problem. */ + if (peer) { + dtls_stop_retransmission(ctx, peer); + } + + /* The following switch construct handles the given message with + * respect to the current internal state for this peer. In case of + * error, it is left with return 0. */ + + dtls_debug("handle handshake packet of type: %s (%i)\n", + dtls_handshake_type_to_name(data[0]), data[0]); + switch (data[0]) { + + /************************************************************************ + * Client states + ************************************************************************/ + case DTLS_HT_HELLO_VERIFY_REQUEST: + + if (state != DTLS_STATE_CLIENTHELLO) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_server_hello_verify_request(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_server_hello_verify_request err: %i\n", err); + return err; + } + + break; + case DTLS_HT_SERVER_HELLO: + + if (state != DTLS_STATE_CLIENTHELLO) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_server_hello(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_server_hello err: %i\n", err); + return err; + } + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) + peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; + else + peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; + /* update_hs_hash(peer, data, data_length); */ + + break; + +#ifdef DTLS_ECC + case DTLS_HT_CERTIFICATE: + + if ((role == DTLS_CLIENT && state != DTLS_STATE_WAIT_SERVERCERTIFICATE) || + (role == DTLS_SERVER && state != DTLS_STATE_WAIT_CLIENTCERTIFICATE)) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + err = check_server_certificate(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_server_certificate err: %i\n", err); + return err; + } + if (role == DTLS_CLIENT) { + peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; + } else if (role == DTLS_SERVER){ + peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; + } + /* update_hs_hash(peer, data, data_length); */ + + break; +#endif /* DTLS_ECC */ + + case DTLS_HT_SERVER_KEY_EXCHANGE: + +#ifdef DTLS_ECC + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) { + if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + err = check_server_key_exchange_ecdsa(ctx, peer, data, data_length); + } +#endif /* DTLS_ECC */ +#ifdef DTLS_PSK + if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) { + if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + err = check_server_key_exchange_psk(ctx, peer, data, data_length); + } +#endif /* DTLS_PSK */ + + if (err < 0) { + dtls_warn("error in check_server_key_exchange err: %i\n", err); + return err; + } + peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; + /* update_hs_hash(peer, data, data_length); */ + + break; + + case DTLS_HT_SERVER_HELLO_DONE: + + if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_server_hellodone(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_server_hellodone err: %i\n", err); + return err; + } + peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; + /* update_hs_hash(peer, data, data_length); */ + + break; + + case DTLS_HT_CERTIFICATE_REQUEST: + + if (state != DTLS_STATE_WAIT_SERVERHELLODONE) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_certificate_request(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_certificate_request err: %i\n", err); + return err; + } + + break; + + case DTLS_HT_FINISHED: + /* expect a Finished message from server */ + + if (state != DTLS_STATE_WAIT_FINISHED) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_finished(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_finished err: %i\n", err); + return err; + } + if (role == DTLS_SERVER) { + /* send ServerFinished */ + update_hs_hash(peer, data, data_length); + + /* send change cipher spec message and switch to new configuration */ + err = dtls_send_ccs(ctx, peer); + if (err < 0) { + dtls_warn("cannot send CCS message\n"); + return err; + } + + dtls_security_params_switch(peer); + + err = dtls_send_finished(ctx, peer, PRF_LABEL(server), PRF_LABEL_SIZE(server)); + if (err < 0) { + dtls_warn("sending server Finished failed\n"); + return err; + } + } + dtls_handshake_free(peer->handshake_params); + peer->handshake_params = NULL; + dtls_debug("Handshake complete\n"); + check_stack(); + peer->state = DTLS_STATE_CONNECTED; + + /* return here to not increase the message receive counter */ + return err; + + /************************************************************************ + * Server states + ************************************************************************/ + + case DTLS_HT_CLIENT_KEY_EXCHANGE: + /* handle ClientHello, update msg and msglen and goto next if not finished */ + + if (state != DTLS_STATE_WAIT_CLIENTKEYEXCHANGE) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_client_keyexchange(ctx, peer->handshake_params, data, data_length); + if (err < 0) { + dtls_warn("error in check_client_keyexchange err: %i\n", err); + return err; + } + update_hs_hash(peer, data, data_length); + + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && + is_ecdsa_client_auth_supported(ctx)) + peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; + else + peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; + break; + +#ifdef DTLS_ECC + case DTLS_HT_CERTIFICATE_VERIFY: + + if (state != DTLS_STATE_WAIT_CERTIFICATEVERIFY) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + err = check_client_certificate_verify(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error in check_client_certificate_verify err: %i\n", err); + return err; + } + + update_hs_hash(peer, data, data_length); + peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; + break; +#endif /* DTLS_ECC */ + + case DTLS_HT_CLIENT_HELLO: + + if ((peer && state != DTLS_STATE_CONNECTED && state != DTLS_STATE_WAIT_CLIENTHELLO) || + (!peer && state != DTLS_STATE_WAIT_CLIENTHELLO)) { + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + /* When no DTLS state exists for this peer, we only allow a + Client Hello message with + + a) a valid cookie, or + b) no cookie. + + Anything else will be rejected. Fragementation is not allowed + here as it would require peer state as well. + */ + err = dtls_verify_peer(ctx, peer, session, state, data, data_length); + if (err < 0) { + dtls_warn("error in dtls_verify_peer err: %i\n", err); + return err; + } + + if (err > 0) { + dtls_debug("server hello verify was sent\n"); + break; + } + + /* At this point, we have a good relationship with this peer. This + * state is left for re-negotiation of key material. */ + /* As per RFC 6347 - section 4.2.8 if this is an attempt to + * rehandshake, we can delete the existing key material + * as the client has demonstrated reachibility by completing + * the cookie exchange */ + if (peer && state == DTLS_STATE_WAIT_CLIENTHELLO) { + dtls_debug("removing the peer\n"); +#ifndef WITH_CONTIKI + HASH_DEL_PEER(ctx->peers, peer); +#else /* WITH_CONTIKI */ + list_remove(ctx->peers, peer); +#endif /* WITH_CONTIKI */ + + dtls_free_peer(peer); + peer = NULL; + } + if (!peer) { + dtls_debug("creating new peer\n"); + dtls_security_parameters_t *security; + + /* msg contains a Client Hello with a valid cookie, so we can + * safely create the server state machine and continue with + * the handshake. */ + peer = dtls_new_peer(session); + if (!peer) { + dtls_alert("cannot create peer\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + peer->role = DTLS_SERVER; + + /* Initialize record sequence number to 1 for new peers. The first + * record with sequence number 0 is a stateless Hello Verify Request. + */ + security = dtls_security_params(peer); + security->rseq = 1; + dtls_add_peer(ctx, peer); + } + if (peer && !peer->handshake_params) { + dtls_handshake_header_t *hs_header = DTLS_HANDSHAKE_HEADER(data); + + peer->handshake_params = dtls_handshake_new(); + if (!peer->handshake_params) + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + + LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); + peer->handshake_params->hs_state.mseq_r = dtls_uint16_to_int(hs_header->message_seq); + peer->handshake_params->hs_state.mseq_s = 1; + } + + clear_hs_hash(peer); + + /* First negotiation step: check for PSK + * + * Note that we already have checked that msg is a Handshake + * message containing a ClientHello. dtls_get_cipher() therefore + * does not check again. + */ + err = dtls_update_parameters(ctx, peer, data, data_length); + if (err < 0) { + dtls_warn("error updating security parameters\n"); + return err; + } + + /* update finish MAC */ + update_hs_hash(peer, data, data_length); + + err = dtls_send_server_hello_msgs(ctx, peer); + if (err < 0) { + return err; + } + if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) && + is_ecdsa_client_auth_supported(ctx)) + peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; + else + peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; + + /* after sending the ServerHelloDone, we expect the + * ClientKeyExchange (possibly containing the PSK id), + * followed by a ChangeCipherSpec and an encrypted Finished. + */ + + break; + + case DTLS_HT_HELLO_REQUEST: + + if (state != DTLS_STATE_CONNECTED) { + /* we should just ignore such packets when in handshake */ + return 0; + } + + if (peer && !peer->handshake_params) { + peer->handshake_params = dtls_handshake_new(); + if (!peer->handshake_params) + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + + LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); + peer->handshake_params->hs_state.mseq_r = 0; + peer->handshake_params->hs_state.mseq_s = 0; + } + + /* send ClientHello with empty Cookie */ + err = dtls_send_client_hello(ctx, peer, NULL, 0); + if (err < 0) { + dtls_warn("cannot send ClientHello\n"); + return err; + } + peer->state = DTLS_STATE_CLIENTHELLO; + break; + + default: + dtls_crit("unhandled message %d\n", data[0]); + return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE); + } + + if (peer && peer->handshake_params && err >= 0) { + peer->handshake_params->hs_state.mseq_r++; + } + + return err; +} + +static int +handle_handshake(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session, + const dtls_peer_type role, const dtls_state_t state, + uint8 *data, size_t data_length) +{ + dtls_handshake_header_t *hs_header; + int res; + + if (data_length < DTLS_HS_LENGTH) { + dtls_warn("handshake message too short\n"); + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + } + hs_header = DTLS_HANDSHAKE_HEADER(data); + + dtls_debug("received handshake packet of type: %s (%i)\n", + dtls_handshake_type_to_name(hs_header->msg_type), hs_header->msg_type); + + if (!peer || !peer->handshake_params) { + /* This is the initial ClientHello */ + if (hs_header->msg_type != DTLS_HT_CLIENT_HELLO && !peer) { + dtls_warn("If there is no peer only ClientHello is allowed\n"); + return dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE); + } + + /* This is a ClientHello or Hello Request send when doing TLS renegotiation */ + if (hs_header->msg_type == DTLS_HT_CLIENT_HELLO || + hs_header->msg_type == DTLS_HT_HELLO_REQUEST) { + return handle_handshake_msg(ctx, peer, session, role, state, data, + data_length); + } else { + dtls_warn("ignore unexpected handshake message\n"); + return 0; + } + } + + if (dtls_uint16_to_int(hs_header->message_seq) < peer->handshake_params->hs_state.mseq_r) { + dtls_warn("The message sequence number is too small, expected %i, got: %i\n", + peer->handshake_params->hs_state.mseq_r, dtls_uint16_to_int(hs_header->message_seq)); + return 0; + } else if (dtls_uint16_to_int(hs_header->message_seq) > peer->handshake_params->hs_state.mseq_r) { + /* A packet in between is missing, buffer this packet. */ + netq_t *n; + + /* TODO: only add packet that are not too new. */ + if (data_length > DTLS_MAX_BUF) { + dtls_warn("the packet is too big to buffer for reoder\n"); + return 0; + } + + netq_t *node = netq_head(peer->handshake_params->reorder_queue); + while (node) { + dtls_handshake_header_t *node_header = DTLS_HANDSHAKE_HEADER(node->data); + if (dtls_uint16_to_int(node_header->message_seq) == dtls_uint16_to_int(hs_header->message_seq)) { + dtls_warn("a packet with this sequence number is already stored\n"); + return 0; + } + node = netq_next(node); + } + + n = netq_node_new(data_length); + if (!n) { + dtls_warn("no space in reoder buffer\n"); + return 0; + } + + n->peer = peer; + n->length = data_length; + memcpy(n->data, data, data_length); + + if (!netq_insert_node(peer->handshake_params->reorder_queue, n)) { + dtls_warn("cannot add packet to reoder buffer\n"); + netq_node_free(n); + } + dtls_info("Added packet for reordering\n"); + return 0; + } else if (dtls_uint16_to_int(hs_header->message_seq) == peer->handshake_params->hs_state.mseq_r) { + /* Found the expected packet, use this and all the buffered packet */ + int next = 1; + + res = handle_handshake_msg(ctx, peer, session, role, state, data, data_length); + if (res < 0) + return res; + + /* We do not know in which order the packet are in the list just search the list for every packet. */ + while (next && peer->handshake_params) { + next = 0; + netq_t *node = netq_head(peer->handshake_params->reorder_queue); + while (node) { + dtls_handshake_header_t *node_header = DTLS_HANDSHAKE_HEADER(node->data); + + if (dtls_uint16_to_int(node_header->message_seq) == peer->handshake_params->hs_state.mseq_r) { + netq_remove(peer->handshake_params->reorder_queue, node); + next = 1; + res = handle_handshake_msg(ctx, peer, session, role, peer->state, node->data, node->length); + if (res < 0) { + return res; + } + + break; + } else { + node = netq_next(node); + } + } + } + return res; + } + assert(0); + return 0; +} + +static int +handle_ccs(dtls_context_t *ctx, dtls_peer_t *peer, + uint8 *record_header, uint8 *data, size_t data_length) +{ + int err; + dtls_handshake_parameters_t *handshake = peer->handshake_params; + + /* A CCS message is handled after a KeyExchange message was + * received from the client. When security parameters have been + * updated successfully and a ChangeCipherSpec message was sent + * by ourself, the security context is switched and the record + * sequence number is reset. */ + + if (!peer || peer->state != DTLS_STATE_WAIT_CHANGECIPHERSPEC) { + dtls_warn("expected ChangeCipherSpec during handshake\n"); + return 0; + } + + if (data_length < 1 || data[0] != 1) + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + + /* Just change the cipher when we are on the same epoch */ + if (peer->role == DTLS_SERVER) { + err = calculate_key_block(ctx, handshake, peer, + &peer->session, peer->role); + if (err < 0) { + return err; + } + } + + peer->state = DTLS_STATE_WAIT_FINISHED; + + return 0; +} + +/** + * Handles incoming Alert messages. This function returns \c 1 if the + * connection should be closed and the peer is to be invalidated. + */ +static int +handle_alert(dtls_context_t *ctx, dtls_peer_t *peer, + uint8 *record_header, uint8 *data, size_t data_length) { + int free_peer = 0; /* indicates whether to free peer */ + + if (data_length < 2) + return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR); + + dtls_info("** Alert: level %d, description %d\n", data[0], data[1]); + + if (!peer) { + dtls_warn("got an alert for an unknown peer, we probably already removed it, ignore it\n"); + return 0; + } + + /* The peer object is invalidated for FATAL alerts and close + * notifies. This is done in two steps.: First, remove the object + * from our list of peers. After that, the event handler callback is + * invoked with the still existing peer object. Finally, the storage + * used by peer is released. + */ + if (data[0] == DTLS_ALERT_LEVEL_FATAL || data[1] == DTLS_ALERT_CLOSE_NOTIFY) { + dtls_alert("%d invalidate peer\n", data[1]); + +#ifndef WITH_CONTIKI + HASH_DEL_PEER(ctx->peers, peer); +#else /* WITH_CONTIKI */ + list_remove(ctx->peers, peer); + +#ifndef NDEBUG + PRINTF("removed peer ["); + PRINT6ADDR(&peer->session.addr); + PRINTF("]:%d\n", uip_ntohs(peer->session.port)); +#endif +#endif /* WITH_CONTIKI */ + + free_peer = 1; + + } + + (void)CALL(ctx, event, &peer->session, + (dtls_alert_level_t)data[0], (unsigned short)data[1]); + switch (data[1]) { + case DTLS_ALERT_CLOSE_NOTIFY: + /* If state is DTLS_STATE_CLOSING, we have already sent a + * close_notify so, do not send that again. */ + if (peer->state != DTLS_STATE_CLOSING) { + peer->state = DTLS_STATE_CLOSING; + dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_CLOSE_NOTIFY); + } else + peer->state = DTLS_STATE_CLOSED; + break; + default: + ; + } + + if (free_peer) { + dtls_stop_retransmission(ctx, peer); + dtls_destroy_peer(ctx, peer, 0); + } + + return free_peer; +} + +static int dtls_alert_send_from_err(dtls_context_t *ctx, dtls_peer_t *peer, + session_t *session, int err) +{ + int level; + int desc; + + if (err < -(1 << 8) && err > -(3 << 8)) { + level = ((-err) & 0xff00) >> 8; + desc = (-err) & 0xff; + if (!peer) { + peer = dtls_get_peer(ctx, session); + } + if (peer) { + peer->state = DTLS_STATE_CLOSING; + return dtls_send_alert(ctx, peer, level, desc); + } + } else if (err == -1) { + if (!peer) { + peer = dtls_get_peer(ctx, session); + } + if (peer) { + peer->state = DTLS_STATE_CLOSING; + return dtls_send_alert(ctx, peer, DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_INTERNAL_ERROR); + } + } + return -1; +} + +/** + * Handles incoming data as DTLS message from given peer. + */ +int +dtls_handle_message(dtls_context_t *ctx, + session_t *session, + uint8 *msg, int msglen) { + dtls_peer_t *peer = NULL; + unsigned int rlen; /* record length */ + uint8 *data; /* (decrypted) payload */ + int data_length; /* length of decrypted payload + (without MAC and padding) */ + int err; + + /* check if we have DTLS state for addr/port/ifindex */ + peer = dtls_get_peer(ctx, session); + + if (!peer) { + dtls_debug("dtls_handle_message: PEER NOT FOUND\n"); + dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "peer addr", session); + } else { + dtls_debug("dtls_handle_message: FOUND PEER\n"); + } + + while ((rlen = is_record(msg,msglen))) { + dtls_peer_type role; + dtls_state_t state; + + dtls_debug("got packet %d (%d bytes)\n", msg[0], rlen); + if (peer) { + data_length = decrypt_verify(peer, msg, rlen, &data); + if (data_length < 0) { + if (hs_attempt_with_existing_peer(msg, rlen, peer)) { + data = msg + DTLS_RH_LENGTH; + data_length = rlen - DTLS_RH_LENGTH; + state = DTLS_STATE_WAIT_CLIENTHELLO; + role = DTLS_SERVER; + } else { + int err = dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); + dtls_info("decrypt_verify() failed\n"); + if (peer->state < DTLS_STATE_CONNECTED) { + dtls_alert_send_from_err(ctx, peer, &peer->session, err); + peer->state = DTLS_STATE_CLOSED; + /* dtls_stop_retransmission(ctx, peer); */ + dtls_destroy_peer(ctx, peer, 1); + } + return err; + } + } else { + role = peer->role; + state = peer->state; + } + } else { + /* is_record() ensures that msg contains at least a record header */ + data = msg + DTLS_RH_LENGTH; + data_length = rlen - DTLS_RH_LENGTH; + state = DTLS_STATE_WAIT_CLIENTHELLO; + role = DTLS_SERVER; + } + + dtls_debug_hexdump("receive header", msg, sizeof(dtls_record_header_t)); + dtls_debug_hexdump("receive unencrypted", data, data_length); + + /* Handle received record according to the first byte of the + * message, i.e. the subprotocol. We currently do not support + * combining multiple fragments of one type into a single + * record. */ + + switch (msg[0]) { + + case DTLS_CT_CHANGE_CIPHER_SPEC: + if (peer) { + dtls_stop_retransmission(ctx, peer); + } + err = handle_ccs(ctx, peer, msg, data, data_length); + if (err < 0) { + dtls_warn("error while handling ChangeCipherSpec message\n"); + dtls_alert_send_from_err(ctx, peer, session, err); + + /* invalidate peer */ + dtls_destroy_peer(ctx, peer, 1); + peer = NULL; + + return err; + } + break; + + case DTLS_CT_ALERT: + if (peer) { + dtls_stop_retransmission(ctx, peer); + } + err = handle_alert(ctx, peer, msg, data, data_length); + if (err < 0 || err == 1) { + dtls_warn("received alert, peer has been invalidated\n"); + /* handle alert has invalidated peer */ + peer = NULL; + return err < 0 ?err:-1; + } + break; + + case DTLS_CT_HANDSHAKE: + /* Handshake messages other than Finish must use the current + * epoch, Finish has epoch + 1. */ + + if (peer) { + uint16_t expected_epoch = dtls_security_params(peer)->epoch; + uint16_t msg_epoch = + dtls_uint16_to_int(DTLS_RECORD_HEADER(msg)->epoch); + + /* The new security parameters must be used for all messages + * that are sent after the ChangeCipherSpec message. This + * means that the client's Finished message uses epoch + 1 + * while the server is still in the old epoch. + */ + if (role == DTLS_SERVER && state == DTLS_STATE_WAIT_FINISHED) { + expected_epoch++; + } + + if (expected_epoch != msg_epoch) { + if (hs_attempt_with_existing_peer(msg, rlen, peer)) { + state = DTLS_STATE_WAIT_CLIENTHELLO; + role = DTLS_SERVER; + } else { + dtls_warn("Wrong epoch, expected %i, got: %i\n", + expected_epoch, msg_epoch); + break; + } + } + } + + err = handle_handshake(ctx, peer, session, role, state, data, data_length); + if (err < 0) { + dtls_warn("error while handling handshake packet\n"); + dtls_alert_send_from_err(ctx, peer, session, err); + return err; + } + if (peer && peer->state == DTLS_STATE_CONNECTED) { + /* stop retransmissions */ + dtls_stop_retransmission(ctx, peer); + CALL(ctx, event, &peer->session, 0, DTLS_EVENT_CONNECTED); + } + break; + + case DTLS_CT_APPLICATION_DATA: + dtls_info("** application data:\n"); + if (!peer) { + dtls_warn("no peer available, send an alert\n"); + // TODO: should we send a alert here? + return -1; + } + dtls_stop_retransmission(ctx, peer); + CALL(ctx, read, &peer->session, data, data_length); + break; + default: + dtls_info("dropped unknown message of type %d\n",msg[0]); + } + + /* advance msg by length of ciphertext */ + msg += rlen; + msglen -= rlen; + } + + return 0; +} + +dtls_context_t * +dtls_new_context(void *app_data) { + dtls_context_t *c; + dtls_tick_t now; +#ifndef WITH_CONTIKI + FILE *urandom = fopen("/dev/urandom", "r"); + unsigned char buf[sizeof(unsigned long)]; +#endif /* WITH_CONTIKI */ + + dtls_ticks(&now); +#ifdef WITH_CONTIKI + /* FIXME: need something better to init PRNG here */ + dtls_prng_init(now); +#else /* WITH_CONTIKI */ + if (!urandom) { + dtls_emerg("cannot initialize PRNG\n"); + return NULL; + } + + if (fread(buf, 1, sizeof(buf), urandom) != sizeof(buf)) { + dtls_emerg("cannot initialize PRNG\n"); + return NULL; + } + + fclose(urandom); + dtls_prng_init((unsigned long)*buf); +#endif /* WITH_CONTIKI */ + + c = malloc_context(); + if (!c) + goto error; + + memset(c, 0, sizeof(dtls_context_t)); + c->app = app_data; + + LIST_STRUCT_INIT(c, sendqueue); + +#ifdef WITH_CONTIKI + LIST_STRUCT_INIT(c, peers); + /* LIST_STRUCT_INIT(c, key_store); */ + + process_start(&dtls_retransmit_process, (char *)c); + PROCESS_CONTEXT_BEGIN(&dtls_retransmit_process); + /* the retransmit timer must be initialized to some large value */ + etimer_set(&c->retransmit_timer, 0xFFFF); + PROCESS_CONTEXT_END(&coap_retransmit_process); +#endif /* WITH_CONTIKI */ + + if (dtls_prng(c->cookie_secret, DTLS_COOKIE_SECRET_LENGTH)) + c->cookie_secret_age = now; + else + goto error; + + return c; + + error: + dtls_alert("cannot create DTLS context\n"); + if (c) + dtls_free_context(c); + return NULL; +} + +void +dtls_free_context(dtls_context_t *ctx) { + dtls_peer_t *p; + + if (!ctx) { + return; + } + +#ifndef WITH_CONTIKI + dtls_peer_t *tmp; + + if (ctx->peers) { + HASH_ITER(hh, ctx->peers, p, tmp) { + dtls_destroy_peer(ctx, p, 1); + } + } +#else /* WITH_CONTIKI */ + for (p = list_head(ctx->peers); p; p = list_item_next(p)) + dtls_destroy_peer(ctx, p, 1); +#endif /* WITH_CONTIKI */ + + free_context(ctx); +} + +int +dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer) { + int res; + + assert(peer); + if (!peer) + return -1; + + /* check if the same peer is already in our list */ + if (peer == dtls_get_peer(ctx, &peer->session)) { + dtls_debug("found peer, try to re-connect\n"); + return dtls_renegotiate(ctx, &peer->session); + } + + /* set local peer role to client, remote is server */ + peer->role = DTLS_CLIENT; + + dtls_add_peer(ctx, peer); + + /* send ClientHello with empty Cookie */ + peer->handshake_params = dtls_handshake_new(); + if (!peer->handshake_params) + return -1; + + peer->handshake_params->hs_state.mseq_r = 0; + peer->handshake_params->hs_state.mseq_s = 0; + LIST_STRUCT_INIT(peer->handshake_params, reorder_queue); + res = dtls_send_client_hello(ctx, peer, NULL, 0); + if (res < 0) + dtls_warn("cannot send ClientHello\n"); + else + peer->state = DTLS_STATE_CLIENTHELLO; + + return res; +} + +int +dtls_connect(dtls_context_t *ctx, const session_t *dst) { + dtls_peer_t *peer; + int res; + + peer = dtls_get_peer(ctx, dst); + + if (!peer) + peer = dtls_new_peer(dst); + + if (!peer) { + dtls_crit("cannot create new peer\n"); + return -1; + } + + res = dtls_connect_peer(ctx, peer); + + /* Invoke event callback to indicate connection attempt or + * re-negotiation. */ + if (res > 0) { + CALL(ctx, event, &peer->session, 0, DTLS_EVENT_CONNECT); + } else if (res == 0) { + CALL(ctx, event, &peer->session, 0, DTLS_EVENT_RENEGOTIATE); + } + + return res; +} + +static void +dtls_retransmit(dtls_context_t *context, netq_t *node) { + if (!context || !node) + return; + + /* re-initialize timeout when maximum number of retransmissions are not reached yet */ + if (node->retransmit_cnt < DTLS_DEFAULT_MAX_RETRANSMIT) { + unsigned char sendbuf[DTLS_MAX_BUF]; + size_t len = sizeof(sendbuf); + int err; + unsigned char *data = node->data; + size_t length = node->length; + dtls_tick_t now; + dtls_security_parameters_t *security = dtls_security_params_epoch(node->peer, node->epoch); + + dtls_ticks(&now); + node->retransmit_cnt++; + node->t = now + (node->timeout << node->retransmit_cnt); + netq_insert_node(context->sendqueue, node); + + if (node->type == DTLS_CT_HANDSHAKE) { + dtls_handshake_header_t *hs_header = DTLS_HANDSHAKE_HEADER(data); + + dtls_debug("** retransmit handshake packet of type: %s (%i)\n", + dtls_handshake_type_to_name(hs_header->msg_type), hs_header->msg_type); + } else { + dtls_debug("** retransmit packet\n"); + } + + err = dtls_prepare_record(node->peer, security, node->type, &data, &length, + 1, sendbuf, &len); + if (err < 0) { + dtls_warn("can not retransmit packet, err: %i\n", err); + return; + } + dtls_debug_hexdump("retransmit header", sendbuf, + sizeof(dtls_record_header_t)); + dtls_debug_hexdump("retransmit unencrypted", node->data, node->length); + + (void)CALL(context, write, &node->peer->session, sendbuf, len); + return; + } + + /* no more retransmissions, remove node from system */ + + dtls_debug("** removed transaction\n"); + + /* And finally delete the node */ + netq_node_free(node); +} + +static void +dtls_stop_retransmission(dtls_context_t *context, dtls_peer_t *peer) { + netq_t *node; + node = list_head(context->sendqueue); + + while (node) { + if (dtls_session_equals(&node->peer->session, &peer->session)) { + netq_t *tmp = node; + node = list_item_next(node); + list_remove(context->sendqueue, tmp); + netq_node_free(tmp); + } else + node = list_item_next(node); + } +} + +void +dtls_check_retransmit(dtls_context_t *context, clock_time_t *next) { + dtls_tick_t now; + netq_t *node = netq_head(context->sendqueue); + + dtls_ticks(&now); + while (node && node->t <= now) { + netq_pop_first(context->sendqueue); + dtls_retransmit(context, node); + node = netq_head(context->sendqueue); + } + + if (next && node) + *next = node->t; +} + +#ifdef WITH_CONTIKI +/*---------------------------------------------------------------------------*/ +/* message retransmission */ +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(dtls_retransmit_process, ev, data) +{ + clock_time_t now; + netq_t *node; + + PROCESS_BEGIN(); + + dtls_debug("Started DTLS retransmit process\r\n"); + + while(1) { + PROCESS_YIELD(); + if (ev == PROCESS_EVENT_TIMER) { + if (etimer_expired(&the_dtls_context.retransmit_timer)) { + + node = list_head(the_dtls_context.sendqueue); + + now = clock_time(); + if (node && node->t <= now) { + dtls_retransmit(&the_dtls_context, list_pop(the_dtls_context.sendqueue)); + node = list_head(the_dtls_context.sendqueue); + } + + /* need to set timer to some value even if no nextpdu is available */ + if (node) { + etimer_set(&the_dtls_context.retransmit_timer, + node->t <= now ? 1 : node->t - now); + } else { + etimer_set(&the_dtls_context.retransmit_timer, 0xFFFF); + } + } + } + } + + PROCESS_END(); +} +#endif /* WITH_CONTIKI */ diff --git a/extlibs/tinydtls/dtls.h b/extlibs/tinydtls/dtls.h new file mode 100644 index 0000000..7ebde6b --- /dev/null +++ b/extlibs/tinydtls/dtls.h @@ -0,0 +1,746 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file dtls.h + * @brief High level DTLS API and visible structures. + */ + +#ifndef _DTLS_DTLS_H_ +#define _DTLS_DTLS_H_ + +#include + +#include "t_list.h" +#include "state.h" +#include "peer.h" + +#ifndef WITH_CONTIKI +#include "uthash.h" +#include "t_list.h" +#endif /* WITH_CONTIKI */ + +#include "alert.h" +#include "crypto.h" +#include "hmac.h" + +#include "global.h" +#include "dtls_time.h" + +#ifndef DTLSv12 +#define DTLS_VERSION 0xfeff /* DTLS v1.1 */ +#else +#define DTLS_VERSION 0xfefd /* DTLS v1.2 */ +#endif + +typedef enum dtls_credentials_type_t { + DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY +} dtls_credentials_type_t; + +typedef struct dtls_ecdsa_key_t { + dtls_ecdh_curve curve; + const unsigned char *priv_key; /** < private key as bytes > */ + const unsigned char *pub_key_x; /** < x part of the public key for the given private key > */ + const unsigned char *pub_key_y; /** < y part of the public key for the given private key > */ +} dtls_ecdsa_key_t; + +/** Length of the secret that is used for generating Hello Verify cookies. */ +#define DTLS_COOKIE_SECRET_LENGTH 12 + +struct dtls_context_t; + +/** + * This structure contains callback functions used by tinydtls to + * communicate with the application. At least the write function must + * be provided. It is called by the DTLS state machine to send packets + * over the network. The read function is invoked to deliver decrypted + * and verfified application data. The third callback is an event + * handler function that is called when alert messages are encountered + * or events generated by the library have occured. + */ +typedef struct { + /** + * Called from dtls_handle_message() to send DTLS packets over the + * network. The callback function must use the network interface + * denoted by session->ifindex to send the data. + * + * @param ctx The current DTLS context. + * @param session The session object, including the address of the + * remote peer where the data shall be sent. + * @param buf The data to send. + * @param len The actual length of @p buf. + * @return The callback function must return the number of bytes + * that were sent, or a value less than zero to indicate an + * error. + */ + int (*write)(struct dtls_context_t *ctx, + session_t *session, uint8 *buf, size_t len); + + /** + * Called from dtls_handle_message() deliver application data that was + * received on the given session. The data is delivered only after + * decryption and verification have succeeded. + * + * @param ctx The current DTLS context. + * @param session The session object, including the address of the + * data's origin. + * @param buf The received data packet. + * @param len The actual length of @p buf. + * @return ignored + */ + int (*read)(struct dtls_context_t *ctx, + session_t *session, uint8 *buf, size_t len); + + /** + * The event handler is called when a message from the alert + * protocol is received or the state of the DTLS session changes. + * + * @param ctx The current dtls context. + * @param session The session object that was affected. + * @param level The alert level or @c 0 when an event ocurred that + * is not an alert. + * @param code Values less than @c 256 indicate alerts, while + * @c 256 or greater indicate internal DTLS session changes. + * @return ignored + */ + int (*event)(struct dtls_context_t *ctx, session_t *session, + dtls_alert_level_t level, unsigned short code); + +#ifdef DTLS_PSK + /** + * Called during handshake to get information related to the + * psk key exchange. The type of information requested is + * indicated by @p type which will be one of DTLS_PSK_HINT, + * DTLS_PSK_IDENTITY, or DTLS_PSK_KEY. The called function + * must store the requested item in the buffer @p result of + * size @p result_length. On success, the function must return + * the actual number of bytes written to @p result, of a + * value less than zero on error. The parameter @p desc may + * contain additional request information (e.g. the psk_identity + * for which a key is requested when @p type == @c DTLS_PSK_KEY. + * + * @param ctx The current dtls context. + * @param session The session where the key will be used. + * @param type The type of the requested information. + * @param desc Additional request information + * @param desc_len The actual length of desc. + * @param result Must be filled with the requested information. + * @param result_length Maximum size of @p result. + * @return The number of bytes written to @p result or a value + * less than zero on error. + */ + int (*get_psk_info)(struct dtls_context_t *ctx, + const session_t *session, + dtls_credentials_type_t type, + const unsigned char *desc, size_t desc_len, + unsigned char *result, size_t result_length); + +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC + /** + * Called during handshake to get the server's or client's ecdsa + * key used to authenticate this server or client in this + * session. If found, the key must be stored in @p result and + * the return value must be @c 0. If not found, @p result is + * undefined and the return value must be less than zero. + * + * If ECDSA should not be supported, set this pointer to NULL. + * + * Implement this if you want to provide your own certificate to + * the other peer. This is mandatory for a server providing ECDSA + * support and optional for a client. A client doing DTLS client + * authentication has to implementing this callback. + * + * @param ctx The current dtls context. + * @param session The session where the key will be used. + * @param result Must be set to the key object to used for the given + * session. + * @return @c 0 if result is set, or less than zero on error. + */ + int (*get_ecdsa_key)(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecdsa_key_t **result); + + /** + * Called during handshake to check the peer's pubic key in this + * session. If the public key matches the session and should be + * considerated valid the return value must be @c 0. If not valid, + * the return value must be less than zero. + * + * If ECDSA should not be supported, set this pointer to NULL. + * + * Implement this if you want to verify the other peers public key. + * This is mandatory for a DTLS client doing based ECDSA + * authentication. A server implementing this will request the + * client to do DTLS client authentication. + * + * @param ctx The current dtls context. + * @param session The session where the key will be used. + * @param other_pub_x x component of the public key. + * @param other_pub_y y component of the public key. + * @return @c 0 if public key matches, or less than zero on error. + * error codes: + * return dtls_alert_fatal_create(DTLS_ALERT_BAD_CERTIFICATE); + * return dtls_alert_fatal_create(DTLS_ALERT_UNSUPPORTED_CERTIFICATE); + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_REVOKED); + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_EXPIRED); + * return dtls_alert_fatal_create(DTLS_ALERT_CERTIFICATE_UNKNOWN); + * return dtls_alert_fatal_create(DTLS_ALERT_UNKNOWN_CA); + */ + int (*verify_ecdsa_key)(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char *other_pub_x, + const unsigned char *other_pub_y, + size_t key_size); +#endif /* DTLS_ECC */ +} dtls_handler_t; + +/** Holds global information of the DTLS engine. */ +typedef struct dtls_context_t { + unsigned char cookie_secret[DTLS_COOKIE_SECRET_LENGTH]; + clock_time_t cookie_secret_age; /**< the time the secret has been generated */ + +#ifndef WITH_CONTIKI + dtls_peer_t *peers; /**< peer hash map */ +#else /* WITH_CONTIKI */ + LIST_STRUCT(peers); + + struct etimer retransmit_timer; /**< fires when the next packet must be sent */ +#endif /* WITH_CONTIKI */ + + LIST_STRUCT(sendqueue); /**< the packets to send */ + + void *app; /**< application-specific data */ + + dtls_handler_t *h; /**< callback handlers */ + + unsigned char readbuf[DTLS_MAX_BUF]; +} dtls_context_t; + +/** + * This function initializes the tinyDTLS memory management and must + * be called first. + */ +void dtls_init(); + +/** + * Creates a new context object. The storage allocated for the new + * object must be released with dtls_free_context(). */ +dtls_context_t *dtls_new_context(void *app_data); + +/** Releases any storage that has been allocated for \p ctx. */ +void dtls_free_context(dtls_context_t *ctx); + +#define dtls_set_app_data(CTX,DATA) ((CTX)->app = (DATA)) +#define dtls_get_app_data(CTX) ((CTX)->app) + +/** Sets the callback handler object for @p ctx to @p h. */ +static inline void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) { + ctx->h = h; +} + +/** + * Establishes a DTLS channel with the specified remote peer @p dst. + * This function returns @c 0 if that channel already exists, a value + * greater than zero when a new ClientHello message was sent, and + * a value less than zero on error. + * + * @param ctx The DTLS context to use. + * @param dst The remote party to connect to. + * @return A value less than zero on error, greater or equal otherwise. + */ +int dtls_connect(dtls_context_t *ctx, const session_t *dst); + +/** + * Establishes a DTLS channel with the specified remote peer. + * This function returns @c 0 if that channel already exists, a value + * greater than zero when a new ClientHello message was sent, and + * a value less than zero on error. + * + * @param ctx The DTLS context to use. + * @param peer The peer object that describes the session. + * @return A value less than zero on error, greater or equal otherwise. + */ +int dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer); + +/** + * Closes the DTLS connection associated with @p remote. This function + * returns zero on success, and a value less than zero on error. + */ +int dtls_close(dtls_context_t *ctx, const session_t *remote); + +int dtls_renegotiate(dtls_context_t *ctx, const session_t *dst); + +/** + * Writes the application data given in @p buf to the peer specified + * by @p session. + * + * @param ctx The DTLS context to use. + * @param session The remote transport address and local interface. + * @param buf The data to write. + * @param len The actual length of @p data. + * + * @return The number of bytes written or @c -1 on error. + */ +int dtls_write(struct dtls_context_t *ctx, session_t *session, + uint8 *buf, size_t len); + +/** + * Checks sendqueue of given DTLS context object for any outstanding + * packets to be transmitted. + * + * @param context The DTLS context object to use. + * @param next If not NULL, @p next is filled with the timestamp + * of the next scheduled retransmission, or @c 0 when no packets are + * waiting. + */ +void dtls_check_retransmit(dtls_context_t *context, clock_time_t *next); + +#define DTLS_COOKIE_LENGTH 16 + +#define DTLS_CT_CHANGE_CIPHER_SPEC 20 +#define DTLS_CT_ALERT 21 +#define DTLS_CT_HANDSHAKE 22 +#define DTLS_CT_APPLICATION_DATA 23 + +/** Generic header structure of the DTLS record layer. */ +typedef struct __attribute__((__packed__)) { + uint8 content_type; /**< content type of the included message */ + uint16 version; /**< Protocol version */ + uint16 epoch; /**< counter for cipher state changes */ + uint48 sequence_number; /**< sequence number */ + uint16 length; /**< length of the following fragment */ + /* fragment */ +} dtls_record_header_t; + +/* Handshake types */ + +#define DTLS_HT_HELLO_REQUEST 0 +#define DTLS_HT_CLIENT_HELLO 1 +#define DTLS_HT_SERVER_HELLO 2 +#define DTLS_HT_HELLO_VERIFY_REQUEST 3 +#define DTLS_HT_CERTIFICATE 11 +#define DTLS_HT_SERVER_KEY_EXCHANGE 12 +#define DTLS_HT_CERTIFICATE_REQUEST 13 +#define DTLS_HT_SERVER_HELLO_DONE 14 +#define DTLS_HT_CERTIFICATE_VERIFY 15 +#define DTLS_HT_CLIENT_KEY_EXCHANGE 16 +#define DTLS_HT_FINISHED 20 + +/** Header structure for the DTLS handshake protocol. */ +typedef struct __attribute__((__packed__)) { + uint8 msg_type; /**< Type of handshake message (one of DTLS_HT_) */ + uint24 length; /**< length of this message */ + uint16 message_seq; /**< Message sequence number */ + uint24 fragment_offset; /**< Fragment offset. */ + uint24 fragment_length; /**< Fragment length. */ + /* body */ +} dtls_handshake_header_t; + +/** Structure of the Client Hello message. */ +typedef struct __attribute__((__packed__)) { + uint16 version; /**< Client version */ + uint32 gmt_random; /**< GMT time of the random byte creation */ + unsigned char random[28]; /**< Client random bytes */ + /* session id (up to 32 bytes) */ + /* cookie (up to 32 bytes) */ + /* cipher suite (2 to 2^16 -1 bytes) */ + /* compression method */ +} dtls_client_hello_t; + +/** Structure of the Hello Verify Request. */ +typedef struct __attribute__((__packed__)) { + uint16 version; /**< Server version */ + uint8 cookie_length; /**< Length of the included cookie */ + uint8 cookie[]; /**< up to 32 bytes making up the cookie */ +} dtls_hello_verify_t; + +#if 0 +/** + * Checks a received DTLS record for consistency and eventually decrypt, + * verify, decompress and reassemble the contained fragment for + * delivery to high-lever clients. + * + * \param state The DTLS record state for the current session. + * \param + */ +int dtls_record_read(dtls_state_t *state, uint8 *msg, int msglen); +#endif + +/** + * Handles incoming data as DTLS message from given peer. + * + * @param ctx The dtls context to use. + * @param session The current session + * @param msg The received data + * @param msglen The actual length of @p msg. + * @return A value less than zero on error, zero on success. + */ +int dtls_handle_message(dtls_context_t *ctx, session_t *session, + uint8 *msg, int msglen); + +/** + * Check if @p session is associated with a peer object in @p context. + * This function returns a pointer to the peer if found, NULL otherwise. + * + * @param context The DTLS context to search. + * @param session The remote address and local interface + * @return A pointer to the peer associated with @p session or NULL if + * none exists. + */ +dtls_peer_t *dtls_get_peer(const dtls_context_t *context, + const session_t *session); + + +#endif /* _DTLS_DTLS_H_ */ + +/** + * @mainpage + * + * @author Olaf Bergmann, TZI Uni Bremen + * + * This library provides a very simple datagram server with DTLS + * support. It is designed to support session multiplexing in + * single-threaded applications and thus targets specifically on + * embedded systems. + * + * @section license License + * + * This software is under the MIT License. + * + * @subsection uthash UTHash + * + * This library uses uthash to manage + * its peers (not used for Contiki). @b uthash uses the BSD revised license, see + * http://uthash.sourceforge.net/license.html. + * + * @subsection sha256 Aaron D. Gifford's SHA256 Implementation + * + * tinyDTLS provides HMAC-SHA256 with BSD-licensed code from Aaron D. Gifford, + * see www.aarongifford.com. + * + * @subsection aes Rijndael Implementation From OpenBSD + * + * The AES implementation is taken from rijndael.{c,h} contained in the crypto + * sub-system of the OpenBSD operating system. It is copyright by Vincent Rijmen, * + * Antoon Bosselaers and Paulo Barreto. See rijndael.c + * for License info. + * + * @section download Getting the Files + * + * You can get the sources either from the downloads section or + * through git from the project develop page. + * + * @section config Configuration + * + * Use @c configure to set up everything for a successful build. For Contiki, use the + * option @c --with-contiki. + * + * @section build Building + * + * After configuration, just type + * @code +make + * @endcode + * optionally followed by + * @code +make install + * @endcode + * The Contiki version is integrated with the Contiki build system, hence you do not + * need to invoke @c make explicitely. Just add @c tinydtls to the variable @c APPS + * in your @c Makefile. + * + * @addtogroup dtls_usage DTLS Usage + * + * @section dtls_server_example DTLS Server Example + * + * This section shows how to use the DTLS library functions to setup a + * simple secure UDP echo server. The application is responsible for the + * entire network communication and thus will look like a usual UDP + * server with socket creation and binding and a typical select-loop as + * shown below. The minimum configuration required for DTLS is the + * creation of the dtls_context_t using dtls_new_context(), and a callback + * for sending data. Received packets are read by the application and + * passed to dtls_handle_message() as shown in @ref dtls_read_cb. + * For any useful communication to happen, read and write call backs + * and a key management function should be registered as well. + * + * @code + dtls_context_t *the_context = NULL; + int fd, result; + + static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, + .get_psk_key = get_psk_key + }; + + fd = socket(...); + if (fd < 0 || bind(fd, ...) < 0) + exit(-1); + + the_context = dtls_new_context(&fd); + dtls_set_handler(the_context, &cb); + + while (1) { + ...initialize fd_set rfds and timeout ... + result = select(fd+1, &rfds, NULL, 0, NULL); + + if (FD_ISSET(fd, &rfds)) + dtls_handle_read(the_context); + } + + dtls_free_context(the_context); + * @endcode + * + * @subsection dtls_read_cb The Read Callback + * + * The DTLS library expects received raw data to be passed to + * dtls_handle_message(). The application is responsible for + * filling a session_t structure with the address data of the + * remote peer as illustrated by the following example: + * + * @code +int dtls_handle_read(struct dtls_context_t *ctx) { + int *fd; + session_t session; + static uint8 buf[DTLS_MAX_BUF]; + int len; + + fd = dtls_get_app_data(ctx); + + assert(fd); + + session.size = sizeof(session.addr); + len = recvfrom(*fd, buf, sizeof(buf), 0, &session.addr.sa, &session.size); + + return len < 0 ? len : dtls_handle_message(ctx, &session, buf, len); +} + * @endcode + * + * Once a new DTLS session was established and DTLS ApplicationData has been + * received, the DTLS server invokes the read callback with the MAC-verified + * cleartext data as its argument. A read callback for a simple echo server + * could look like this: + * @code +int read_from_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { + return dtls_write(ctx, session, data, len); +} + * @endcode + * + * @subsection dtls_send_cb The Send Callback + * + * The callback function send_to_peer() is called whenever data must be + * sent over the network. Here, the sendto() system call is used to + * transmit data within the given session. The socket descriptor required + * by sendto() has been registered as application data when the DTLS context + * was created with dtls_new_context(). + * Note that it is on the application to buffer the data when it cannot be + * sent at the time this callback is invoked. The following example thus + * is incomplete as it would have to deal with EAGAIN somehow. + * @code +int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { + int fd = *(int *)dtls_get_app_data(ctx); + return sendto(fd, data, len, MSG_DONTWAIT, &session->addr.sa, session->size); +} + * @endcode + * + * @subsection dtls_get_psk_info The Key Storage + * + * When a new DTLS session is created, the library must ask the application + * for keying material. To do so, it invokes the registered call-back function + * get_psk_info() with the current context and session information as parameter. + * When the call-back function is invoked with the parameter @p type set to + * @c DTLS_PSK_IDENTITY, the result parameter @p result must be filled with + * the psk_identity_hint in case of a server, or the actual psk_identity in + * case of a client. When @p type is @c DTLS_PSK_KEY, the result parameter + * must be filled with a key for the given identity @p id. The function must + * return the number of bytes written to @p result which must not exceed + * @p result_length. + * In case of an error, the function must return a negative value that + * corresponds to a valid error code defined in alert.h. + * + * @code +int get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, + const session_t *session UNUSED_PARAM, + dtls_credentials_type_t type, + const unsigned char *id, size_t id_len, + unsigned char *result, size_t result_length) { + + switch (type) { + case DTLS_PSK_IDENTITY: + if (result_length < psk_id_length) { + dtls_warn("cannot set psk_identity -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_id, psk_id_length); + return psk_id_length; + case DTLS_PSK_KEY: + if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { + dtls_warn("PSK for unknown id requested, exiting\n"); + return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); + } else if (result_length < psk_key_length) { + dtls_warn("cannot set psk -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_key, psk_key_length); + return psk_key_length; + default: + dtls_warn("unsupported request type: %d\n", type); + } + + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); +} + * @endcode + * + * @subsection dtls_events The Event Notifier + * + * Applications that want to be notified whenever the status of a DTLS session + * has changed can register an event handling function with the field @c event + * in the dtls_handler_t structure (see \ref dtls_server_example). The call-back + * function is called for alert messages and internal state changes. For alert + * messages, the argument @p level will be set to a value greater than zero, and + * @p code will indicate the notification code. For internal events, @p level + * is @c 0, and @p code a value greater than @c 255. + * + * Internal events are DTLS_EVENT_CONNECTED, @c DTLS_EVENT_CONNECT, and + * @c DTLS_EVENT_RENEGOTIATE. + * + * @code +int handle_event(struct dtls_context_t *ctx, session_t *session, + dtls_alert_level_t level, unsigned short code) { + ... do something with event ... + return 0; +} + * @endcode + * + * @section dtls_client_example DTLS Client Example + * + * A DTLS client is constructed like a server but needs to actively setup + * a new session by calling dtls_connect() at some point. As this function + * usually returns before the new DTLS channel is established, the application + * must register an event handler and wait for @c DTLS_EVENT_CONNECT before + * it can send data over the DTLS channel. + * + */ + +/** + * @addtogroup contiki Contiki + * + * To use tinyDTLS as Contiki application, place the source code in the directory + * @c apps/tinydtls in the Contiki source tree and invoke configure with the option + * @c --with-contiki. This will define WITH_CONTIKI in tinydtls.h and include + * @c Makefile.contiki in the main Makefile. To cross-compile for another platform + * you will need to set your host and build system accordingly. For example, + * when configuring for ARM, you would invoke + * @code +./configure --with-contiki --build=x86_64-linux-gnu --host=arm-none-eabi + * @endcode + * on an x86_64 linux host. + * + * Then, create a Contiki project with @c APPS += tinydtls in its Makefile. A sample + * server could look like this (with read_from_peer() and get_psk_key() as shown above). + * + * @code +#include "contiki.h" + +#include "tinydtls.h" +#include "dtls.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) + +int send_to_peer(struct dtls_context_t *, session_t *, uint8 *, size_t); + +static struct uip_udp_conn *server_conn; +static dtls_context_t *dtls_context; + +static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, + .get_psk_key = get_psk_key +}; + +PROCESS(server_process, "DTLS server process"); +AUTOSTART_PROCESSES(&server_process); + +PROCESS_THREAD(server_process, ev, data) +{ + PROCESS_BEGIN(); + + dtls_init(); + + server_conn = udp_new(NULL, 0, NULL); + udp_bind(server_conn, UIP_HTONS(5684)); + + dtls_context = dtls_new_context(server_conn); + if (!dtls_context) { + dtls_emerg("cannot create context\n"); + PROCESS_EXIT(); + } + + dtls_set_handler(dtls_context, &cb); + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == tcpip_event && uip_newdata()) { + session_t session; + + uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); + session.port = UIP_UDP_BUF->srcport; + session.size = sizeof(session.addr) + sizeof(session.port); + + dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); + } + } + + PROCESS_END(); +} + +int send_to_peer(struct dtls_context_t *ctx, session_t *session, uint8 *data, size_t len) { + struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); + + uip_ipaddr_copy(&conn->ripaddr, &session->addr); + conn->rport = session->port; + + uip_udp_packet_send(conn, data, len); + + memset(&conn->ripaddr, 0, sizeof(server_conn->ripaddr)); + memset(&conn->rport, 0, sizeof(conn->rport)); + + return len; +} + * @endcode + */ diff --git a/extlibs/tinydtls/dtls_config.h b/extlibs/tinydtls/dtls_config.h new file mode 100644 index 0000000..39df8c9 --- /dev/null +++ b/extlibs/tinydtls/dtls_config.h @@ -0,0 +1,171 @@ +/* dtls_config.h. Generated from dtls_config.h.in by configure. */ +/* tinydtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file dtls_config.h + * @brief internal configuration for tinydtls library + * + * This file has been generated by configure from dtls_config.h.in. + */ + +/* dummy definitions for PACKAGE_NAME and PACKAGE_VERSION */ +#define PACKAGE_NAME "tinydtls" +#define PACKAGE_STRING "tinydtls 0.8.1" +#define PACKAGE_VERSION "0.8.1" + +#ifdef CONTIKI +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include "contiki-conf.h" + +/* global constants for constrained devices running Contiki */ +#ifndef DTLS_PEER_MAX +/** The maximum number DTLS peers (i.e. sessions). */ +# define DTLS_PEER_MAX 1 +#endif + +#ifndef DTLS_HANDSHAKE_MAX +/** The maximum number of concurrent DTLS handshakes. */ +# define DTLS_HANDSHAKE_MAX 1 +#endif + +#ifndef DTLS_SECURITY_MAX +/** The maximum number of concurrently used cipher keys */ +# define DTLS_SECURITY_MAX (DTLS_PEER_MAX + DTLS_HANDSHAKE_MAX) +#endif + +#ifndef DTLS_HASH_MAX +/** The maximum number of hash functions that can be used in parallel. */ +# define DTLS_HASH_MAX (3 * DTLS_PEER_MAX) +#endif +#endif /* CONTIKI */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strnlen' function. */ +#define HAVE_STRNLEN 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "tinydtls" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "tinydtls 0.8.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "tinydtls" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.8.1" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +/* #undef malloc */ +/* Define to `unsigned int' if does not define. */ + +/* #undef size_t */ + +/************************************************************************/ +/* Specific Contiki platforms */ +/************************************************************************/ + +#ifdef CONTIKI + +#if CONTIKI_TARGET_ECONOTAG +# include "platform-specific/config-econotag.h" +#endif /* CONTIKI_TARGET_ECONOTAG */ + +#ifdef CONTIKI_TARGET_CC2538DK +# include "platform-specific/config-cc2538dk.h" +#endif /* CONTIKI_TARGET_CC2538DK */ + +#ifdef CONTIKI_TARGET_WISMOTE +# include "platform-specific/config-wismote.h" +#endif /* CONTIKI_TARGET_WISMOTE */ + +#ifdef CONTIKI_TARGET_SKY +# include "platform-specific/config-sky.h" +#endif /* CONTIKI_TARGET_SKY */ + +#ifdef CONTIKI_TARGET_MINIMAL_NET +# include "platform-specific/config-minimal-net.h" +#endif /* CONTIKI_TARGET_MINIMAL_NET */ + +#endif /* CONTIKI */ diff --git a/extlibs/tinydtls/dtls_config.h.in b/extlibs/tinydtls/dtls_config.h.in new file mode 100644 index 0000000..a29077c --- /dev/null +++ b/extlibs/tinydtls/dtls_config.h.in @@ -0,0 +1,218 @@ +/* tinydtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file dtls_config.h + * @brief internal configuration for tinydtls library + * + * This file has been generated by configure from dtls_config.h.in. + */ + +/* dummy definitions for PACKAGE_NAME and PACKAGE_VERSION */ +#define PACKAGE_NAME "tinydtls" +#define PACKAGE_STRING PACKAGE_NAME +#define PACKAGE_VERSION PACKAGE_VERSION + +#ifdef CONTIKI +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include "contiki-conf.h" + +/* global constants for constrained devices running Contiki */ +#ifndef DTLS_PEER_MAX +/** The maximum number DTLS peers (i.e. sessions). */ +# define DTLS_PEER_MAX 1 +#endif + +#ifndef DTLS_HANDSHAKE_MAX +/** The maximum number of concurrent DTLS handshakes. */ +# define DTLS_HANDSHAKE_MAX 1 +#endif + +#ifndef DTLS_SECURITY_MAX +/** The maximum number of concurrently used cipher keys */ +# define DTLS_SECURITY_MAX (DTLS_PEER_MAX + DTLS_HANDSHAKE_MAX) +#endif + +#ifndef DTLS_HASH_MAX +/** The maximum number of hash functions that can be used in parallel. */ +# define DTLS_HASH_MAX (3 * DTLS_PEER_MAX) +#endif +#endif /* CONTIKI */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fls' function. */ +#undef HAVE_FLS + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if struct sockaddr_in6 has a member sin6_len. */ +#undef HAVE_SOCKADDR_IN6_SIN6_LEN + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strnlen' function. */ +#undef HAVE_STRNLEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc +/* Define to `unsigned int' if does not define. */ + +#undef size_t + +/************************************************************************/ +/* Specific Contiki platforms */ +/************************************************************************/ + +#ifdef CONTIKI + +#if CONTIKI_TARGET_ECONOTAG +# include "platform-specific/config-econotag.h" +#endif /* CONTIKI_TARGET_ECONOTAG */ + +#ifdef CONTIKI_TARGET_CC2538DK +# include "platform-specific/config-cc2538dk.h" +#endif /* CONTIKI_TARGET_CC2538DK */ + +#ifdef CONTIKI_TARGET_WISMOTE +# include "platform-specific/config-wismote.h" +#endif /* CONTIKI_TARGET_WISMOTE */ + +#ifdef CONTIKI_TARGET_SKY +# include "platform-specific/config-sky.h" +#endif /* CONTIKI_TARGET_SKY */ + +#ifdef CONTIKI_TARGET_MINIMAL_NET +# include "platform-specific/config-minimal-net.h" +#endif /* CONTIKI_TARGET_MINIMAL_NET */ + +#endif /* CONTIKI */ diff --git a/extlibs/tinydtls/dtls_time.c b/extlibs/tinydtls/dtls_time.c new file mode 100644 index 0000000..88c292a --- /dev/null +++ b/extlibs/tinydtls/dtls_time.c @@ -0,0 +1,80 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file dtls_time.c + * @brief Clock Handling + */ + +#include "tinydtls.h" +#include "dtls_config.h" +#include "dtls_time.h" + +#ifdef WITH_CONTIKI +clock_time_t dtls_clock_offset; + +void +dtls_clock_init(void) { + clock_init(); + dtls_clock_offset = clock_time(); +} + +void +dtls_ticks(dtls_tick_t *t) { + *t = clock_time(); +} + +#else /* WITH_CONTIKI */ + +time_t dtls_clock_offset; + +void +dtls_clock_init(void) { +#ifdef HAVE_TIME_H + dtls_clock_offset = time(NULL); +#else +# ifdef __GNUC__ + /* Issue a warning when using gcc. Other prepropressors do + * not seem to have a similar feature. */ +# warning "cannot initialize clock" +# endif + dtls_clock_offset = 0; +#endif +} + +void dtls_ticks(dtls_tick_t *t) { +#ifdef HAVE_SYS_TIME_H + struct timeval tv; + gettimeofday(&tv, NULL); + *t = (tv.tv_sec - dtls_clock_offset) * DTLS_TICKS_PER_SECOND + + (tv.tv_usec * DTLS_TICKS_PER_SECOND / 1000000); +#else +#error "clock not implemented" +#endif +} + +#endif /* WITH_CONTIKI */ + + diff --git a/extlibs/tinydtls/dtls_time.h b/extlibs/tinydtls/dtls_time.h new file mode 100644 index 0000000..82ff062 --- /dev/null +++ b/extlibs/tinydtls/dtls_time.h @@ -0,0 +1,69 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file dtls_time.h + * @brief Clock Handling + */ + +#ifndef _DTLS_DTLS_TIME_H_ +#define _DTLS_DTLS_TIME_H_ + +#include +#include + +#include "tinydtls.h" + +/** + * @defgroup clock Clock Handling + * Default implementation of internal clock. You should redefine this if + * you do not have time() and gettimeofday(). + * @{ + */ + +#ifdef WITH_CONTIKI +#include "clock.h" +#else /* WITH_CONTIKI */ +#include + +#ifndef CLOCK_SECOND +# define CLOCK_SECOND 1000 +#endif + +typedef uint32_t clock_time_t; +#endif /* WITH_CONTIKI */ + +typedef clock_time_t dtls_tick_t; + +#ifndef DTLS_TICKS_PER_SECOND +#define DTLS_TICKS_PER_SECOND CLOCK_SECOND +#endif /* DTLS_TICKS_PER_SECOND */ + +void dtls_clock_init(void); +void dtls_ticks(dtls_tick_t *t); + +/** @} */ + +#endif /* _DTLS_DTLS_TIME_H_ */ diff --git a/extlibs/tinydtls/ecc/LICENSE.txt b/extlibs/tinydtls/ecc/LICENSE.txt new file mode 100644 index 0000000..ab099ae --- /dev/null +++ b/extlibs/tinydtls/ecc/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2014, Kenneth MacKay +All rights reserved. + +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. + +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 HOLDER 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. diff --git a/extlibs/tinydtls/ecc/Makefile.contiki b/extlibs/tinydtls/ecc/Makefile.contiki new file mode 100644 index 0000000..7787d2d --- /dev/null +++ b/extlibs/tinydtls/ecc/Makefile.contiki @@ -0,0 +1,7 @@ +CONTIKI=../../.. + +APPS += ecc + +CFLAGS += -DTEST_INCLUDE + +include $(CONTIKI)/Makefile.include diff --git a/extlibs/tinydtls/ecc/Makefile.ecc b/extlibs/tinydtls/ecc/Makefile.ecc new file mode 100644 index 0000000..382e48f --- /dev/null +++ b/extlibs/tinydtls/ecc/Makefile.ecc @@ -0,0 +1,3 @@ +# This is a -*- Makefile -*- + +ecc_src = ecc.c test_helper.c diff --git a/extlibs/tinydtls/ecc/Makefile.in b/extlibs/tinydtls/ecc/Makefile.in new file mode 100644 index 0000000..2a38603 --- /dev/null +++ b/extlibs/tinydtls/ecc/Makefile.in @@ -0,0 +1,93 @@ +# Makefile for tinydtls +# +# Copyright (C) 2011 Olaf Bergmann +# Copyright (C) 2013 Hauke Mehrtens +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_srcdir:= @top_srcdir@ + + +ECC_SOURCES:= ecc.c test/test_ecdh.c test/test_ecdsa.c +ECC_HEADERS:= ecc.h +FILES:=Makefile.in Makefile.contiki $(ECC_SOURCES) $(ECC_HEADERS) +DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ + +ifeq ("@WITH_CONTIKI@", "1") +include Makefile.contiki +else +ECC_OBJECTS:= $(patsubst %.c, %.o, $(ECC_SOURCES)) ecc_test.o +PROGRAMS:= test_ecdh test_ecdsa +CPPFLAGS=@CPPFLAGS@ +CFLAGS=-Wall -std=c99 @CFLAGS@ -DTEST_INCLUDE +LDLIBS=@LIBS@ + +.PHONY: all dirs clean install distclean .gitignore doc + +.SUFFIXES: +.SUFFIXES: .c .o + +all: $(PROGRAMS) + +ecc_test.o: ecc.c ecc.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + +test_ecdh: ecc.c test/test_ecdh.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o test_ecdh ecc.c test/test_ecdh.c + +test_ecdsa:ecc.c test/test_ecdsa.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o test_ecdsa ecc.c test/test_ecdsa.c + +check: + echo DISTDIR: $(DISTDIR) + echo top_builddir: $(top_builddir) + +clean: + @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean ; \ + done + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ $(DISTDIR).tar.gz +endif # WITH_CONTIKI + +dist: $(FILES) + test -d $(DISTDIR)/ecc || mkdir $(DISTDIR)/ecc + cp -p $(FILES) $(DISTDIR)/ecc + +install: $(HEADERS) + test -d $(includedir)/ecc || mkdir -p $(includedir)/ecc + $(install) $(HEADERS) $(includedir)/ecc + +.gitignore: + echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/extlibs/tinydtls/ecc/README.md b/extlibs/tinydtls/ecc/README.md new file mode 100644 index 0000000..24f1231 --- /dev/null +++ b/extlibs/tinydtls/ecc/README.md @@ -0,0 +1,208 @@ +micro-ecc +========== + +A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors. + +The old version of micro-ecc can be found in the "old" branch. + +Features +-------- + + * Resistant to known side-channel attacks. + * Written in C, with optional GCC inline assembly for AVR, ARM and Thumb platforms. + * Supports 8, 32, and 64-bit architectures. + * Small code size. + * No dynamic memory allocation. + * Support for 4 standard curves: secp160r1, secp192r1, secp256r1, and secp256k1. + * BSD 2-clause license. + +Usage Notes +----------- +### Point Representation ### +Compressed points are represented in the standard format as defined in http://www.secg.org/collateral/sec1_final.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. `uECC_make_key()`, `uECC_shared_secret()`, `uECC_sign()`, and `uECC_verify()` only handle uncompressed points; you can use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations. + +Private keys are represented in the standard format. + +### Using the Code ### + +I recommend just copying (or symlink) uECC.h, uECC.c, and the appropriate asm\_<arch>\_.inc (if any) into your project. Then just `#include "uECC.h"` to use the micro-ecc functions. + +For use with Arduino, you can just create a symlink to the `uECC` directory in your Arduino `libraries` directory. You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu). + +See uECC.h for documentation for each function. + +### Compilation Notes ### + + * Should compile with any C/C++ compiler that supports stdint.h (this includes Visual Studio 2013). + * If you want to change the defaults for `uECC_CURVE` and `uECC_ASM`, you must change them in your Makefile or similar so that uECC.c is compiled with the desired values (ie, compile uECC.c with `-DuECC_CURVE=uECC_secp256r1` or whatever). + * When compiling for a Thumb-1 platform with inline assembly enabled (ie, `uECC_ASM` is defined to `uECC_asm_small` or `uECC_asm_fast`), you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for an ARM/Thumb-2 platform with fast inline assembly enabled (ie, `uECC_ASM` is defined to `uECC_asm_fast`), you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for AVR with inline assembly enabled, you must have optimizations enabled (compile with `-O1` or higher). + * When building for Windows, you will need to link in the `advapi32.lib` system library. + +ARM Performance +--------------- + +All tests were built using gcc 4.8.2 with `-O3`, and were run on a Raspberry Pi B+. `uECC_ASM` was defined to `uECC_asm_fast` and `ECC_SQUARE_FUNC` was defined to `1` in all cases. All times are in milliseconds. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
secp160r1secp192r1secp256r1secp256k1
ECDH:2.32.77.96.5
ECDSA sign:2.83.18.67.2
ECDSA verify:2.73.29.27.0
+ +AVR Performance +--------------- + +All tests were built using avr-gcc 4.8.1 with `-Os`, and were run on a 16 MHz ATmega256RFR2. Code size refers to the space used by micro-ecc code and data. + +#### ECDH (fast) #### + +In these tests, `uECC_ASM` was defined to `uECC_asm_fast` and `ECC_SQUARE_FUNC` was defined to `1` in all cases. + + + + + + + + + + + + + + + + + + + + + + + +
secp160r1secp192r1secp256r1secp256k1
ECDH time (ms):47081022201615
Code size (bytes):10768131122088621126
+ +#### ECDH (small) #### + +In these tests, `uECC_ASM` was defined to `uECC_asm_small` and `ECC_SQUARE_FUNC` was defined to `0` in all cases. + + + + + + + + + + + + + + + + + + + + + + + +
secp160r1secp192r1secp256r1secp256k1
ECDH time (ms):1250181047904700
Code size (bytes):3244340052743426
+ +#### ECDSA (fast) #### + +In these tests, `uECC_ASM` was defined to `uECC_asm_fast` and `ECC_SQUARE_FUNC` was defined to `1` in all cases. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
secp160r1secp192r1secp256r1secp256k1
ECDSA sign time (ms):55590223861773
ECDSA verify time (ms):59099026501800
Code size (bytes):13246147982259422826
+ +#### ECDSA (small) #### + +In these tests, `uECC_ASM` was defined to `uECC_asm_small` and `ECC_SQUARE_FUNC` was defined to `0` in all cases. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
secp160r1secp192r1secp256r1secp256k1
ECDSA sign time (ms):1359193149984904
ECDSA verify time (ms):1515216057005220
Code size (bytes):5690505469805080
diff --git a/extlibs/tinydtls/ecc/asm_arm.inc b/extlibs/tinydtls/ecc/asm_arm.inc new file mode 100755 index 0000000..f181b17 --- /dev/null +++ b/extlibs/tinydtls/ecc/asm_arm.inc @@ -0,0 +1,1905 @@ +#define DEC_5 4 +#define DEC_6 5 +#define DEC_8 7 + +#define DEC(N) uECC_CONCAT(DEC_, N) + +#define REPEAT_1(stuff) stuff +#define REPEAT_2(stuff) REPEAT_1(stuff) stuff +#define REPEAT_3(stuff) REPEAT_2(stuff) stuff +#define REPEAT_4(stuff) REPEAT_3(stuff) stuff +#define REPEAT_5(stuff) REPEAT_4(stuff) stuff +#define REPEAT_6(stuff) REPEAT_5(stuff) stuff +#define REPEAT_7(stuff) REPEAT_6(stuff) stuff +#define REPEAT_8(stuff) REPEAT_7(stuff) stuff + +#define REPEAT(N, stuff) uECC_CONCAT(REPEAT_, N)(stuff) + +#define STR2(thing) #thing +#define STR(thing) STR2(thing) + +#if (uECC_ASM == uECC_asm_fast) + +static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_carry = 0; + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "adds %[left], %[right] \n\t" /* Add first word. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + + /* Now we just do the remaining words with the carry bit (using ADC) */ + REPEAT(DEC(uECC_WORDS), "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return l_carry; +} +#define asm_add 1 + +static uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_carry = 0; + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "subs %[left], %[right] \n\t" /* Subtract. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + + /* Now we just do the remaining words with the carry bit (using SBC) */ + REPEAT(DEC(uECC_WORDS), "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return !l_carry; // note that on ARM, carry flag set means "no borrow" when subtracting (for some reason...) +} +#define asm_sub 1 + +#if (uECC_PLATFORM != uECC_arm_thumb) +#if (uECC_WORDS == 5) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 12 \n\t" + "add r2, 12 \n\t" + "ldmia r1!, {r3,r4} \n\t" + "ldmia r2!, {r6,r7} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adc r10, r14 \n\t" + "stmia r0!, {r9, r10} \n\t" + + "sub r0, 28 \n\t" + "sub r2, 20 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + "ldmia r1!, {r5} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adc r11, r9 \n\t" + "stmia r0!, {r10, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 5) */ + +#if (uECC_WORDS == 6) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 12 \n\t" + "add r2, 12 \n\t" + "ldmia r1!, {r3,r4,r5} \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adc r12, r10 \n\t" + "stmia r0!, {r11, r12} \n\t" + + "sub r0, 36 \n\t" + "sub r2, 24 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r1!, {r5} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r2!, {r8} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r3, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "mov r14, #0 \n\t" + "umull r9, r10, r4, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r5, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "umull r10, r11, r5, r8 \n\t" + "adds r12, r10 \n\t" + "adc r14, r11 \n\t" + "stmia r0!, {r12, r14} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 6) */ + +#if (uECC_WORDS == 8) +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "add r0, 24 \n\t" + "add r2, 24 \n\t" + "ldmia r1!, {r3,r4} \n\t" + "ldmia r2!, {r6,r7} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adc r10, r14 \n\t" + "stmia r0!, {r9, r10} \n\t" + + "sub r0, 28 \n\t" + "sub r2, 20 \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + "ldmia r1!, {r5} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adc r11, r9 \n\t" + "stmia r0!, {r10, r11} \n\t" + + "sub r0, 52 \n\t" + "sub r1, 20 \n\t" + "sub r2, 32 \n\t" + "ldmia r1!, {r3,r4,r5} \n\t" + "ldmia r2!, {r6,r7,r8} \n\t" + + "umull r11, r12, r3, r6 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r9, r3, r7 \n\t" + "adds r12, r11 \n\t" + "adc r9, #0 \n\t" + "umull r11, r14, r4, r6 \n\t" + "adds r12, r11 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r11, #0 \n\t" + "umull r12, r14, r3, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r5, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r4, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r5, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r1!, {r5} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r3, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r5, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r4, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r5, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r1!, {r4} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r5, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r3, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r12, #0 \n\t" + "umull r14, r9, r5, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r3, r8 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r10, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r14, #0 \n\t" + "umull r9, r10, r5, r7 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r3, r6 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "umull r9, r10, r4, r8 \n\t" + "adds r11, r9 \n\t" + "adcs r12, r10 \n\t" + "adc r14, #0 \n\t" + "ldr r9, [r0] \n\t" + "adds r11, r9 \n\t" + "adcs r12, #0 \n\t" + "adc r14, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "ldmia r2!, {r8} \n\t" + "mov r9, #0 \n\t" + "umull r10, r11, r5, r8 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r3, r7 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "umull r10, r11, r4, r6 \n\t" + "adds r12, r10 \n\t" + "adcs r14, r11 \n\t" + "adc r9, #0 \n\t" + "ldr r10, [r0] \n\t" + "adds r12, r10 \n\t" + "adcs r14, #0 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "ldmia r2!, {r6} \n\t" + "mov r10, #0 \n\t" + "umull r11, r12, r5, r6 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r8 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r4, r7 \n\t" + "adds r14, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "ldr r11, [r0] \n\t" + "adds r14, r11 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r14} \n\t" + + "ldmia r2!, {r7} \n\t" + "mov r11, #0 \n\t" + "umull r12, r14, r5, r7 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r3, r6 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "umull r12, r14, r4, r8 \n\t" + "adds r9, r12 \n\t" + "adcs r10, r14 \n\t" + "adc r11, #0 \n\t" + "ldr r12, [r0] \n\t" + "adds r9, r12 \n\t" + "adcs r10, #0 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "mov r12, #0 \n\t" + "umull r14, r9, r3, r7 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "umull r14, r9, r4, r6 \n\t" + "adds r10, r14 \n\t" + "adcs r11, r9 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r10} \n\t" + + "umull r9, r10, r4, r7 \n\t" + "adds r11, r9 \n\t" + "adc r12, r10 \n\t" + "stmia r0!, {r11, r12} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1), "+r" (r2) + : + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* (uECC_WORDS == 8) */ + +#if (uECC_WORDS == 5) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "umull r1, r14, r3, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "umull r1, r14, r3, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r4, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r3, r6 \n\t" + "umull r1, r14, r4, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r4, r6 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r5, r5 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r5, r6 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r6, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 5) */ + +#if (uECC_WORDS == 6) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "umull r1, r14, r3, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "umull r1, r14, r3, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r4, r4 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r7 \n\t" + "umull r1, r14, r3, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "umull r1, r14, r4, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r3, r7 \n\t" + "umull r1, r14, r4, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "umull r1, r14, r5, r5 \n\t" + "adds r8, r1 \n\t" + "adcs r9, r14 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r4, r7 \n\t" + "umull r1, r14, r5, r6 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r14 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r5, r7 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r6, r6 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r6, r7 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r7, r7 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 6) */ + +#if (uECC_WORDS == 8) +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "ldmia r1!, {r2, r3} \n\t" + "add r1, 16 \n\t" + "ldmia r1!, {r5, r6} \n\t" + "add r0, 24 \n\t" + + "umull r8, r9, r2, r5 \n\t" + "stmia r0!, {r8} \n\t" + + "umull r12, r10, r2, r6 \n\t" + "adds r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r9} \n\t" + + "umull r8, r9, r3, r6 \n\t" + "adds r10, r8 \n\t" + "adc r11, r9, #0 \n\t" + "stmia r0!, {r10, r11} \n\t" + + "sub r0, 40 \n\t" + "sub r1, 32 \n\t" + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" + + "umull r11, r12, r2, r2 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r9, #0 \n\t" + "umull r10, r11, r2, r3 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11, #0 \n\t" + "adc r9, #0 \n\t" + "adds r12, r10 \n\t" + "adcs r8, r11 \n\t" + "adc r9, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "mov r10, #0 \n\t" + "umull r11, r12, r2, r4 \n\t" + "adds r11, r11 \n\t" + "adcs r12, r12 \n\t" + "adc r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "umull r11, r12, r3, r3 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r5 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r3, r4 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r2, r6 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r3, r5 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r4, r4 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r2, r7 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r3, r6 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r4, r5 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "ldmia r1!, {r2} \n\t" + "mov r10, #0 \n\t" + "umull r8, r9, r3, r7 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r4, r6 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r5, r5 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r3, r2 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r4, r7 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r5, r6 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "ldmia r1!, {r3} \n\t" + "mov r10, #0 \n\t" + "umull r8, r9, r4, r2 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r5, r7 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r9, #0 \n\t" + "adc r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r6, r6 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r4, r3 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r5, r2 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r6, r7 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "ldr r14, [r0] \n\t" + "adds r8, r14 \n\t" + "adcs r11, #0 \n\t" + "adc r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r10, #0 \n\t" + "umull r8, r9, r5, r3 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r6, r2 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r9, r9 \n\t" + "adc r10, r10 \n\t" + "mov r14, r9 \n\t" + "umlal r8, r9, r7, r7 \n\t" + "cmp r14, r9 \n\t" + "it hi \n\t" + "adchi r10, #0 \n\t" + "adds r8, r11 \n\t" + "adcs r9, r12 \n\t" + "adc r10, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r12, #0 \n\t" + "umull r8, r11, r6, r3 \n\t" + "mov r14, r11 \n\t" + "umlal r8, r11, r7, r2 \n\t" + "cmp r14, r11 \n\t" + "it hi \n\t" + "adchi r12, #0 \n\t" + "adds r8, r8 \n\t" + "adcs r11, r11 \n\t" + "adc r12, r12 \n\t" + "adds r8, r9 \n\t" + "adcs r11, r10 \n\t" + "adc r12, #0 \n\t" + "stmia r0!, {r8} \n\t" + + "mov r8, #0 \n\t" + "umull r1, r10, r7, r3 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r8, #0 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "umull r1, r10, r2, r2 \n\t" + "adds r11, r1 \n\t" + "adcs r12, r10 \n\t" + "adc r8, #0 \n\t" + "stmia r0!, {r11} \n\t" + + "mov r11, #0 \n\t" + "umull r1, r10, r2, r3 \n\t" + "adds r1, r1 \n\t" + "adcs r10, r10 \n\t" + "adc r11, #0 \n\t" + "adds r12, r1 \n\t" + "adcs r8, r10 \n\t" + "adc r11, #0 \n\t" + "stmia r0!, {r12} \n\t" + + "umull r1, r10, r3, r3 \n\t" + "adds r8, r1 \n\t" + "adcs r11, r10 \n\t" + "stmia r0!, {r8, r11} \n\t" + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : "+r" (r0), "+r" (r1) + : + : "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* (uECC_WORDS == 8) */ + +#endif /* (uECC_PLATFORM != uECC_arm_thumb) */ + +#endif /* (uECC_ASM == uECC_asm_fast) */ + +#if !asm_add +static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_counter = uECC_WORDS; + uint32_t l_carry = 0; /* carry = 0 initially */ + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (l_carry = 0 after this). */ + "adcs %[left], %[right] \n\t" /* Add with carry. */ + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement index. */ + "bne 1b \n\t" /* Loop until index == 0. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [ctr] "+l" (l_counter), [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [ctr] "+r" (l_counter), [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return l_carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +static uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ + uint32_t l_counter = uECC_WORDS; + uint32_t l_carry = 1; /* carry = 1 initially (means don't borrow) */ + uint32_t l_left; + uint32_t l_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (l_carry = 0 after this). */ + "sbcs %[left], %[right] \n\t" /* Subtract with borrow. */ + "adcs %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement index. */ + "bne 1b \n\t" /* Loop until index == 0. */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + #if (uECC_PLATFORM == uECC_arm_thumb) + : [dptr] "+l" (p_result), [lptr] "+l" (p_left), [rptr] "+l" (p_right), + [ctr] "+l" (l_counter), [carry] "+l" (l_carry), [left] "=l" (l_left), [right] "=l" (l_right) + #else + : [dptr] "+r" (p_result), [lptr] "+r" (p_left), [rptr] "+r" (p_right), + [ctr] "+r" (l_counter), [carry] "+r" (l_carry), [left] "=r" (l_left), [right] "=r" (l_right) + #endif + : + : "cc", "memory" + ); + return !l_carry; +} +#define asm_sub 1 +#endif + +#if !asm_mult +static void vli_mult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right) +{ +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < uECC_WORDS) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= uECC_WORDS) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[eccdm1] \n\t" /* i = k - (uECC_WORDS - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[t0], %[k], %[i] \n\t" /* t0 = k-i */ + + "ldr %[t1], [%[right], %[t0]] \n\t" /* t1 = p_right[k-i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = p_left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = p_left[i] * p_right[k-i] */ + + "adds %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[eccd] \n\t" /* i < uECC_WORDS (times 4)? */ + "bge 4f \n\t" /* if not, exit the loop */ + "cmp %[i], %[k] \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* p_result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ + "blt 1b \n\t" /* if not, loop back, start with i = 0 */ + "cmp %[k], %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ + "blt 2b \n\t" /* if not, loop back, start with i = (k+1) - uECC_WORDS */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* p_result[uECC_WORDS * 2 - 1] = c0 */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), [k] "+r" (k), [i] "=&r" (i), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (p_result), [left] "r" (p_left), [right] "r" (p_right), + [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) + : "cc", "memory" + ); + +#else /* Thumb-1 */ + + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + register uint32_t *r2 __asm__("r2") = p_right; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs r3, #0 \n\t" /* c0 = 0 */ + "movs r4, #0 \n\t" /* c1 = 0 */ + "movs r5, #0 \n\t" /* c2 = 0 */ + "movs r6, #0 \n\t" /* k = 0 */ + + "push {r0} \n\t" /* keep p_result on the stack */ + + "1: \n\t" /* outer loop (k < uECC_WORDS) */ + "movs r7, #0 \n\t" /* r7 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= uECC_WORDS) */ + "movs r7, r6 \n\t" /* r7 = k */ + "subs r7, %[eccdm1] \n\t" /* r7 = i = k - (uECC_WORDS - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "push {r3, r4, r5, r6} \n\t" /* push things, r3 (c0) is at the top of stack. */ + "subs r0, r6, r7 \n\t" /* r0 = k-i */ + + "ldr r4, [r2, r0] \n\t" /* r4 = p_right[k-i] */ + "ldr r0, [r1, r7] \n\t" /* r0 = p_left[i] */ + + "lsrs r3, r0, #16 \n\t" /* r3 = a1 */ + "uxth r0, r0 \n\t" /* r0 = a0 */ + + "lsrs r5, r4, #16 \n\t" /* r5 = b1 */ + "uxth r4, r4 \n\t" /* r4 = b0 */ + + "movs r6, r3 \n\t" /* r6 = a1 */ + "muls r6, r5, r6 \n\t" /* r6 = a1*b1 */ + "muls r3, r4, r3 \n\t" /* r3 = b0*a1 */ + "muls r5, r0, r5 \n\t" /* r5 = a0*b1 */ + "muls r0, r4, r0 \n\t" /* r0 = a0*b0 */ + + "movs r4, #0 \n\t" /* r4 = 0 */ + "adds r3, r5 \n\t" /* r3 = b0*a1 + a0*b1 */ + "adcs r4, r4 \n\t" /* r4 = carry */ + "lsls r4, #16 \n\t" /* r4 = carry << 16 */ + "adds r6, r4 \n\t" /* r6 = a1*b1 + carry */ + + "lsls r4, r3, #16 \n\t" /* r4 = (b0*a1 + a0*b1) << 16 */ + "lsrs r3, #16 \n\t" /* r3 = (b0*a1 + a0*b1) >> 16 */ + "adds r0, r4 \n\t" /* r0 = low word = a0*b0 + ((b0*a1 + a0*b1) << 16) */ + "adcs r6, r3 \n\t" /* r6 = high word = a1*b1 + carry + ((b0*a1 + a0*b1) >> 16) */ + + "pop {r3, r4, r5} \n\t" /* r3 = c0, r4 = c1, r5 = c2 */ + "adds r3, r0 \n\t" /* add low word to c0 */ + "adcs r4, r6 \n\t" /* add high word to c1, including carry */ + "movs r0, #0 \n\t" /* r0 = 0 (does not affect carry bit) */ + "adcs r5, r0 \n\t" /* add carry to c2 */ + + "pop {r6} \n\t" /* r6 = k */ + + "adds r7, #4 \n\t" /* i += 4 */ + "cmp r7, %[eccd] \n\t" /* i < uECC_WORDS (times 4)? */ + "bge 4f \n\t" /* if not, exit the loop */ + "cmp r7, r6 \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "ldr r0, [sp, #0] \n\t" /* r0 = p_result */ + + "str r3, [r0, r6] \n\t" /* p_result[k] = c0 */ + "mov r3, r4 \n\t" /* c0 = c1 */ + "mov r4, r5 \n\t" /* c1 = c2 */ + "movs r5, #0 \n\t" /* c2 = 0 */ + "adds r6, #4 \n\t" /* k += 4 */ + "cmp r6, %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ + "blt 1b \n\t" /* if not, loop back, start with i = 0 */ + "cmp r6, %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ + "blt 2b \n\t" /* if not, loop back, start with i = (k+1) - uECC_WORDS */ + /* end outer loop */ + + "str r3, [r0, r6] \n\t" /* p_result[uECC_WORDS * 2 - 1] = c0 */ + "pop {r0} \n\t" /* pop p_result off the stack */ + + ".syntax divided \n\t" + : + : [r0] "l" (r0), [r1] "l" (r1), [r2] "l" (r2), [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) + : "r3", "r4", "r5", "r6", "r7", "cc", "memory" + ); +#endif +} +#define asm_mult 1 +#endif /* !asm_mult */ + +#if uECC_SQUARE_FUNC +#if !asm_square +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i, tt; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < uECC_WORDS) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= uECC_WORDS) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[eccdm1] \n\t" /* i = k - (uECC_WORDS - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k-i */ + + "ldr %[t1], [%[left], %[tt]] \n\t" /* t1 = p_left[k-i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = p_left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = p_left[i] * p_right[k-i] */ + + "cmp %[i], %[tt] \n\t" /* (i < k-i) ? */ + "bge 4f \n\t" /* if i >= k-i, skip */ + "lsls %[t1], #1 \n\t" /* high word << 1 */ + "adc %[c2], #0 \n\t" /* add carry bit to c2 */ + "lsls %[t0], #1 \n\t" /* low word << 1 */ + "adc %[t1], #0 \n\t" /* add carry bit to high word */ + + "4: \n\t" + + "adds %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adc %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[k] \n\t" /* i <= k? */ + "bge 5f \n\t" /* if not, exit the loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k-i */ + "cmp %[i], %[tt] \n\t" /* i <= k-i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* p_result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ + "blt 1b \n\t" /* if not, loop back, start with i = 0 */ + "cmp %[k], %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ + "blt 2b \n\t" /* if not, loop back, start with i = (k+1) - uECC_WORDS */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* p_result[uECC_WORDS * 2 - 1] = c0 */ + #if (uECC_PLATFORM != uECC_arm_thumb2) + ".syntax divided \n\t" + #endif + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), [k] "+r" (k), [i] "=&r" (i), [tt] "=&r" (tt), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (p_result), [left] "r" (p_left), + [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) + : "cc", "memory" + ); + +#else + + register uint32_t *r0 __asm__("r0") = p_result; + register uint32_t *r1 __asm__("r1") = p_left; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs r2, #0 \n\t" /* c0 = 0 */ + "movs r3, #0 \n\t" /* c1 = 0 */ + "movs r4, #0 \n\t" /* c2 = 0 */ + "movs r5, #0 \n\t" /* k = 0 */ + + "push {r0} \n\t" /* keep p_result on the stack */ + + "1: \n\t" /* outer loop (k < uECC_WORDS) */ + "movs r6, #0 \n\t" /* r6 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= uECC_WORDS) */ + "movs r6, r5 \n\t" /* r6 = k */ + "subs r6, %[eccdm1] \n\t" /* r6 = i = k - (uECC_WORDS - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "push {r2, r3, r4, r5} \n\t" /* push things, r2 (c0) is at the top of stack. */ + "subs r7, r5, r6 \n\t" /* r7 = k-i */ + + "ldr r3, [r1, r7] \n\t" /* r3 = p_left[k-i] */ + "ldr r0, [r1, r6] \n\t" /* r0 = p_left[i] */ + + "lsrs r2, r0, #16 \n\t" /* r2 = a1 */ + "uxth r0, r0 \n\t" /* r0 = a0 */ + + "lsrs r4, r3, #16 \n\t" /* r4 = b1 */ + "uxth r3, r3 \n\t" /* r3 = b0 */ + + "movs r5, r2 \n\t" /* r5 = a1 */ + "muls r5, r4, r5 \n\t" /* r5 = a1*b1 */ + "muls r2, r3, r2 \n\t" /* r2 = b0*a1 */ + "muls r4, r0, r4 \n\t" /* r4 = a0*b1 */ + "muls r0, r3, r0 \n\t" /* r0 = a0*b0 */ + + "movs r3, #0 \n\t" /* r3 = 0 */ + "adds r2, r4 \n\t" /* r2 = b0*a1 + a0*b1 */ + "adcs r3, r3 \n\t" /* r3 = carry */ + "lsls r3, #16 \n\t" /* r3 = carry << 16 */ + "adds r5, r3 \n\t" /* r5 = a1*b1 + carry */ + + "lsls r3, r2, #16 \n\t" /* r3 = (b0*a1 + a0*b1) << 16 */ + "lsrs r2, #16 \n\t" /* r2 = (b0*a1 + a0*b1) >> 16 */ + "adds r0, r3 \n\t" /* r0 = low word = a0*b0 + ((b0*a1 + a0*b1) << 16) */ + "adcs r5, r2 \n\t" /* r5 = high word = a1*b1 + carry + ((b0*a1 + a0*b1) >> 16) */ + + "movs r3, #0 \n\t" /* r3 = 0 */ + "cmp r6, r7 \n\t" /* (i < k-i) ? */ + "mov r7, r3 \n\t" /* r7 = 0 (does not affect condition)*/ + "bge 4f \n\t" /* if i >= k-i, skip */ + "lsls r5, #1 \n\t" /* high word << 1 */ + "adcs r7, r3 \n\t" /* r7 = carry bit for c2 */ + "lsls r0, #1 \n\t" /* low word << 1 */ + "adcs r5, r3 \n\t" /* add carry from shift to high word */ + + "4: \n\t" + "pop {r2, r3, r4} \n\t" /* r2 = c0, r3 = c1, r4 = c2 */ + "adds r2, r0 \n\t" /* add low word to c0 */ + "adcs r3, r5 \n\t" /* add high word to c1, including carry */ + "movs r0, #0 \n\t" /* r0 = 0 (does not affect carry bit) */ + "adcs r4, r0 \n\t" /* add carry to c2 */ + "adds r4, r7 \n\t" /* add carry from doubling (if any) */ + + "pop {r5} \n\t" /* r5 = k */ + + "adds r6, #4 \n\t" /* i += 4 */ + "cmp r6, r5 \n\t" /* i <= k? */ + "bge 5f \n\t" /* if not, exit the loop */ + "subs r7, r5, r6 \n\t" /* r7 = k-i */ + "cmp r6, r7 \n\t" /* i <= k-i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "ldr r0, [sp, #0] \n\t" /* r0 = p_result */ + + "str r2, [r0, r5] \n\t" /* p_result[k] = c0 */ + "mov r2, r3 \n\t" /* c0 = c1 */ + "mov r3, r4 \n\t" /* c1 = c2 */ + "movs r4, #0 \n\t" /* c2 = 0 */ + "adds r5, #4 \n\t" /* k += 4 */ + "cmp r5, %[eccd] \n\t" /* k < uECC_WORDS (times 4) ? */ + "blt 1b \n\t" /* if not, loop back, start with i = 0 */ + "cmp r5, %[eccd2m1] \n\t" /* k < uECC_WORDS * 2 - 1 (times 4) ? */ + "blt 2b \n\t" /* if not, loop back, start with i = (k+1) - uECC_WORDS */ + /* end outer loop */ + + "str r2, [r0, r5] \n\t" /* p_result[uECC_WORDS * 2 - 1] = c0 */ + "pop {r0} \n\t" /* pop p_result off the stack */ + + ".syntax divided \n\t" + : [r0] "+l" (r0), [r1] "+l" (r1) + : [eccd] "I" (uECC_WORDS * 4), [eccdm1] "I" ((uECC_WORDS-1) * 4), [eccd2m1] "I" ((uECC_WORDS * 2 - 1) * 4) + : "r2", "r3", "r4", "r5", "r6", "r7", "cc", "memory" + ); +#endif +} +#define asm_square 1 +#endif /* !asm_square */ +#endif /* uECC_SQUARE_FUNC */ diff --git a/extlibs/tinydtls/ecc/asm_avr.inc b/extlibs/tinydtls/ecc/asm_avr.inc new file mode 100755 index 0000000..a945e52 --- /dev/null +++ b/extlibs/tinydtls/ecc/asm_avr.inc @@ -0,0 +1,16276 @@ +#define DEC_20 19 +#define DEC_24 23 +#define DEC_32 31 + +#define DEC(N) uECC_CONCAT(DEC_, N) + +#define REPEAT_1(stuff) stuff +#define REPEAT_2(stuff) REPEAT_1(stuff) stuff +#define REPEAT_3(stuff) REPEAT_2(stuff) stuff +#define REPEAT_4(stuff) REPEAT_3(stuff) stuff +#define REPEAT_5(stuff) REPEAT_4(stuff) stuff +#define REPEAT_6(stuff) REPEAT_5(stuff) stuff +#define REPEAT_7(stuff) REPEAT_6(stuff) stuff +#define REPEAT_8(stuff) REPEAT_7(stuff) stuff +#define REPEAT_9(stuff) REPEAT_8(stuff) stuff +#define REPEAT_10(stuff) REPEAT_9(stuff) stuff +#define REPEAT_11(stuff) REPEAT_10(stuff) stuff +#define REPEAT_12(stuff) REPEAT_11(stuff) stuff +#define REPEAT_13(stuff) REPEAT_12(stuff) stuff +#define REPEAT_14(stuff) REPEAT_13(stuff) stuff +#define REPEAT_15(stuff) REPEAT_14(stuff) stuff +#define REPEAT_16(stuff) REPEAT_15(stuff) stuff +#define REPEAT_17(stuff) REPEAT_16(stuff) stuff +#define REPEAT_18(stuff) REPEAT_17(stuff) stuff +#define REPEAT_19(stuff) REPEAT_18(stuff) stuff +#define REPEAT_20(stuff) REPEAT_19(stuff) stuff +#define REPEAT_21(stuff) REPEAT_20(stuff) stuff +#define REPEAT_22(stuff) REPEAT_21(stuff) stuff +#define REPEAT_23(stuff) REPEAT_22(stuff) stuff +#define REPEAT_24(stuff) REPEAT_23(stuff) stuff +#define REPEAT_25(stuff) REPEAT_24(stuff) stuff +#define REPEAT_26(stuff) REPEAT_25(stuff) stuff +#define REPEAT_27(stuff) REPEAT_26(stuff) stuff +#define REPEAT_28(stuff) REPEAT_27(stuff) stuff +#define REPEAT_29(stuff) REPEAT_28(stuff) stuff +#define REPEAT_30(stuff) REPEAT_29(stuff) stuff +#define REPEAT_31(stuff) REPEAT_30(stuff) stuff +#define REPEAT_32(stuff) REPEAT_31(stuff) stuff + +#define REPEAT(N, stuff) uECC_CONCAT(REPEAT_, N)(stuff) + +#define STR2(thing) #thing +#define STR(thing) STR2(thing) + +#if (uECC_ASM == uECC_asm_fast) + +static void vli_clear(uint8_t *p_vli) +{ + __asm__ volatile ( + REPEAT(uECC_BYTES, "st %a[ptr]+, r1 \n\t") + + : [ptr] "+e" (p_vli) + : + : "r0", "cc", "memory" + ); +} +#define asm_clear 1 + +static void vli_set(uint8_t *p_dest, const uint8_t *p_src) +{ + __asm__ volatile ( + REPEAT(uECC_BYTES, "ld r0, %a[sptr]+ \n\t" + "st %a[dptr]+, r0 \n\t") + : [dptr] "+e" (p_dest), [sptr] "+e" (p_src) + : + : "r0", "cc", "memory" + ); +} +#define asm_set 1 + +static void vli_rshift1(uint8_t *p_vli) +{ + __asm__ volatile ( + "adiw r30, " STR(uECC_BYTES) " \n\t" + "ld r0, -z \n\t" /* Load byte. */ + "lsr r0 \n\t" /* Shift. */ + "st z, r0 \n\t" /* Store the first result byte. */ + + /* Now we just do the remaining bytes with the carry bit (using ROR) */ + REPEAT(DEC(uECC_BYTES), "ld r0, -z \n\t" + "ror r0 \n\t" + "st z, r0 \n\t") + + : "+z" (p_vli) + : + : "r0", "cc", "memory" + ); +} +#define asm_rshift1 1 + +/* Computes p_result = p_left + p_right, returning carry. Can modify in place. */ +static uint8_t vli_add(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t l_carry = 0; + uint8_t l_left; + uint8_t l_right; + + __asm__ volatile ( + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "add %[left], %[right] \n\t" /* Add the first byte. */ + "st z+, %[left] \n\t" /* Store the first result byte. */ + + /* Now we just do the remaining bytes with the carry bit (using ADC) */ + REPEAT(DEC(uECC_BYTES), "ld %[left], x+ \n\t" + "ld %[right], y+ \n\t" + "adc %[left], %[right] \n\t" + "st z+, %[left] \n\t") + + "adc %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + + "sbiw r28, " STR(uECC_BYTES) " \n\t" /* Restore Y */ + + : "+z" (p_result), "+x" (p_left), + [carry] "+r" (l_carry), [left] "=&r" (l_left), [right] "=&r" (l_right) + : "y" (p_right) + : "cc", "memory" + ); + return l_carry; +} +#define asm_add 1 + +/* Computes p_result = p_left - p_right, returning borrow. Can modify in place. */ +static uint8_t vli_sub(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t l_borrow = 0; + uint8_t l_left; + uint8_t l_right; + + __asm__ volatile ( + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "sub %[left], %[right] \n\t" /* Subtract the first byte. */ + "st z+, %[left] \n\t" /* Store the first result byte. */ + + /* Now we just do the remaining bytes with the carry bit (using SBC) */ + REPEAT(DEC(uECC_BYTES), "ld %[left], x+ \n\t" + "ld %[right], y+ \n\t" + "sbc %[left], %[right] \n\t" + "st z+, %[left] \n\t") + + "adc %[borrow], %[borrow] \n\t" /* Store carry bit in l_borrow. */ + + "sbiw r28, " STR(uECC_BYTES) " \n\t" /* Restore Y */ + + : "+z" (p_result), "+x" (p_left), + [borrow] "+r" (l_borrow), [left] "=&r" (l_left), [right] "=&r" (l_right) + : "y" (p_right) + : "cc", "memory" + ); + return l_borrow; +} +#define asm_sub 1 + +#if (uECC_BYTES == 20) +__attribute((noinline)) +static void vli_mult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + __asm__ volatile ( + "adiw r30, 10 \n\t" + "adiw r28, 10 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ld r16, y+ \n\t" + "ld r17, y+ \n\t" + "ld r18, y+ \n\t" + "ld r19, y+ \n\t" + "ld r20, y+ \n\t" + "ld r21, y+ \n\t" + "ldi r25, 0 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r24 \n\t" + "st z+, r22 \n\t" + + "sbiw r30, 30 \n\t" + "sbiw r28, 20 \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ld r16, y+ \n\t" + "ld r17, y+ \n\t" + "ld r18, y+ \n\t" + "ld r19, y+ \n\t" + "ld r20, y+ \n\t" + "ld r21, y+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r5, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r6, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r7, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r8, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r9, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r10, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r11, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r12, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r14, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r15, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r16, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r17, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r18, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r19, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r20, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r21, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r3, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r4, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r6, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r7, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r9, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r10, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r24 \n\t" + "eor r1, r1 \n\t" + : "+x" (p_left), "+y" (p_right), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "cc", "memory" + ); +} +#define asm_mult 1 +#elif (uECC_BYTES == 24) +__attribute((noinline)) +static void vli_mult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + __asm__ volatile ( + "adiw r30, 20 \n\t" + "adiw r28, 20 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ldi r25, 0 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r24 \n\t" + "st z+, r22 \n\t" + + "sbiw r30, 18 \n\t" + "sbiw r28, 14 \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ld r16, y+ \n\t" + "ld r17, y+ \n\t" + "ld r18, y+ \n\t" + "ld r19, y+ \n\t" + "ld r20, y+ \n\t" + "ld r21, y+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r5, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r12, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r14, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r15, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r4, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r24 \n\t" + + "sbiw r30, 38 \n\t" + "sbiw r28, 24 \n\t" + "sbiw r26, 14 \n\t" + "ld r2, x+ \n\t" + "ld r12, y+ \n\t" + "ld r3, x+ \n\t" + "ld r13, y+ \n\t" + "ld r4, x+ \n\t" + "ld r14, y+ \n\t" + "ld r5, x+ \n\t" + "ld r15, y+ \n\t" + "ld r6, x+ \n\t" + "ld r16, y+ \n\t" + "ld r7, x+ \n\t" + "ld r17, y+ \n\t" + "ld r8, x+ \n\t" + "ld r18, y+ \n\t" + "ld r9, x+ \n\t" + "ld r19, y+ \n\t" + "ld r10, x+ \n\t" + "ld r20, y+ \n\t" + "ld r11, x+ \n\t" + "ld r21, y+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r5, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r6, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r7, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r8, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r9, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r10, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r11, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r2, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r3, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r4, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r5, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r12, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r13, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r14, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r15, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r16, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r17, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r18, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r19, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r20, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r21, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r12, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r13, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r14, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r15, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + + "eor r1, r1 \n\t" + : "+x" (p_left), "+y" (p_right), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "cc", "memory" + ); +} +#define asm_mult 1 +#elif (uECC_BYTES == 32) +__attribute((noinline)) +static void vli_mult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + __asm__ volatile ( + "adiw r30, 30 \n\t" + "adiw r28, 30 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ldi r25, 0 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r24 \n\t" + + "sbiw r30, 14 \n\t" + "sbiw r28, 12 \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ld r16, y+ \n\t" + "ld r17, y+ \n\t" + "ld r18, y+ \n\t" + "ld r19, y+ \n\t" + "ld r20, y+ \n\t" + "ld r21, y+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r12, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r13, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + + "sbiw r30, 34 \n\t" + "sbiw r28, 22 \n\t" + "sbiw r26, 12 \n\t" + "ld r2, x+ \n\t" + "ld r12, y+ \n\t" + "ld r3, x+ \n\t" + "ld r13, y+ \n\t" + "ld r4, x+ \n\t" + "ld r14, y+ \n\t" + "ld r5, x+ \n\t" + "ld r15, y+ \n\t" + "ld r6, x+ \n\t" + "ld r16, y+ \n\t" + "ld r7, x+ \n\t" + "ld r17, y+ \n\t" + "ld r8, x+ \n\t" + "ld r18, y+ \n\t" + "ld r9, x+ \n\t" + "ld r19, y+ \n\t" + "ld r10, x+ \n\t" + "ld r20, y+ \n\t" + "ld r11, x+ \n\t" + "ld r21, y+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r5, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r6, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r7, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r8, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r9, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r10, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r11, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r2, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r3, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r12, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r13, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r14, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r15, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r16, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r17, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r18, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r19, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r20, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r21, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r12, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r24 \n\t" + "st z+, r22 \n\t" + + "sbiw r30, 54 \n\t" + "sbiw r28, 32 \n\t" + "sbiw r26, 22 \n\t" + "ld r2, x+ \n\t" + "ld r12, y+ \n\t" + "ld r3, x+ \n\t" + "ld r13, y+ \n\t" + "ld r4, x+ \n\t" + "ld r14, y+ \n\t" + "ld r5, x+ \n\t" + "ld r15, y+ \n\t" + "ld r6, x+ \n\t" + "ld r16, y+ \n\t" + "ld r7, x+ \n\t" + "ld r17, y+ \n\t" + "ld r8, x+ \n\t" + "ld r18, y+ \n\t" + "ld r9, x+ \n\t" + "ld r19, y+ \n\t" + "ld r10, x+ \n\t" + "ld r20, y+ \n\t" + "ld r11, x+ \n\t" + "ld r21, y+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r5, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r6, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r7, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r8, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r9, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r10, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r11, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r2, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r3, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r4, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r5, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r6, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r7, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r7, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r8, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r8, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r9, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r10, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r10, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r11, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r11, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r2, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r3, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r3, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r12, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r14, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r15, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r16, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r17, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r18, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r19, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r20, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r21, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r12, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r13, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r14, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r15, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r16, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r17, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r18, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r19, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r20, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r21, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r4, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "ld r0, z \n\t" + "add r24, r0 \n\t" + "adc r22, r25 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r12, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "ld r0, z \n\t" + "add r22, r0 \n\t" + "adc r23, r25 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r13, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r5, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r8, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r6, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r8, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r9, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r8, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r9, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r10, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r11, r20 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r19 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r18 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r9, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r10, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r11, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r11, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r21 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r24 \n\t" + + "eor r1, r1 \n\t" + : "+x" (p_left), "+y" (p_right), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "cc", "memory" + ); +} +#define asm_mult 1 +#endif /* uECC_BYTES == 32 */ + +#if uECC_SQUARE_FUNC + +#if (uECC_BYTES == 20) +static void vli_square(uint8_t *p_result, uint8_t *p_left) +{ + __asm__ volatile ( + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + "ld r12, x+ \n\t" + "ld r13, x+ \n\t" + "ld r14, x+ \n\t" + "ld r15, x+ \n\t" + "ld r16, x+ \n\t" + "ld r17, x+ \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + "ldi r27, 0 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r2 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r3 \n\t" + "lsl r0 \n\t" + "rol r1 \n\t" + "adc r24, r27 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r27 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r4 \n\t" + "lsl r0 \n\t" + "rol r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r3, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r5 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r4 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r6 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r4, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r7 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r6 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r5 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r8 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r5, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r9 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r8 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r7 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r6 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r10 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r6, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r11 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r10 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r9 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r8 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r7 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r12 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r7, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r13 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r11 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r10 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r9 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r8 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r8, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r15 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r11 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r10 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r9 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r16 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r8, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r9, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r17 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r11 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r9, r10 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r18 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r9, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r10, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r19 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r10, r11 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r11, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r2, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r12, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r4, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r12, r13 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r5, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r12, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r13, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r6, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r12, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r13, r14 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r12, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r13, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r14, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r8, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r12, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r13, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r14, r15 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r9, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r12, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r13, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r14, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r15, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r10, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r12, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r13, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r14, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r15, r16 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r11, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r12, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r13, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r14, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r15, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r16, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r12, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r13, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r14, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r15, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r16, r17 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r13, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r14, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r15, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r16, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r17, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r14, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r15, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r16, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r17, r18 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r15, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r16, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "mul r17, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r18, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r16, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r17, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "mul r18, r19 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r17, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r18, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r19, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r27 \n\t" + "add r23, r25 \n\t" + "adc r24, r26 \n\t" + "adc r22, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r26, 0 \n\t" + "mul r18, r21 \n\t" + "mov r23, r0 \n\t" + "mov r25, r1 \n\t" + "mul r19, r20 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "adc r26, r27 \n\t" + "lsl r23 \n\t" + "rol r25 \n\t" + "rol r26 \n\t" + "add r23, r24 \n\t" + "adc r25, r22 \n\t" + "adc r26, r27 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r19, r21 \n\t" + "lsl r0 \n\t" + "rol r1 \n\t" + "adc r23, r27 \n\t" + "add r25, r0 \n\t" + "adc r26, r1 \n\t" + "adc r23, r27 \n\t" + "mul r20, r20 \n\t" + "add r25, r0 \n\t" + "adc r26, r1 \n\t" + "adc r23, r27 \n\t" + "st z+, r25 \n\t" + + "ldi r25, 0 \n\t" + "mul r20, r21 \n\t" + "lsl r0 \n\t" + "rol r1 \n\t" + "adc r25, r27 \n\t" + "add r26, r0 \n\t" + "adc r23, r1 \n\t" + "adc r25, r27 \n\t" + "st z+, r26 \n\t" + + "mul r21, r21 \n\t" + "add r23, r0 \n\t" + "adc r25, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r25 \n\t" + "eor r1, r1 \n\t" + : "+x" (p_left), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "cc", "memory" + ); +} +#define asm_square 1 + +#elif (uECC_BYTES == 24) + +__attribute((noinline)) +static void vli_square(uint8_t *p_result, uint8_t *p_left) +{ + __asm__ volatile ( + "ldi r25, 0 \n\t" + "movw r28, r26 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "adiw r28, 20 \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "adiw r30, 20 \n\t" + + "ldi r23, 0 \n\t" + "mul 2, 12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r12, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r2, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r3, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "mul r3, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r24 \n\t" + "st z+, r22 \n\t" + + "sbiw r26, 4 \n\t" + "sbiw r30, 28 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + "ld r12, x+ \n\t" + "ld r13, x+ \n\t" + "ld r14, x+ \n\t" + "ld r15, x+ \n\t" + "ld r16, x+ \n\t" + "ld r17, x+ \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r2 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r3 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r6 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r4, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r7 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r8 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r5, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r9 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r10 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r6, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r11 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r12 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r7, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r8, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r15 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r16 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r9, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r17 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r18 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r10, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r19 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r11, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r21 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r2, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r12, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r3, r2 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r2 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r13, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r4, r3 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r5, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r5, r3 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r6, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r14, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r5, r4 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r6, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r5, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r4 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r7, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r15, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r6, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r7, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r8, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r16, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r8, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r9, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r9, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r10, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r17, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r10, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r11, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r11, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r12, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r18, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r12, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r13, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r13, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r14, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r19, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r14, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r15, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r15, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r16, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r20, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r16, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r17, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r17, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r18, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r21, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r18, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r19, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r19, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r20, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r2, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r20, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r21, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r21, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r2, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r3, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r3, r5 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r4 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r28 \n\t" + + "ldi r28, 0 \n\t" + "mul r4, r5 \n\t" + "add r29, r0 \n\t" + "adc r23, r1 \n\t" + "adc r28, r25 \n\t" + "add r29, r0 \n\t" + "adc r23, r1 \n\t" + "adc r28, r25 \n\t" + "st z+, r29 \n\t" + + "mul r5, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r28 \n\t" + "eor r1, r1 \n\t" + : "+x" (p_left), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r28", "r29", "cc", "memory" + ); +} +#define asm_square 1 + +#elif (uECC_BYTES == 32) + +__attribute((noinline)) +static void vli_square(uint8_t *p_result, uint8_t *p_left) +{ + __asm__ volatile ( + "ldi r25, 0 \n\t" + "movw r28, r26 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "adiw r28, 20 \n\t" + "ld r12, y+ \n\t" + "ld r13, y+ \n\t" + "ld r14, y+ \n\t" + "ld r15, y+ \n\t" + "ld r16, y+ \n\t" + "ld r17, y+ \n\t" + "adiw r30, 20 \n\t" + + "ldi r23, 0 \n\t" + "mul 2, 12 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r12, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r13, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r14, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r15, y+ \n\t" + "ldi r23, 0 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r16, y+ \n\t" + "ldi r24, 0 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r12 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r17, y+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r2, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r6, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r13 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r12 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r3, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r6, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r7, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r13 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r4, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ld r5, x+ \n\t" + "ldi r23, 0 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r7, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r2, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r3, r14 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ld r6, x+ \n\t" + "ldi r24, 0 \n\t" + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r2, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r3, r15 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r4, r14 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ld r7, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r2, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r3, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r4, r16 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "mul r5, r15 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "ldi r24, 0 \n\t" + "mul r4, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "mul r5, r16 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r6, r17 \n\t" + "add r24, r0 \n\t" + "adc r22, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r24 \n\t" + + "mul r7, r17 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + + "sbiw r26, 12 \n\t" + "sbiw r30, 44 \n\t" + "ld r2, x+ \n\t" + "ld r3, x+ \n\t" + "ld r4, x+ \n\t" + "ld r5, x+ \n\t" + "ld r6, x+ \n\t" + "ld r7, x+ \n\t" + "ld r8, x+ \n\t" + "ld r9, x+ \n\t" + "ld r10, x+ \n\t" + "ld r11, x+ \n\t" + "ld r12, x+ \n\t" + "ld r13, x+ \n\t" + "ld r14, x+ \n\t" + "ld r15, x+ \n\t" + "ld r16, x+ \n\t" + "ld r17, x+ \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + + "ldi r23, 0 \n\t" + "mul r2, r2 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + + "ldi r24, 0 \n\t" + "mul r2, r3 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "adc r24, r25 \n\t" + "st z+, r22 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r6 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r4, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r7 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r8 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r5, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r9 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r10 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r6, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r11 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r12 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r7, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r14 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r8, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r15 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r16 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r9, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r17 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r18 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r10, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r19 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r2, r20 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r3, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r11, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r21 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r2, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r3, r21 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r4, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r12, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r3, r2 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r4, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r3, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r4, r2 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r5, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r13, r13 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r4, r3 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r5, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r14 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r4, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r5, r3 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r6, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r14, r14 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r5, r4 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r6, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r15 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r5, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r6, r4 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r7, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r15, r15 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r6, r5 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r7, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r16 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r6, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r7, r5 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r8, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r16, r16 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r7, r6 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r8, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r17 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r7, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r8, r6 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r9, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r10, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r17, r17 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r8, r7 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r9, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r18 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r8, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r9, r7 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r10, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r11, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r18, r18 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r9, r8 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r10, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r11, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r19 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r9, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r10, r8 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r11, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r12, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r19, r19 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r10, r9 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r11, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r12, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r20 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r10, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r11, r9 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r12, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r13, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r20, r20 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r11, r10 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r12, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r13, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r21 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r11, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r12, r10 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r13, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r14, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r21, r21 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r12, r11 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r13, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r14, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r2 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r12, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r13, r11 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r14, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r15, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r2, r2 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r13, r12 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r14, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r15, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r3 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ld r13, x+ \n\t" + "ldi r22, 0 \n\t" + "mul r14, r12 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r15, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r16, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r24, r25 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r3, r3 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r14, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r15, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r16, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r17, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r3, r4 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "ld r0, z \n\t" + "add r23, r0 \n\t" + "adc r28, r25 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r15, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r16, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r17, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r18, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r4, r4 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r16, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r17, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r18, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r19, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r3, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r5 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r17, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r18, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r19, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r20, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r5, r5 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r18, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r19, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r20, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r21, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r3, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r6 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r19, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r20, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r21, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r2, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r6, r6 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r20, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r21, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r2, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r3, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r7 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r21, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r2, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r3, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r4, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r7, r7 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r2, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r3, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r4, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r5, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r8 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r3, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r4, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r5, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r6, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r8, r8 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r4, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r5, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r6, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r7, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r9 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r5, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r6, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r7, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r8, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r9, r9 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r6, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r7, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r8, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r9, r10 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r7, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r8, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "mul r9, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r10, r10 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r8, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r9, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "mul r10, r11 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r22, 0 \n\t" + "mul r9, r13 \n\t" + "mov r23, r0 \n\t" + "mov r24, r1 \n\t" + "mul r10, r12 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "lsl r23 \n\t" + "rol r24 \n\t" + "rol r22 \n\t" + "mul r11, r11 \n\t" + "add r23, r0 \n\t" + "adc r24, r1 \n\t" + "adc r22, r25 \n\t" + "add r23, r28 \n\t" + "adc r24, r29 \n\t" + "adc r22, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r29, 0 \n\t" + "mul r10, r13 \n\t" + "mov r23, r0 \n\t" + "mov r28, r1 \n\t" + "mul r11, r12 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "adc r29, r25 \n\t" + "lsl r23 \n\t" + "rol r28 \n\t" + "rol r29 \n\t" + "add r23, r24 \n\t" + "adc r28, r22 \n\t" + "adc r29, r25 \n\t" + "st z+, r23 \n\t" + + "ldi r23, 0 \n\t" + "mul r11, r13 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "mul r12, r12 \n\t" + "add r28, r0 \n\t" + "adc r29, r1 \n\t" + "adc r23, r25 \n\t" + "st z+, r28 \n\t" + + "ldi r28, 0 \n\t" + "mul r12, r13 \n\t" + "add r29, r0 \n\t" + "adc r23, r1 \n\t" + "adc r28, r25 \n\t" + "add r29, r0 \n\t" + "adc r23, r1 \n\t" + "adc r28, r25 \n\t" + "st z+, r29 \n\t" + + "mul r13, r13 \n\t" + "add r23, r0 \n\t" + "adc r28, r1 \n\t" + "st z+, r23 \n\t" + "st z+, r28 \n\t" + "eor r1, r1 \n\t" + : "+x" (p_left), "+z" (p_result) + : + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", + "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r28", "r29", "cc", "memory" + ); +} +#define asm_square 1 + +#endif /* uECC_BYTES == xx */ +#endif /* uECC_SQUARE_FUNC */ + +static void vli_modSub_fast(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t t1, t2; + __asm__ volatile ( + "push r28 \n\t" /* Save Y */ + "push r29 \n\t" + + "ld %[t1], x+ \n\t" /* Load left word. */ + "ld %[t2], y+ \n\t" /* Load right word. */ + "sub %[t1], %[t2] \n\t" /* Subtract the first word. */ + "st z+, %[t1] \n\t" /* Store the first result word. */ + + /* Now we just do the remaining words with the carry bit (using SBC) */ + REPEAT(DEC(uECC_BYTES), "ld %[t1], x+ \n\t" + "ld %[t2], y+ \n\t" + "sbc %[t1], %[t2] \n\t" + "st z+, %[t1] \n\t") + + "brcs 1f \n\t" /* If borrow is set, then we need to add */ + "rjmp done \n\t" /* otherwise we are done */ + "1: \n\t" + + "sbiw r30, " STR(uECC_BYTES) " \n\t" /* make z point at p_result again */ + "ldi r28, lo8(curve_p) \n\t" /* make y point at curve_p */ + "ldi r29, hi8(curve_p) \n\t" + + /* do the addition */ + "ld %[t1], z \n\t" + "ld %[t2], y+ \n\t" + "add %[t1], %[t2] \n\t" + "st z+, %[t1] \n\t" + REPEAT(DEC(uECC_BYTES), "ld %[t1], z \n\t" + "ld %[t2], y+ \n\t" + "adc %[t1], %[t2] \n\t" + "st z+, %[t1] \n\t") + + "done: \n\t" + "pop r29 \n\t" /* Restore Y */ + "pop r28 \n\t" + + : "+z" (p_result), "+x" (p_left), + [t1] "=&r" (t1), [t2] "=&r" (t2) + : "y" (p_right) + : "cc", "memory" + ); +} +#define asm_modSub_fast 1 + +#if uECC_CURVE == uECC_secp160r1 +static void vli_mmod_fast(uint8_t *RESTRICT p_result, uint8_t *RESTRICT p_product) +{ + uint8_t l_carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 24 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 25 \n\t" /* we are shifting by 31 bits, so shift over 4 bytes (+ 1 since z initially points below the stack) */ + "adiw r26, 40 \n\t" /* end of p_product */ + "ld r18, -x \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -z, r18 \n\t" /* Store the first result word. */ + + /* Now we just do the remaining words with the carry bit (using ROR) */ + REPEAT(19, "ld r18, -x \n\t" + "ror r18 \n\t" + "st -z, r18 \n\t") + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -z, r18 \n\t" /* store it */ + + "sbiw r30, 3 \n\t" /* move z back to point at tmp */ + /* now we add p_right */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + + "ld r18, x+ \n\t" + "ld r19, z \n\t" + "add r18, r19 \n\t" + "st z+, r18 \n\t" + + /* Now we just do the remaining words with the carry bit (using ADC) */ + REPEAT(16, "ld r18, x+ \n\t" + "ld r19, z \n\t" + "adc r18, r19 \n\t" + "st z+, r18 \n\t") + + /* Propagate over the remaining bytes of p_result */ + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "sbiw r30, 24 \n\t" /* move z back to point at tmp */ + "sbiw r26, 40 \n\t" /* move x back to point at p_product */ + + /* add low bytes of tmp to p_product, storing in p_result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(19, "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of p_product, y is at the end of p_result, z is 20 bytes into tmp */ + "sbiw r28, 20 \n\t" /* move y back to point at p_result */ + "adiw r30, 4 \n\t" /* move z to point to the end of tmp */ + + /* do omega_mult again with the 4 relevant bytes */ + /* z points to the end of tmp, x points to the end of p_product */ + "ld r18, -z \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -x, r18 \n\t" /* Store the first result word. */ + + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -x, r18 \n\t" /* store it */ + + "sbiw r26, 3 \n\t" /* move x back to point at beginning */ + /* now we add a copy of the 4 bytes */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + + "ld r18, z+ \n\t" + "ld r19, x \n\t" + "add r18, r19 \n\t" + "st x+, r18 \n\t" + + /* Propagate over the remaining bytes */ + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + /* now z points to the end of tmp, x points to the end of p_product (y still points at p_result) */ + "sbiw r26, 8 \n\t" /* move x back to point at beginning of actual data */ + /* add into p_result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(7, "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(12, "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 20 \n\t" /* move y back to point at p_result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (p_product), [carry] "+r" (l_carry) + : "y" (p_result) + : "r0", "r18", "r19", "r30", "r31", "cc", "memory" + ); + + if(l_carry > 0) + { + --l_carry; + vli_sub(p_result, p_result, curve_p); + } + if(l_carry > 0) + { + vli_sub(p_result, p_result, curve_p); + } + + if(vli_cmp(p_result, curve_p) > 0) + { + vli_sub(p_result, p_result, curve_p); + } +} +#define asm_mmod_fast 1 + +#elif (uECC_CURVE == uECC_secp256k1) +static void vli_mmod_fast(uint8_t *RESTRICT p_result, uint8_t *RESTRICT p_product) +{ + uint8_t l_carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 37 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 1 \n\t" /* add 1 since z initially points below the stack */ + "adiw r26, 32 \n\t" /* p_product + uECC_WORDS */ + "ldi r25, 0x03 \n\t" + "ldi r24, 0xD1 \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + + "mul r24, r18 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* now we start adding the 2^32 part as well */ + "add r23, r18 \n\t" // 28 + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" // 27 + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + REPEAT(6, // 26 - 3 + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t") + + "add r23, r20 \n\t" // 2 + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" // 1 + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* Now finish the carries etc */ + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + "sbiw r30, 37 \n\t" /* move z back to point at tmp */ + "subi r26, 64 \n\t" /* move x back to point at p_product */ + "sbc r27, __zero_reg__ \n\t" + + /* add low bytes of tmp to p_product, storing in p_result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(31, "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of p_product, y is at the end of p_result, z is 32 bytes into tmp */ + "sbiw r28, 32 \n\t" /* move y back to point at p_result */ + + /* do omega_mult again with the 5 relevant bytes */ + /* z points to l_tmp + uECC_WORDS, x points to the end of p_product */ + "sbiw r26, 32 \n\t" /* shift x back to point into the p_product buffer (we can overwrite it now) */ + + "ld r18, z+ \n\t" + "ld r19, z+ \n\t" + "ld r20, z+ \n\t" + "ld r21, z+ \n\t" + + "mul r24, r18 \n\t" + "st x+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, z+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + /* Now finish the carries etc */ + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "st x+, r22 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + /* now z points to the end of tmp, x points to the end of p_product (y still points at p_result) */ + "sbiw r26, 10 \n\t" /* move x back to point at beginning of actual data */ + /* add into p_result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(9, "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(22, "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 32 \n\t" /* move y back to point at p_result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (p_product), [carry] "+r" (l_carry) + : "y" (p_result) + : "r0", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r30", "r31", "cc", "memory" + ); + + if(l_carry > 0) + { + --l_carry; + vli_sub(p_result, p_result, curve_p); + } + if(l_carry > 0) + { + vli_sub(p_result, p_result, curve_p); + } + + if(vli_cmp(p_result, curve_p) > 0) + { + vli_sub(p_result, p_result, curve_p); + } +} +#define asm_mmod_fast 1 + +#endif /* (uECC_CURVE == uECC_secp256k1) */ + +#endif /* (uECC_ASM == uECC_asm_fast) */ + +#if !asm_rshift1 +static void vli_rshift1(uint8_t *p_vli) +{ + uint8_t i = uECC_BYTES; + __asm__ volatile ( + "adiw r30, " STR(uECC_BYTES) " \n\t" + "clc \n\t" + + "1: \n\t" + "ld r0, -z \n\t" + "ror r0 \n\t" + "st z, r0 \n\t" + "dec %[i] \n\t" + "brne 1b \n\t" + + : "+z" (p_vli), [i] "+r" (i) + : + : "r0", "cc", "memory" + ); +} +#define asm_rshift1 1 +#endif + +#if !asm_add +static uint8_t vli_add(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t i = uECC_BYTES; + uint8_t l_carry = 0; + uint8_t l_left; + uint8_t l_right; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "adc %[left], %[right] \n\t" /* Add. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[carry], %[carry] \n\t" /* Store carry bit in l_carry. */ + + "sbiw r28, " STR(uECC_BYTES) " \n\t" /* Restore Y */ + + : "+z" (p_result), "+x" (p_left), [i] "+r" (i), + [carry] "+r" (l_carry), [left] "=&r" (l_left), [right] "=&r" (l_right) + : "y" (p_right) + : "cc", "memory" + ); + return l_carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +static uint8_t vli_sub(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t i = uECC_BYTES; + uint8_t l_borrow = 0; + uint8_t l_left; + uint8_t l_right; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "sbc %[left], %[right] \n\t" /* Subtract. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[borrow], %[borrow] \n\t" /* Store carry bit in l_borrow. */ + + "sbiw r28, " STR(uECC_BYTES) " \n\t" /* Restore Y */ + + : "+z" (p_result), "+x" (p_left), [i] "+r" (i), + [borrow] "+r" (l_borrow), [left] "=&r" (l_left), [right] "=&r" (l_right) + : "y" (p_right) + : "cc", "memory" + ); + return l_borrow; +} +#define asm_sub 1 +#endif + +#if !asm_mult +__attribute((noinline)) +static void vli_mult(uint8_t *p_result, uint8_t *p_left, uint8_t *p_right) +{ + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + + uint8_t l_zero = 0; + + uint8_t k, i; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < uECC_BYTES; ++k */ + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i=0; i < k; ++i */ + + "add r28, %[k] \n\t" /* pre-add right ptr */ + "adc r29, %[zero] \n\t" + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "sub r26, %[k] \n\t" /* fix up left ptr */ + "sbc r27, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cpi %[k], " STR(uECC_BYTES) " \n\t" + "brlo 1b \n\t" /* loop if k < uECC_BYTES */ + + /* second half */ + "ldi %[k], " STR(uECC_BYTES) " \n\t" /* k = uECC_BYTES; k > 0; --k */ + "adiw r28, " STR(uECC_BYTES) " \n\t" /* move right ptr to point at the end of p_right */ + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i=0; i < k; ++i */ + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "add r28, %[k] \n\t" /* fix up right ptr */ + "adc r29, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "dec %[k] \n\t" + "sub r26, %[k] \n\t" /* fix up left ptr (after k is decremented, so next time we start 1 higher) */ + "sbc r27, %[zero] \n\t" + + "cpi %[k], 0 \n\t" + "brne 1b \n\t" /* loop if k > 0 */ + + "st z+, %[r0] \n\t" /* Store last result byte. */ + + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + "sbiw r28, " STR(uECC_BYTES) " \n\t" /* Restore Y */ + + : "+z" (p_result), "+x" (p_left), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [zero] "+r" (l_zero), + [k] "=&a" (k), [i] "=&a" (i) + : "y" (p_right) + : "r0", "cc", "memory" + ); +} +#define asm_mult 1 +#endif + +#if uECC_SQUARE_FUNC +#if !asm_square +static void vli_square(uint8_t *p_result, uint8_t *p_left) +{ + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + + uint8_t l_zero = 0; + + uint8_t k; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < uECC_BYTES*2; ++k */ + + "1: \n\t" + + "movw r26, %[orig] \n\t" /* copy orig ptr to 'left' ptr */ + "movw r30, %[orig] \n\t" /* copy orig ptr to 'right' ptr */ + "cpi %[k], " STR(uECC_BYTES) " \n\t" + "brlo 2f \n\t" + "breq 2f \n\t" + + /* when k > uECC_BYTES, we start from (k - uECC_BYTES) on the 'left' ptr */ + "add r26, %[k] \n\t" + "adc r27, %[zero] \n\t" + "subi r26, " STR(uECC_BYTES) " \n\t" + "sbc r27, %[zero] \n\t" + "adiw r30, " STR(uECC_BYTES) " \n\t" /* move right ptr to point at the end */ + "rjmp 3f \n\t" + + "2: \n\t" /* when k <= uECC_BYTES, we add k to the 'right' ptr */ + "add r30, %[k] \n\t" /* pre-add 'right' ptr */ + "adc r31, %[zero] \n\t" + + "3: \n\t" + "ld r0, x+ \n\t" + "cp r26, r30 \n\t" /* if left == right here, then we are done after this mult (and we don't need to double) */ + "breq 4f \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + + /* add twice since it costs the same as doubling */ + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "cpse r26, r30 \n\t" /* if left == right here, then we are done */ + "rjmp 3b \n\t" + "rjmp 5f \n\t" /* skip code for non-doubled mult */ + + "4: \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "5: \n\t" + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store the result. */ + "movw %[result], r30 \n\t" /* update result ptr*/ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cpi %[k], %[max] \n\t" + "brlo 1b \n\t" /* loop if k < uECC_BYTES */ + + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store last result byte. */ + + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + : [result] "+r" (p_result), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [zero] "+r" (l_zero), + [k] "=&a" (k) + : [orig] "r" (p_left), [max] "M" (2*uECC_BYTES) + : "r0", "r26", "r27", "r30", "r31", "cc", "memory" + ); +} +#define asm_square 1 +#endif +#endif /* uECC_SQUARE_FUNC */ diff --git a/extlibs/tinydtls/ecc/ecc.c b/extlibs/tinydtls/ecc/ecc.c new file mode 100644 index 0000000..c9bd8c5 --- /dev/null +++ b/extlibs/tinydtls/ecc/ecc.c @@ -0,0 +1,2335 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "ecc.h" + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_CURVE == uECC_secp160r1) && (uECC_WORD_SIZE == 8) + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 + #if (uECC_PLATFORM == uECC_x86_64) + #undef uECC_PLATFORM + #define uECC_PLATFORM uECC_x86 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if (uECC_ASM && (uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 when using AVR asm") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if (uECC_ASM && (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb) && (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 when using ARM asm") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if __STDC_VERSION__ >= 199901L + #define RESTRICT restrict +#else + #define RESTRICT +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +#define MAX_TRIES 16 + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; +typedef uint8_t wordcount_t; +typedef int8_t swordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#define uECC_WORDS_1 20 +#define uECC_WORDS_2 24 +#define uECC_WORDS_3 32 +#define uECC_WORDS_4 32 + +#define uECC_N_WORDS_1 21 +#define uECC_N_WORDS_2 24 +#define uECC_N_WORDS_3 32 +#define uECC_N_WORDS_4 32 + +#define Curve_P_1 {0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF} +#define Curve_P_2 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +#define Curve_P_3 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF} +#define Curve_P_4 {0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + +#define Curve_B_1 {0x45, 0xFA, 0x65, 0xC5, 0xAD, 0xD4, 0xD4, 0x81, \ + 0x9F, 0xF8, 0xAC, 0x65, 0x8B, 0x7A, 0xBD, 0x54, \ + 0xFC, 0xBE, 0x97, 0x1C} +#define Curve_B_2 {0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE, \ + 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F, \ + 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64} +#define Curve_B_3 {0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B, \ + 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65, \ + 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3, \ + 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A} +#define Curve_B_4 {0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} + +#define Curve_G_1 { \ + {0x82, 0xFC, 0xCB, 0x13, 0xB9, 0x8B, 0xC3, 0x68, \ + 0x89, 0x69, 0x64, 0x46, 0x28, 0x73, 0xF5, 0x8E, \ + 0x68, 0xB5, 0x96, 0x4A}, \ + {0x32, 0xFB, 0xC5, 0x7A, 0x37, 0x51, 0x23, 0x04, \ + 0x12, 0xC9, 0xDC, 0x59, 0x7D, 0x94, 0x68, 0x31, \ + 0x55, 0x28, 0xA6, 0x23}} + +#define Curve_G_2 { \ + {0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4, \ + 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C, \ + 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18}, \ + {0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73, \ + 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63, \ + 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07}} + +#define Curve_G_3 { \ + {0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4, \ + 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77, \ + 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8, \ + 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B}, \ + {0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB, \ + 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B, \ + 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E, \ + 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F}} + +#define Curve_G_4 { \ + {0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59, \ + 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02, \ + 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55, \ + 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79}, \ + {0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C, \ + 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD, \ + 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D, \ + 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48}} + +#define Curve_N_1 {0x57, 0x22, 0x75, 0xCA, 0xD3, 0xAE, 0x27, 0xF9, \ + 0xC8, 0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x01} +#define Curve_N_2 {0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14, \ + 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +#define Curve_N_3 {0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3, \ + 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF} +#define Curve_N_4 {0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF, \ + 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA, \ + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; +typedef unsigned wordcount_t; +typedef int swordcount_t; +typedef int bitcount_t; +typedef int cmpresult_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#define uECC_WORDS_1 5 +#define uECC_WORDS_2 6 +#define uECC_WORDS_3 8 +#define uECC_WORDS_4 8 + +#define uECC_N_WORDS_1 6 +#define uECC_N_WORDS_2 6 +#define uECC_N_WORDS_3 8 +#define uECC_N_WORDS_4 8 + +#define Curve_P_1 {0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +#define Curve_P_2 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +#define Curve_P_3 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF} +#define Curve_P_4 {0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} + +#define Curve_B_1 {0xC565FA45, 0x81D4D4AD, 0x65ACF89F, 0x54BD7A8B, 0x1C97BEFC} +#define Curve_B_2 {0xC146B9B1, 0xFEB8DEEC, 0x72243049, 0x0FA7E9AB, 0xE59C80E7, 0x64210519} +#define Curve_B_3 {0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8} +#define Curve_B_4 {0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000} + +#define Curve_G_1 { \ + {0x13CBFC82, 0x68C38BB9, 0x46646989, 0x8EF57328, 0x4A96B568}, \ + {0x7AC5FB32, 0x04235137, 0x59DCC912, 0x3168947D, 0x23A62855}} + +#define Curve_G_2 { \ + {0x82FF1012, 0xF4FF0AFD, 0x43A18800, 0x7CBF20EB, 0xB03090F6, 0x188DA80E}, \ + {0x1E794811, 0x73F977A1, 0x6B24CDD5, 0x631011ED, 0xFFC8DA78, 0x07192B95}} + +#define Curve_G_3 { \ + {0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2}, \ + {0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2}} + +#define Curve_G_4 { \ + {0x16F81798, 0x59F2815B, 0x2DCE28D9, 0x029BFCDB, 0xCE870B07, 0x55A06295, 0xF9DCBBAC, 0x79BE667E}, \ + {0xFB10D4B8, 0x9C47D08F, 0xA6855419, 0xFD17B448, 0x0E1108A8, 0x5DA4FBFC, 0x26A3C465, 0x483ADA77}} + +#define Curve_N_1 {0xCA752257, 0xF927AED3, 0x0001F4C8, 0x00000000, 0x00000000, 0x00000001} +#define Curve_N_2 {0xB4D22831, 0x146BC9B1, 0x99DEF836, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +#define Curve_N_3 {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF} +#define Curve_N_4 {0xD0364141, 0xBFD25E8C, 0xAF48A03B, 0xBAAEDCE6, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif +typedef unsigned wordcount_t; +typedef int swordcount_t; +typedef int bitcount_t; +typedef int cmpresult_t; + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#define uECC_WORDS_1 3 +#define uECC_WORDS_2 3 +#define uECC_WORDS_3 4 +#define uECC_WORDS_4 4 + +#define uECC_N_WORDS_1 3 +#define uECC_N_WORDS_2 3 +#define uECC_N_WORDS_3 4 +#define uECC_N_WORDS_4 4 + +#define Curve_P_1 {0xFFFFFFFF7FFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull} +#define Curve_P_2 {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull} +#define Curve_P_3 {0xFFFFFFFFFFFFFFFFull, 0x00000000FFFFFFFFull, 0x0000000000000000ull, 0xFFFFFFFF00000001ull} +#define Curve_P_4 {0xFFFFFFFEFFFFFC2Full, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull} + +#define Curve_B_1 {0x81D4D4ADC565FA45ull, 0x54BD7A8B65ACF89Full, 0x000000001C97BEFCull} +#define Curve_B_2 {0xFEB8DEECC146B9B1ull, 0x0FA7E9AB72243049ull, 0x64210519E59C80E7ull} +#define Curve_B_3 {0x3BCE3C3E27D2604Bull, 0x651D06B0CC53B0F6ull, 0xB3EBBD55769886BCull, 0x5AC635D8AA3A93E7ull} +#define Curve_B_4 {0x0000000000000007ull, 0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull} + +#define Curve_G_1 { \ + {0x68C38BB913CBFC82ull, 0x8EF5732846646989ull, 0x000000004A96B568ull}, \ + {0x042351377AC5FB32ull, 0x3168947D59DCC912ull, 0x0000000023A62855ull}} + +#define Curve_G_2 { \ + {0xF4FF0AFD82FF1012ull, 0x7CBF20EB43A18800ull, 0x188DA80EB03090F6ull}, \ + {0x73F977A11E794811ull, 0x631011ED6B24CDD5ull, 0x07192B95FFC8DA78ull}} + +#define Curve_G_3 { \ + {0xF4A13945D898C296ull, 0x77037D812DEB33A0ull, 0xF8BCE6E563A440F2ull, 0x6B17D1F2E12C4247ull}, \ + {0xCBB6406837BF51F5ull, 0x2BCE33576B315ECEull, 0x8EE7EB4A7C0F9E16ull, 0x4FE342E2FE1A7F9Bull}} + +#define Curve_G_4 { \ + {0x59F2815B16F81798, 0x029BFCDB2DCE28D9, 0x55A06295CE870B07, 0x79BE667EF9DCBBAC}, \ + {0x9C47D08FFB10D4B8, 0xFD17B448A6855419, 0x5DA4FBFC0E1108A8, 0x483ADA7726A3C465}} + +#define Curve_N_1 {0xF927AED3CA752257ull, 0x000000000001F4C8ull, 0x0000000100000000ull} +#define Curve_N_2 {0x146BC9B1B4D22831ull, 0xFFFFFFFF99DEF836ull, 0xFFFFFFFFFFFFFFFFull} +#define Curve_N_3 {0xF3B9CAC2FC632551ull, 0xBCE6FAADA7179E84ull, 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFF00000000ull} +#define Curve_N_4 {0xBFD25E8CD0364141, 0xBAAEDCE6AF48A03B, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF} + +#endif /* (uECC_WORD_SIZE == 8) */ + +#define uECC_WORDS uECC_CONCAT(uECC_WORDS_, uECC_CURVE) +#define uECC_N_WORDS uECC_CONCAT(uECC_N_WORDS_, uECC_CURVE) + +typedef struct EccPoint +{ + uECC_word_t x[uECC_WORDS]; + uECC_word_t y[uECC_WORDS]; +} EccPoint; + +static uECC_word_t curve_p[uECC_WORDS] = uECC_CONCAT(Curve_P_, uECC_CURVE); +static uECC_word_t curve_b[uECC_WORDS] = uECC_CONCAT(Curve_B_, uECC_CURVE); +static EccPoint curve_G = uECC_CONCAT(Curve_G_, uECC_CURVE); +static uECC_word_t curve_n[uECC_N_WORDS] = uECC_CONCAT(Curve_N_, uECC_CURVE); + +static void vli_clear(uECC_word_t *p_vli); +static uECC_word_t vli_isZero(const uECC_word_t *p_vli); +static uECC_word_t vli_testBit(const uECC_word_t *p_vli, bitcount_t p_bit); +static bitcount_t vli_numBits(const uECC_word_t *p_vli, wordcount_t p_maxWords); +static void vli_set(uECC_word_t *p_dest, const uECC_word_t *p_src); +static cmpresult_t vli_cmp(uECC_word_t *p_left, uECC_word_t *p_right); +static void vli_rshift1(uECC_word_t *p_vli); +static uECC_word_t vli_add(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right); +static uECC_word_t vli_sub(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right); +static void vli_mult(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right); +static void vli_modAdd(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right, uECC_word_t *p_mod); +static void vli_modSub(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right, uECC_word_t *p_mod); +static void vli_mmod_fast(uECC_word_t *RESTRICT p_result, uECC_word_t *RESTRICT p_product); +static void vli_modMult_fast(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right); +static void vli_modInv(uECC_word_t *p_result, uECC_word_t *p_input, uECC_word_t *p_mod); +#if uECC_SQUARE_FUNC +static void vli_square(uECC_word_t *p_result, uECC_word_t *p_left); +static void vli_modSquare_fast(uECC_word_t *p_result, uECC_word_t *p_left); +#endif + +#if (defined(_WIN32) || defined(_WIN64)) +/* Windows */ + +#define WIN32_LEAN_AND_MEAN +#include +#include + +static int default_RNG(uint8_t *p_dest, unsigned p_size) +{ + HCRYPTPROV l_prov; + if(!CryptAcquireContext(&l_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + return 0; + } + + CryptGenRandom(l_prov, p_size, (BYTE *)p_dest); + CryptReleaseContext(l_prov, 0); + + return 1; +} + +#elif defined(unix) || defined(__linux__) || defined(__unix__) || defined(__unix) || \ + (defined(__APPLE__) && defined(__MACH__)) || defined(uECC_POSIX) + +/* Some POSIX-like system with /dev/urandom or /dev/random. */ +#include +#include +#include + +#ifndef O_CLOEXEC + #define O_CLOEXEC 0 +#endif + +static int default_RNG(uint8_t *p_dest, unsigned p_size) +{ + int l_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + if(l_fd == -1) + { + l_fd = open("/dev/random", O_RDONLY | O_CLOEXEC); + if(l_fd == -1) + { + return 0; + } + } + + char *l_ptr = (char *)p_dest; + size_t l_left = p_size; + while(l_left > 0) + { + int l_read = read(l_fd, l_ptr, l_left); + if(l_read <= 0) + { // read failed + close(l_fd); + return 0; + } + l_left -= l_read; + l_ptr += l_read; + } + + close(l_fd); + return 1; +} + +#else /* Some other platform */ + +static int default_RNG(uint8_t *p_dest, unsigned p_size) +{ + return 0; +} + +#endif + +static uECC_RNG_Function g_rng = &default_RNG; + +void uECC_set_rng(uECC_RNG_Function p_rng) +{ + g_rng = p_rng; +} + +#ifdef __GNUC__ /* Only support GCC inline asm for now */ + #if (uECC_ASM && (uECC_PLATFORM == uECC_avr)) + #include "asm_avr.inc" + #endif + + #if (uECC_ASM && (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || uECC_PLATFORM == uECC_arm_thumb2)) + #include "asm_arm.inc" + #endif +#endif + +#if !asm_clear +static void vli_clear(uECC_word_t *p_vli) +{ + wordcount_t i; + for(i = 0; i < uECC_WORDS; ++i) + { + p_vli[i] = 0; + } +} +#endif + +/* Returns 1 if p_vli == 0, 0 otherwise. */ +#if !asm_isZero +static uECC_word_t vli_isZero(const uECC_word_t *p_vli) +{ + wordcount_t i; + for(i = 0; i < uECC_WORDS; ++i) + { + if(p_vli[i]) + { + return 0; + } + } + return 1; +} +#endif + +/* Returns nonzero if bit p_bit of p_vli is set. */ +#if !asm_testBit +static uECC_word_t vli_testBit(const uECC_word_t *p_vli, bitcount_t p_bit) +{ + return (p_vli[p_bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (p_bit & uECC_WORD_BITS_MASK))); +} +#endif + +/* Counts the number of words in p_vli. */ +#if !asm_numBits +static wordcount_t vli_numDigits(const uECC_word_t *p_vli, wordcount_t p_maxWords) +{ + swordcount_t i; + /* Search from the end until we find a non-zero digit. + We do it in reverse because we expect that most digits will be nonzero. */ + for(i = p_maxWords-1; i >= 0 && p_vli[i] == 0; --i) + { + } + + return (i + 1); +} + +/* Counts the number of bits required to represent p_vli. */ +static bitcount_t vli_numBits(const uECC_word_t *p_vli, wordcount_t p_maxWords) +{ + uECC_word_t i; + uECC_word_t l_digit; + + wordcount_t l_numDigits = vli_numDigits(p_vli, p_maxWords); + if(l_numDigits == 0) + { + return 0; + } + + l_digit = p_vli[l_numDigits - 1]; + for(i = 0; l_digit; ++i) + { + l_digit >>= 1; + } + + return (((bitcount_t)(l_numDigits - 1) << uECC_WORD_BITS_SHIFT) + i); +} +#endif /* !asm_numBits */ + +/* Sets p_dest = p_src. */ +#if !asm_set +static void vli_set(uECC_word_t *p_dest, const uECC_word_t *p_src) +{ + wordcount_t i; + for(i=0; i= 0; --i) + { + if(p_left[i] > p_right[i]) + { + return 1; + } + else if(p_left[i] < p_right[i]) + { + return -1; + } + } + return 0; +} +#endif + +/* Computes p_vli = p_vli >> 1. */ +#if !asm_rshift1 +static void vli_rshift1(uECC_word_t *p_vli) +{ + uECC_word_t *l_end = p_vli; + uECC_word_t l_carry = 0; + + p_vli += uECC_WORDS; + while(p_vli-- > l_end) + { + uECC_word_t l_temp = *p_vli; + *p_vli = (l_temp >> 1) | l_carry; + l_carry = l_temp << (uECC_WORD_BITS - 1); + } +} +#endif + +/* Computes p_result = p_left + p_right, returning carry. Can modify in place. */ +#if !asm_add +static uECC_word_t vli_add(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_carry = 0; + wordcount_t i; + for(i = 0; i < uECC_WORDS; ++i) + { + uECC_word_t l_sum = p_left[i] + p_right[i] + l_carry; + if(l_sum != p_left[i]) + { + l_carry = (l_sum < p_left[i]); + } + p_result[i] = l_sum; + } + return l_carry; +} +#endif + +/* Computes p_result = p_left - p_right, returning borrow. Can modify in place. */ +#if !asm_sub +static uECC_word_t vli_sub(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_borrow = 0; + wordcount_t i; + for(i = 0; i < uECC_WORDS; ++i) + { + uECC_word_t l_diff = p_left[i] - p_right[i] - l_borrow; + if(l_diff != p_left[i]) + { + l_borrow = (l_diff > p_left[i]); + } + p_result[i] = l_diff; + } + return l_borrow; +} +#endif + +#if (!asm_mult || !asm_square || uECC_CURVE == uECC_secp256k1) +static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t *r0, uECC_word_t *r1, uECC_word_t *r2) +{ +#if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128 + uint64_t a0 = a & 0xffffffffull; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if(i2 < i1) + { // overflow + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} +#define muladd_exists 1 +#endif + +#if !asm_mult +static void vli_mult(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t i, k; + + /* Compute each digit of p_result in sequence, maintaining the carries. */ + for(k = 0; k < uECC_WORDS; ++k) + { + for(i = 0; i <= k; ++i) + { + muladd(p_left[i], p_right[k-i], &r0, &r1, &r2); + } + p_result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + for(k = uECC_WORDS; k < uECC_WORDS*2 - 1; ++k) + { + for(i = (k + 1) - uECC_WORDS; i> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if(i2 < i1) + { // overflow + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r2 += (p1 >> 63); + p1 = (p1 << 1) | (p0 >> 63); + p0 <<= 1; + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + *r2 += (p >> (uECC_WORD_BITS * 2 - 1)); + p *= 2; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} + +static void vli_square(uECC_word_t *p_result, uECC_word_t *p_left) +{ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t i, k; + + for(k = 0; k < uECC_WORDS*2 - 1; ++k) + { + uECC_word_t l_min = (k < uECC_WORDS ? 0 : (k + 1) - uECC_WORDS); + for(i = l_min; i<=k && i<=k-i; ++i) + { + if(i < k-i) + { + mul2add(p_left[i], p_left[k-i], &r0, &r1, &r2); + } + else + { + muladd(p_left[i], p_left[k-i], &r0, &r1, &r2); + } + } + p_result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + p_result[uECC_WORDS*2 - 1] = r0; +} +#endif + +#else /* uECC_SQUARE_FUNC */ + +#define vli_square(result, left, size) vli_mult((result), (left), (left), (size)) + +#endif /* uECC_SQUARE_FUNC */ + + +/* Computes p_result = (p_left + p_right) % p_mod. + Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ +#if !asm_modAdd +static void vli_modAdd(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right, uECC_word_t *p_mod) +{ + uECC_word_t l_carry = vli_add(p_result, p_left, p_right); + if(l_carry || vli_cmp(p_result, p_mod) >= 0) + { /* p_result > p_mod (p_result = p_mod + remainder), so subtract p_mod to get remainder. */ + vli_sub(p_result, p_result, p_mod); + } +} +#endif + +/* Computes p_result = (p_left - p_right) % p_mod. + Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. */ +#if !asm_modSub +static void vli_modSub(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right, uECC_word_t *p_mod) +{ + uECC_word_t l_borrow = vli_sub(p_result, p_left, p_right); + if(l_borrow) + { /* In this case, p_result == -diff == (max int) - diff. + Since -x % d == d - x, we can get the correct result from p_result + p_mod (with overflow). */ + vli_add(p_result, p_result, p_mod); + } +} +#endif + +#if !asm_modSub_fast + #define vli_modSub_fast(result, left, right) vli_modSub((result), (left), (right), curve_p) +#endif + +#if !asm_mmod_fast + +#if (uECC_CURVE == uECC_secp160r1 || uECC_CURVE == uECC_secp256k1) +/* omega_mult() is defined farther below for the different curves / word sizes */ +static void omega_mult(uECC_word_t * RESTRICT p_result, uECC_word_t * RESTRICT p_right); + +/* Computes p_result = p_product % curve_p + see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 + + Note that this only works if log2(omega) < log2(p)/2 */ +static void vli_mmod_fast(uECC_word_t *RESTRICT p_result, uECC_word_t *RESTRICT p_product) +{ + uECC_word_t l_tmp[2*uECC_WORDS]; + uECC_word_t l_carry; + + vli_clear(l_tmp); + vli_clear(l_tmp + uECC_WORDS); + + omega_mult(l_tmp, p_product + uECC_WORDS); /* (Rq, q) = q * c */ + + l_carry = vli_add(p_result, p_product, l_tmp); /* (C, r) = r + q */ + vli_clear(p_product); + omega_mult(p_product, l_tmp + uECC_WORDS); /* Rq*c */ + l_carry += vli_add(p_result, p_result, p_product); /* (C1, r) = r + Rq*c */ + + while(l_carry > 0) + { + --l_carry; + vli_sub(p_result, p_result, curve_p); + } + + if(vli_cmp(p_result, curve_p) > 0) + { + vli_sub(p_result, p_result, curve_p); + } +} + +#endif + +#if uECC_CURVE == uECC_secp160r1 + +#if uECC_WORD_SIZE == 1 +static void omega_mult(uint8_t * RESTRICT p_result, uint8_t * RESTRICT p_right) +{ + uint8_t l_carry; + uint8_t i; + + /* Multiply by (2^31 + 1). */ + vli_set(p_result + 4, p_right); /* 2^32 */ + vli_rshift1(p_result + 4); /* 2^31 */ + p_result[3] = p_right[0] << 7; /* get last bit from shift */ + + l_carry = vli_add(p_result, p_result, p_right); /* 2^31 + 1 */ + for(i = uECC_WORDS; l_carry; ++i) + { + uint16_t l_sum = (uint16_t)p_result[i] + l_carry; + p_result[i] = (uint8_t)l_sum; + l_carry = l_sum >> 8; + } +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult(uint32_t * RESTRICT p_result, uint32_t * RESTRICT p_right) +{ + uint32_t l_carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + vli_set(p_result + 1, p_right); /* 2^32 */ + vli_rshift1(p_result + 1); /* 2^31 */ + p_result[0] = p_right[0] << 31; /* get last bit from shift */ + + l_carry = vli_add(p_result, p_result, p_right); /* 2^31 + 1 */ + for(i = uECC_WORDS; l_carry; ++i) + { + uint64_t l_sum = (uint64_t)p_result[i] + l_carry; + p_result[i] = (uint32_t)l_sum; + l_carry = l_sum >> 32; + } +} +#endif /* uECC_WORD_SIZE */ + +#elif uECC_CURVE == uECC_secp192r1 + +/* Computes p_result = p_product % curve_p. + See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast(uint8_t *RESTRICT p_result, uint8_t *RESTRICT p_product) +{ + uint8_t l_tmp[uECC_WORDS]; + uint8_t l_carry; + + vli_set(p_result, p_product); + + vli_set(l_tmp, &p_product[24]); + l_carry = vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = l_tmp[1] = l_tmp[2] = l_tmp[3] = l_tmp[4] = l_tmp[5] = l_tmp[6] = l_tmp[7] = 0; + l_tmp[8] = p_product[24]; l_tmp[9] = p_product[25]; l_tmp[10] = p_product[26]; l_tmp[11] = p_product[27]; + l_tmp[12] = p_product[28]; l_tmp[13] = p_product[29]; l_tmp[14] = p_product[30]; l_tmp[15] = p_product[31]; + l_tmp[16] = p_product[32]; l_tmp[17] = p_product[33]; l_tmp[18] = p_product[34]; l_tmp[19] = p_product[35]; + l_tmp[20] = p_product[36]; l_tmp[21] = p_product[37]; l_tmp[22] = p_product[38]; l_tmp[23] = p_product[39]; + l_carry += vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = l_tmp[8] = p_product[40]; + l_tmp[1] = l_tmp[9] = p_product[41]; + l_tmp[2] = l_tmp[10] = p_product[42]; + l_tmp[3] = l_tmp[11] = p_product[43]; + l_tmp[4] = l_tmp[12] = p_product[44]; + l_tmp[5] = l_tmp[13] = p_product[45]; + l_tmp[6] = l_tmp[14] = p_product[46]; + l_tmp[7] = l_tmp[15] = p_product[47]; + l_tmp[16] = l_tmp[17] = l_tmp[18] = l_tmp[19] = l_tmp[20] = l_tmp[21] = l_tmp[22] = l_tmp[23] = 0; + l_carry += vli_add(p_result, p_result, l_tmp); + + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast(uint32_t *RESTRICT p_result, uint32_t *RESTRICT p_product) +{ + uint32_t l_tmp[uECC_WORDS]; + int l_carry; + + vli_set(p_result, p_product); + + vli_set(l_tmp, &p_product[6]); + l_carry = vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = l_tmp[1] = 0; + l_tmp[2] = p_product[6]; + l_tmp[3] = p_product[7]; + l_tmp[4] = p_product[8]; + l_tmp[5] = p_product[9]; + l_carry += vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = l_tmp[2] = p_product[10]; + l_tmp[1] = l_tmp[3] = p_product[11]; + l_tmp[4] = l_tmp[5] = 0; + l_carry += vli_add(p_result, p_result, l_tmp); + + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } +} +#else +static void vli_mmod_fast(uint64_t *RESTRICT p_result, uint64_t *RESTRICT p_product) +{ + uint64_t l_tmp[uECC_WORDS]; + int l_carry; + + vli_set(p_result, p_product); + + vli_set(l_tmp, &p_product[3]); + l_carry = vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = 0; + l_tmp[1] = p_product[3]; + l_tmp[2] = p_product[4]; + l_carry += vli_add(p_result, p_result, l_tmp); + + l_tmp[0] = l_tmp[1] = p_product[5]; + l_tmp[2] = 0; + l_carry += vli_add(p_result, p_result, l_tmp); + + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } +} +#endif /* uECC_WORD_SIZE */ + +#elif uECC_CURVE == uECC_secp256r1 + +/* Computes p_result = p_product % curve_p + from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast(uint8_t *RESTRICT p_result, uint8_t *RESTRICT p_product) +{ + uint8_t l_tmp[uECC_BYTES]; + int8_t l_carry; + + /* t */ + vli_set(p_result, p_product); + + /* s1 */ + l_tmp[0] = l_tmp[1] = l_tmp[2] = l_tmp[3] = 0; + l_tmp[4] = l_tmp[5] = l_tmp[6] = l_tmp[7] = 0; + l_tmp[8] = l_tmp[9] = l_tmp[10] = l_tmp[11] = 0; + l_tmp[12] = p_product[44]; l_tmp[13] = p_product[45]; l_tmp[14] = p_product[46]; l_tmp[15] = p_product[47]; + l_tmp[16] = p_product[48]; l_tmp[17] = p_product[49]; l_tmp[18] = p_product[50]; l_tmp[19] = p_product[51]; + l_tmp[20] = p_product[52]; l_tmp[21] = p_product[53]; l_tmp[22] = p_product[54]; l_tmp[23] = p_product[55]; + l_tmp[24] = p_product[56]; l_tmp[25] = p_product[57]; l_tmp[26] = p_product[58]; l_tmp[27] = p_product[59]; + l_tmp[28] = p_product[60]; l_tmp[29] = p_product[61]; l_tmp[30] = p_product[62]; l_tmp[31] = p_product[63]; + l_carry = vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s2 */ + l_tmp[12] = p_product[48]; l_tmp[13] = p_product[49]; l_tmp[14] = p_product[50]; l_tmp[15] = p_product[51]; + l_tmp[16] = p_product[52]; l_tmp[17] = p_product[53]; l_tmp[18] = p_product[54]; l_tmp[19] = p_product[55]; + l_tmp[20] = p_product[56]; l_tmp[21] = p_product[57]; l_tmp[22] = p_product[58]; l_tmp[23] = p_product[59]; + l_tmp[24] = p_product[60]; l_tmp[25] = p_product[61]; l_tmp[26] = p_product[62]; l_tmp[27] = p_product[63]; + l_tmp[28] = l_tmp[29] = l_tmp[30] = l_tmp[31] = 0; + l_carry += vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s3 */ + l_tmp[0] = p_product[32]; l_tmp[1] = p_product[33]; l_tmp[2] = p_product[34]; l_tmp[3] = p_product[35]; + l_tmp[4] = p_product[36]; l_tmp[5] = p_product[37]; l_tmp[6] = p_product[38]; l_tmp[7] = p_product[39]; + l_tmp[8] = p_product[40]; l_tmp[9] = p_product[41]; l_tmp[10] = p_product[42]; l_tmp[11] = p_product[43]; + l_tmp[12] = l_tmp[13] = l_tmp[14] = l_tmp[15] = 0; + l_tmp[16] = l_tmp[17] = l_tmp[18] = l_tmp[19] = 0; + l_tmp[20] = l_tmp[21] = l_tmp[22] = l_tmp[23] = 0; + l_tmp[24] = p_product[56]; l_tmp[25] = p_product[57]; l_tmp[26] = p_product[58]; l_tmp[27] = p_product[59]; + l_tmp[28] = p_product[60]; l_tmp[29] = p_product[61]; l_tmp[30] = p_product[62]; l_tmp[31] = p_product[63]; + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s4 */ + l_tmp[0] = p_product[36]; l_tmp[1] = p_product[37]; l_tmp[2] = p_product[38]; l_tmp[3] = p_product[39]; + l_tmp[4] = p_product[40]; l_tmp[5] = p_product[41]; l_tmp[6] = p_product[42]; l_tmp[7] = p_product[43]; + l_tmp[8] = p_product[44]; l_tmp[9] = p_product[45]; l_tmp[10] = p_product[46]; l_tmp[11] = p_product[47]; + l_tmp[12] = p_product[52]; l_tmp[13] = p_product[53]; l_tmp[14] = p_product[54]; l_tmp[15] = p_product[55]; + l_tmp[16] = p_product[56]; l_tmp[17] = p_product[57]; l_tmp[18] = p_product[58]; l_tmp[19] = p_product[59]; + l_tmp[20] = p_product[60]; l_tmp[21] = p_product[61]; l_tmp[22] = p_product[62]; l_tmp[23] = p_product[63]; + l_tmp[24] = p_product[52]; l_tmp[25] = p_product[53]; l_tmp[26] = p_product[54]; l_tmp[27] = p_product[55]; + l_tmp[28] = p_product[32]; l_tmp[29] = p_product[33]; l_tmp[30] = p_product[34]; l_tmp[31] = p_product[35]; + l_carry += vli_add(p_result, p_result, l_tmp); + + /* d1 */ + l_tmp[0] = p_product[44]; l_tmp[1] = p_product[45]; l_tmp[2] = p_product[46]; l_tmp[3] = p_product[47]; + l_tmp[4] = p_product[48]; l_tmp[5] = p_product[49]; l_tmp[6] = p_product[50]; l_tmp[7] = p_product[51]; + l_tmp[8] = p_product[52]; l_tmp[9] = p_product[53]; l_tmp[10] = p_product[54]; l_tmp[11] = p_product[55]; + l_tmp[12] = l_tmp[13] = l_tmp[14] = l_tmp[15] = 0; + l_tmp[16] = l_tmp[17] = l_tmp[18] = l_tmp[19] = 0; + l_tmp[20] = l_tmp[21] = l_tmp[22] = l_tmp[23] = 0; + l_tmp[24] = p_product[32]; l_tmp[25] = p_product[33]; l_tmp[26] = p_product[34]; l_tmp[27] = p_product[35]; + l_tmp[28] = p_product[40]; l_tmp[29] = p_product[41]; l_tmp[30] = p_product[42]; l_tmp[31] = p_product[43]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d2 */ + l_tmp[0] = p_product[48]; l_tmp[1] = p_product[49]; l_tmp[2] = p_product[50]; l_tmp[3] = p_product[51]; + l_tmp[4] = p_product[52]; l_tmp[5] = p_product[53]; l_tmp[6] = p_product[54]; l_tmp[7] = p_product[55]; + l_tmp[8] = p_product[56]; l_tmp[9] = p_product[57]; l_tmp[10] = p_product[58]; l_tmp[11] = p_product[59]; + l_tmp[12] = p_product[60]; l_tmp[13] = p_product[61]; l_tmp[14] = p_product[62]; l_tmp[15] = p_product[63]; + l_tmp[16] = l_tmp[17] = l_tmp[18] = l_tmp[19] = 0; + l_tmp[20] = l_tmp[21] = l_tmp[22] = l_tmp[23] = 0; + l_tmp[24] = p_product[36]; l_tmp[25] = p_product[37]; l_tmp[26] = p_product[38]; l_tmp[27] = p_product[39]; + l_tmp[28] = p_product[44]; l_tmp[29] = p_product[45]; l_tmp[30] = p_product[46]; l_tmp[31] = p_product[47]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d3 */ + l_tmp[0] = p_product[52]; l_tmp[1] = p_product[53]; l_tmp[2] = p_product[54]; l_tmp[3] = p_product[55]; + l_tmp[4] = p_product[56]; l_tmp[5] = p_product[57]; l_tmp[6] = p_product[58]; l_tmp[7] = p_product[59]; + l_tmp[8] = p_product[60]; l_tmp[9] = p_product[61]; l_tmp[10] = p_product[62]; l_tmp[11] = p_product[63]; + l_tmp[12] = p_product[32]; l_tmp[13] = p_product[33]; l_tmp[14] = p_product[34]; l_tmp[15] = p_product[35]; + l_tmp[16] = p_product[36]; l_tmp[17] = p_product[37]; l_tmp[18] = p_product[38]; l_tmp[19] = p_product[39]; + l_tmp[20] = p_product[40]; l_tmp[21] = p_product[41]; l_tmp[22] = p_product[42]; l_tmp[23] = p_product[43]; + l_tmp[24] = l_tmp[25] = l_tmp[26] = l_tmp[27] = 0; + l_tmp[28] = p_product[48]; l_tmp[29] = p_product[49]; l_tmp[30] = p_product[50]; l_tmp[31] = p_product[51]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d4 */ + l_tmp[0] = p_product[56]; l_tmp[1] = p_product[57]; l_tmp[2] = p_product[58]; l_tmp[3] = p_product[59]; + l_tmp[4] = p_product[60]; l_tmp[5] = p_product[61]; l_tmp[6] = p_product[62]; l_tmp[7] = p_product[63]; + l_tmp[8] = l_tmp[9] = l_tmp[10] = l_tmp[11] = 0; + l_tmp[12] = p_product[36]; l_tmp[13] = p_product[37]; l_tmp[14] = p_product[38]; l_tmp[15] = p_product[39]; + l_tmp[16] = p_product[40]; l_tmp[17] = p_product[41]; l_tmp[18] = p_product[42]; l_tmp[19] = p_product[43]; + l_tmp[20] = p_product[44]; l_tmp[21] = p_product[45]; l_tmp[22] = p_product[46]; l_tmp[23] = p_product[47]; + l_tmp[24] = l_tmp[25] = l_tmp[26] = l_tmp[27] = 0; + l_tmp[28] = p_product[52]; l_tmp[29] = p_product[53]; l_tmp[30] = p_product[54]; l_tmp[31] = p_product[55]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + if(l_carry < 0) + { + do + { + l_carry += vli_add(p_result, p_result, curve_p); + } while(l_carry < 0); + } + else + { + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast(uint32_t *RESTRICT p_result, uint32_t *RESTRICT p_product) +{ + uint32_t l_tmp[uECC_WORDS]; + int l_carry; + + /* t */ + vli_set(p_result, p_product); + + /* s1 */ + l_tmp[0] = l_tmp[1] = l_tmp[2] = 0; + l_tmp[3] = p_product[11]; + l_tmp[4] = p_product[12]; + l_tmp[5] = p_product[13]; + l_tmp[6] = p_product[14]; + l_tmp[7] = p_product[15]; + l_carry = vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s2 */ + l_tmp[3] = p_product[12]; + l_tmp[4] = p_product[13]; + l_tmp[5] = p_product[14]; + l_tmp[6] = p_product[15]; + l_tmp[7] = 0; + l_carry += vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s3 */ + l_tmp[0] = p_product[8]; + l_tmp[1] = p_product[9]; + l_tmp[2] = p_product[10]; + l_tmp[3] = l_tmp[4] = l_tmp[5] = 0; + l_tmp[6] = p_product[14]; + l_tmp[7] = p_product[15]; + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s4 */ + l_tmp[0] = p_product[9]; + l_tmp[1] = p_product[10]; + l_tmp[2] = p_product[11]; + l_tmp[3] = p_product[13]; + l_tmp[4] = p_product[14]; + l_tmp[5] = p_product[15]; + l_tmp[6] = p_product[13]; + l_tmp[7] = p_product[8]; + l_carry += vli_add(p_result, p_result, l_tmp); + + /* d1 */ + l_tmp[0] = p_product[11]; + l_tmp[1] = p_product[12]; + l_tmp[2] = p_product[13]; + l_tmp[3] = l_tmp[4] = l_tmp[5] = 0; + l_tmp[6] = p_product[8]; + l_tmp[7] = p_product[10]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d2 */ + l_tmp[0] = p_product[12]; + l_tmp[1] = p_product[13]; + l_tmp[2] = p_product[14]; + l_tmp[3] = p_product[15]; + l_tmp[4] = l_tmp[5] = 0; + l_tmp[6] = p_product[9]; + l_tmp[7] = p_product[11]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d3 */ + l_tmp[0] = p_product[13]; + l_tmp[1] = p_product[14]; + l_tmp[2] = p_product[15]; + l_tmp[3] = p_product[8]; + l_tmp[4] = p_product[9]; + l_tmp[5] = p_product[10]; + l_tmp[6] = 0; + l_tmp[7] = p_product[12]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d4 */ + l_tmp[0] = p_product[14]; + l_tmp[1] = p_product[15]; + l_tmp[2] = 0; + l_tmp[3] = p_product[9]; + l_tmp[4] = p_product[10]; + l_tmp[5] = p_product[11]; + l_tmp[6] = 0; + l_tmp[7] = p_product[13]; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + if(l_carry < 0) + { + do + { + l_carry += vli_add(p_result, p_result, curve_p); + } while(l_carry < 0); + } + else + { + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } + } +} +#else +static void vli_mmod_fast(uint64_t *RESTRICT p_result, uint64_t *RESTRICT p_product) +{ + uint64_t l_tmp[uECC_WORDS]; + int l_carry; + + /* t */ + vli_set(p_result, p_product); + + /* s1 */ + l_tmp[0] = 0; + l_tmp[1] = p_product[5] & 0xffffffff00000000ull; + l_tmp[2] = p_product[6]; + l_tmp[3] = p_product[7]; + l_carry = vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s2 */ + l_tmp[1] = p_product[6] << 32; + l_tmp[2] = (p_product[6] >> 32) | (p_product[7] << 32); + l_tmp[3] = p_product[7] >> 32; + l_carry += vli_add(l_tmp, l_tmp, l_tmp); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s3 */ + l_tmp[0] = p_product[4]; + l_tmp[1] = p_product[5] & 0xffffffff; + l_tmp[2] = 0; + l_tmp[3] = p_product[7]; + l_carry += vli_add(p_result, p_result, l_tmp); + + /* s4 */ + l_tmp[0] = (p_product[4] >> 32) | (p_product[5] << 32); + l_tmp[1] = (p_product[5] >> 32) | (p_product[6] & 0xffffffff00000000ull); + l_tmp[2] = p_product[7]; + l_tmp[3] = (p_product[6] >> 32) | (p_product[4] << 32); + l_carry += vli_add(p_result, p_result, l_tmp); + + /* d1 */ + l_tmp[0] = (p_product[5] >> 32) | (p_product[6] << 32); + l_tmp[1] = (p_product[6] >> 32); + l_tmp[2] = 0; + l_tmp[3] = (p_product[4] & 0xffffffff) | (p_product[5] << 32); + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d2 */ + l_tmp[0] = p_product[6]; + l_tmp[1] = p_product[7]; + l_tmp[2] = 0; + l_tmp[3] = (p_product[4] >> 32) | (p_product[5] & 0xffffffff00000000ull); + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d3 */ + l_tmp[0] = (p_product[6] >> 32) | (p_product[7] << 32); + l_tmp[1] = (p_product[7] >> 32) | (p_product[4] << 32); + l_tmp[2] = (p_product[4] >> 32) | (p_product[5] << 32); + l_tmp[3] = (p_product[6] << 32); + l_carry -= vli_sub(p_result, p_result, l_tmp); + + /* d4 */ + l_tmp[0] = p_product[7]; + l_tmp[1] = p_product[4] & 0xffffffff00000000ull; + l_tmp[2] = p_product[5]; + l_tmp[3] = p_product[6] & 0xffffffff00000000ull; + l_carry -= vli_sub(p_result, p_result, l_tmp); + + if(l_carry < 0) + { + do + { + l_carry += vli_add(p_result, p_result, curve_p); + } while(l_carry < 0); + } + else + { + while(l_carry || vli_cmp(curve_p, p_result) != 1) + { + l_carry -= vli_sub(p_result, p_result, curve_p); + } + } +} +#endif /* uECC_WORD_SIZE */ + +#elif uECC_CURVE == uECC_secp256k1 + +#if uECC_WORD_SIZE == 1 +static void omega_mult(uint8_t * RESTRICT p_result, uint8_t * RESTRICT p_right) +{ + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t k; + + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + muladd(0xD1, p_right[0], &r0, &r1, &r2); + p_result[0] = r0; + r0 = r1; + r1 = r2; + /* r2 is still 0 */ + + for(k = 1; k < uECC_WORDS; ++k) + { + muladd(0x03, p_right[k-1], &r0, &r1, &r2); + muladd(0xD1, p_right[k], &r0, &r1, &r2); + p_result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + muladd(0x03, p_right[uECC_WORDS-1], &r0, &r1, &r2); + p_result[uECC_WORDS] = r0; + p_result[uECC_WORDS + 1] = r1; + + p_result[4 + uECC_WORDS] = vli_add(p_result + 4, p_result + 4, p_right); /* add the 2^32 multiple */ +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult(uint32_t * RESTRICT p_result, uint32_t * RESTRICT p_right) +{ + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uint32_t l_carry = 0; + wordcount_t k; + + for(k = 0; k < uECC_WORDS; ++k) + { + uint64_t p = (uint64_t)0x3D1 * p_right[k] + l_carry; + p_result[k] = (p & 0xffffffff); + l_carry = p >> 32; + } + p_result[uECC_WORDS] = l_carry; + + p_result[1 + uECC_WORDS] = vli_add(p_result + 1, p_result + 1, p_right); /* add the 2^32 multiple */ +} +#else +static void omega_mult(uint64_t * RESTRICT p_result, uint64_t * RESTRICT p_right) +{ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t k; + + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + for(k = 0; k < uECC_WORDS; ++k) + { + muladd(0x1000003D1ull, p_right[k], &r0, &r1, &r2); + p_result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + p_result[uECC_WORDS] = r0; +} +#endif /* uECC_WORD_SIZE */ + +#endif /* uECC_CURVE */ +#endif /* !asm_mmod_fast */ + +/* Computes p_result = (p_left * p_right) % curve_p. */ +static void vli_modMult_fast(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_product[2 * uECC_WORDS]; + vli_mult(l_product, p_left, p_right); + vli_mmod_fast(p_result, l_product); +} + +#if uECC_SQUARE_FUNC + +/* Computes p_result = p_left^2 % curve_p. */ +static void vli_modSquare_fast(uECC_word_t *p_result, uECC_word_t *p_left) +{ + uECC_word_t l_product[2 * uECC_WORDS]; + vli_square(l_product, p_left); + vli_mmod_fast(p_result, l_product); +} + +#else /* uECC_SQUARE_FUNC */ + +#define vli_modSquare_fast(result, left) vli_modMult_fast((result), (left), (left)) + +#endif /* uECC_SQUARE_FUNC */ + + +#define EVEN(vli) (!(vli[0] & 1)) +/* Computes p_result = (1 / p_input) % p_mod. All VLIs are the same size. + See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" + https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf */ +#if !asm_modInv +static void vli_modInv(uECC_word_t *p_result, uECC_word_t *p_input, uECC_word_t *p_mod) +{ + uECC_word_t a[uECC_WORDS], b[uECC_WORDS], u[uECC_WORDS], v[uECC_WORDS]; + uECC_word_t l_carry; + cmpresult_t l_cmpResult; + + if(vli_isZero(p_input)) + { + vli_clear(p_result); + return; + } + + vli_set(a, p_input); + vli_set(b, p_mod); + vli_clear(u); + u[0] = 1; + vli_clear(v); + while((l_cmpResult = vli_cmp(a, b)) != 0) + { + l_carry = 0; + if(EVEN(a)) + { + vli_rshift1(a); + if(!EVEN(u)) + { + l_carry = vli_add(u, u, p_mod); + } + vli_rshift1(u); + if(l_carry) + { + u[uECC_WORDS-1] |= HIGH_BIT_SET; + } + } + else if(EVEN(b)) + { + vli_rshift1(b); + if(!EVEN(v)) + { + l_carry = vli_add(v, v, p_mod); + } + vli_rshift1(v); + if(l_carry) + { + v[uECC_WORDS-1] |= HIGH_BIT_SET; + } + } + else if(l_cmpResult > 0) + { + vli_sub(a, a, b); + vli_rshift1(a); + if(vli_cmp(u, v) < 0) + { + vli_add(u, u, p_mod); + } + vli_sub(u, u, v); + if(!EVEN(u)) + { + l_carry = vli_add(u, u, p_mod); + } + vli_rshift1(u); + if(l_carry) + { + u[uECC_WORDS-1] |= HIGH_BIT_SET; + } + } + else + { + vli_sub(b, b, a); + vli_rshift1(b); + if(vli_cmp(v, u) < 0) + { + vli_add(v, v, p_mod); + } + vli_sub(v, v, u); + if(!EVEN(v)) + { + l_carry = vli_add(v, v, p_mod); + } + vli_rshift1(v); + if(l_carry) + { + v[uECC_WORDS-1] |= HIGH_BIT_SET; + } + } + } + + vli_set(p_result, u); +} +#endif /* !asm_modInv */ + +/* ------ Point operations ------ */ + +/* Returns 1 if p_point is the point at infinity, 0 otherwise. */ +static cmpresult_t EccPoint_isZero(EccPoint *p_point) +{ + return (vli_isZero(p_point->x) && vli_isZero(p_point->y)); +} + +/* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. +From http://eprint.iacr.org/2011/338.pdf +*/ + +/* Double in place */ +#if (uECC_CURVE == uECC_secp256k1) +static void EccPoint_double_jacobian(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, uECC_word_t * RESTRICT Z1) +{ + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[uECC_WORDS]; + uECC_word_t t5[uECC_WORDS]; + + if(vli_isZero(Z1)) + { + return; + } + + vli_modSquare_fast(t5, Y1); /* t5 = y1^2 */ + vli_modMult_fast(t4, X1, t5); /* t4 = x1*y1^2 = A */ + vli_modSquare_fast(X1, X1); /* t1 = x1^2 */ + vli_modSquare_fast(t5, t5); /* t5 = y1^4 */ + vli_modMult_fast(Z1, Y1, Z1); /* t3 = y1*z1 = z3 */ + + vli_modAdd(Y1, X1, X1, curve_p); /* t2 = 2*x1^2 */ + vli_modAdd(Y1, Y1, X1, curve_p); /* t2 = 3*x1^2 */ + if(vli_testBit(Y1, 0)) + { + uECC_word_t l_carry = vli_add(Y1, Y1, curve_p); + vli_rshift1(Y1); + Y1[uECC_WORDS-1] |= l_carry << (uECC_WORD_BITS - 1); + } + else + { + vli_rshift1(Y1); + } + /* t2 = 3/2*(x1^2) = B */ + + vli_modSquare_fast(X1, Y1); /* t1 = B^2 */ + vli_modSub(X1, X1, t4, curve_p); /* t1 = B^2 - A */ + vli_modSub(X1, X1, t4, curve_p); /* t1 = B^2 - 2A = x3 */ + + vli_modSub(t4, t4, X1, curve_p); /* t4 = A - x3 */ + vli_modMult_fast(Y1, Y1, t4); /* t2 = B * (A - x3) */ + vli_modSub(Y1, Y1, t5, curve_p); /* t2 = B * (A - x3) - y1^4 = y3 */ +} +#else +static void EccPoint_double_jacobian(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, uECC_word_t * RESTRICT Z1) +{ + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[uECC_WORDS]; + uECC_word_t t5[uECC_WORDS]; + + if(vli_isZero(Z1)) + { + return; + } + + vli_modSquare_fast(t4, Y1); /* t4 = y1^2 */ + vli_modMult_fast(t5, X1, t4); /* t5 = x1*y1^2 = A */ + vli_modSquare_fast(t4, t4); /* t4 = y1^4 */ + vli_modMult_fast(Y1, Y1, Z1); /* t2 = y1*z1 = z3 */ + vli_modSquare_fast(Z1, Z1); /* t3 = z1^2 */ + + vli_modAdd(X1, X1, Z1, curve_p); /* t1 = x1 + z1^2 */ + vli_modAdd(Z1, Z1, Z1, curve_p); /* t3 = 2*z1^2 */ + vli_modSub_fast(Z1, X1, Z1); /* t3 = x1 - z1^2 */ + vli_modMult_fast(X1, X1, Z1); /* t1 = x1^2 - z1^4 */ + + vli_modAdd(Z1, X1, X1, curve_p); /* t3 = 2*(x1^2 - z1^4) */ + vli_modAdd(X1, X1, Z1, curve_p); /* t1 = 3*(x1^2 - z1^4) */ + if(vli_testBit(X1, 0)) + { + uECC_word_t l_carry = vli_add(X1, X1, curve_p); + vli_rshift1(X1); + X1[uECC_WORDS-1] |= l_carry << (uECC_WORD_BITS - 1); + } + else + { + vli_rshift1(X1); + } + /* t1 = 3/2*(x1^2 - z1^4) = B */ + + vli_modSquare_fast(Z1, X1); /* t3 = B^2 */ + vli_modSub_fast(Z1, Z1, t5); /* t3 = B^2 - A */ + vli_modSub_fast(Z1, Z1, t5); /* t3 = B^2 - 2A = x3 */ + vli_modSub_fast(t5, t5, Z1); /* t5 = A - x3 */ + vli_modMult_fast(X1, X1, t5); /* t1 = B * (A - x3) */ + vli_modSub_fast(t4, X1, t4); /* t4 = B * (A - x3) - y1^4 = y3 */ + + vli_set(X1, Z1); + vli_set(Z1, Y1); + vli_set(Y1, t4); +} +#endif + +/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ +static void apply_z(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, uECC_word_t * RESTRICT Z) +{ + uECC_word_t t1[uECC_WORDS]; + + vli_modSquare_fast(t1, Z); /* z^2 */ + vli_modMult_fast(X1, X1, t1); /* x1 * z^2 */ + vli_modMult_fast(t1, t1, Z); /* z^3 */ + vli_modMult_fast(Y1, Y1, t1); /* y1 * z^3 */ +} + +/* P = (x1, y1) => 2P, (x2, y2) => P' */ +static void XYcZ_initial_double(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, + uECC_word_t * RESTRICT X2, uECC_word_t * RESTRICT Y2, const uECC_word_t * RESTRICT p_initialZ) +{ + uECC_word_t z[uECC_WORDS]; + + vli_set(X2, X1); + vli_set(Y2, Y1); + + vli_clear(z); + z[0] = 1; + if(p_initialZ) + { + vli_set(z, p_initialZ); + } + + apply_z(X1, Y1, z); + + EccPoint_double_jacobian(X1, Y1, z); + + apply_z(X2, Y2, z); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) + or P => P', Q => P + Q +*/ +static void XYcZ_add(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, uECC_word_t * RESTRICT X2, uECC_word_t * RESTRICT Y2) +{ + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_WORDS]; + + vli_modSub_fast(t5, X2, X1); /* t5 = x2 - x1 */ + vli_modSquare_fast(t5, t5); /* t5 = (x2 - x1)^2 = A */ + vli_modMult_fast(X1, X1, t5); /* t1 = x1*A = B */ + vli_modMult_fast(X2, X2, t5); /* t3 = x2*A = C */ + vli_modSub_fast(Y2, Y2, Y1); /* t4 = y2 - y1 */ + vli_modSquare_fast(t5, Y2); /* t5 = (y2 - y1)^2 = D */ + + vli_modSub_fast(t5, t5, X1); /* t5 = D - B */ + vli_modSub_fast(t5, t5, X2); /* t5 = D - B - C = x3 */ + vli_modSub_fast(X2, X2, X1); /* t3 = C - B */ + vli_modMult_fast(Y1, Y1, X2); /* t2 = y1*(C - B) */ + vli_modSub_fast(X2, X1, t5); /* t3 = B - x3 */ + vli_modMult_fast(Y2, Y2, X2); /* t4 = (y2 - y1)*(B - x3) */ + vli_modSub_fast(Y2, Y2, Y1); /* t4 = y3 */ + + vli_set(X2, t5); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3) + or P => P - Q, Q => P + Q +*/ +static void XYcZ_addC(uECC_word_t * RESTRICT X1, uECC_word_t * RESTRICT Y1, uECC_word_t * RESTRICT X2, uECC_word_t * RESTRICT Y2) +{ + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_WORDS]; + uECC_word_t t6[uECC_WORDS]; + uECC_word_t t7[uECC_WORDS]; + + vli_modSub_fast(t5, X2, X1); /* t5 = x2 - x1 */ + vli_modSquare_fast(t5, t5); /* t5 = (x2 - x1)^2 = A */ + vli_modMult_fast(X1, X1, t5); /* t1 = x1*A = B */ + vli_modMult_fast(X2, X2, t5); /* t3 = x2*A = C */ + vli_modAdd(t5, Y2, Y1, curve_p); /* t4 = y2 + y1 */ + vli_modSub_fast(Y2, Y2, Y1); /* t4 = y2 - y1 */ + + vli_modSub_fast(t6, X2, X1); /* t6 = C - B */ + vli_modMult_fast(Y1, Y1, t6); /* t2 = y1 * (C - B) */ + vli_modAdd(t6, X1, X2, curve_p); /* t6 = B + C */ + vli_modSquare_fast(X2, Y2); /* t3 = (y2 - y1)^2 */ + vli_modSub_fast(X2, X2, t6); /* t3 = x3 */ + + vli_modSub_fast(t7, X1, X2); /* t7 = B - x3 */ + vli_modMult_fast(Y2, Y2, t7); /* t4 = (y2 - y1)*(B - x3) */ + vli_modSub_fast(Y2, Y2, Y1); /* t4 = y3 */ + + vli_modSquare_fast(t7, t5); /* t7 = (y2 + y1)^2 = F */ + vli_modSub_fast(t7, t7, t6); /* t7 = x3' */ + vli_modSub_fast(t6, t7, X1); /* t6 = x3' - B */ + vli_modMult_fast(t6, t6, t5); /* t6 = (y2 + y1)*(x3' - B) */ + vli_modSub_fast(Y1, t6, Y1); /* t2 = y3' */ + + vli_set(X1, t7); +} + +static void EccPoint_mult(EccPoint * RESTRICT p_result, EccPoint * RESTRICT p_point, + const uECC_word_t * RESTRICT p_scalar, const uECC_word_t * RESTRICT p_initialZ, bitcount_t p_numBits) +{ + /* R0 and R1 */ + uECC_word_t Rx[2][uECC_WORDS]; + uECC_word_t Ry[2][uECC_WORDS]; + uECC_word_t z[uECC_WORDS]; + + bitcount_t i; + uECC_word_t nb; + + vli_set(Rx[1], p_point->x); + vli_set(Ry[1], p_point->y); + + XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], p_initialZ); + + for(i = p_numBits - 2; i > 0; --i) + { + nb = !vli_testBit(p_scalar, i); + XYcZ_addC(Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]); + XYcZ_add(Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]); + } + + nb = !vli_testBit(p_scalar, 0); + XYcZ_addC(Rx[1-nb], Ry[1-nb], Rx[nb], Ry[nb]); + + /* Find final 1/Z value. */ + vli_modSub_fast(z, Rx[1], Rx[0]); /* X1 - X0 */ + vli_modMult_fast(z, z, Ry[1-nb]); /* Yb * (X1 - X0) */ + vli_modMult_fast(z, z, p_point->x); /* xP * Yb * (X1 - X0) */ + vli_modInv(z, z, curve_p); /* 1 / (xP * Yb * (X1 - X0)) */ + vli_modMult_fast(z, z, p_point->y); /* yP / (xP * Yb * (X1 - X0)) */ + vli_modMult_fast(z, z, Rx[1-nb]); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + /* End 1/Z calculation */ + + XYcZ_add(Rx[nb], Ry[nb], Rx[1-nb], Ry[1-nb]); + + apply_z(Rx[0], Ry[0], z); + + vli_set(p_result->x, Rx[0]); + vli_set(p_result->y, Ry[0]); +} + +/* Compute a = sqrt(a) (mod curve_p). */ +static void mod_sqrt(uECC_word_t *a) +{ + bitcount_t i; + uECC_word_t p1[uECC_WORDS] = {1}; + uECC_word_t l_result[uECC_WORDS] = {1}; + + /* Since curve_p == 3 (mod 4) for all supported curves, we can + compute sqrt(a) = a^((curve_p + 1) / 4) (mod curve_p). */ + vli_add(p1, curve_p, p1); /* p1 = curve_p + 1 */ + for(i = vli_numBits(p1, uECC_WORDS) - 1; i > 1; --i) + { + vli_modSquare_fast(l_result, l_result); + if(vli_testBit(p1, i)) + { + vli_modMult_fast(l_result, l_result, a); + } + } + vli_set(a, l_result); +} + +#if uECC_WORD_SIZE == 1 + +static void vli_nativeToBytes(uint8_t * RESTRICT p_dest, const uint8_t * RESTRICT p_src) +{ + uint8_t i; + for(i=0; i> 24; + p_digit[1] = p_native[i] >> 16; + p_digit[2] = p_native[i] >> 8; + p_digit[3] = p_native[i]; + } +} + +static void vli_bytesToNative(uint32_t *p_native, const uint8_t *p_bytes) +{ + unsigned i; + for(i=0; i> 56; + p_digit[1] = p_native[i] >> 48; + p_digit[2] = p_native[i] >> 40; + p_digit[3] = p_native[i] >> 32; + p_digit[4] = p_native[i] >> 24; + p_digit[5] = p_native[i] >> 16; + p_digit[6] = p_native[i] >> 8; + p_digit[7] = p_native[i]; + } +} + +static void vli_bytesToNative(uint64_t *p_native, const uint8_t *p_bytes) +{ + unsigned i; + for(i=0; i= MAX_TRIES)) + { + return 0; + } + if(vli_isZero(l_private)) + { + goto repeat; + } + + /* Make sure the private key is in the range [1, n-1]. */ + #if uECC_CURVE != uECC_secp160r1 + if(vli_cmp(curve_n, l_private) != 1) + { + goto repeat; + } + #endif + + EccPoint_mult(&l_public, &curve_G, l_private, 0, vli_numBits(l_private, uECC_WORDS)); + } while(EccPoint_isZero(&l_public)); + + vli_nativeToBytes(p_privateKey, l_private); + vli_nativeToBytes(p_publicKey, l_public.x); + vli_nativeToBytes(p_publicKey + uECC_BYTES, l_public.y); + return 1; +} + +int uECC_shared_secret(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_privateKey[uECC_BYTES], uint8_t p_secret[uECC_BYTES]) +{ + EccPoint l_public; + uECC_word_t l_private[uECC_WORDS]; + uECC_word_t l_random[uECC_WORDS]; + + g_rng((uint8_t *)l_random, sizeof(l_random)); + + vli_bytesToNative(l_private, p_privateKey); + vli_bytesToNative(l_public.x, p_publicKey); + vli_bytesToNative(l_public.y, p_publicKey + uECC_BYTES); + + EccPoint l_product; + EccPoint_mult(&l_product, &l_public, l_private, (vli_isZero(l_random) ? 0: l_random), vli_numBits(l_private, uECC_WORDS)); + + vli_nativeToBytes(p_secret, l_product.x); + + return !EccPoint_isZero(&l_product); +} + +void uECC_compress(const uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_compressed[uECC_BYTES+1]) +{ + wordcount_t i; + for(i=0; i p_right[uECC_N_WORDS-1]) + { + return 1; + } + else if(p_left[uECC_N_WORDS-1] < p_right[uECC_N_WORDS-1]) + { + return -1; + } + return vli_cmp(p_left, p_right); +} + +static void vli_rshift1_n(uECC_word_t *p_vli) +{ + vli_rshift1(p_vli); + p_vli[uECC_N_WORDS-2] |= p_vli[uECC_N_WORDS-1] << (uECC_WORD_BITS - 1); + p_vli[uECC_N_WORDS-1] = p_vli[uECC_N_WORDS-1] >> 1; +} + +static uECC_word_t vli_add_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_carry = vli_add(p_result, p_left, p_right); + uECC_word_t l_sum = p_left[uECC_N_WORDS-1] + p_right[uECC_N_WORDS-1] + l_carry; + if(l_sum != p_left[uECC_N_WORDS-1]) + { + l_carry = (l_sum < p_left[uECC_N_WORDS-1]); + } + p_result[uECC_N_WORDS-1] = l_sum; + return l_carry; +} + +static uECC_word_t vli_sub_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_borrow = vli_sub(p_result, p_left, p_right); + uECC_word_t l_diff = p_left[uECC_N_WORDS-1] - p_right[uECC_N_WORDS-1] - l_borrow; + if(l_diff != p_left[uECC_N_WORDS-1]) + { + l_borrow = (l_diff > p_left[uECC_N_WORDS-1]); + } + p_result[uECC_N_WORDS-1] = l_diff; + return l_borrow; +} + +#if !muladd_exists +static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t *r0, uECC_word_t *r1, uECC_word_t *r2) +{ + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +} +#define muladd_exists 1 +#endif + +static void vli_mult_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t i, k; + for(k = 0; k < uECC_N_WORDS*2 - 1; ++k) + { + wordcount_t l_min = (k < uECC_N_WORDS ? 0 : (k + 1) - uECC_N_WORDS); + wordcount_t l_max = (k < uECC_N_WORDS ? k : uECC_N_WORDS-1); + for(i = l_min; i <= l_max; ++i) + { + muladd(p_left[i], p_right[k-i], &r0, &r1, &r2); + } + p_result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + p_result[uECC_N_WORDS*2 - 1] = r0; +} + +static void vli_modAdd_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right, uECC_word_t *p_mod) +{ + uECC_word_t l_carry = vli_add_n(p_result, p_left, p_right); + if(l_carry || vli_cmp_n(p_result, p_mod) >= 0) + { + vli_sub_n(p_result, p_result, p_mod); + } +} + +static void vli_modInv_n(uECC_word_t *p_result, uECC_word_t *p_input, uECC_word_t *p_mod) +{ + uECC_word_t a[uECC_N_WORDS], b[uECC_N_WORDS], u[uECC_N_WORDS], v[uECC_N_WORDS]; + uECC_word_t l_carry; + cmpresult_t l_cmpResult; + + if(vli_isZero_n(p_input)) + { + vli_clear_n(p_result); + return; + } + + vli_set_n(a, p_input); + vli_set_n(b, p_mod); + vli_clear_n(u); + u[0] = 1; + vli_clear_n(v); + while((l_cmpResult = vli_cmp_n(a, b)) != 0) + { + l_carry = 0; + if(EVEN(a)) + { + vli_rshift1_n(a); + if(!EVEN(u)) l_carry = vli_add_n(u, u, p_mod); + vli_rshift1_n(u); + if(l_carry) u[uECC_N_WORDS-1] |= HIGH_BIT_SET; + } + else if(EVEN(b)) + { + vli_rshift1_n(b); + if(!EVEN(v)) l_carry = vli_add_n(v, v, p_mod); + vli_rshift1_n(v); + if(l_carry) v[uECC_N_WORDS-1] |= HIGH_BIT_SET; + } + else if(l_cmpResult > 0) + { + vli_sub_n(a, a, b); + vli_rshift1_n(a); + if(vli_cmp_n(u, v) < 0) vli_add_n(u, u, p_mod); + vli_sub_n(u, u, v); + if(!EVEN(u)) l_carry = vli_add_n(u, u, p_mod); + vli_rshift1_n(u); + if(l_carry) u[uECC_N_WORDS-1] |= HIGH_BIT_SET; + } + else + { + vli_sub_n(b, b, a); + vli_rshift1_n(b); + if(vli_cmp_n(v, u) < 0) vli_add_n(v, v, p_mod); + vli_sub_n(v, v, u); + if(!EVEN(v)) l_carry = vli_add_n(v, v, p_mod); + vli_rshift1_n(v); + if(l_carry) v[uECC_N_WORDS-1] |= HIGH_BIT_SET; + } + } + + vli_set_n(p_result, u); +} + +static void vli2_rshift1_n(uECC_word_t *p_vli) +{ + vli_rshift1_n(p_vli); + p_vli[uECC_N_WORDS-1] |= p_vli[uECC_N_WORDS] << (uECC_WORD_BITS - 1); + vli_rshift1_n(p_vli + uECC_N_WORDS); +} + +static uECC_word_t vli2_sub_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_borrow = 0; + wordcount_t i; + for(i=0; i p_left[i]); + } + p_result[i] = l_diff; + } + return l_borrow; +} + +/* Computes p_result = (p_left * p_right) % curve_n. */ +static void vli_modMult_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_product[2 * uECC_N_WORDS]; + uECC_word_t l_modMultiple[2 * uECC_N_WORDS]; + uECC_word_t l_tmp[2 * uECC_N_WORDS]; + uECC_word_t *v[2] = {l_tmp, l_product}; + + vli_mult_n(l_product, p_left, p_right); + vli_clear_n(l_modMultiple); + vli_set(l_modMultiple + uECC_N_WORDS + 1, curve_n); + vli_rshift1(l_modMultiple + uECC_N_WORDS + 1); + l_modMultiple[2 * uECC_N_WORDS - 1] |= HIGH_BIT_SET; + l_modMultiple[uECC_N_WORDS] = HIGH_BIT_SET; + + bitcount_t i; + uECC_word_t l_index = 1; + for(i=0; i<=((((bitcount_t)uECC_N_WORDS) << uECC_WORD_BITS_SHIFT) + (uECC_WORD_BITS - 1)); ++i) + { + uECC_word_t l_borrow = vli2_sub_n(v[1-l_index], v[l_index], l_modMultiple); + l_index = !(l_index ^ l_borrow); /* Swap the index if there was no borrow */ + vli2_rshift1_n(l_modMultiple); + } + + vli_set_n(p_result, v[l_index]); +} + +#else + +#define vli_modInv_n vli_modInv +#define vli_modAdd_n vli_modAdd + +static void vli2_rshift1(uECC_word_t *p_vli) +{ + vli_rshift1(p_vli); + p_vli[uECC_WORDS-1] |= p_vli[uECC_WORDS] << (uECC_WORD_BITS - 1); + vli_rshift1(p_vli + uECC_WORDS); +} + +static uECC_word_t vli2_sub(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_borrow = 0; + wordcount_t i; + for(i=0; i p_left[i]); + } + p_result[i] = l_diff; + } + return l_borrow; +} + +/* Computes p_result = (p_left * p_right) % curve_n. */ +static void vli_modMult_n(uECC_word_t *p_result, uECC_word_t *p_left, uECC_word_t *p_right) +{ + uECC_word_t l_product[2 * uECC_WORDS]; + uECC_word_t l_modMultiple[2 * uECC_WORDS]; + uECC_word_t l_tmp[2 * uECC_WORDS]; + uECC_word_t *v[2] = {l_tmp, l_product}; + + vli_mult(l_product, p_left, p_right); + vli_set(l_modMultiple + uECC_WORDS, curve_n); /* works if curve_n has its highest bit set */ + vli_clear(l_modMultiple); + + bitcount_t i; + uECC_word_t l_index = 1; + for(i=0; i<=uECC_BYTES * 8; ++i) + { + uECC_word_t l_borrow = vli2_sub(v[1-l_index], v[l_index], l_modMultiple); + l_index = !(l_index ^ l_borrow); /* Swap the index if there was no borrow */ + vli2_rshift1(l_modMultiple); + } + + vli_set(p_result, v[l_index]); +} +#endif /* (uECC_CURVE != uECC_secp160r1) */ + +int uECC_sign(const uint8_t p_privateKey[uECC_BYTES], const uint8_t p_hash[uECC_BYTES], uint8_t p_signature[uECC_BYTES*2]) +{ + uECC_word_t k[uECC_N_WORDS]; + uECC_word_t l_tmp[uECC_N_WORDS]; + uECC_word_t s[uECC_N_WORDS]; + uECC_word_t *k2[2] = {l_tmp, s}; + EccPoint p; + uECC_word_t l_tries = 0; + + do + { + repeat: + if(!g_rng((uint8_t *)k, sizeof(k)) || (l_tries++ >= MAX_TRIES)) + { + return 0; + } + + if(vli_isZero(k)) + { + goto repeat; + } + + #if (uECC_CURVE == uECC_secp160r1) + k[uECC_WORDS] &= 0x01; + if(vli_cmp_n(curve_n, k) != 1) + { + goto repeat; + } + + /* make sure that we don't leak timing information about k. See http://eprint.iacr.org/2011/232.pdf */ + vli_add_n(l_tmp, k, curve_n); + uECC_word_t l_carry = (l_tmp[uECC_WORDS] & 0x02); + vli_add_n(s, l_tmp, curve_n); + + /* p = k * G */ + EccPoint_mult(&p, &curve_G, k2[!l_carry], 0, (uECC_BYTES * 8) + 2); + #else + if(vli_cmp(curve_n, k) != 1) + { + goto repeat; + } + + /* make sure that we don't leak timing information about k. See http://eprint.iacr.org/2011/232.pdf */ + uECC_word_t l_carry = vli_add(l_tmp, k, curve_n); + vli_add(s, l_tmp, curve_n); + + /* p = k * G */ + EccPoint_mult(&p, &curve_G, k2[!l_carry], 0, (uECC_BYTES * 8) + 1); + + /* r = x1 (mod n) */ + if(vli_cmp(curve_n, p.x) != 1) + { + vli_sub(p.x, p.x, curve_n); + } + #endif + } while(vli_isZero(p.x)); + + l_tries = 0; + do + { + if(!g_rng((uint8_t *)l_tmp, sizeof(l_tmp)) || (l_tries++ >= MAX_TRIES)) + { + return 0; + } + } while(vli_isZero(l_tmp)); + + /* Prevent side channel analysis of vli_modInv() to determine + bits of k / the private key by premultiplying by a random number */ + vli_modMult_n(k, k, l_tmp); /* k' = rand * k */ + vli_modInv_n(k, k, curve_n); /* k = 1 / k' */ + vli_modMult_n(k, k, l_tmp); /* k = 1 / k */ + + vli_nativeToBytes(p_signature, p.x); /* store r */ + + l_tmp[uECC_N_WORDS-1] = 0; + vli_bytesToNative(l_tmp, p_privateKey); /* tmp = d */ + s[uECC_N_WORDS-1] = 0; + vli_set(s, p.x); + vli_modMult_n(s, l_tmp, s); /* s = r*d */ + + vli_bytesToNative(l_tmp, p_hash); + vli_modAdd_n(s, l_tmp, s, curve_n); /* s = e + r*d */ + vli_modMult_n(s, s, k); /* s = (e + r*d) / k */ +#if (uECC_CURVE == uECC_secp160r1) + if(s[uECC_N_WORDS-1]) + { + goto repeat; + } +#endif + vli_nativeToBytes(p_signature + uECC_BYTES, s); + + return 1; +} + +static bitcount_t smax(bitcount_t a, bitcount_t b) +{ + return (a > b ? a : b); +} + +int uECC_verify(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uECC_BYTES], const uint8_t p_signature[uECC_BYTES*2]) +{ + uECC_word_t u1[uECC_N_WORDS], u2[uECC_N_WORDS]; + uECC_word_t z[uECC_N_WORDS]; + EccPoint l_public, l_sum; + uECC_word_t rx[uECC_WORDS]; + uECC_word_t ry[uECC_WORDS]; + uECC_word_t tx[uECC_WORDS]; + uECC_word_t ty[uECC_WORDS]; + uECC_word_t tz[uECC_WORDS]; + + uECC_word_t r[uECC_N_WORDS], s[uECC_N_WORDS]; + r[uECC_N_WORDS-1] = 0; + s[uECC_N_WORDS-1] = 0; + + vli_bytesToNative(l_public.x, p_publicKey); + vli_bytesToNative(l_public.y, p_publicKey + uECC_BYTES); + vli_bytesToNative(r, p_signature); + vli_bytesToNative(s, p_signature + uECC_BYTES); + + if(vli_isZero(r) || vli_isZero(s)) + { /* r, s must not be 0. */ + return 0; + } + +#if (uECC_CURVE != uECC_secp160r1) + if(vli_cmp(curve_n, r) != 1 || vli_cmp(curve_n, s) != 1) + { /* r, s must be < n. */ + return 0; + } +#endif + + /* Calculate u1 and u2. */ + vli_modInv_n(z, s, curve_n); /* Z = s^-1 */ + u1[uECC_N_WORDS-1] = 0; + vli_bytesToNative(u1, p_hash); + vli_modMult_n(u1, u1, z); /* u1 = e/s */ + vli_modMult_n(u2, r, z); /* u2 = r/s */ + + /* Calculate l_sum = G + Q. */ + vli_set(l_sum.x, l_public.x); + vli_set(l_sum.y, l_public.y); + vli_set(tx, curve_G.x); + vli_set(ty, curve_G.y); + vli_modSub_fast(z, l_sum.x, tx); /* Z = x2 - x1 */ + XYcZ_add(tx, ty, l_sum.x, l_sum.y); + vli_modInv(z, z, curve_p); /* Z = 1/Z */ + apply_z(l_sum.x, l_sum.y, z); + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + EccPoint *l_points[4] = {0, &curve_G, &l_public, &l_sum}; + bitcount_t l_numBits = smax(vli_numBits(u1, uECC_N_WORDS), vli_numBits(u2, uECC_N_WORDS)); + + EccPoint *l_point = l_points[(!!vli_testBit(u1, l_numBits-1)) | ((!!vli_testBit(u2, l_numBits-1)) << 1)]; + vli_set(rx, l_point->x); + vli_set(ry, l_point->y); + vli_clear(z); + z[0] = 1; + + bitcount_t i; + for(i = l_numBits - 2; i >= 0; --i) + { + EccPoint_double_jacobian(rx, ry, z); + + uECC_word_t l_index = (!!vli_testBit(u1, i)) | ((!!vli_testBit(u2, i)) << 1); + l_point = l_points[l_index]; + if(l_point) + { + vli_set(tx, l_point->x); + vli_set(ty, l_point->y); + apply_z(tx, ty, z); + vli_modSub_fast(tz, rx, tx); /* Z = x2 - x1 */ + XYcZ_add(tx, ty, rx, ry); + vli_modMult_fast(z, z, tz); + } + } + + vli_modInv(z, z, curve_p); /* Z = 1/Z */ + apply_z(rx, ry, z); + + /* v = x1 (mod n) */ +#if (uECC_CURVE != uECC_secp160r1) + if(vli_cmp(curve_n, rx) != 1) + { + vli_sub(rx, rx, curve_n); + } +#endif + + /* Accept only if v == r. */ + return (vli_cmp(rx, r) == 0); +} diff --git a/extlibs/tinydtls/ecc/ecc.h b/extlibs/tinydtls/ecc/ecc.h new file mode 100644 index 0000000..92e1313 --- /dev/null +++ b/extlibs/tinydtls/ecc/ecc.h @@ -0,0 +1,171 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _MICRO_ECC_H_ +#define _MICRO_ECC_H_ + +#include + +/* Platform selection options. +If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. +Possible values for uECC_PLATFORM are defined below: */ +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_avr 5 + +/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). +If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your platform. */ + +/* Inline assembly options. +uECC_asm_none - Use standard C99 only. +uECC_asm_small - Use GCC inline assembly for the target platform (if available), optimized for minimum size. +uECC_asm_fast - Use GCC inline assembly optimized for maximum speed. */ +#define uECC_asm_none 0 +#define uECC_asm_small 1 +#define uECC_asm_fast 2 +#ifndef uECC_ASM + #define uECC_ASM uECC_asm_none//uECC_asm_fast +#endif + +/* Curve selection options. */ +#define uECC_secp160r1 1 +#define uECC_secp192r1 2 +#define uECC_secp256r1 3 +#define uECC_secp256k1 4 +#ifndef uECC_CURVE + #define uECC_CURVE uECC_secp256r1 +#endif + +/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be used for (scalar) squaring + instead of the generic multiplication function. This will make things faster by about 8% but increases the code size. */ +#define uECC_SQUARE_FUNC 1 + +#define uECC_CONCAT1(a, b) a##b +#define uECC_CONCAT(a, b) uECC_CONCAT1(a, b) + +#define uECC_size_1 20 /* secp160r1 */ +#define uECC_size_2 24 /* secp192r1 */ +#define uECC_size_3 32 /* secp256r1 */ +#define uECC_size_4 32 /* secp256k1 */ + +#define uECC_BYTES uECC_CONCAT(uECC_size_, uECC_CURVE) + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* uECC_RNG_Function type +The RNG function should fill p_size random bytes into p_dest. It should return 1 if +p_dest was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + +A correctly functioning RNG function must be set (using uECC_set_rng()) before calling +uECC_make_key() or uECC_sign(). + +A correct RNG function is set by default when building for Windows, Linux, or OS X. +If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, +you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined +RNG function; you must provide your own. +*/ +typedef int (*uECC_RNG_Function)(uint8_t *p_dest, unsigned p_size); + +/* uECC_set_rng() function. +Set the function that will be used to generate random bytes. The RNG function should +return 1 if the random data was generated, or 0 if the random data could not be generated. + +On platforms where there is no predefined RNG function (eg embedded platforms), this must +be called before uECC_make_key() or uECC_sign() are used. + +Inputs: + p_rng - The function that will be used to generate random bytes. +*/ +void uECC_set_rng(uECC_RNG_Function p_rng); + +/* uECC_make_key() function. +Create a public/private key pair. + +Outputs: + p_publicKey - Will be filled in with the public key. + p_privateKey - Will be filled in with the private key. + +Returns 1 if the key pair was generated successfully, 0 if an error occurred. +*/ +int uECC_make_key(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKey[uECC_BYTES]); + +/* uECC_shared_secret() function. +Compute a shared secret given your secret key and someone else's public key. +Note: It is recommended that you hash the result of uECC_shared_secret() before using it for symmetric encryption or HMAC. + +Inputs: + p_publicKey - The public key of the remote party. + p_privateKey - Your private key. + +Outputs: + p_secret - Will be filled in with the shared secret value. + +Returns 1 if the shared secret was generated successfully, 0 if an error occurred. +*/ +int uECC_shared_secret(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_privateKey[uECC_BYTES], uint8_t p_secret[uECC_BYTES]); + +/* uECC_compress() function. +Compress a public key. + +Inputs: + p_publicKey - The public key to compress. + +Outputs: + p_compressed - Will be filled in with the compressed public key. +*/ +void uECC_compress(const uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_compressed[uECC_BYTES+1]); + +/* uECC_decompress() function. +Decompress a compressed public key. + +Inputs: + p_compressed - The compressed public key. + +Outputs: + p_publicKey - Will be filled in with the decompressed public key. +*/ +void uECC_decompress(const uint8_t p_compressed[uECC_BYTES+1], uint8_t p_publicKey[uECC_BYTES*2]); + +/* uECC_sign() function. +Generate an ECDSA signature for a given hash value. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to +this function along with your private key. + +Inputs: + p_privateKey - Your private key. + p_hash - The message hash to sign. + +Outputs: + p_signature - Will be filled in with the signature value. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign(const uint8_t p_privateKey[uECC_BYTES], const uint8_t p_hash[uECC_BYTES], uint8_t p_signature[uECC_BYTES*2]); + +/* uECC_verify() function. +Verify an ECDSA signature. + +Usage: Compute the hash of the signed data using the same hash as the signer and +pass it to this function along with the signer's public key and the signature values (r and s). + +Inputs: + p_publicKey - The signer's public key + p_hash - The hash of the signed data. + p_signature - The signature value. + +Returns 1 if the signature is valid, 0 if it is invalid. +*/ +int uECC_verify(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uECC_BYTES], const uint8_t p_signature[uECC_BYTES*2]); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _MICRO_ECC_H_ */ diff --git a/extlibs/tinydtls/ecc/test/ecc_test/ecc_test.ino b/extlibs/tinydtls/ecc/test/ecc_test/ecc_test.ino new file mode 100755 index 0000000..04c5e4a --- /dev/null +++ b/extlibs/tinydtls/ecc/test/ecc_test/ecc_test.ino @@ -0,0 +1,115 @@ +#include + +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include + + +#include + +extern "C" { + +static int RNG(uint8_t *p_dest, unsigned p_size) +{ + // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of random noise) + // This can take a long time to generate random data if the result of analogRead(0) doesn't change very frequently. + while(p_size) { + uint8_t l_val = 0; + for(unsigned i=0; i<8; ++i) + { + int l_init = analogRead(0); + int l_count = 0; + while(analogRead(0) == l_init) + { + ++l_count; + } + + if(l_count == 0) + { + l_val = (l_val << 1) | (l_init & 0x01); + } + else + { + l_val = (l_val << 1) | (l_count & 0x01); + } + } + *p_dest = l_val; + ++p_dest; + --p_size; + } + + // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar. + return 1; +} + +} + +void setup() +{ + Scout.setup(); + + Serial.print("Testing ecc\n"); + + uECC_set_rng(&RNG); +} + +void loop() { + uint8_t l_private1[uECC_BYTES]; + uint8_t l_private2[uECC_BYTES]; + + uint8_t l_public1[uECC_BYTES * 2]; + uint8_t l_public2[uECC_BYTES * 2]; + + uint8_t l_secret1[uECC_BYTES]; + uint8_t l_secret2[uECC_BYTES]; + + unsigned long a = millis(); + uECC_make_key(l_public1, l_private1); + unsigned long b = millis(); + + Serial.print("Made key 1 in "); Serial.println(b-a); + a = millis(); + uECC_make_key(l_public2, l_private2); + b = millis(); + Serial.print("Made key 2 in "); Serial.println(b-a); + + a = millis(); + int r = uECC_shared_secret(l_public2, l_private1, l_secret1); + b = millis(); + Serial.print("Shared secret 1 in "); Serial.println(b-a); + if(!r) + { + Serial.print("shared_secret() failed (1)\n"); + return; + } + + a = millis(); + r = uECC_shared_secret(l_public1, l_private2, l_secret2); + b = millis(); + Serial.print("Shared secret 2 in "); Serial.println(b-a); + if(!r) + { + Serial.print("shared_secret() failed (2)\n"); + return; + } + + if(memcmp(l_secret1, l_secret2, sizeof(l_secret1)) != 0) + { + Serial.print("Shared secrets are not identical!\n"); + } + else + { + Serial.print("Shared secrets are identical\n"); + } +} + diff --git a/extlibs/tinydtls/ecc/test/emk_rules.py b/extlibs/tinydtls/ecc/test/emk_rules.py new file mode 100755 index 0000000..956ccf5 --- /dev/null +++ b/extlibs/tinydtls/ecc/test/emk_rules.py @@ -0,0 +1,4 @@ +c, link = emk.module("c", "link") +link.depdirs += [ + "$:proj:$" +] diff --git a/extlibs/tinydtls/ecc/test/test_ecdh.c b/extlibs/tinydtls/ecc/test/test_ecdh.c new file mode 100644 index 0000000..cef274d --- /dev/null +++ b/extlibs/tinydtls/ecc/test/test_ecdh.c @@ -0,0 +1,107 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "../ecc.h" + +#include +#include + +#if LPC11XX + +#include "/Projects/lpc11xx/peripherals/uart.h" +#include "/Projects/lpc11xx/peripherals/time.h" + +static uint64_t g_rand = 88172645463325252ull; +int fake_rng(uint8_t *p_dest, unsigned p_size) +{ + while(p_size) + { + g_rand ^= (g_rand << 13); + g_rand ^= (g_rand >> 7); + g_rand ^= (g_rand << 17); + + unsigned l_amount = (p_size > 8 ? 8 : p_size); + memcpy(p_dest, &g_rand, l_amount); + p_size -= l_amount; + } + return 1; +} + +#endif + +void vli_print(uint8_t *p_vli, unsigned int p_size) +{ + while(p_size) + { + printf("%02X ", (unsigned)p_vli[p_size - 1]); + --p_size; + } +} + +int main() +{ +#if LPC11XX + uartInit(BAUD_115200); + initTime(); + + uECC_set_rng(&fake_rng); +#endif + + int i; + + uint8_t l_private1[uECC_BYTES]; + uint8_t l_private2[uECC_BYTES]; + + uint8_t l_public1[uECC_BYTES * 2]; + uint8_t l_public2[uECC_BYTES * 2]; + + uint8_t l_secret1[uECC_BYTES]; + uint8_t l_secret2[uECC_BYTES]; + + printf("Testing 256 random private key pairs\n"); + + for(i=0; i<256; ++i) + { + printf("."); + #if !LPC11XX + fflush(stdout); + #endif + + if(!uECC_make_key(l_public1, l_private1) || !uECC_make_key(l_public2, l_private2)) + { + printf("uECC_make_key() failed\n"); + return 1; + } + + if(!uECC_shared_secret(l_public2, l_private1, l_secret1)) + { + printf("shared_secret() failed (1)\n"); + return 1; + } + + if(!uECC_shared_secret(l_public1, l_private2, l_secret2)) + { + printf("shared_secret() failed (2)\n"); + return 1; + } + + if(memcmp(l_secret1, l_secret2, sizeof(l_secret1)) != 0) + { + printf("Shared secrets are not identical!\n"); + printf("Shared secret 1 = "); + vli_print(l_secret1, uECC_BYTES); + printf("\n"); + printf("Shared secret 2 = "); + vli_print(l_secret2, uECC_BYTES); + printf("\n"); + printf("Private key 1 = "); + vli_print(l_private1, uECC_BYTES); + printf("\n"); + printf("Private key 2 = "); + vli_print(l_private2, uECC_BYTES); + printf("\n"); + } + } + printf("\n"); + + return 0; +} diff --git a/extlibs/tinydtls/ecc/test/test_ecdsa.c b/extlibs/tinydtls/ecc/test/test_ecdsa.c new file mode 100644 index 0000000..f3983bb --- /dev/null +++ b/extlibs/tinydtls/ecc/test/test_ecdsa.c @@ -0,0 +1,79 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "../ecc.h" + +#include +#include + +#if LPC11XX + +#include "/Projects/lpc11xx/peripherals/uart.h" +#include "/Projects/lpc11xx/peripherals/time.h" + +static uint64_t g_rand = 88172645463325252ull; +int fake_rng(uint8_t *p_dest, unsigned p_size) +{ + while(p_size) + { + g_rand ^= (g_rand << 13); + g_rand ^= (g_rand >> 7); + g_rand ^= (g_rand << 17); + + unsigned l_amount = (p_size > 8 ? 8 : p_size); + memcpy(p_dest, &g_rand, l_amount); + p_size -= l_amount; + } + return 1; +} + +#endif + +int main() +{ +#if LPC11XX + uartInit(BAUD_115200); + initTime(); + + uECC_set_rng(&fake_rng); +#endif + + uint8_t l_public[uECC_BYTES*2]; + uint8_t l_private[uECC_BYTES]; + + uint8_t l_hash[uECC_BYTES]; + + uint8_t l_sig[uECC_BYTES*2]; + + int i; + + printf("Testing 256 signatures\n"); + + for(i=0; i<256; ++i) + { + printf("."); + #if !LPC11XX + fflush(stdout); + #endif + + if(!uECC_make_key(l_public, l_private)) + { + printf("uECC_make_key() failed\n"); + continue; + } + memcpy(l_hash, l_public, uECC_BYTES); + + if(!uECC_sign(l_private, l_hash, l_sig)) + { + printf("uECC_sign() failed\n"); + continue; + } + + if(!uECC_verify(l_public, l_hash, l_sig)) + { + printf("uECC_verify() failed\n"); + } + } + printf("\n"); + + return 0; +} diff --git a/extlibs/tinydtls/ecc/test_helper.c b/extlibs/tinydtls/ecc/test_helper.c new file mode 100644 index 0000000..bda44ba --- /dev/null +++ b/extlibs/tinydtls/ecc/test_helper.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2009 Chris K Cockrum + * + * Copyright (c) 2013 Jens Trillmann + * Copyright (c) 2013 Marc Müller-Weinhardt + * Copyright (c) 2013 Lars Schmertmann + * Copyright (c) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * This implementation is based in part on the paper Implementation of an + * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by + * Chris K Cockrum . + * + * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf + * + * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU + * architectures. It provides basic operations on the secp256r1 curve and support + * for ECDH and ECDSA. + */ +#include "test_helper.h" +#include "ecc.h" +#include +#include +#include + +void ecc_printNumber(const uint32_t *x, int numberLength){ //here the values are turned to MSB! + int n; + + for(n = numberLength - 1; n >= 0; n--){ + printf("%08x", x[n]); + } + printf("\n"); +} + +void ecc_setRandom(uint32_t *secret){ + int i; + + for (i = 0; i < arrayLength; ++i) + { + secret[i] = rand(); + } +} +const uint32_t ecc_prime_m[8] = {0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xffffffff}; + + +/* This is added after an static byte addition if the answer has a carry in MSB*/ +const uint32_t ecc_prime_r[8] = {0x00000001, 0x00000000, 0x00000000, 0xffffffff, + 0xffffffff, 0xffffffff, 0xfffffffe, 0x00000000}; + +#ifdef CONTIKI +void +test_assert(const char *file, int lineno) +{ + printf("Assertion failed: file %s, line %d.\n", file, lineno); + /* + * loop for a while; + * call _reset_vector__(); + */ +} +#endif diff --git a/extlibs/tinydtls/ecc/test_helper.h b/extlibs/tinydtls/ecc/test_helper.h new file mode 100644 index 0000000..38a194e --- /dev/null +++ b/extlibs/tinydtls/ecc/test_helper.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009 Chris K Cockrum + * + * Copyright (c) 2013 Jens Trillmann + * Copyright (c) 2013 Marc Müller-Weinhardt + * Copyright (c) 2013 Lars Schmertmann + * Copyright (c) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * This implementation is based in part on the paper Implementation of an + * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by + * Chris K Cockrum . + * + * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf + * + * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU + * architectures. It provides basic operations on the secp256r1 curve and support + * for ECDH and ECDSA. + */ +#include + +extern const uint32_t ecc_prime_m[8]; +extern const uint32_t ecc_prime_r[8]; + +//debug function to print long numbers +void ecc_printNumber(const uint32_t *x, int numberLength); +void ecc_setRandom(uint32_t *secret); + +#ifdef CONTIKI +#undef assert +#define assert(e) ((e) ? (void)0 : test_assert(__FILE__, __LINE__)) +void test_assert(const char *, int); +#endif diff --git a/extlibs/tinydtls/ecc/testecc.c b/extlibs/tinydtls/ecc/testecc.c new file mode 100644 index 0000000..b36d46b --- /dev/null +++ b/extlibs/tinydtls/ecc/testecc.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2009 Chris K Cockrum + * + * Copyright (c) 2013 Jens Trillmann + * Copyright (c) 2013 Marc Müller-Weinhardt + * Copyright (c) 2013 Lars Schmertmann + * Copyright (c) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * This implementation is based in part on the paper Implementation of an + * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by + * Chris K Cockrum . + * + * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf + * + * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU + * architectures. It provides basic operations on the secp256r1 curve and support + * for ECDH and ECDSA. + */ + +#include +#include +#include +#include + +#include "ecc.h" +#include "test_helper.h" + +#ifdef CONTIKI +#include "contiki.h" +#else +#include +#endif /* CONTIKI */ + +//These are testvalues taken from the NIST P-256 definition +//6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296 +uint32_t BasePointx[8] = { 0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, + 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2}; + +//4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5 +uint32_t BasePointy[8] = { 0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, + 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2}; + +//de2444be bc8d36e6 82edd27e 0f271508 617519b3 221a8fa0 b77cab39 89da97c9 +uint32_t Sx[8] = { 0x89da97c9, 0xb77cab39, 0x221a8fa0, 0x617519b3, + 0x0f271508, 0x82edd27e, 0xbc8d36e6, 0xde2444be}; + +//c093ae7f f36e5380 fc01a5aa d1e66659 702de80f 53cec576 b6350b24 3042a256 +uint32_t Sy[8] = { 0x3042a256, 0xb6350b24, 0x53cec576, 0x702de80f, + 0xd1e66659, 0xfc01a5aa, 0xf36e5380, 0xc093ae7f}; + +//55a8b00f 8da1d44e 62f6b3b2 5316212e 39540dc8 61c89575 bb8cf92e 35e0986b +uint32_t Tx[8] = { 0x35e0986b, 0xbb8cf92e, 0x61c89575, 0x39540dc8, + 0x5316212e, 0x62f6b3b2, 0x8da1d44e, 0x55a8b00f}; + +//5421c320 9c2d6c70 4835d82a c4c3dd90 f61a8a52 598b9e7a b656e9d8 c8b24316 +uint32_t Ty[8] = { 0xc8b24316, 0xb656e9d8, 0x598b9e7a, 0xf61a8a52, + 0xc4c3dd90, 0x4835d82a, 0x9c2d6c70, 0x5421c320}; + +//c51e4753 afdec1e6 b6c6a5b9 92f43f8d d0c7a893 3072708b 6522468b 2ffb06fd +uint32_t secret[8] = { 0x2ffb06fd, 0x6522468b, 0x3072708b, 0xd0c7a893, + 0x92f43f8d, 0xb6c6a5b9, 0xafdec1e6, 0xc51e4753}; + +//72b13dd4 354b6b81 745195e9 8cc5ba69 70349191 ac476bd4 553cf35a 545a067e +uint32_t resultAddx[8] = { 0x545a067e, 0x553cf35a, 0xac476bd4, 0x70349191, + 0x8cc5ba69, 0x745195e9, 0x354b6b81, 0x72b13dd4}; + +//8d585cbb 2e1327d7 5241a8a1 22d7620d c33b1331 5aa5c9d4 6d013011 744ac264 +uint32_t resultAddy[8] = { 0x744ac264, 0x6d013011, 0x5aa5c9d4, 0xc33b1331, + 0x22d7620d, 0x5241a8a1, 0x2e1327d7, 0x8d585cbb}; + +//7669e690 1606ee3b a1a8eef1 e0024c33 df6c22f3 b17481b8 2a860ffc db6127b0 +uint32_t resultDoublex[8] = { 0xdb6127b0, 0x2a860ffc, 0xb17481b8, 0xdf6c22f3, + 0xe0024c33, 0xa1a8eef1, 0x1606ee3b, 0x7669e690}; + +//fa878162 187a54f6 c39f6ee0 072f33de 389ef3ee cd03023d e10ca2c1 db61d0c7 +uint32_t resultDoubley[8] = { 0xdb61d0c7, 0xe10ca2c1, 0xcd03023d, 0x389ef3ee, + 0x072f33de, 0xc39f6ee0, 0x187a54f6, 0xfa878162}; + +//51d08d5f 2d427888 2946d88d 83c97d11 e62becc3 cfc18bed acc89ba3 4eeca03f +uint32_t resultMultx[8] = { 0x4eeca03f, 0xacc89ba3, 0xcfc18bed, 0xe62becc3, + 0x83c97d11, 0x2946d88d, 0x2d427888, 0x51d08d5f}; + +//75ee68eb 8bf626aa 5b673ab5 1f6e744e 06f8fcf8 a6c0cf30 35beca95 6a7b41d5 +uint32_t resultMulty[8] = { 0x6a7b41d5, 0x35beca95, 0xa6c0cf30, 0x06f8fcf8, + 0x1f6e744e, 0x5b673ab5, 0x8bf626aa, 0x75ee68eb}; + +static const uint32_t ecdsaTestMessage[] = { 0x65637572, 0x20612073, 0x68206F66, 0x20686173, 0x69732061, 0x68697320, 0x6F2C2054, 0x48616C6C}; + +static const uint32_t ecdsaTestSecret[] = {0x94A949FA, 0x401455A1, 0xAD7294CA, 0x896A33BB, 0x7A80E714, 0x4321435B, 0x51247A14, 0x41C1CB6B}; + +static const uint32_t ecdsaTestRand1[] = { 0x1D1E1F20, 0x191A1B1C, 0x15161718, 0x11121314, 0x0D0E0F10, 0x090A0B0C, 0x05060708, 0x01020304}; +static const uint32_t ecdsaTestresultR1[] = { 0xC3B4035F, 0x515AD0A6, 0xBF375DCA, 0x0CC1E997, 0x7F54FDCD, 0x04D3FECA, 0xB9E396B9, 0x515C3D6E}; +static const uint32_t ecdsaTestresultS1[] = { 0x5366B1AB, 0x0F1DBF46, 0xB0C8D3C4, 0xDB755B6F, 0xB9BF9243, 0xE644A8BE, 0x55159A59, 0x6F9E52A6}; + +static const uint32_t ecdsaTestRand2[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01FFFFFF}; +static const uint32_t ecdsaTestresultR2[] = { 0x14146C91, 0xE878724D, 0xCD4FF928, 0xCC24BC04, 0xAC403390, 0x650C0060, 0x4A30B3F1, 0x9C69B726}; +static const uint32_t ecdsaTestresultS2[] = { 0x433AAB6F, 0x808250B1, 0xE46F90F4, 0xB342E972, 0x18B2F7E4, 0x2DB981A2, 0x6A288FA4, 0x41CF59DB}; + +void addTest(){ + uint32_t tempx[8]; + uint32_t tempy[8]; + + ecc_ec_add(Tx, Ty, Sx, Sy, tempx, tempy); + assert(ecc_isSame(tempx, resultAddx, arrayLength)); + assert(ecc_isSame(tempy, resultAddy, arrayLength)); +} + +void doubleTest(){ + uint32_t tempx[8]; + uint32_t tempy[8]; + + ecc_ec_double(Sx, Sy, tempx, tempy); + assert(ecc_isSame(tempx, resultDoublex, arrayLength)); + assert(ecc_isSame(tempy, resultDoubley, arrayLength)); +} + +void multTest(){ + uint32_t tempx[8]; + uint32_t tempy[8]; + + ecc_ec_mult(Sx, Sy, secret, tempx, tempy); + assert(ecc_isSame(tempx, resultMultx, arrayLength)); + assert(ecc_isSame(tempy, resultMulty, arrayLength)); +} + +void eccdhTest(){ + uint32_t tempx[8]; + uint32_t tempy[8]; + uint32_t tempAx2[8]; + uint32_t tempAy2[8]; + uint32_t tempBx1[8]; + uint32_t tempBy1[8]; + uint32_t tempBx2[8]; + uint32_t tempBy2[8]; + uint32_t secretA[8]; + uint32_t secretB[8]; + ecc_setRandom(secretA); + ecc_printNumber(secretA, 8); + ecc_setRandom(secretB); + ecc_printNumber(secretB, 8); + ecc_ec_mult(BasePointx, BasePointy, secretA, tempx, tempy); + ecc_ec_mult(BasePointx, BasePointy, secretB, tempBx1, tempBy1); + //public key exchange + ecc_ec_mult(tempBx1, tempBy1, secretA, tempAx2, tempAy2); + ecc_ec_mult(tempx, tempy, secretB, tempBx2, tempBy2); + assert(ecc_isSame(tempAx2, tempBx2, arrayLength)); + assert(ecc_isSame(tempAy2, tempBy2, arrayLength)); + +} + +void ecdsaTest() { + int ret __attribute__((unused)); + uint32_t tempx[9]; + uint32_t tempy[9]; + uint32_t pub_x[8]; + uint32_t pub_y[8]; + + ecc_ec_mult(BasePointx, BasePointy, ecdsaTestSecret, pub_x, pub_y); + + ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand1, tempx, tempy); + assert(ecc_isSame(tempx, ecdsaTestresultR1, arrayLength)); + assert(ecc_isSame(tempy, ecdsaTestresultS1, arrayLength)); + assert(ret == 0); + + ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy); + assert(!ret); + + + ret = ecc_ecdsa_sign(ecdsaTestSecret, ecdsaTestMessage, ecdsaTestRand2, tempx, tempy); + assert(ecc_isSame(tempx, ecdsaTestresultR2, arrayLength)); + assert(ecc_isSame(tempy, ecdsaTestresultS2, arrayLength)); + assert(ret == 0); + + ret = ecc_ecdsa_validate(pub_x, pub_y, ecdsaTestMessage, tempx, tempy); + assert(!ret); +} + +#ifdef CONTIKI +PROCESS(ecc_filed_test, "ECC test"); +AUTOSTART_PROCESSES(&ecc_filed_test); +PROCESS_THREAD(ecc_filed_test, ev, d) +{ + PROCESS_BEGIN(); + + srand(1234); + addTest(); + doubleTest(); + multTest(); + eccdhTest(); + ecdsaTest(); + printf("%s\n", "All Tests successful."); + + PROCESS_END(); +} +#else /* CONTIKI */ +int main(int argc, char const *argv[]) +{ + srand(time(NULL)); + addTest(); + doubleTest(); + multTest(); + eccdhTest(); + ecdsaTest(); + printf("%s\n", "All Tests successful."); + return 0; +} +#endif /* CONTIKI */ diff --git a/extlibs/tinydtls/ecc/testfield.c b/extlibs/tinydtls/ecc/testfield.c new file mode 100644 index 0000000..30a690e --- /dev/null +++ b/extlibs/tinydtls/ecc/testfield.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2009 Chris K Cockrum + * + * Copyright (c) 2013 Jens Trillmann + * Copyright (c) 2013 Marc Müller-Weinhardt + * Copyright (c) 2013 Lars Schmertmann + * Copyright (c) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * + * This implementation is based in part on the paper Implementation of an + * Elliptic Curve Cryptosystem on an 8-bit Microcontroller [0] by + * Chris K Cockrum . + * + * [0]: http://cockrum.net/Implementation_of_ECC_on_an_8-bit_microcontroller.pdf + * + * This is a efficient ECC implementation on the secp256r1 curve for 32 Bit CPU + * architectures. It provides basic operations on the secp256r1 curve and support + * for ECDH and ECDSA. + */ +#include +#include +#include +#include "ecc.h" +#include "test_helper.h" + +#ifdef CONTIKI +#include "contiki.h" +#endif /* CONTIKI */ + +//arbitrary test values and results +uint32_t null[8] = { 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t null64[16] = { 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t one[8] = { 0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t one64[16] = { 0x00000001,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t two[8] = { 0x00000002,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t two64[16] = { 0x00000002,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t three[8] = { 0x00000003,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t four[8] = {0x00000004,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t four64[16] = { 0x00000004,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t six[8] = { 0x00000006,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t eight[8] = { 0x00000008,0x00000000,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000}; +uint32_t full[8] = { 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; +//00000000fffffffeffffffffffffffffffffffff000000000000000000000001_16 +uint32_t resultFullAdd[8] = { 0x00000001,0x00000000,0x00000000,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000000}; +uint32_t primeMinusOne[8]= { 0xfffffffe,0xffffffff,0xffffffff,0x00000000, + 0x00000000,0x00000000,0x00000001,0xffffffff}; +uint32_t resultDoubleMod[8] = { 0xfffffffd,0xffffffff,0xffffffff,0x00000000, + 0x00000000,0x00000000,0x00000001,0xffffffff}; +//fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffc00000003fffffffcfffffffffffffffffffffffc000000000000000000000004_16 +uint32_t resultQuadMod[16] = { 0x00000004,0x00000000,0x00000000,0xFFFFFFFC, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFC,0x00000003, + 0xFFFFFFFC,0x00000001,0xFFFFFFFE,0x00000001, + 0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE}; +//00000002fffffffffffffffffffffffefffffffdffffffff0000000000000002_16 +uint32_t resultFullMod[8] = { 0x00000002,0x00000000,0xFFFFFFFF,0xFFFFFFFD, + 0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000002}; + +static const uint32_t orderMinusOne[8] = {0xFC632550, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; +static const uint32_t orderResultDoubleMod[8] = {0xFC63254F, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF}; + +uint32_t temp[8]; +uint32_t temp2[16]; + +void nullEverything(){ + memset(temp, 0, sizeof(temp)); + memset(temp2, 0, sizeof(temp)); +} + +void fieldAddTest(){ + assert(ecc_isSame(one, one, arrayLength)); + ecc_fieldAdd(one, null, ecc_prime_r, temp); + assert(ecc_isSame(temp, one, arrayLength)); + nullEverything(); + ecc_fieldAdd(one, one, ecc_prime_r, temp); + assert(ecc_isSame(temp, two, arrayLength)); + nullEverything(); + ecc_add(full, one, temp, 32); + assert(ecc_isSame(null, temp, arrayLength)); + nullEverything(); + ecc_fieldAdd(full, one, ecc_prime_r, temp); + assert(ecc_isSame(temp, resultFullAdd, arrayLength)); +} + +void fieldSubTest(){ + assert(ecc_isSame(one, one, arrayLength)); + ecc_fieldSub(one, null, ecc_prime_m, temp); + assert(ecc_isSame(one, temp, arrayLength)); + nullEverything(); + ecc_fieldSub(one, one, ecc_prime_m, temp); + assert(ecc_isSame(null, temp, arrayLength)); + nullEverything(); + ecc_fieldSub(null, one, ecc_prime_m, temp); + assert(ecc_isSame(primeMinusOne, temp, arrayLength)); +} + +void fieldMultTest(){ + ecc_fieldMult(one, null, temp2, arrayLength); + assert(ecc_isSame(temp2, null64, arrayLength * 2)); + nullEverything(); + ecc_fieldMult(one, two, temp2, arrayLength); + assert(ecc_isSame(temp2, two64, arrayLength * 2)); + nullEverything(); + ecc_fieldMult(two, two, temp2, arrayLength); + assert(ecc_isSame(temp2, four64, arrayLength * 2)); + nullEverything(); + ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength); + assert(ecc_isSame(temp2, resultQuadMod, arrayLength * 2)); + nullEverything(); + ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, two, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(temp, one, arrayLength)); +} + +void fieldModPTest(){ + ecc_fieldMult(primeMinusOne, primeMinusOne, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(temp, one, arrayLength)); + nullEverything(); + ecc_fieldModP(temp, one64); + assert(ecc_isSame(temp, one, arrayLength)); + nullEverything(); + ecc_fieldMult(two, primeMinusOne, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(temp, resultDoubleMod, arrayLength)); + nullEverything(); + /*fieldMult(full, full, temp2, arrayLength); //not working, maybe because of the number bigger than p^2? + fieldModP(temp, temp2); + assert(ecc_isSame(temp, resultFullMod, arrayLength));*/ +} + +void fieldModOTest(){ + ecc_fieldMult(orderMinusOne, orderMinusOne, temp2, arrayLength); + ecc_fieldModO(temp2, temp, arrayLength * 2); + assert(ecc_isSame(temp, one, arrayLength)); + nullEverything(); + ecc_fieldModO(one64, temp, arrayLength * 2); + assert(ecc_isSame(temp, one, arrayLength)); + nullEverything(); + ecc_fieldMult(two, orderMinusOne, temp2, arrayLength); + ecc_fieldModO(temp2, temp, arrayLength * 2); + assert(ecc_isSame(temp, orderResultDoubleMod, arrayLength)); + nullEverything(); +} + + +// void rShiftTest(){ +// printNumber(full, 32); +// rshift(full); +// printNumber(full, 32); +// printNumber(two, 32); +// rshift(two); +// printNumber(two, 32); +// printNumber(four, 32); +// rshift(four); +// printNumber(four, 32); +// } + +// void isOneTest(){ +// printf("%d\n", isone(one)); +// printf("%d\n", isone(two)); +// printf("%d\n", isone(four)); +// printf("%d\n", isone(full)); +// printf("%d\n", isone(null)); +// } + +void fieldInvTest(){ + nullEverything(); + ecc_fieldInv(two, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, two, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(one, temp, arrayLength)); + nullEverything(); + ecc_fieldInv(eight, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, eight, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(one, temp, arrayLength)); + nullEverything(); + ecc_fieldInv(three, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, three, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(one, temp, arrayLength)); + nullEverything(); + ecc_fieldInv(six, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, six, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(one, temp, arrayLength)); + nullEverything(); + ecc_fieldInv(primeMinusOne, ecc_prime_m, ecc_prime_r, temp); + ecc_fieldMult(temp, primeMinusOne, temp2, arrayLength); + ecc_fieldModP(temp, temp2); + assert(ecc_isSame(one, temp, arrayLength)); +} + +// void randomStuff(){ + +// } + +#ifdef CONTIKI +PROCESS(ecc_filed_test, "ECC field test"); +AUTOSTART_PROCESSES(&ecc_filed_test); +PROCESS_THREAD(ecc_filed_test, ev, d) +{ + PROCESS_BEGIN(); + + nullEverything(); + //randomStuff(); + nullEverything(); + fieldAddTest(); + nullEverything(); + fieldSubTest(); + nullEverything(); + fieldMultTest(); + nullEverything(); + fieldModPTest(); + nullEverything(); + fieldModOTest(); + nullEverything(); + fieldInvTest(); + nullEverything(); + //rShiftTest(); + //isOneTest(); + printf("%s\n", "All Tests succesfull!"); + + PROCESS_END(); +} +#else /* CONTIKI */ +int main(int argc, char const *argv[]) +{ + nullEverything(); + //randomStuff(); + nullEverything(); + fieldAddTest(); + nullEverything(); + fieldSubTest(); + nullEverything(); + fieldMultTest(); + nullEverything(); + fieldModPTest(); + nullEverything(); + fieldModOTest(); + nullEverything(); + fieldInvTest(); + nullEverything(); + //rShiftTest(); + //isOneTest(); + printf("%s\n", "All Tests succesfull!"); + return 0; +} +#endif /* CONTIKI */ diff --git a/extlibs/tinydtls/examples/contiki/Makefile.in b/extlibs/tinydtls/examples/contiki/Makefile.in new file mode 100644 index 0000000..770f220 --- /dev/null +++ b/extlibs/tinydtls/examples/contiki/Makefile.in @@ -0,0 +1,61 @@ +######################################################################## +# platform-specific options + +ifeq ($(TARGET), econotag) +CFLAGS += -DUIP_CONF_TCP=0 +endif + +ifeq ($(TARGET), minimal-net) +UIP_CONF_IPV6_RPL=0 +CFLAGS += -DUIP_CONF_IPV6_RPL=0 -DRPL_BORDER_ROUTER=0 +endif + +# usually, you should not need changing anything beyond this line +######################################################################## + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_srcdir:= @top_srcdir@ +DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ +DTLS_SOURCES:=dtls-server.c dtls-client.c +FILES:=Makefile.in $(DTLS_SOURCES) + +all: dtls-server dtls-client + $(MAKE) $(MAKEFLAGS) ROLE=server dtls-server + $(MAKE) $(MAKEFLAGS) clean + $(MAKE) $(MAKEFLAGS) ROLE=client dtls-client + +CONTIKI=$(top_srcdir)/../.. + +WITH_UIP6=1 +UIP_CONF_IPV6=1 + +ifneq ($(ROLE),client) + CFLAGS+= -DHARD_CODED_ADDRESS=\"aaaa::02:232\" +else + CFLAGS+= -DUDP_CONNECTION_ADDR="fe80::ff:fe02:232" \ + -DHARD_CODED_ADDRESS=\"aaaa::02:230\" +endif + +CFLAGS += -ffunction-sections +LDFLAGS += -Wl,--gc-sections,--undefined=_reset_vector__,--undefined=InterruptVectors,--undefined=_copy_data_init__,--undefined=_clear_bss_init__,--undefined=_end_of_init__ + +CFLAGS += -DSHA2_USE_INTTYPES_H + +APPS += tinydtls/aes tinydtls/sha2 tinydtls/ecc tinydtls + +ccm-test: tests/ccm-test + +dist: $(FILES) + test -d $(DISTDIR)/examples/contiki || $(MKDIR) -p $(DISTDIR)/examples/contiki + cp $(FILES) $(DISTDIR)/examples/contiki + +include $(CONTIKI)/Makefile.include diff --git a/extlibs/tinydtls/examples/contiki/dtls-client.c b/extlibs/tinydtls/examples/contiki/dtls-client.c new file mode 100644 index 0000000..b1af669 --- /dev/null +++ b/extlibs/tinydtls/examples/contiki/dtls-client.c @@ -0,0 +1,337 @@ +/* + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#include "dev/serial-line.h" + +#include + +#include "tinydtls.h" + +#ifndef DEBUG +#define DEBUG DEBUG_PRINT +#endif +#include "net/ip/uip-debug.h" + +#include "debug.h" +#include "dtls.h" + +#ifdef DTLS_PSK +/* The PSK information for DTLS */ +/* make sure that default identity and key fit into buffer, i.e. + * sizeof(PSK_DEFAULT_IDENTITY) - 1 <= PSK_ID_MAXLEN and + * sizeof(PSK_DEFAULT_KEY) - 1 <= PSK_MAXLEN +*/ + +#define PSK_ID_MAXLEN 32 +#define PSK_MAXLEN 32 +#define PSK_DEFAULT_IDENTITY "Client_identity" +#define PSK_DEFAULT_KEY "secretPSK" +#endif /* DTLS_PSK */ + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) + +#define MAX_PAYLOAD_LEN 120 + +static struct uip_udp_conn *client_conn; +static dtls_context_t *dtls_context; +static char buf[200]; +static size_t buflen = 0; + +static const unsigned char ecdsa_priv_key[] = { + 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, + 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, + 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, + 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA}; + +static const unsigned char ecdsa_pub_key_x[] = { + 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, + 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, + 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, + 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52}; + +static const unsigned char ecdsa_pub_key_y[] = { + 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, + 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, + 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, + 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29}; + +static void +try_send(struct dtls_context_t *ctx, session_t *dst) { + int res; + res = dtls_write(ctx, dst, (uint8 *)buf, buflen); + if (res >= 0) { + memmove(buf, buf + res, buflen - res); + buflen -= res; + } +} + +static int +read_from_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + size_t i; + for (i = 0; i < len; i++) + PRINTF("%c", data[i]); + return 0; +} + +static int +send_to_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + + struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); + + uip_ipaddr_copy(&conn->ripaddr, &session->addr); + conn->rport = session->port; + + PRINTF("send to "); + PRINT6ADDR(&conn->ripaddr); + PRINTF(":%u\n", uip_ntohs(conn->rport)); + + uip_udp_packet_send(conn, data, len); + + /* Restore server connection to allow data from any node */ + /* FIXME: do we want this at all? */ + memset(&conn->ripaddr, 0, sizeof(conn->ripaddr)); + memset(&conn->rport, 0, sizeof(conn->rport)); + + return len; +} + +#ifdef DTLS_PSK +static unsigned char psk_id[PSK_ID_MAXLEN] = PSK_DEFAULT_IDENTITY; +static size_t psk_id_length = sizeof(PSK_DEFAULT_IDENTITY) - 1; +static unsigned char psk_key[PSK_MAXLEN] = PSK_DEFAULT_KEY; +static size_t psk_key_length = sizeof(PSK_DEFAULT_KEY) - 1; + +#ifdef __GNUC__ +#define UNUSED_PARAM __attribute__((unused)) +#else +#define UNUSED_PARAM +#endif /* __GNUC__ */ + +/* This function is the "key store" for tinyDTLS. It is called to + * retrieve a key for the given identity within this particular + * session. */ +static int +get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, + const session_t *session UNUSED_PARAM, + dtls_credentials_type_t type, + const unsigned char *id, size_t id_len, + unsigned char *result, size_t result_length) { + + switch (type) { + case DTLS_PSK_IDENTITY: + if (result_length < psk_id_length) { + dtls_warn("cannot set psk_identity -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_id, psk_id_length); + return psk_id_length; + case DTLS_PSK_KEY: + if (id_len != psk_id_length || memcmp(psk_id, id, id_len) != 0) { + dtls_warn("PSK for unknown id requested, exiting\n"); + return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); + } else if (result_length < psk_key_length) { + dtls_warn("cannot set psk -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_key, psk_key_length); + return psk_key_length; + default: + dtls_warn("unsupported request type: %d\n", type); + } + + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); +} +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC +static int +get_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecdsa_key_t **result) { + static const dtls_ecdsa_key_t ecdsa_key = { + .curve = DTLS_ECDH_CURVE_SECP256R1, + .priv_key = ecdsa_priv_key, + .pub_key_x = ecdsa_pub_key_x, + .pub_key_y = ecdsa_pub_key_y + }; + + *result = &ecdsa_key; + return 0; +} + +static int +verify_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char *other_pub_x, + const unsigned char *other_pub_y, + size_t key_size) { + return 0; +} +#endif /* DTLS_ECC */ + +PROCESS(udp_server_process, "UDP server process"); +AUTOSTART_PROCESSES(&udp_server_process); +/*---------------------------------------------------------------------------*/ +static void +dtls_handle_read(dtls_context_t *ctx) { + static session_t session; + + if(uip_newdata()) { + uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); + session.port = UIP_UDP_BUF->srcport; + session.size = sizeof(session.addr) + sizeof(session.port); + + ((char *)uip_appdata)[uip_datalen()] = 0; + PRINTF("Client received message from "); + PRINT6ADDR(&session.addr); + PRINTF(":%d\n", uip_ntohs(session.port)); + + dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); + } +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Client IPv6 addresses: "); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + } + } +} + +static void +set_connection_address(uip_ipaddr_t *ipaddr) +{ +#define _QUOTEME(x) #x +#define QUOTEME(x) _QUOTEME(x) +#ifdef UDP_CONNECTION_ADDR + if(uiplib_ipaddrconv(QUOTEME(UDP_CONNECTION_ADDR), ipaddr) == 0) { + PRINTF("UDP client failed to parse address '%s'\n", QUOTEME(UDP_CONNECTION_ADDR)); + } +#elif UIP_CONF_ROUTER + uip_ip6addr(ipaddr,0xaaaa,0,0,0,0x0200,0x0000,0x0000,0x0001); +#else + uip_ip6addr(ipaddr,0xfe80,0,0,0,0x6466,0x6666,0x6666,0x6666); +#endif /* UDP_CONNECTION_ADDR */ +} + +void +init_dtls(session_t *dst) { + static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, +#ifdef DTLS_PSK + .get_psk_info = get_psk_info, +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + .get_ecdsa_key = get_ecdsa_key, + .verify_ecdsa_key = verify_ecdsa_key +#endif /* DTLS_ECC */ + }; + PRINTF("DTLS client started\n"); + + print_local_addresses(); + + dst->size = sizeof(dst->addr) + sizeof(dst->port); + dst->port = UIP_HTONS(20220); + + set_connection_address(&dst->addr); + client_conn = udp_new(&dst->addr, 0, NULL); + udp_bind(client_conn, dst->port); + + PRINTF("set connection address to "); + PRINT6ADDR(&dst->addr); + PRINTF(":%d\n", uip_ntohs(dst->port)); + + dtls_set_log_level(DTLS_LOG_DEBUG); + + dtls_context = dtls_new_context(client_conn); + if (dtls_context) + dtls_set_handler(dtls_context, &cb); +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_server_process, ev, data) +{ + static int connected = 0; + static session_t dst; + + PROCESS_BEGIN(); + + dtls_init(); + + init_dtls(&dst); + serial_line_init(); + + if (!dtls_context) { + dtls_emerg("cannot create context\n"); + PROCESS_EXIT(); + } + + while(1) { + PROCESS_YIELD(); + if(ev == tcpip_event) { + dtls_handle_read(dtls_context); + } else if (ev == serial_line_event_message) { + register size_t len = min(strlen(data), sizeof(buf) - buflen); + memcpy(buf + buflen, data, len); + buflen += len; + if (buflen < sizeof(buf) - 1) + buf[buflen++] = '\n'; /* serial event does not contain LF */ + } + + if (buflen) { + if (!connected) + connected = dtls_connect(dtls_context, &dst) >= 0; + + try_send(dtls_context, &dst); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/extlibs/tinydtls/examples/contiki/dtls-server.c b/extlibs/tinydtls/examples/contiki/dtls-server.c new file mode 100644 index 0000000..d9269a8 --- /dev/null +++ b/extlibs/tinydtls/examples/contiki/dtls-server.c @@ -0,0 +1,332 @@ +/* + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + +#if UIP_CONF_IPV6_RPL +#include "net/rpl/rpl.h" +#endif /* UIP_CONF_IPV6_RPL */ + +#include + +#include "tinydtls.h" + +#ifndef DEBUG +#define DEBUG DEBUG_PRINT +#endif +#include "net/ip/uip-debug.h" + +#include "debug.h" +#include "dtls.h" + +#ifdef ENABLE_POWERTRACE +#include "powertrace.h" +#endif + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) + +#define MAX_PAYLOAD_LEN 120 + +static struct uip_udp_conn *server_conn; + +static dtls_context_t *dtls_context; + +static const unsigned char ecdsa_priv_key[] = { + 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, + 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, + 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, + 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; + +static const unsigned char ecdsa_pub_key_x[] = { + 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, + 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, + 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, + 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; + +static const unsigned char ecdsa_pub_key_y[] = { + 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, + 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, + 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, + 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; + +static int +read_from_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + size_t i; + for (i = 0; i < len; i++) + PRINTF("%c", data[i]); + + /* echo incoming application data */ + dtls_write(ctx, session, data, len); + return 0; +} + +static int +send_to_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + + struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx); + + uip_ipaddr_copy(&conn->ripaddr, &session->addr); + conn->rport = session->port; + + PRINTF("send to "); + PRINT6ADDR(&conn->ripaddr); + PRINTF(":%u\n", uip_ntohs(conn->rport)); + + uip_udp_packet_send(conn, data, len); + + /* Restore server connection to allow data from any node */ + memset(&conn->ripaddr, 0, sizeof(conn->ripaddr)); + memset(&conn->rport, 0, sizeof(conn->rport)); + + return len; +} + +#ifdef DTLS_PSK +/* This function is the "key store" for tinyDTLS. It is called to + * retrieve a key for the given identity within this particular + * session. */ +static int +get_psk_info(struct dtls_context_t *ctx, const session_t *session, + dtls_credentials_type_t type, + const unsigned char *id, size_t id_len, + unsigned char *result, size_t result_length) { + + struct keymap_t { + unsigned char *id; + size_t id_length; + unsigned char *key; + size_t key_length; + } psk[3] = { + { (unsigned char *)"Client_identity", 15, + (unsigned char *)"secretPSK", 9 }, + { (unsigned char *)"default identity", 16, + (unsigned char *)"\x11\x22\x33", 3 }, + { (unsigned char *)"\0", 2, + (unsigned char *)"", 1 } + }; + + if (type != DTLS_PSK_KEY) { + return 0; + } + + if (id) { + int i; + for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { + if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { + if (result_length < psk[i].key_length) { + dtls_warn("buffer too small for PSK"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk[i].key, psk[i].key_length); + return psk[i].key_length; + } + } + } + + return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); +} +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC +static int +get_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecdsa_key_t **result) { + static const dtls_ecdsa_key_t ecdsa_key = { + .curve = DTLS_ECDH_CURVE_SECP256R1, + .priv_key = ecdsa_priv_key, + .pub_key_x = ecdsa_pub_key_x, + .pub_key_y = ecdsa_pub_key_y + }; + + *result = &ecdsa_key; + return 0; +} + +static int +verify_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char *other_pub_x, + const unsigned char *other_pub_y, + size_t key_size) { + return 0; +} +#endif /* DTLS_ECC */ + +PROCESS(udp_server_process, "UDP server process"); +AUTOSTART_PROCESSES(&udp_server_process); +/*---------------------------------------------------------------------------*/ +static void +dtls_handle_read(dtls_context_t *ctx) { + session_t session; + + if(uip_newdata()) { + uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr); + session.port = UIP_UDP_BUF->srcport; + session.size = sizeof(session.addr) + sizeof(session.port); + + dtls_handle_message(ctx, &session, uip_appdata, uip_datalen()); + } +} +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTF("Server IPv6 addresses: \n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); + PRINTF("\n"); + } + } +} + +#if 0 +static void +create_rpl_dag(uip_ipaddr_t *ipaddr) +{ + struct uip_ds6_addr *root_if; + + root_if = uip_ds6_addr_lookup(ipaddr); + if(root_if != NULL) { + rpl_dag_t *dag; + uip_ipaddr_t prefix; + + rpl_set_root(RPL_DEFAULT_INSTANCE, ipaddr); + dag = rpl_get_any_dag(); + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } else { + PRINTF("failed to create a new RPL DAG\n"); + } +} +#endif + +void +init_dtls() { + static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, +#ifdef DTLS_PSK + .get_psk_info = get_psk_info, +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + .get_ecdsa_key = get_ecdsa_key, + .verify_ecdsa_key = verify_ecdsa_key +#endif /* DTLS_ECC */ + }; +#if 0 + uip_ipaddr_t ipaddr; + /* struct uip_ds6_addr *root_if; */ +#endif /* UIP_CONF_ROUTER */ + + PRINTF("DTLS server started\n"); + +#if 0 /* TEST */ + memset(&tmp_addr, 0, sizeof(rimeaddr_t)); + if(get_eui64_from_eeprom(tmp_addr.u8)); +#if UIP_CONF_IPV6 + memcpy(&uip_lladdr.addr, &tmp_addr.u8, 8); +#endif +#endif /* TEST */ + +#if 0 +/* uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); */ +/* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */ +/* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */ + +/* create_rpl_dag(&ipaddr); */ +/* #else */ + /* uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); */ + + uip_ip6addr(&ipaddr, 0xaaaa, 0,0,0,0x0200,0,0,0x0003); + uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL); + + create_rpl_dag(&ipaddr); +#endif /* UIP_CONF_ROUTER */ + + server_conn = udp_new(NULL, 0, NULL); + udp_bind(server_conn, UIP_HTONS(20220)); + + dtls_set_log_level(DTLS_LOG_DEBUG); + + dtls_context = dtls_new_context(server_conn); + if (dtls_context) + dtls_set_handler(dtls_context, &cb); +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(udp_server_process, ev, data) +{ + PROCESS_BEGIN(); + + dtls_init(); + init_dtls(); + + print_local_addresses(); + + if (!dtls_context) { + dtls_emerg("cannot create context\n"); + PROCESS_EXIT(); + } + +#ifdef ENABLE_POWERTRACE + powertrace_start(CLOCK_SECOND * 2); +#endif + + while(1) { + PROCESS_WAIT_EVENT(); + if(ev == tcpip_event) { + dtls_handle_read(dtls_context); + } +#if 0 + if (bytes_read > 0) { + /* dtls_handle_message(dtls_context, &the_session, readbuf, bytes_read); */ + read_from_peer(dtls_context, &the_session, readbuf, bytes_read); + } + dtls_handle_message(ctx, &session, uip_appdata, bytes_read); +#endif + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h new file mode 100644 index 0000000..f0977c8 --- /dev/null +++ b/extlibs/tinydtls/global.h @@ -0,0 +1,147 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_GLOBAL_H_ +#define _DTLS_GLOBAL_H_ + +#include +#include + +#include "tinydtls.h" + +#ifndef DTLSv12 +/* The current version of tinyDTLS supports DTLSv1.2 only. */ +#define DTLSv12 1 +#endif + +#ifndef WITH_SHA256 +/* The current version of tinyDTLS supports DTLSv1.2 with SHA256 PRF + only. */ +#define WITH_SHA256 1 +#endif + +/* Define our own types as at least uint32_t does not work on my amd64. */ + +typedef unsigned char uint8; +typedef unsigned char uint16[2]; +typedef unsigned char uint24[3]; +typedef unsigned char uint32[4]; +typedef unsigned char uint48[6]; + +#ifndef DTLS_MAX_BUF +/** Maximum size of DTLS message. + When Peers are sending bigger messages this causes problems. Californium + with ECDSA needs at least 220 */ +#ifdef WITH_CONTIKI +#ifdef DTLS_ECC +#define DTLS_MAX_BUF 200 +#else /* DTLS_ECC */ +#define DTLS_MAX_BUF 100 +#endif /* DTLS_ECC */ +#else /* WITH_CONTIKI */ +#define DTLS_MAX_BUF 1400 +#endif /* WITH_CONTIKI */ +#endif + +#ifndef DTLS_DEFAULT_MAX_RETRANSMIT +/** Number of message retransmissions. */ +#define DTLS_DEFAULT_MAX_RETRANSMIT 7 +#endif + +/** Known cipher suites.*/ +typedef enum { + TLS_NULL_WITH_NULL_NULL = 0x0000, /**< NULL cipher */ + TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */ + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */ +} dtls_cipher_t; + +/** Known compression suites.*/ +typedef enum { + TLS_COMPRESSION_NULL = 0x0000 /* NULL compression */ +} dtls_compression_t; + +#define TLS_EXT_ELLIPTIC_CURVES 10 /* see RFC 4492 */ +#define TLS_EXT_EC_POINT_FORMATS 11 /* see RFC 4492 */ +#define TLS_EXT_SIG_HASH_ALGO 13 /* see RFC 5246 */ +#define TLS_EXT_CLIENT_CERTIFICATE_TYPE 19 /* see RFC 7250 */ +#define TLS_EXT_SERVER_CERTIFICATE_TYPE 20 /* see RFC 7250 */ +#define TLS_EXT_ENCRYPT_THEN_MAC 22 /* see RFC 7366 */ + +#define TLS_CERT_TYPE_RAW_PUBLIC_KEY 2 /* see RFC 7250 */ + +#define TLS_EXT_ELLIPTIC_CURVES_SECP256R1 23 /* see RFC 4492 */ + +#define TLS_EXT_EC_POINT_FORMATS_UNCOMPRESSED 0 /* see RFC 4492 */ + +#define TLS_EC_CURVE_TYPE_NAMED_CURVE 3 /* see RFC 4492 */ + +#define TLS_CLIENT_CERTIFICATE_TYPE_ECDSA_SIGN 64 /* see RFC 4492 */ + +#define TLS_EXT_SIG_HASH_ALGO_SHA256 4 /* see RFC 5246 */ +#define TLS_EXT_SIG_HASH_ALGO_ECDSA 3 /* see RFC 5246 */ + +/** + * XORs \p n bytes byte-by-byte starting at \p y to the memory area + * starting at \p x. */ +static inline void +memxor(unsigned char *x, const unsigned char *y, size_t n) { + while(n--) { + *x ^= *y; + x++; y++; + } +} + +/** + * Compares \p len bytes from @p a with @p b in constant time. This + * functions always traverses the entire length to prevent timing + * attacks. + * + * \param a Byte sequence to compare + * \param b Byte sequence to compare + * \param len Number of bytes to compare. + * \return \c 1 if \p a and \p b are equal, \c 0 otherwise. + */ +static inline int +equals(unsigned char *a, unsigned char *b, size_t len) { + int result = 1; + while (len--) { + result &= (*a++ == *b++); + } + return result; +} + +#ifdef HAVE_FLS +#define dtls_fls(i) fls(i) +#else +static inline int +dtls_fls(unsigned int i) { + int n; + for (n = 0; i; n++) + i >>= 1; + return n; +} +#endif /* HAVE_FLS */ + +#endif /* _DTLS_GLOBAL_H_ */ diff --git a/extlibs/tinydtls/hmac.c b/extlibs/tinydtls/hmac.c new file mode 100644 index 0000000..0a9b8f7 --- /dev/null +++ b/extlibs/tinydtls/hmac.c @@ -0,0 +1,173 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include + +#include "dtls_config.h" + +#ifdef HAVE_ASSERT_H +#include +#else +#define assert(x) +#endif + +#include "debug.h" +#include "hmac.h" + +/* use malloc()/free() on platforms other than Contiki */ +#ifndef WITH_CONTIKI +#include + +static inline dtls_hmac_context_t * +dtls_hmac_context_new() { + return (dtls_hmac_context_t *)malloc(sizeof(dtls_hmac_context_t)); +} + +static inline void +dtls_hmac_context_free(dtls_hmac_context_t *ctx) { + free(ctx); +} + +#else /* WITH_CONTIKI */ +#include "memb.h" +MEMB(hmac_context_storage, dtls_hmac_context_t, DTLS_HASH_MAX); + +static inline dtls_hmac_context_t * +dtls_hmac_context_new() { + return (dtls_hmac_context_t *)memb_alloc(&hmac_context_storage); +} + +static inline void +dtls_hmac_context_free(dtls_hmac_context_t *ctx) { + memb_free(&hmac_context_storage, ctx); +} + +void +dtls_hmac_storage_init() { + memb_init(&hmac_context_storage); +} +#endif /* WITH_CONTIKI */ + +void +dtls_hmac_update(dtls_hmac_context_t *ctx, + const unsigned char *input, size_t ilen) { + assert(ctx); + dtls_hash_update(&ctx->data, input, ilen); +} + +dtls_hmac_context_t * +dtls_hmac_new(const unsigned char *key, size_t klen) { + dtls_hmac_context_t *ctx; + + ctx = dtls_hmac_context_new(); + if (ctx) + dtls_hmac_init(ctx, key, klen); + + return ctx; +} + +void +dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen) { + int i; + + assert(ctx); + + memset(ctx, 0, sizeof(dtls_hmac_context_t)); + + if (klen > DTLS_HMAC_BLOCKSIZE) { + dtls_hash_init(&ctx->data); + dtls_hash_update(&ctx->data, key, klen); + dtls_hash_finalize(ctx->pad, &ctx->data); + } else + memcpy(ctx->pad, key, klen); + + /* create ipad: */ + for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) + ctx->pad[i] ^= 0x36; + + dtls_hash_init(&ctx->data); + dtls_hmac_update(ctx, ctx->pad, DTLS_HMAC_BLOCKSIZE); + + /* create opad by xor-ing pad[i] with 0x36 ^ 0x5C: */ + for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) + ctx->pad[i] ^= 0x6A; +} + +void +dtls_hmac_free(dtls_hmac_context_t *ctx) { + if (ctx) + dtls_hmac_context_free(ctx); +} + +int +dtls_hmac_finalize(dtls_hmac_context_t *ctx, unsigned char *result) { + unsigned char buf[DTLS_HMAC_DIGEST_SIZE]; + size_t len; + + assert(ctx); + assert(result); + + len = dtls_hash_finalize(buf, &ctx->data); + + dtls_hash_init(&ctx->data); + dtls_hash_update(&ctx->data, ctx->pad, DTLS_HMAC_BLOCKSIZE); + dtls_hash_update(&ctx->data, buf, len); + + len = dtls_hash_finalize(result, &ctx->data); + + return len; +} + +#ifdef HMAC_TEST +#include + +int main(int argc, char **argv) { + static unsigned char buf[DTLS_HMAC_DIGEST_SIZE]; + size_t len, i; + dtls_hmac_context_t *ctx; + + if (argc < 3) { + fprintf(stderr, "usage: %s key text", argv[0]); + return -1; + } + + dtls_hmac_storage_init(); + ctx = dtls_hmac_new(argv[1], strlen(argv[1])); + assert(ctx); + dtls_hmac_update(ctx, argv[2], strlen(argv[2])); + + len = dtls_hmac_finalize(ctx, buf); + + for(i = 0; i < len; i++) + printf("%02x", buf[i]); + printf("\n"); + + dtls_hmac_free(ctx); + + return 0; +} +#endif diff --git a/extlibs/tinydtls/hmac.h b/extlibs/tinydtls/hmac.h new file mode 100644 index 0000000..d9c5e53 --- /dev/null +++ b/extlibs/tinydtls/hmac.h @@ -0,0 +1,154 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_HMAC_H_ +#define _DTLS_HMAC_H_ + +#include + +#include "global.h" + +#ifdef WITH_SHA256 +/** Aaron D. Gifford's implementation of SHA256 + * see http://www.aarongifford.com/ */ +#include "sha2/sha2.h" + +typedef SHA256_CTX dtls_hash_ctx; +typedef dtls_hash_ctx *dtls_hash_t; +#define DTLS_HASH_CTX_SIZE sizeof(SHA256_CTX) + +static inline void +dtls_hash_init(dtls_hash_t ctx) { + SHA256_Init((SHA256_CTX *)ctx); +} + +static inline void +dtls_hash_update(dtls_hash_t ctx, const unsigned char *input, size_t len) { + SHA256_Update((SHA256_CTX *)ctx, input, len); +} + +static inline size_t +dtls_hash_finalize(unsigned char *buf, dtls_hash_t ctx) { + SHA256_Final(buf, (SHA256_CTX *)ctx); + return SHA256_DIGEST_LENGTH; +} +#endif /* WITH_SHA256 */ + +#ifndef WITH_CONTIKI +static inline void dtls_hmac_storage_init() +{ } +#else +void dtls_hmac_storage_init(); +#endif + +/** + * \defgroup HMAC Keyed-Hash Message Authentication Code (HMAC) + * NIST Standard FIPS 198 describes the Keyed-Hash Message Authentication + * Code (HMAC) which is used as hash function for the DTLS PRF. + * @{ + */ + +#define DTLS_HMAC_BLOCKSIZE 64 /**< size of hmac blocks */ +#define DTLS_HMAC_DIGEST_SIZE 32 /**< digest size (for SHA-256) */ +#define DTLS_HMAC_MAX 64 /**< max number of bytes in digest */ + +/** + * List of known hash functions for use in dtls_hmac_init(). The + * identifiers are the same as the HashAlgorithm defined in + * Section 7.4.1.4.1 of RFC 5246. + */ +typedef enum { + HASH_NONE=0, HASH_MD5=1, HASH_SHA1=2, HASH_SHA224=3, + HASH_SHA256=4, HASH_SHA384=5, HASH_SHA512=6 +} dtls_hashfunc_t; + +/** + * Context for HMAC generation. This object is initialized with + * dtls_hmac_init() and must be passed to dtls_hmac_update() and + * dtls_hmac_finalize(). Once, finalized, the component \c H is + * invalid and must be initialized again with dtls_hmac_init() before + * the structure can be used again. + */ +typedef struct { + unsigned char pad[DTLS_HMAC_BLOCKSIZE]; /**< ipad and opad storage */ + dtls_hash_ctx data; /**< context for hash function */ +} dtls_hmac_context_t; + +/** + * Initializes an existing HMAC context. + * + * @param ctx The HMAC context to initialize. + * @param key The secret key. + * @param klen The length of @p key. + */ +void dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen); + +/** + * Allocates a new HMAC context \p ctx with the given secret key. + * This function returns \c 1 if \c ctx has been set correctly, or \c + * 0 or \c -1 otherwise. Note that this function allocates new storage + * that must be released by dtls_hmac_free(). + * + * \param key The secret key. + * \param klen The length of \p key. + * \return A new dtls_hmac_context_t object or @c NULL on error + */ +dtls_hmac_context_t *dtls_hmac_new(const unsigned char *key, size_t klen); + +/** + * Releases the storage for @p ctx that has been allocated by + * dtls_hmac_new(). + * + * @param ctx The dtls_hmac_context_t to free. + */ +void dtls_hmac_free(dtls_hmac_context_t *ctx); + +/** + * Updates the HMAC context with data from \p input. + * + * \param ctx The HMAC context. + * \param input The input data. + * \param ilen Size of \p input. + */ +void dtls_hmac_update(dtls_hmac_context_t *ctx, + const unsigned char *input, size_t ilen); + +/** + * Completes the HMAC generation and writes the result to the given + * output parameter \c result. The buffer must be large enough to hold + * the message digest created by the actual hash function. If in + * doubt, use \c DTLS_HMAC_MAX. The function returns the number of + * bytes written to \c result. + * + * \param ctx The HMAC context. + * \param result Output parameter where the MAC is written to. + * \return Length of the MAC written to \p result. + */ +int dtls_hmac_finalize(dtls_hmac_context_t *ctx, unsigned char *result); + +/**@}*/ + +#endif /* _DTLS_HMAC_H_ */ diff --git a/extlibs/tinydtls/netq.c b/extlibs/tinydtls/netq.c new file mode 100644 index 0000000..0a10a50 --- /dev/null +++ b/extlibs/tinydtls/netq.c @@ -0,0 +1,140 @@ +/* netq.h -- Simple packet queue + * + * Copyright (C) 2010--2012 Olaf Bergmann + * + * This file is part of the library tinyDTLS. Please see the file + * LICENSE for terms of use. + */ + +#include "dtls_config.h" +#include "debug.h" +#include "netq.h" + +#ifdef HAVE_ASSERT_H +#include +#else +#ifndef assert +#warning "assertions are disabled" +# define assert(x) +#endif +#endif + +#include "t_list.h" + +#ifndef WITH_CONTIKI +#include + +static inline netq_t * +netq_malloc_node(size_t size) { + return (netq_t *)malloc(sizeof(netq_t) + size); +} + +static inline void +netq_free_node(netq_t *node) { + free(node); +} + +/* FIXME: implement Contiki's list functions using utlist.h */ + +#else /* WITH_CONTIKI */ +#include "memb.h" + +MEMB(netq_storage, netq_t, NETQ_MAXCNT); + +static inline netq_t * +netq_malloc_node(size_t size) { + return (netq_t *)memb_alloc(&netq_storage); +} + +static inline void +netq_free_node(netq_t *node) { + memb_free(&netq_storage, node); +} + +void +netq_init() { + memb_init(&netq_storage); +} +#endif /* WITH_CONTIKI */ + +int +netq_insert_node(list_t queue, netq_t *node) { + netq_t *p; + + assert(queue); + assert(node); + + p = (netq_t *)list_head(queue); + while(p && p->t <= node->t && list_item_next(p)) + p = list_item_next(p); + + if (p) + list_insert(queue, p, node); + else + list_push(queue, node); + + return 1; +} + +netq_t * +netq_head(list_t queue) { + if (!queue) + return NULL; + + return list_head(queue); +} + +netq_t * +netq_next(netq_t *p) { + if (!p) + return NULL; + + return list_item_next(p); +} + +void +netq_remove(list_t queue, netq_t *p) { + if (!queue || !p) + return; + + list_remove(queue, p); +} + +netq_t *netq_pop_first(list_t queue) { + if (!queue) + return NULL; + + return list_pop(queue); +} + +netq_t * +netq_node_new(size_t size) { + netq_t *node; + node = netq_malloc_node(size); + +#ifndef NDEBUG + if (!node) + dtls_warn("netq_node_new: malloc\n"); +#endif + + if (node) + memset(node, 0, sizeof(netq_t)); + + return node; +} + +void +netq_node_free(netq_t *node) { + if (node) + netq_free_node(node); +} + +void +netq_delete_all(list_t queue) { + netq_t *p; + if (queue) { + while((p = list_pop(queue))) + netq_free_node(p); + } +} + diff --git a/extlibs/tinydtls/netq.h b/extlibs/tinydtls/netq.h new file mode 100644 index 0000000..a771b23 --- /dev/null +++ b/extlibs/tinydtls/netq.h @@ -0,0 +1,103 @@ +/* netq.h -- Simple packet queue + * + * Copyright (C) 2010--2012 Olaf Bergmann + * + * This file is part of the library tinyDTLS. Please see the file + * LICENSE for terms of use. + */ + +#ifndef _DTLS_NETQ_H_ +#define _DTLS_NETQ_H_ + +#include "tinydtls.h" +#include "global.h" +#include "dtls.h" +#include "dtls_time.h" + +/** + * \defgroup netq Network Packet Queue + * The netq utility functions implement an ordered queue of data packets + * to send over the network and can also be used to queue received packets + * from the network. + * @{ + */ + +#ifndef NETQ_MAXCNT +#ifdef DTLS_ECC +#define NETQ_MAXCNT 5 /**< maximum number of elements in netq structure */ +#elif defined(DTLS_PSK) +#define NETQ_MAXCNT 3 /**< maximum number of elements in netq structure */ +#endif +#endif + +/** + * Datagrams in the netq_t structure have a fixed maximum size of + * DTLS_MAX_BUF to simplify memory management on constrained nodes. */ +typedef unsigned char netq_packet_t[DTLS_MAX_BUF]; + +typedef struct netq_t { + struct netq_t *next; + + clock_time_t t; /**< when to send PDU for the next time */ + unsigned int timeout; /**< randomized timeout value */ + + dtls_peer_t *peer; /**< remote address */ + uint16_t epoch; + uint8_t type; + unsigned char retransmit_cnt; /**< retransmission counter, will be removed when zero */ + + size_t length; /**< actual length of data */ +#ifndef WITH_CONTIKI + unsigned char data[]; /**< the datagram to send */ +#else + netq_packet_t data; /**< the datagram to send */ +#endif +} netq_t; + +#ifndef WITH_CONTIKI +static inline void netq_init() +{ } +#else +void netq_init(); +#endif + +/** + * Adds a node to the given queue, ordered by their time-stamp t. + * This function returns @c 0 on error, or non-zero if @p node has + * been added successfully. + * + * @param queue A pointer to the queue head where @p node will be added. + * @param node The new item to add. + * @return @c 0 on error, or non-zero if the new item was added. + */ +int netq_insert_node(list_t queue, netq_t *node); + +/** Destroys specified node and releases any memory that was allocated + * for the associated datagram. */ +void netq_node_free(netq_t *node); + +/** Removes all items from given queue and frees the allocated storage */ +void netq_delete_all(list_t queue); + +/** Creates a new node suitable for adding to a netq_t queue. */ +netq_t *netq_node_new(size_t size); + +/** + * Returns a pointer to the first item in given queue or NULL if + * empty. + */ +netq_t *netq_head(list_t queue); + +netq_t *netq_next(netq_t *p); +void netq_remove(list_t queue, netq_t *p); + +/** + * Removes the first item in given queue and returns a pointer to the + * removed element. If queue is empty when netq_pop_first() is called, + * this function returns NULL. + */ +netq_t *netq_pop_first(list_t queue); + +/**@}*/ + +#endif /* _DTLS_NETQ_H_ */ diff --git a/extlibs/tinydtls/numeric.h b/extlibs/tinydtls/numeric.h new file mode 100644 index 0000000..e319f5b --- /dev/null +++ b/extlibs/tinydtls/numeric.h @@ -0,0 +1,142 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_NUMERIC_H_ +#define _DTLS_NUMERIC_H_ + +#include + +#ifndef min +#define min(A,B) ((A) <= (B) ? (A) : (B)) +#endif + +#ifndef max +#define max(A,B) ((A) < (B) ? (B) : (A)) +#endif + +/* this one is for consistency... */ +static inline int dtls_int_to_uint8(unsigned char *field, uint8_t value) +{ + field[0] = value & 0xff; + return 1; +} + +static inline int dtls_int_to_uint16(unsigned char *field, uint16_t value) +{ + field[0] = (value >> 8) & 0xff; + field[1] = value & 0xff; + return 2; +} + +static inline int dtls_int_to_uint24(unsigned char *field, uint32_t value) +{ + field[0] = (value >> 16) & 0xff; + field[1] = (value >> 8) & 0xff; + field[2] = value & 0xff; + return 3; +} + +static inline int dtls_int_to_uint32(unsigned char *field, uint32_t value) +{ + field[0] = (value >> 24) & 0xff; + field[1] = (value >> 16) & 0xff; + field[2] = (value >> 8) & 0xff; + field[3] = value & 0xff; + return 4; +} + +static inline int dtls_int_to_uint48(unsigned char *field, uint64_t value) +{ + field[0] = (value >> 40) & 0xff; + field[1] = (value >> 32) & 0xff; + field[2] = (value >> 24) & 0xff; + field[3] = (value >> 16) & 0xff; + field[4] = (value >> 8) & 0xff; + field[5] = value & 0xff; + return 6; +} + +static inline int dtls_int_to_uint64(unsigned char *field, uint64_t value) +{ + field[0] = (value >> 56) & 0xff; + field[1] = (value >> 48) & 0xff; + field[2] = (value >> 40) & 0xff; + field[3] = (value >> 32) & 0xff; + field[4] = (value >> 24) & 0xff; + field[5] = (value >> 16) & 0xff; + field[6] = (value >> 8) & 0xff; + field[7] = value & 0xff; + return 8; +} + +static inline uint8_t dtls_uint8_to_int(const unsigned char *field) +{ + return (uint8_t)field[0]; +} + +static inline uint16_t dtls_uint16_to_int(const unsigned char *field) +{ + return ((uint16_t)field[0] << 8) + | (uint16_t)field[1]; +} + +static inline uint32_t dtls_uint24_to_int(const unsigned char *field) +{ + return ((uint32_t)field[0] << 16) + | ((uint32_t)field[1] << 8) + | (uint32_t)field[2]; +} + +static inline uint32_t dtls_uint32_to_int(const unsigned char *field) +{ + return ((uint32_t)field[0] << 24) + | ((uint32_t)field[1] << 16) + | ((uint32_t)field[2] << 8) + | (uint32_t)field[3]; +} + +static inline uint64_t dtls_uint48_to_int(const unsigned char *field) +{ + return ((uint64_t)field[0] << 40) + | ((uint64_t)field[1] << 32) + | ((uint64_t)field[2] << 24) + | ((uint64_t)field[3] << 16) + | ((uint64_t)field[4] << 8) + | (uint64_t)field[5]; +} + +static inline uint64_t dtls_uint64_to_int(const unsigned char *field) +{ + return ((uint64_t)field[0] << 56) + | ((uint64_t)field[1] << 48) + | ((uint64_t)field[2] << 40) + | ((uint64_t)field[3] << 32) + | ((uint64_t)field[4] << 24) + | ((uint64_t)field[5] << 16) + | ((uint64_t)field[6] << 8) + | (uint64_t)field[7]; +} + +#endif /* _DTLS_NUMERIC_H_ */ diff --git a/extlibs/tinydtls/peer.c b/extlibs/tinydtls/peer.c new file mode 100644 index 0000000..8f2876c --- /dev/null +++ b/extlibs/tinydtls/peer.c @@ -0,0 +1,90 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "global.h" +#include "peer.h" +#include "debug.h" + +#ifndef WITH_CONTIKI +void peer_init() +{ +} + +static inline dtls_peer_t * +dtls_malloc_peer() { + return (dtls_peer_t *)malloc(sizeof(dtls_peer_t)); +} + +void +dtls_free_peer(dtls_peer_t *peer) { + dtls_handshake_free(peer->handshake_params); + dtls_security_free(peer->security_params[0]); + dtls_security_free(peer->security_params[1]); + free(peer); +} +#else /* WITH_CONTIKI */ + +#include "memb.h" +MEMB(peer_storage, dtls_peer_t, DTLS_PEER_MAX); + +void +peer_init() { + memb_init(&peer_storage); +} + +static inline dtls_peer_t * +dtls_malloc_peer() { + return memb_alloc(&peer_storage); +} + +void +dtls_free_peer(dtls_peer_t *peer) { + dtls_handshake_free(peer->handshake_params); + dtls_security_free(peer->security_params[0]); + dtls_security_free(peer->security_params[1]); + memb_free(&peer_storage, peer); +} +#endif /* WITH_CONTIKI */ + +dtls_peer_t * +dtls_new_peer(const session_t *session) { + dtls_peer_t *peer; + + peer = dtls_malloc_peer(); + if (peer) { + memset(peer, 0, sizeof(dtls_peer_t)); + memcpy(&peer->session, session, sizeof(session_t)); + peer->security_params[0] = dtls_security_new(); + + if (!peer->security_params[0]) { + dtls_free_peer(peer); + return NULL; + } + + dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "dtls_new_peer", session); + } + + return peer; +} diff --git a/extlibs/tinydtls/peer.h b/extlibs/tinydtls/peer.h new file mode 100644 index 0000000..af7c205 --- /dev/null +++ b/extlibs/tinydtls/peer.h @@ -0,0 +1,148 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file peer.h + * @brief information about peers in a DTLS session + */ + +#ifndef _DTLS_PEER_H_ +#define _DTLS_PEER_H_ + +#include + +#include "tinydtls.h" +#include "global.h" +#include "session.h" + +#include "state.h" +#include "crypto.h" + +#ifndef WITH_CONTIKI +#include "uthash.h" +#endif /* WITH_CONTIKI */ + +typedef enum { DTLS_CLIENT=0, DTLS_SERVER } dtls_peer_type; + +/** + * Holds security parameters, local state and the transport address + * for each peer. */ +typedef struct dtls_peer_t { +#ifndef WITH_CONTIKI + UT_hash_handle hh; +#else /* WITH_CONTIKI */ + struct dtls_peer_t *next; +#endif /* WITH_CONTIKI */ + + session_t session; /**< peer address and local interface */ + + dtls_peer_type role; /**< denotes if this host is DTLS_CLIENT or DTLS_SERVER */ + dtls_state_t state; /**< DTLS engine state */ + + dtls_security_parameters_t *security_params[2]; + dtls_handshake_parameters_t *handshake_params; +} dtls_peer_t; + +static inline dtls_security_parameters_t *dtls_security_params_epoch(dtls_peer_t *peer, uint16_t epoch) +{ + if (peer->security_params[0] && peer->security_params[0]->epoch == epoch) { + return peer->security_params[0]; + } else if (peer->security_params[1] && peer->security_params[1]->epoch == epoch) { + return peer->security_params[1]; + } else { + return NULL; + } +} + +static inline dtls_security_parameters_t *dtls_security_params(dtls_peer_t *peer) +{ + return peer->security_params[0]; +} + +static inline dtls_security_parameters_t *dtls_security_params_next(dtls_peer_t *peer) +{ + if (peer->security_params[1]) + dtls_security_free(peer->security_params[1]); + + peer->security_params[1] = dtls_security_new(); + if (!peer->security_params[1]) { + return NULL; + } + peer->security_params[1]->epoch = peer->security_params[0]->epoch + 1; + return peer->security_params[1]; +} + +static inline void dtls_security_params_free_other(dtls_peer_t *peer) +{ + dtls_security_parameters_t * security0 = peer->security_params[0]; + dtls_security_parameters_t * security1 = peer->security_params[1]; + + if (!security0 || !security1 || security0->epoch < security1->epoch) + return; + + dtls_security_free(security1); + peer->security_params[1] = NULL; +} + +static inline void dtls_security_params_switch(dtls_peer_t *peer) +{ + dtls_security_parameters_t * security = peer->security_params[1]; + + peer->security_params[1] = peer->security_params[0]; + peer->security_params[0] = security; +} + +void peer_init(); + +/** + * Creates a new peer for given @p session. The current configuration + * is initialized with the cipher suite TLS_NULL_WITH_NULL_NULL (i.e. + * no security at all). This function returns a pointer to the new + * peer or NULL on error. The caller is responsible for releasing the + * storage allocated for this peer using dtls_free_peer(). + * + * @param session The remote peer's address and local interface index. + * @return A pointer to a newly created and initialized peer object + * or NULL on error. + */ +dtls_peer_t *dtls_new_peer(const session_t *session); + +/** Releases the storage allocated to @p peer. */ +void dtls_free_peer(dtls_peer_t *peer); + +/** Returns the current state of @p peer. */ +static inline dtls_state_t dtls_peer_state(const dtls_peer_t *peer) { + return peer->state; +} + +/** + * Checks if given @p peer is connected. This function returns + * @c 1 if connected, or @c 0 otherwise. + */ +static inline int dtls_peer_is_connected(const dtls_peer_t *peer) { + return peer->state == DTLS_STATE_CONNECTED; +} + +#endif /* _DTLS_PEER_H_ */ diff --git a/extlibs/tinydtls/platform-specific/Makefile.in b/extlibs/tinydtls/platform-specific/Makefile.in new file mode 100644 index 0000000..6b30d21 --- /dev/null +++ b/extlibs/tinydtls/platform-specific/Makefile.in @@ -0,0 +1,27 @@ +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +top_builddir = @top_builddir@ + +THIS=platform-specific +DISTDIR?=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ +FILES:=Makefile.in $(wildcard *.h) + +clean: + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ + +dist: + test -d $(DISTDIR)/$(THIS) || mkdir $(DISTDIR)/$(THIS) + cp -r $(FILES) $(DISTDIR)/$(THIS) + +# this directory contains no installation candidates +install: + : diff --git a/extlibs/tinydtls/platform-specific/config-cc2538dk.h b/extlibs/tinydtls/platform-specific/config-cc2538dk.h new file mode 100644 index 0000000..38bc85e --- /dev/null +++ b/extlibs/tinydtls/platform-specific/config-cc2538dk.h @@ -0,0 +1,2 @@ +#define BYTE_ORDER 1234 +#define HAVE_ASSERT_H 1 diff --git a/extlibs/tinydtls/platform-specific/config-econotag.h b/extlibs/tinydtls/platform-specific/config-econotag.h new file mode 100644 index 0000000..38bc85e --- /dev/null +++ b/extlibs/tinydtls/platform-specific/config-econotag.h @@ -0,0 +1,2 @@ +#define BYTE_ORDER 1234 +#define HAVE_ASSERT_H 1 diff --git a/extlibs/tinydtls/platform-specific/config-minimal-net.h b/extlibs/tinydtls/platform-specific/config-minimal-net.h new file mode 100644 index 0000000..547a1b6 --- /dev/null +++ b/extlibs/tinydtls/platform-specific/config-minimal-net.h @@ -0,0 +1 @@ +#define HAVE_ASSERT_H 1 diff --git a/extlibs/tinydtls/platform-specific/config-sky.h b/extlibs/tinydtls/platform-specific/config-sky.h new file mode 100644 index 0000000..f49ff3b --- /dev/null +++ b/extlibs/tinydtls/platform-specific/config-sky.h @@ -0,0 +1,3 @@ +#define BYTE_ORDER 1234 +#define HAVE_ASSERT_H 1 +typedef int ssize_t; diff --git a/extlibs/tinydtls/platform-specific/config-wismote.h b/extlibs/tinydtls/platform-specific/config-wismote.h new file mode 100644 index 0000000..547a1b6 --- /dev/null +++ b/extlibs/tinydtls/platform-specific/config-wismote.h @@ -0,0 +1 @@ +#define HAVE_ASSERT_H 1 diff --git a/extlibs/tinydtls/prng.h b/extlibs/tinydtls/prng.h new file mode 100644 index 0000000..48c1f95 --- /dev/null +++ b/extlibs/tinydtls/prng.h @@ -0,0 +1,82 @@ +/* prng.h -- Pseudo Random Numbers + * + * Copyright (C) 2010--2012 Olaf Bergmann + * + * This file is part of the library tinydtls. Please see + * README for terms of use. + */ + +/** + * @file prng.h + * @brief Pseudo Random Numbers + */ + +#ifndef _DTLS_PRNG_H_ +#define _DTLS_PRNG_H_ + +#include "tinydtls.h" + +/** + * @defgroup prng Pseudo Random Numbers + * @{ + */ + +#ifndef WITH_CONTIKI +#include + +/** + * Fills \p buf with \p len random bytes. This is the default + * implementation for prng(). You might want to change prng() to use + * a better PRNG on your specific platform. + */ +static inline int +dtls_prng(unsigned char *buf, size_t len) { + while (len--) + *buf++ = rand() & 0xFF; + return 1; +} + +static inline void +dtls_prng_init(unsigned short seed) { + srand(seed); +} +#else /* WITH_CONTIKI */ +#include +#include "random.h" + +#ifdef HAVE_PRNG +static inline int +dtls_prng(unsigned char *buf, size_t len) +{ + return contiki_prng_impl(buf, len); +} +#else +/** + * Fills \p buf with \p len random bytes. This is the default + * implementation for prng(). You might want to change prng() to use + * a better PRNG on your specific platform. + */ +static inline int +dtls_prng(unsigned char *buf, size_t len) { + unsigned short v = random_rand(); + while (len > sizeof(v)) { + memcpy(buf, &v, sizeof(v)); + len -= sizeof(v); + buf += sizeof(v); + v = random_rand(); + } + + memcpy(buf, &v, len); + return 1; +} +#endif /* HAVE_PRNG */ + +static inline void +dtls_prng_init(unsigned short seed) { + random_init(seed); +} +#endif /* WITH_CONTIKI */ + +/** @} */ + +#endif /* _DTLS_PRNG_H_ */ diff --git a/extlibs/tinydtls/session.c b/extlibs/tinydtls/session.c new file mode 100644 index 0000000..9acf565 --- /dev/null +++ b/extlibs/tinydtls/session.c @@ -0,0 +1,83 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "dtls_config.h" +#include "session.h" + +#ifdef HAVE_ASSERT_H +#include +#else +#ifndef assert +#warning "assertions are disabled" +# define assert(x) +#endif +#endif + +#ifdef WITH_CONTIKI +#define _dtls_address_equals_impl(A,B) \ + ((A)->size == (B)->size \ + && (A)->port == (B)->port \ + && uip_ipaddr_cmp(&((A)->addr),&((B)->addr)) \ + && (A)->ifindex == (B)->ifindex) + +#else /* WITH_CONTIKI */ + +static inline int +_dtls_address_equals_impl(const session_t *a, + const session_t *b) { + if (a->ifindex != b->ifindex || + a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family) + return 0; + + /* need to compare only relevant parts of sockaddr_in6 */ + switch (a->addr.sa.sa_family) { + case AF_INET: + return + a->addr.sin.sin_port == b->addr.sin.sin_port && + memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, + sizeof(struct in_addr)) == 0; + case AF_INET6: + return a->addr.sin6.sin6_port == b->addr.sin6.sin6_port && + memcmp(&a->addr.sin6.sin6_addr, &b->addr.sin6.sin6_addr, + sizeof(struct in6_addr)) == 0; + default: /* fall through and signal error */ + ; + } + return 0; +} +#endif /* WITH_CONTIKI */ + +void +dtls_session_init(session_t *sess) { + assert(sess); + memset(sess, 0, sizeof(session_t)); + sess->size = sizeof(sess->addr); +} + +int +dtls_session_equals(const session_t *a, const session_t *b) { + assert(a); assert(b); + return _dtls_address_equals_impl(a, b); +} diff --git a/extlibs/tinydtls/session.h b/extlibs/tinydtls/session.h new file mode 100644 index 0000000..61b5661 --- /dev/null +++ b/extlibs/tinydtls/session.h @@ -0,0 +1,76 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _DTLS_SESSION_H_ +#define _DTLS_SESSION_H_ + +#include + +#include "tinydtls.h" +#include "global.h" + +#ifdef WITH_CONTIKI +#include "ip/uip.h" +typedef struct { + unsigned char size; + uip_ipaddr_t addr; + unsigned short port; + int ifindex; +} session_t; + +#else /* WITH_CONTIKI */ + +#include +#include +#include + +typedef struct { + socklen_t size; /**< size of addr */ + union { + struct sockaddr sa; + struct sockaddr_storage st; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; + uint8_t ifindex; +} session_t; +#endif /* WITH_CONTIKI */ + +/** + * Resets the given session_t object @p sess to its default + * values. In particular, the member rlen must be initialized to the + * available size for storing addresses. + * + * @param sess The session_t object to initialize. + */ +void dtls_session_init(session_t *sess); + +/** + * Compares the given session objects. This function returns @c 0 + * when @p a and @p b differ, @c 1 otherwise. + */ +int dtls_session_equals(const session_t *a, const session_t *b); + +#endif /* _DTLS_SESSION_H_ */ diff --git a/extlibs/tinydtls/sha2/Makefile.in b/extlibs/tinydtls/sha2/Makefile.in new file mode 100644 index 0000000..85ce9ce --- /dev/null +++ b/extlibs/tinydtls/sha2/Makefile.in @@ -0,0 +1,78 @@ +# Makefile for tinydtls +# +# Copyright (C) 2011 Olaf Bergmann +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_srcdir:= @top_srcdir@ + +SOURCES:= sha2.c +HEADERS:=sha2.h +OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) +CPPFLAGS=@CPPFLAGS@ -I$(top_srcdir) +CFLAGS=-Wall -std=c99 -pedantic @CFLAGS@ +LDLIBS=@LIBS@ +FILES:=Makefile.in $(SOURCES) $(HEADERS) README sha2prog.c sha2speed.c sha2test.pl +DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ + +.PHONY: all dirs clean install dist distclean .gitignore doc + +.SUFFIXES: +.SUFFIXES: .c .o + +all: + +check: + echo DISTDIR: $(DISTDIR) + echo top_builddir: $(top_builddir) + +clean: + @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean ; \ + done + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ $(DISTDIR).tar.gz + +dist: $(FILES) + test -d $(DISTDIR)/sha2 || mkdir $(DISTDIR)/sha2 + cp -p $(FILES) $(DISTDIR)/sha2 + test -d $(DISTDIR)/sha2/testvectors || mkdir $(DISTDIR)/sha2/testvectors + cp -pr testvectors $(DISTDIR)/sha2/testvectors + +install: $(HEADERS) + test -d $(includedir)/sha2 || mkdir -p $(includedir)/sha2 + $(install) $(HEADERS) $(includedir)/sha2 + +.gitignore: + echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/extlibs/tinydtls/sha2/README b/extlibs/tinydtls/sha2/README new file mode 100644 index 0000000..95e57f3 --- /dev/null +++ b/extlibs/tinydtls/sha2/README @@ -0,0 +1,272 @@ +VERSION: + +This is version 1.0 RELEASE + +While this is my "release" version, due to lack of additional +official test vectors against which to verify this implementation's +correctness, beware that there may be implementation bugs. Also, +it has not yet been tested on very many other architectures, +big-endian machines in particular. + + +LICENSE: + +This implementation is released freely under an open-source BSD +license which appears at the top of each source code file. + + +WHAT IT IS: + +The files sha2.h and sha2.c implement the SHA-256, SHA-384, and SHA-512 +hash algorithms as described in the PDF document found at the following +web address: + + http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf + +The interface is similar to the interface to SHA-1 found in the OpenSSL +library. + +The file sha2prog.c is a simple program that accepts input from either +STDIN or reads one or more files specified on the command line, and then +generates the specified hash (either SHA-256, SHA-384, SHA-512, or any +combination thereof, including all three at once). + + +LIMITATIONS: + +This implementation has several limitations: + + * Input data is only accepted in octet-length increments. No sub-byte + data is handled. The NIST document describes how to handle sub-byte + input data, but for ease of implementation this version will only + accept message data in multiples of bytes. + * This implementation utilizes 64-bit integer data types. If your + system and compiler does not have a 64-bit integer data type, this + implementation will not work. + * Because of the use of 64-bit operations, many 32-bit architectures + that do have 64-bit data types but do operations most efficiently + on 32-bit words, this implementation may be slower than an + implementation designed to use only 32-bit words (emulating the + 64-bit operations). + * On platforms with 128-bit integer data types, the SHA-384 and SHA-512 + bit counters used by this implementation might be better off using + the 128-bit type instead of simulating it with two 64-bit integers. + * This implementation was written in C in hopes of portability and for + the fun of it during my spare time. It is probably not the most + efficient or fastest C implementation. I welcome suggestions, + however, that suggest ways to speed things up without breaking + portability. I also welcome suggestions to improve portability. + * As mentioned above, this code has NOT been thoroughly tested. + This is perhaps the most severe limitation. + + +BEFORE YOU COMPILE (OPTIONS): + +Each of the options described below may either be defined in the sha2.h +header file (or in the sha2.c file in some cases), or on the command +line at compile time if your compiler supports such things. For +example: + + #define SHA2_USE_INTTYPES_H + #define SHA2_UNROLL_TRANSFORM + +Or: + + cc -c -DSHA2_UNROLL_TRANSFORM sha2.c + cc -c -DBYTE_ORDER=4321 -DBIG_ENDIAN=4321 sha2.c + +Here are the available options. Read on below for a description of +each one: + + SHA2_USE_INTTYPES_H + SHA2_USE_MEMSET_MEMCPY/SHA2_USE_BZERO_BCOPY + SHA2_UNROLL_TRANSFORM + BYTE_ORDER (LITTLE_ENDIAN/BIG_ENDIAN) + +* SHA2_USE_INTTYPES_H option: +By default, this code uses u_intXX_t data types for 8 bit, 32 bit, and +64 bit unsigned integer type definitions. Most BSD systems define these, +as does Linux. However, some (like Compaq's Tru64 Unix) may instead +use uintXX_t data types as defined by recent ANSI C standards and as +included in the inttypes.h header file. Those wanting to use inttypes.h +need to define this either in sha.h or at compile time. + +On those systems where NEITHER definitions are available, you will need +to edit both sha2.h and sha2.c and define things by hand in the appropriate +sections. + +* BYTE_ORDER definitions: +This code assumes that BYTE_ORDER will be defined by the system during +compile to either equal LITTLE_ENDIAN or BIG_ENDIAN. If your system +does not define these, you may need to define them by hand in the sha.c +file according to the byte ordering conventions of your system. + +* SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY +The code in sha2.c can use either memset()/memcpy() for memory block +operations, or bzero()/mcopy(). If you define neither of these, the +code will default to memset()/memcpy(). You can define either at the +command line or in sha2.h or in sha2.c. + +* SHA2_UNROLL_TRANSFORM +By defining this either on the command line or in sha2.h or sha2.c, +the code will use macros to partially "unroll" the SHA transform +function. This usually generates bigger executables. It CAN (but +not necessarily WILL) generate faster code when you tell your compiler +to optimize things. For example, on the FreeBSD and Linux x86 systems +I tested things on (using gcc), when I optimized with just -O2 and +unrolled the transform, the hash transform was faster by 15-30%. On +these same systems, if I did NO optimization, the unrolled transform +was SLOWER, much slower (I'm guessing because the code was breaking +the cache, but I'm not sure). Your mileage may vary. + + +PORTABILITY: + +The code in sha2.c and sha2.h is intended to be portable. It may +require that you do a few #definitions in the .h file. I've successfully +compiled and tested the sha2.c and sha2.h code on Apple's OS X (on +a PPC), FreeBSD 4.1.1 on Intel, Linux on Intel, FreeBSD on the Alpha, +and even under Windows98SE using Metrowerks C. The utility/example +programs (sha2prog.c, sha2test.c, and sha2speed.c) will very likely +have more trouble in portability since they do I/O. + +To get sha2.c/sha2.h working under Windows, I had to define +SHA2_USE_INTTYPES_H, BYTE_ORDER, LITTLE_ENDIAN, and had to comment +out the include of in sha2.h. With a bit more work +I got the test program to run and verified that all the test +cases passed. + + +SUGGESTIONS/BUG FIXES: + +If you make changes to get it working on other architectures, if you fix +any bugs, or if you make changes that improve this implementation's +efficiency that would be relatively portable and you're willing to release +your changes under the same license, please send them to me for possible +inclusion in future versions. + +If you know where I can find some additional test vectors, please let me +know. + + +CHANGE HISTORY: + +0.8 to 0.9 - Fixed spelling errors, changed to u_intXX_t type usage, + removed names from prototypes, added prototypes to sha2.c, + and a few things I can't recall. + +0.9 to 0.9.5 - Add a new define in sha2.c that permits one to compile + it to either use memcpy()/memset() or bcopy()/bzero() + for memory block copying and zeroing. Added support + for unrolled SHA-256/384/512 transform loops. Just + compile with SHA2_UNROLL_TRANSFORM to enable. It takes + longer to compile, but I hope it is a bit faster. I + need to do some test to see whether or not it is. Oh, + in sha2.c, you either need to define SHA2_USE_BZERO_BCOPY + or SHA2_USE_MEMSET_MEMCPY to choose which way you want + to compile. *Whew* It's amazing how quickly something + simple starts to grow more complex even in the span of + just a few hours. I didn't really intend to do this much. +0.9.5 to 0.9.6 - Added a test program (sha2test) which tests against several + known test vectors. WARNING: Some of the test output + hashes are NOT from NIST's documentation and are the + output of this implementation and so may be incorrect. +0.9.6 to 0.9.7 - Fixed a bug that could cause invalid output in certain + cases and added an assumed scenario where zero-length + data is hashed. Also changed the rotation macros to use + a temporary variable as this reduces the number of operations. + When data is fed in blocks of the right length, copying of + data is reduced in this version. Added SHAYXZ_Data() + functions for ease of hashing a set of data. Added another + file sha2speed.c for doing speed testing. Added another test + vector with a larger data size (16KB). Fixed u_intXX_t and + uintXX_t handling by adding a define for SHA2_USE_INTTYPES_H + as well as made a few other minor changes to get rid of + warnings when compiling on Compaq's Tru64 Unix. +0.9.7 to 0.9.8 - The bug fix in 0.9.7 was incomplete and in some cases made + things worse. I believe that 0.9.8 fixes the bug completely + so that output is correct. I cannot verify this, however, + because of the lack of test vectors against which to do such + verification. All versions correctly matched the very few + NIST-provided vectors, but unfortunately the bug only + appeared in longer message data sets. +0.9.8 to 0.9.9 - Fixed some really bad typos and mistakes on my part that + only affected big-endian systems. I didn't have direct + access for testing before this version. Thanks to + Lucas Marshall for giving me access to his OS X system. +0.9.9 to 1.0.0b1 Added a few more test samples and made a few changes to + make things easier compiling on several other platforms. + Also I experimented with alternate macro definitions + in the SHA2_UNROLL_TRANSFORM version (see sha2.slower.c) + and eliminated the T1 temporary variable (the compiler + would of course still use internal temporary storage + during expression evaluation, but I'd hoped the compiler + would be more efficient), but unfortunately under FreeBSD + 4.1.1-STABLE on an x86 platform, the change slowed things + down. +1.0.0b1 to 1.0 RELEASE Fixed an off-by-one implementation bug that affected + SHA-256 when hashed data length L = 55 + 64 * X where X is + either zero or a positive integer, and another (basically + the same bug) bug in SHA-384 and SHA-512 that showed up when + hashed data lengths L = 111 + 128 * X. Thanks to Rogier + van de Pol for sending me test data that revealed the bug. + The fix was very simple (just two tiny changes). Also, + I finally put the files into RCS so future changes will be + easier to manage. The sha2prog.c file was rewritten to + be more useful to me, and I got rid of the old C testing + program and now use a perl script with a subdirectory full + of test data. It's a more flexible test system. + + +LATEST VERSION: + +The latest version and documentation (if any ;) should always be available +on the web at: + + http://www.aarongifford.com/computers/sha.html + + +CONTACT ME: + +I can be reached via email at: + + Aaron Gifford + +Please don't send support questions. I don't have the time to answer and +they'll probably be ignored. Bug fixes, or patches that add something useful +will be gratefully accepted, however. + +If you use this implementation, I would enjoy getting a brief email message +letting me know who you are and what use to which it is being put. There +is no requirement to do so. I just think it would be fun. + + +EXAMPLES: + +Here's an example of compiling and using the sha2 program (in this example +I build it using the unrolled transform version with -O2 optimizations), +and then running the perl testing script: + + cc -O2 -DSHA2_UNROLL_TRANSFORM -Wall -o sha2 sha2prog.c sha2.c + % ./sha2test.pl + + [most of the perl script output deleted for brevity] + + ===== RESULTS (18 VECTOR DATA FILES HASHED) ===== + + HASH TYPE NO. OF TESTS PASSED FAILED + --------- ------------ ------ ------ + SHA-256 18 18 0 + SHA-384 18 18 0 + SHA-512 18 18 0 + ---------------------------------------------- + TOTAL: 54 54 0 + + NO ERRORS! ALL TESTS WERE SUCCESSFUL! + + ALL TEST VECTORS PASSED! + +That's all folks! Have fun! + +Aaron out. + diff --git a/extlibs/tinydtls/sha2/sha2.c b/extlibs/tinydtls/sha2/sha2.c new file mode 100644 index 0000000..2578f17 --- /dev/null +++ b/extlibs/tinydtls/sha2/sha2.c @@ -0,0 +1,1101 @@ +/* + * FILE: sha2.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + */ + +#include "tinydtls.h" +#include "dtls_config.h" +#include /* memcpy()/memset() or bcopy()/bzero() */ +#ifdef HAVE_ASSERT_H +#include /* assert() */ +#else +#ifndef assert +#warning "assertions are disabled" +# define assert(x) +#endif +#endif +#include "sha2.h" + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * Please make sure that your system defines BYTE_ORDER. If your + * architecture is little-endian, make sure it also defines + * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are + * equivilent. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including (which in turn includes + * where the appropriate definitions are actually + * made). + */ + +/* bergmann: define LITTLE_ENDIAN and BIG_ENDIAN to ease autoconf: */ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#ifndef BYTE_ORDER +# if defined(WORDS_BIGENDIAN) || (defined(AC_APPLE_UNIVERSAL_BUILD) && defined(__BIG_ENDIAN__)) +# define BYTE_ORDER BIG_ENDIAN +# else /* WORDS_BIGENDIAN */ +# define BYTE_ORDER LITTLE_ENDIAN +# endif +#endif + +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/* + * Macros for copying blocks of memory and for zeroing out ranges + * of memory. Using these macros makes it easy to switch from + * using memset()/memcpy() and using bzero()/bcopy(). + * + * Please define either SHA2_USE_MEMSET_MEMCPY or define + * SHA2_USE_BZERO_BCOPY depending on which function set you + * choose to use: + */ +#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) +/* Default to memset()/memcpy() if no option is specified */ +#define SHA2_USE_MEMSET_MEMCPY 1 +#endif +#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) +/* Abort with an error if BOTH options are defined */ +#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! +#endif + +#ifdef SHA2_USE_MEMSET_MEMCPY +#define MEMSET_BZERO(p,l) memset((p), 0, (l)) +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#endif +#ifdef SHA2_USE_BZERO_BCOPY +#define MEMSET_BZERO(p,l) bzero((p), (l)) +#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) +#endif + + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +void SHA512_Last(SHA512_CTX*); +void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + +#ifdef WITH_SHA256 +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; +#endif + +#if defined(WITH_SHA384) || defined(WITH_SHA512) +/* Hash constant words K for SHA-384 and SHA-512: */ +const static sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; +#endif + +#ifdef WITH_SHA384 +/* Initial hash value H for SHA-384 */ +const static sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; +#endif + +#ifdef WITH_SHA512 +/* Initial hash value H for SHA-512 */ +const static sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; +#endif + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +#ifdef WITH_SHA256 +void SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(*context)); + usedspace = 0; +} + +char *SHA256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(*context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} +#endif + +/*** SHA-512: *********************************************************/ +#ifdef WITH_SHA512 +void SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} +#endif + +/*** SHA-384: *********************************************************/ +#ifdef WITH_SHA384 +void SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} +#endif diff --git a/extlibs/tinydtls/sha2/sha2.h b/extlibs/tinydtls/sha2/sha2.h new file mode 100644 index 0000000..709fc80 --- /dev/null +++ b/extlibs/tinydtls/sha2/sha2.h @@ -0,0 +1,215 @@ +/* + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Import u_intXX_t size_t type definitions from system headers. You + * may need to change this, or define these things yourself in this + * file. + */ +#include + +#ifdef SHA2_USE_INTTYPES_H + +#include + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include + * + * If you choose to use then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ +#ifndef NOPROTO +#ifdef SHA2_USE_INTTYPES_H + +#ifdef WITH_SHA256 +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +#endif + +#ifdef WITH_SHA384 +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); +#endif + +#ifdef WITH_SHA512 +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +#endif + +#else /* SHA2_USE_INTTYPES_H */ + +#ifdef WITH_SHA256 +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); +void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +#endif + +#ifdef WITH_SHA384 +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); +#endif + +#ifdef WITH_SHA512 +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +#endif + +#endif /* SHA2_USE_INTTYPES_H */ + +#else /* NOPROTO */ + +#ifdef WITH_SHA256 +void SHA256_Init(); +void SHA256_Update(); +void SHA256_Final(); +char* SHA256_End(); +char* SHA256_Data(); +#endif + +#ifdef WITH_SHA384 +void SHA384_Init(); +void SHA384_Update(); +void SHA384_Final(); +char* SHA384_End(); +char* SHA384_Data(); +#endif + +#ifdef WITH_SHA512 +void SHA512_Init(); +void SHA512_Update(); +void SHA512_Final(); +char* SHA512_End(); +char* SHA512_Data(); +#endif + +#endif /* NOPROTO */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHA2_H__ */ + diff --git a/extlibs/tinydtls/sha2/sha2prog.c b/extlibs/tinydtls/sha2/sha2prog.c new file mode 100644 index 0000000..8d9d6ae --- /dev/null +++ b/extlibs/tinydtls/sha2/sha2prog.c @@ -0,0 +1,132 @@ +/* + * FILE: sha2prog.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $Id: sha2prog.c,v 1.1 2001/11/08 00:02:11 adg Exp adg $ + */ + +#include +#include +#include +#include +#include + +#include "sha2.h" + +void usage(char *prog, char *msg) { + fprintf(stderr, "%s\nUsage:\t%s [options] []\nOptions:\n\t-256\tGenerate SHA-256 hash\n\t-384\tGenerate SHA-284 hash\n\t-512\tGenerate SHA-512 hash\n\t-ALL\tGenerate all three hashes\n\t-q\tQuiet mode - only output hexadecimal hashes, one per line\n\n", msg, prog); + exit(-1); +} + +#define BUFLEN 16384 + +int main(int argc, char **argv) { + int kl, l, fd, ac; + int quiet = 0, hash = 0; + char *av, *file = (char*)0; + FILE *IN = (FILE*)0; + SHA256_CTX ctx256; + SHA384_CTX ctx384; + SHA512_CTX ctx512; + unsigned char buf[BUFLEN]; + + SHA256_Init(&ctx256); + SHA384_Init(&ctx384); + SHA512_Init(&ctx512); + + /* Read data from STDIN by default */ + fd = fileno(stdin); + + ac = 1; + while (ac < argc) { + if (*argv[ac] == '-') { + av = argv[ac] + 1; + if (!strcmp(av, "q")) { + quiet = 1; + } else if (!strcmp(av, "256")) { + hash |= 1; + } else if (!strcmp(av, "384")) { + hash |= 2; + } else if (!strcmp(av, "512")) { + hash |= 4; + } else if (!strcmp(av, "ALL")) { + hash = 7; + } else { + usage(argv[0], "Invalid option."); + } + ac++; + } else { + file = argv[ac++]; + if (ac != argc) { + usage(argv[0], "Too many arguments."); + } + if ((IN = fopen(file, "r")) == NULL) { + perror(argv[0]); + exit(-1); + } + fd = fileno(IN); + } + } + if (hash == 0) + hash = 7; /* Default to ALL */ + + kl = 0; + while ((l = read(fd,buf,BUFLEN)) > 0) { + kl += l; + SHA256_Update(&ctx256, (unsigned char*)buf, l); + SHA384_Update(&ctx384, (unsigned char*)buf, l); + SHA512_Update(&ctx512, (unsigned char*)buf, l); + } + if (file) { + fclose(IN); + } + + if (hash & 1) { + SHA256_End(&ctx256, buf); + if (!quiet) + printf("SHA-256 (%s) = ", file); + printf("%s\n", buf); + } + if (hash & 2) { + SHA384_End(&ctx384, buf); + if (!quiet) + printf("SHA-384 (%s) = ", file); + printf("%s\n", buf); + } + if (hash & 4) { + SHA512_End(&ctx512, buf); + if (!quiet) + printf("SHA-512 (%s) = ", file); + printf("%s\n", buf); + } + + return 1; +} + diff --git a/extlibs/tinydtls/sha2/sha2speed.c b/extlibs/tinydtls/sha2/sha2speed.c new file mode 100644 index 0000000..2e13575 --- /dev/null +++ b/extlibs/tinydtls/sha2/sha2speed.c @@ -0,0 +1,174 @@ +/* + * FILE: sha2speed.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. + * + * $Id: sha2speed.c,v 1.1 2001/11/08 00:02:23 adg Exp adg $ + */ + +#include +#include +#include +#include + +#include "sha2.h" + +#define BUFSIZE 16384 + +void usage(char *prog) { + fprintf(stderr, "Usage:\t%s [] [] []\n", prog); + exit(-1); +} + +void printspeed(char *caption, unsigned long bytes, double time) { + if (bytes / 1073741824UL > 0) { + printf("%s %.4f sec (%.3f GBps)\n", caption, time, (double)bytes/1073741824UL/time); + } else if (bytes / 1048576 > 0) { + printf("%s %.4f (%.3f MBps)\n", caption, time, (double)bytes/1048576/time); + } else if (bytes / 1024 > 0) { + printf("%s %.4f (%.3f KBps)\n", caption, time, (double)bytes/1024/time); + } else { + printf("%s %.4f (%f Bps)\n", caption, time, (double)bytes/time); + } +} + + +int main(int argc, char **argv) { + SHA256_CTX c256; + SHA384_CTX c384; + SHA512_CTX c512; + char buf[BUFSIZE]; + char md[SHA512_DIGEST_STRING_LENGTH]; + int bytes, blocks, rep, i, j; + struct timeval start, end; + double t, ave256, ave384, ave512; + double best256, best384, best512; + + if (argc > 4) { + usage(argv[0]); + } + + /* Default to 1024 16K blocks (16 MB) */ + bytes = 1024 * 1024 * 16; + if (argc > 1) { + blocks = atoi(argv[1]); + } + blocks = bytes / BUFSIZE; + + /* Default to 10 repetitions */ + rep = 10; + if (argc > 2) { + rep = atoi(argv[2]); + } + + /* Set up the input data */ + if (argc > 3) { + memset(buf, atoi(argv[2]), BUFSIZE); + } else { + memset(buf, 0xb7, BUFSIZE); + } + + ave256 = ave384 = ave512 = 0; + best256 = best384 = best512 = 100000; + for (i = 0; i < rep; i++) { + SHA256_Init(&c256); + SHA384_Init(&c384); + SHA512_Init(&c512); + + gettimeofday(&start, (struct timezone*)0); + for (j = 0; j < blocks; j++) { + SHA256_Update(&c256, (unsigned char*)buf, BUFSIZE); + } + if (bytes % BUFSIZE) { + SHA256_Update(&c256, (unsigned char*)buf, bytes % BUFSIZE); + } + SHA256_End(&c256, md); + gettimeofday(&end, (struct timezone*)0); + t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; + ave256 += t; + if (t < best256) { + best256 = t; + } + printf("SHA-256[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave256/(i+1), best256, md); + + gettimeofday(&start, (struct timezone*)0); + for (j = 0; j < blocks; j++) { + SHA384_Update(&c384, (unsigned char*)buf, BUFSIZE); + } + if (bytes % BUFSIZE) { + SHA384_Update(&c384, (unsigned char*)buf, bytes % BUFSIZE); + } + SHA384_End(&c384, md); + gettimeofday(&end, (struct timezone*)0); + t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; + ave384 += t; + if (t < best384) { + best384 = t; + } + printf("SHA-384[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave384/(i+1), best384, md); + + gettimeofday(&start, (struct timezone*)0); + for (j = 0; j < blocks; j++) { + SHA512_Update(&c512, (unsigned char*)buf, BUFSIZE); + } + if (bytes % BUFSIZE) { + SHA512_Update(&c512, (unsigned char*)buf, bytes % BUFSIZE); + } + SHA512_End(&c512, md); + gettimeofday(&end, (struct timezone*)0); + t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0; + ave512 += t; + if (t < best512) { + best512 = t; + } + printf("SHA-512[%d] (%.4f/%.4f/%.4f seconds) = 0x%s\n", i+1, t, ave512/(i+1), best512, md); + } + ave256 /= rep; + ave384 /= rep; + ave512 /= rep; + printf("\nTEST RESULTS SUMMARY:\nTEST REPETITIONS: %d\n", rep); + if (bytes / 1073741824UL > 0) { + printf("TEST SET SIZE: %.3f GB\n", (double)bytes/1073741824UL); + } else if (bytes / 1048576 > 0) { + printf("TEST SET SIZE: %.3f MB\n", (double)bytes/1048576); + } else if (bytes /1024 > 0) { + printf("TEST SET SIZE: %.3f KB\n", (double)bytes/1024); + } else { + printf("TEST SET SIZE: %d B\n", bytes); + } + printspeed("SHA-256 average:", bytes, ave256); + printspeed("SHA-256 best: ", bytes, best256); + printspeed("SHA-384 average:", bytes, ave384); + printspeed("SHA-384 best: ", bytes, best384); + printspeed("SHA-512 average:", bytes, ave512); + printspeed("SHA-512 best: ", bytes, best512); + + return 1; +} + diff --git a/extlibs/tinydtls/sha2/sha2test.pl b/extlibs/tinydtls/sha2/sha2test.pl new file mode 100755 index 0000000..dc884d8 --- /dev/null +++ b/extlibs/tinydtls/sha2/sha2test.pl @@ -0,0 +1,358 @@ +#!/usr/bin/perl +# +# FILE: sha2test.pl +# AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ +# +# Copyright (c) 2001, Aaron D. Gifford +# All rights reserved. +# +# 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 above copyright +# notice, this list of conditions and the following disclaimer. +# 2. 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. +# 3. Neither the name of the copyright holder nor the names of contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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. +# +# $Id: sha2test.pl,v 1.1 2001/11/08 00:02:37 adg Exp adg $ +# + +sub usage { + my ($err) = shift(@_); + + print <] [ [ ...]] + +Options: + -256 Use SHA-256 hashes during testing + -384 Use SHA-384 hashes during testing + -512 Use SHA-512 hashes during testing + -ALL Use all three hashes during testing + -c256 Specify a command to execute to generate a + SHA-256 hash. Be sure to include a '%' + character which will be replaced by the + test vector data filename containing the + data to be hashed. This command implies + the -256 option. + -c384 Specify a command to execute to generate a + SHA-384 hash. See above. Implies -384. + -c512 Specify a command to execute to generate a + SHA-512 hash. See above. Implies -512. + -cALL Specify a command to execute that will + generate all three hashes at once and output + the data in hexadecimal. See above for + information about the . + This option implies the -ALL option, and + also overrides any other command options if + present. + +By default, this program expects to execute the command ./sha2 within the +current working directory to generate all hashes. If no test vector +information files are specified, this program expects to read a series of +files ending in ".info" within a subdirectory of the current working +directory called "testvectors". + +EOM + exit(-1); +} + +$c256 = $c384 = $c512 = $cALL = ""; +$hashes = 0; +@FILES = (); + +# Read all command-line options and files: +while ($opt = shift(@ARGV)) { + if ($opt =~ s/^\-//) { + if ($opt eq "256") { + $hashes |= 1; + } elsif ($opt eq "384") { + $hashes |= 2; + } elsif ($opt eq "512") { + $hashes |= 4; + } elsif ($opt =~ /^ALL$/i) { + $hashes = 7; + } elsif ($opt =~ /^c256$/i) { + $hashes |= 1; + $opt = $c256 = shift(@ARGV); + $opt =~ s/\s+.*$//; + if (!$c256 || $c256 !~ /\%/ || !-x $opt) { + usage("Missing or invalid command specification for option -c256: $opt\n"); + } + } elsif ($opt =~ /^c384$/i) { + $hashes |= 2; + $opt = $c384 = shift(@ARGV); + $opt =~ s/\s+.*$//; + if (!$c384 || $c384 !~ /\%/ || !-x $opt) { + usage("Missing or invalid command specification for option -c384: $opt\n"); + } + } elsif ($opt =~ /^c512$/i) { + $hashes |= 4; + $opt = $c512 = shift(@ARGV); + $opt =~ s/\s+.*$//; + if (!$c512 || $c512 !~ /\%/ || !-x $opt) { + usage("Missing or invalid command specification for option -c512: $opt\n"); + } + } elsif ($opt =~ /^cALL$/i) { + $hashes = 7; + $opt = $cALL = shift(@ARGV); + $opt =~ s/\s+.*$//; + if (!$cALL || $cALL !~ /\%/ || !-x $opt) { + usage("Missing or invalid command specification for option -cALL: $opt\n"); + } + } else { + usage("Unknown/invalid option '$opt'\n"); + } + } else { + usage("Invalid, nonexistent, or unreadable file '$opt': $!\n") if (!-f $opt); + push(@FILES, $opt); + } +} + +# Set up defaults: +if (!$cALL && !$c256 && !$c384 && !$c512) { + $cALL = "./sha2 -ALL %"; + usage("Required ./sha2 binary executable not found.\n") if (!-x "./sha2"); +} +$hashes = 7 if (!$hashes); + +# Do some sanity checks: +usage("No command was supplied to generate SHA-256 hashes.\n") if ($hashes & 1 == 1 && !$cALL && !$c256); +usage("No command was supplied to generate SHA-384 hashes.\n") if ($hashes & 2 == 2 && !$cALL && !$c384); +usage("No command was supplied to generate SHA-512 hashes.\n") if ($hashes & 4 == 4 && !$cALL && !$c512); + +# Default .info files: +if (scalar(@FILES) < 1) { + opendir(DIR, "testvectors") || usage("Unable to scan directory 'testvectors' for vector information files: $!\n"); + @FILES = grep(/\.info$/, readdir(DIR)); + closedir(DIR); + @FILES = map { s/^/testvectors\//; $_; } @FILES; + @FILES = sort(@FILES); +} + +# Now read in each test vector information file: +foreach $file (@FILES) { + $dir = $file; + if ($file !~ /\//) { + $dir = "./"; + } else { + $dir =~ s/\/[^\/]+$//; + $dir .= "/"; + } + open(FILE, "<" . $file) || + usage("Unable to open test vector information file '$file' for reading: $!\n"); + $vec = { desc => "", file => "", sha256 => "", sha384 => "", sha512 => "" }; + $data = $field = ""; + $line = 0; + while() { + $line++; + s/\s*[\r\n]+$//; + next if ($field && $field ne "DESCRIPTION" && !$_); + if (/^(DESCRIPTION|FILE|SHA256|SHA384|SHA512):$/) { + if ($field eq "DESCRIPTION") { + $vec->{desc} = $data; + } elsif ($field eq "FILE") { + $data = $dir . $data if ($data !~ /^\//); + $vec->{file} = $data; + } elsif ($field eq "SHA256") { + $vec->{sha256} = $data; + } elsif ($field eq "SHA384") { + $vec->{sha384} = $data; + } elsif ($field eq "SHA512") { + $vec->{sha512} = $data; + } + $data = ""; + $field = $1; + } elsif ($field eq "DESCRIPTION") { + s/^ //; + $data .= $_ . "\n"; + } elsif ($field =~ /^SHA\d\d\d$/) { + s/^\s+//; + if (!/^([a-f0-9]{32}|[a-f0-9]{64})$/) { + usage("Invalid SHA-256/384/512 test vector information " . + "file format at line $line of file '$file'\n"); + } + $data .= $_; + } elsif ($field eq "FILE") { + s/^ //; + $data .= $_; + } else { + usage("Invalid SHA-256/384/512 test vector information file " . + "format at line $line of file '$file'\n"); + } + } + if ($field eq "DESCRIPTION") { + $data = $dir . $data if ($data !~ /^\//); + $vec->{desc} = $data; + } elsif ($field eq "FILE") { + $vec->{file} = $data; + } elsif ($field eq "SHA256") { + $vec->{sha256} = $data; + } elsif ($field eq "SHA384") { + $vec->{sha384} = $data; + } elsif ($field eq "SHA512") { + $vec->{sha512} = $data; + } else { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. Missing required fields in file '$file'\n"); + } + + # Sanity check all entries: + if (!$vec->{desc}) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. Missing required DESCRIPTION field in file '$file'\n"); + } + if (!$vec->{file}) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. Missing required FILE field in file '$file'\n"); + } + if (! -f $vec->{file}) { + usage("The test vector data file (field FILE) name " . + "'$vec->{file}' is not a readable file. Check the FILE filed in " . + "file '$file'.\n"); + } + if (!($vec->{sha256} || $vec->{sha384} || $vec->{sha512})) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. There must be at least one SHA256, SHA384, or SHA512 " . + "field specified in file '$file'.\n"); + } + if ($vec->{sha256} !~ /^(|[a-f0-9]{64})$/) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. The SHA256 field is invalid in file '$file'.\n"); + } + if ($vec->{sha384} !~ /^(|[a-f0-9]{96})$/) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. The SHA384 field is invalid in file '$file'.\n"); + } + if ($vec->{sha512} !~ /^(|[a-f0-9]{128})$/) { + usage("Invalid SHA-256/384/512 test vector information file " . + "format. The SHA512 field is invalid in file '$file'.\n"); + } + close(FILE); + if ($hashes & (($vec->{sha256} ? 1 : 0) | ($vec->{sha384} ? 2 : 0) | ($vec->{sha512} ? 4 : 0))) { + push(@VECTORS, $vec); + } +} + +usage("There were no test vectors for the specified hash(es) in any of the test vector information files you specified.\n") if (scalar(@VECTORS) < 1); + +$num = $errors = $error256 = $error384 = $error512 = $tests = $test256 = $test384 = $test512 = 0; +foreach $vec (@VECTORS) { + $num++; + print "TEST VECTOR #$num:\n"; + print "\t" . join("\n\t", split(/\n/, $vec->{desc})) . "\n"; + print "VECTOR DATA FILE:\n\t$vec->{file}\n"; + $sha256 = $sha384 = $sha512 = ""; + if ($cALL) { + $prog = $cALL; + $prog =~ s/\%/'$vec->{file}'/g; + @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); + ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA); + ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA); + ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA); + } else { + if ($c256) { + $prog = $c256; + $prog =~ s/\%/'$vec->{file}'/g; + @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); + ($sha256) = grep(/(^[a-fA-F0-9]{64}$|^[a-fA-F0-9]{64}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{64}$|[^a-fA-F0-9][a-fA-F0-9]{64}[^a-fA-F0-9])/, @SHA); + } + if ($c384) { + $prog = $c384; + $prog =~ s/\%/'$vec->{file}'/g; + @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); + ($sha384) = grep(/(^[a-fA-F0-9]{96}$|^[a-fA-F0-9]{96}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{96}$|[^a-fA-F0-9][a-fA-F0-9]{96}[^a-fA-F0-9])/, @SHA); + } + if ($c512) { + $prog = $c512; + $prog =~ s/\%/'$vec->{file}'/g; + @SHA = grep(/[a-fA-f0-9]{64,128}/, split(/\n/, `$prog`)); + ($sha512) = grep(/(^[a-fA-F0-9]{128}$|^[a-fA-F0-9]{128}[^a-fA-F0-9]|[^a-fA-F0-9][a-fA-F0-9]{128}$|[^a-fA-F0-9][a-fA-F0-9]{128}[^a-fA-F0-9])/, @SHA); + } + } + usage("Unable to generate any hashes for file '$vec->{file}'!\n") if (!$sha256 && !$sha384 && $sha512); + $sha256 =~ tr/A-F/a-f/; + $sha384 =~ tr/A-F/a-f/; + $sha512 =~ tr/A-F/a-f/; + $sha256 =~ s/^.*([a-f0-9]{64}).*$/$1/; + $sha384 =~ s/^.*([a-f0-9]{96}).*$/$1/; + $sha512 =~ s/^.*([a-f0-9]{128}).*$/$1/; + + if ($sha256 && $hashes & 1 == 1) { + if ($vec->{sha256} eq $sha256) { + print "SHA256 MATCHES:\n\t$sha256\n" + } else { + print "SHA256 DOES NOT MATCH:\n\tEXPECTED:\n\t\t$vec->{sha256}\n" . + "\tGOT:\n\t\t$sha256\n\n"; + $error256++; + } + $test256++; + } + if ($sha384 && $hashes & 2 == 2) { + if ($vec->{sha384} eq $sha384) { + print "SHA384 MATCHES:\n\t" . substr($sha384, 0, 64) . "\n\t" . + substr($sha384, -32) . "\n"; + } else { + print "SHA384 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" . + substr($vec->{sha384}, 0, 64) . "\n\t\t" . + substr($vec->{sha384}, -32) . "\n\tGOT:\n\t\t" . + substr($sha384, 0, 64) . "\n\t\t" . substr($sha384, -32) . "\n\n"; + $error384++; + } + $test384++; + } + if ($sha512 && $hashes & 4 == 4) { + if ($vec->{sha512} eq $sha512) { + print "SHA512 MATCHES:\n\t" . substr($sha512, 0, 64) . "\n\t" . + substr($sha512, -64) . "\n"; + } else { + print "SHA512 DOES NOT MATCH:\n\tEXPECTED:\n\t\t" . + substr($vec->{sha512}, 0, 64) . "\n\t\t" . + substr($vec->{sha512}, -32) . "\n\tGOT:\n\t\t" . + substr($sha512, 0, 64) . "\n\t\t" . substr($sha512, -64) . "\n\n"; + $error512++; + } + $test512++; + } +} + +$errors = $error256 + $error384 + $error512; +$tests = $test256 + $test384 + $test512; +print "\n\n===== RESULTS ($num VECTOR DATA FILES HASHED) =====\n\n"; +print "HASH TYPE\tNO. OF TESTS\tPASSED\tFAILED\n"; +print "---------\t------------\t------\t------\n"; +if ($test256) { + $pass = $test256 - $error256; + print "SHA-256\t\t".substr(" $test256", -12)."\t".substr(" $pass", -6)."\t".substr(" $error256", -6)."\n"; +} +if ($test384) { + $pass = $test384 - $error384; + print "SHA-384\t\t".substr(" $test384", -12)."\t".substr(" $pass", -6)."\t".substr(" $error384", -6)."\n"; +} +if ($test512) { + $pass = $test512 - $error512; + print "SHA-512\t\t".substr(" $test512", -12)."\t".substr(" $pass", -6)."\t".substr(" $error512", -6)."\n"; +} +print "----------------------------------------------\n"; +$pass = $tests - $errors; +print "TOTAL: ".substr(" $tests", -12)."\t".substr(" $pass", -6)."\t".substr(" $errors", -6)."\n\n"; +print "NO ERRORS! ALL TESTS WERE SUCCESSFUL!\n\n" if (!$errors); + diff --git a/extlibs/tinydtls/sha2/testvectors/vector001.dat b/extlibs/tinydtls/sha2/testvectors/vector001.dat new file mode 100644 index 0000000..f2ba8f8 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector001.dat @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector001.info b/extlibs/tinydtls/sha2/testvectors/vector001.info new file mode 100644 index 0000000..57b444e --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector001.info @@ -0,0 +1,21 @@ +DESCRIPTION: + This test vector is taken from the PDF document that describes + the SHA-256/384/512 algorithms. That document contains sample + output for all three versions (SHA-256, SHA-384, and SHA-512). + + (Total length of test vector data: 3) + +FILE: + vector001.dat + +SHA256: + ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad + +SHA384: + cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed + 8086072ba1e7cc2358baeca134c825a7 + +SHA512: + ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a + 2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f + diff --git a/extlibs/tinydtls/sha2/testvectors/vector002.dat b/extlibs/tinydtls/sha2/testvectors/vector002.dat new file mode 100644 index 0000000..199f24e --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector002.dat @@ -0,0 +1 @@ +abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector002.info b/extlibs/tinydtls/sha2/testvectors/vector002.info new file mode 100644 index 0000000..0fc1ed3 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector002.info @@ -0,0 +1,21 @@ +DESCRIPTION: + The PDF document only provided sample output for SHA-256 using + this test data. I have provided SHA-384 and SHA-512 sample + output from my own implementation which may not be correct. + + (Total length of test vector data: 56) + +FILE: + vector002.dat + +SHA256: + 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1 + +SHA384: + 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6 + b0455a8520bc4e6f5fe95b1fe3c8452b + +SHA512: + 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335 + 96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector003.dat b/extlibs/tinydtls/sha2/testvectors/vector003.dat new file mode 100644 index 0000000..4674ea4 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector003.dat @@ -0,0 +1 @@ +abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector003.info b/extlibs/tinydtls/sha2/testvectors/vector003.info new file mode 100644 index 0000000..17a2ad8 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector003.info @@ -0,0 +1,22 @@ +DESCRIPTION: + For this test data (from the PDF document), no example output + was provided for SHA-256 (SHA-384 and SHA-512 samples were + provided), so the sample for SHA-256 comes from the output of + my own implementation and so may not be correct. + + (Total length of test vector data: 112) + +FILE: + vector003.dat + +SHA256: + cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1 + +SHA384: + 09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712 + fcc7c71a557e2db966c3e9fa91746039 + +SHA512: + 8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018 + 501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector004.dat b/extlibs/tinydtls/sha2/testvectors/vector004.dat new file mode 100644 index 0000000..3d71eba --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector004.dat @@ -0,0 +1 @@ +Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate--we can not consecrate--we can not hallow--this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us--that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion--that we here highly resolve that these dead shall not have died in vain--that this nation, under God, shall have a new birth of freedom--and that government of the people, by the people, for the people, shall not perish from the earth. -- President Abraham Lincoln, November 19, 1863 \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector004.info b/extlibs/tinydtls/sha2/testvectors/vector004.info new file mode 100644 index 0000000..eed148c --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector004.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for this test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample comes from...well + most anyone in the U.S. will know and many outside the U.S. too. + + (Total length of test vector data: 1515) + +FILE: + vector004.dat + +SHA256: + 4d25fccf8752ce470a58cd21d90939b7eb25f3fa418dd2da4c38288ea561e600 + +SHA384: + 69cc75b95280bdd9e154e743903e37b1205aa382e92e051b1f48a6db9d0203f8 + a17c1762d46887037275606932d3381e + +SHA512: + 23450737795d2f6a13aa61adcca0df5eef6df8d8db2b42cd2ca8f783734217a7 + 3e9cabc3c9b8a8602f8aeaeb34562b6b1286846060f9809b90286b3555751f09 + diff --git a/service/soft-sensor-manager/build/tizen/Makefile b/extlibs/tinydtls/sha2/testvectors/vector005.dat similarity index 100% rename from service/soft-sensor-manager/build/tizen/Makefile rename to extlibs/tinydtls/sha2/testvectors/vector005.dat diff --git a/extlibs/tinydtls/sha2/testvectors/vector005.info b/extlibs/tinydtls/sha2/testvectors/vector005.info new file mode 100644 index 0000000..37602d3 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector005.info @@ -0,0 +1,23 @@ +DESCRIPTION: + The output samples for this test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is EMPTY (no bits). + Mr. David A. Ireland's SHA-256 implementation agrees with my own + implementation on the output of this test vector (SHA-256 only). + + (Total length of test vector data: 0) + +FILE: + vector005.dat + +SHA256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + +SHA384: + 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da + 274edebfe76f65fbd51ad2f14898b95b + +SHA512: + cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce + 47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e + diff --git a/extlibs/tinydtls/sha2/testvectors/vector006.dat b/extlibs/tinydtls/sha2/testvectors/vector006.dat new file mode 100644 index 0000000..7caf161 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector006.dat @@ -0,0 +1 @@ +This is exactly 64 bytes long, not counting the terminating byte \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector006.info b/extlibs/tinydtls/sha2/testvectors/vector006.info new file mode 100644 index 0000000..2a0d78a --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector006.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample exactly the same + length as the SHA-256 block length. + + (Total length of test vector data: 64) + +FILE: + vector006.dat + +SHA256: + ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8 + +SHA384: + e28e35e25a1874908bf0958bb088b69f3d742a753c86993e9f4b1c4c21988f95 + 8bd1fe0315b195aca7b061213ac2a9bd + +SHA512: + 70aefeaa0e7ac4f8fe17532d7185a289bee3b428d950c14fa8b713ca09814a38 + 7d245870e007a80ad97c369d193e41701aa07f3221d15f0e65a1ff970cedf030 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector007.dat b/extlibs/tinydtls/sha2/testvectors/vector007.dat new file mode 100644 index 0000000..1caf01b --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector007.dat @@ -0,0 +1 @@ +For this sample, this 63-byte string will be used as input data \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector007.info b/extlibs/tinydtls/sha2/testvectors/vector007.info new file mode 100644 index 0000000..fad860d --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector007.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample one byte shorter + than the SHA-256 block length. + + (Total length of test vector data: 63) + +FILE: + vector007.dat + +SHA256: + f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342 + +SHA384: + 37b49ef3d08de53e9bd018b0630067bd43d09c427d06b05812f48531bce7d2a6 + 98ee2d1ed1ffed46fd4c3b9f38a8a557 + +SHA512: + b3de4afbc516d2478fe9b518d063bda6c8dd65fc38402dd81d1eb7364e72fb6e + 6663cf6d2771c8f5a6da09601712fb3d2a36c6ffea3e28b0818b05b0a8660766 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector008.dat b/extlibs/tinydtls/sha2/testvectors/vector008.dat new file mode 100644 index 0000000..baae226 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector008.dat @@ -0,0 +1 @@ +And this textual data, astonishing as it may appear, is exactly 128 bytes in length, as are both SHA-384 and SHA-512 block sizes \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector008.info b/extlibs/tinydtls/sha2/testvectors/vector008.info new file mode 100644 index 0000000..22cfd81 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector008.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample exactly the same + length as the SHA-384 and SHA-512 block lengths. + + (Total length of test vector data: 128) + +FILE: + vector008.dat + +SHA256: + 0ab803344830f92089494fb635ad00d76164ad6e57012b237722df0d7ad26896 + +SHA384: + e3e3602f4d90c935321d788f722071a8809f4f09366f2825cd85da97ccd2955e + b6b8245974402aa64789ed45293e94ba + +SHA512: + 97fb4ec472f3cb698b9c3c12a12768483e5b62bcdad934280750b4fa4701e5e0 + 550a80bb0828342c19631ba55a55e1cee5de2fda91fc5d40e7bee1d4e6d415b3 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector009.dat b/extlibs/tinydtls/sha2/testvectors/vector009.dat new file mode 100644 index 0000000..9c64af4 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector009.dat @@ -0,0 +1 @@ +By hashing data that is one byte less than a multiple of a hash block length (like this 127-byte string), bugs may be revealed. \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector009.info b/extlibs/tinydtls/sha2/testvectors/vector009.info new file mode 100644 index 0000000..d5fe515 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector009.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is one byte shorter + in length than the SHA-384 and SHA-512 block lengths. + + (Total length of test vector data: 127) + +FILE: + vector009.dat + +SHA256: + e4326d0459653d7d3514674d713e74dc3df11ed4d30b4013fd327fdb9e394c26 + +SHA384: + 1ca650f38480fa9dfb5729636bec4a935ebc1cd4c0055ee50cad2aa627e06687 + 1044fd8e6fdb80edf10b85df15ba7aab + +SHA512: + d399507bbf5f2d0da51db1ff1fc51c1c9ff1de0937e00d01693b240e84fcc340 + 0601429f45c297acc6e8fcf1e4e4abe9ff21a54a0d3d88888f298971bd206cd5 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector010.dat b/extlibs/tinydtls/sha2/testvectors/vector010.dat new file mode 100644 index 0000000..f1681bc Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector010.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector010.info b/extlibs/tinydtls/sha2/testvectors/vector010.info new file mode 100644 index 0000000..df7717d --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector010.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is exactly 5 times + size of the SHA-256 block length. + + (Total length of test vector data: 320) + +FILE: + vector010.dat + +SHA256: + a7f001d996dd25af402d03b5f61aef950565949c1a6ad5004efa730328d2dbf3 + +SHA384: + b8261ddcd7df7b3969a516b72550de6fbf0e394a4a7bb2bbc60ec603c2ceff64 + 3c5bf62bc6dcbfa5beb54b62d750b969 + +SHA512: + caf970d3638e21053173a638c4b94d6d1ff87bc47b58f8ee928fbe9e245c23ab + f81019e45bf017ecc8610e5e0b95e3b025ccd611a772ca4fb3dfba26f0859725 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector011.dat b/extlibs/tinydtls/sha2/testvectors/vector011.dat new file mode 100644 index 0000000..d1609a9 Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector011.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector011.info b/extlibs/tinydtls/sha2/testvectors/vector011.info new file mode 100644 index 0000000..f36988c --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector011.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is one byte less + than 7 times the size of the SHA-256 block length. + + (Total length of test vector data: 447) + +FILE: + vector011.dat + +SHA256: + 6dcd63a07b0922cc3a9b3315b158478681cc32543b0a4180abe58a73c5e14cc2 + +SHA384: + 548e4e9a1ff57f469ed47b023bf5279dfb4d4ca08c65051e3a5c41fab84479a2 + 05496276906008b4b3c5b0970b2f5446 + +SHA512: + ee5d07460183b130687c977e9f8d43110989b0864b18fe6ee00a53dec5eda111 + f3aaa3bac7ab8dae26ed545a4de33ed45190f18fa0c327c44642ab9424265330 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector012.dat b/extlibs/tinydtls/sha2/testvectors/vector012.dat new file mode 100644 index 0000000..d74f1db Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector012.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector012.info b/extlibs/tinydtls/sha2/testvectors/vector012.info new file mode 100644 index 0000000..a1574e1 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector012.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is exactly 5 times + size of the SHA-384 and SHA-512 block lengths. + + (Total length of test vector data: 640) + +FILE: + vector012.dat + +SHA256: + af6ebfde7d93d5badb6cde6287ecc2061c1cafc5b1c1217cd984fbcdb9c61aaa + +SHA384: + c6fec3a3278dd6b5afc8c0971d32d38faf5802f1a21527c32563b32a1ac34065 + 6b433b44fe2648aa2232206f4301193a + +SHA512: + 73ffeb67716c3495fbc33f2d62fe08e2616706a5599881c7e67e9ef2b68f4988 + ea8b3b604ba87e50b07962692705c420fa31a00be41d6aaa9f3b11eafe9cf49b + diff --git a/extlibs/tinydtls/sha2/testvectors/vector013.dat b/extlibs/tinydtls/sha2/testvectors/vector013.dat new file mode 100644 index 0000000..cc8a8ae Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector013.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector013.info b/extlibs/tinydtls/sha2/testvectors/vector013.info new file mode 100644 index 0000000..4fbd4cb --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector013.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample is one byte short + of 17 times size of the SHA-384 and SHA-512 block lengths. + + (Total length of test vector data: 2175) + +FILE: + vector013.dat + +SHA256: + 8ff59c6d33c5a991088bc44dd38f037eb5ad5630c91071a221ad6943e872ac29 + +SHA384: + 92dca5655229b3c34796a227ff1809e273499adc2830149481224e0f54ff4483 + bd49834d4865e508ef53d4cd22b703ce + +SHA512: + 0e928db6207282bfb498ee871202f2337f4074f3a1f5055a24f08e912ac118f8 + 101832cdb9c2f702976e629183db9bacfdd7b086c800687c3599f15de7f7b9dd + diff --git a/extlibs/tinydtls/sha2/testvectors/vector014.dat b/extlibs/tinydtls/sha2/testvectors/vector014.dat new file mode 100644 index 0000000..6ee6629 Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector014.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector014.info b/extlibs/tinydtls/sha2/testvectors/vector014.info new file mode 100644 index 0000000..1780afc --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector014.info @@ -0,0 +1,22 @@ +DESCRIPTION: + The output samples for thi test vector come exclusively from my + own implementation and so may be completely incorrect. Use with + a very large grain of salt. The input sample 4 KB of misc. + data. + + (Total length of test vector data: 16384) + +FILE: + vector014.dat + +SHA256: + 1818e87564e0c50974ecaabbb2eb4ca2f6cc820234b51861e2590be625f1f703 + +SHA384: + 310fbb2027bdb7042f0e09e7b092e9ada506649510a7aa029825c8e8019e9c30 + 749d723f2de1bd8c043d8d89d3748c2f + +SHA512: + a001636f3ff1ce34f432f8e8f7785b78be84318beb8485a406650a8b243c419f + 7db6435cf6bf3000c6524adb5b52bad01afb76b3ceff701331e18b85b0e4cbd3 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector015.dat b/extlibs/tinydtls/sha2/testvectors/vector015.dat new file mode 100644 index 0000000..7d63021 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector015.dat @@ -0,0 +1 @@ +qwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwerty \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector015.info b/extlibs/tinydtls/sha2/testvectors/vector015.info new file mode 100644 index 0000000..d035782 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector015.info @@ -0,0 +1,21 @@ +DESCRIPTION: + This is yet another of my own test vectors for a larger + input data set. The input data is the string "qwerty + repeated 65536 times. + + (Total length of test vector data: 393216) + +FILE: + vector015.dat + +SHA256: + 5e3dfe0cc98fd1c2de2a9d2fd893446da43d290f2512200c515416313cdf3192 + +SHA384: + 0d5e45317bc7997cb9c8a23bad9bac9170d5bc81789b51af6bcd74ace379fd64 + 9a2b48cb56c4cb4ec1477e6933329e0e + +SHA512: + 735bd6bebfe6f8070d70069105bc761f35ed1ac3742f2e372fdc14d2a51898e6 + 153ccaff9073324130abdc451c730dc5dab5a0452487b1171c4dd97f92e267b7 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector016.dat b/extlibs/tinydtls/sha2/testvectors/vector016.dat new file mode 100644 index 0000000..fc00891 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector016.dat @@ -0,0 +1 @@ +Rijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AESRijndael is AES \ No newline at end of file diff --git a/extlibs/tinydtls/sha2/testvectors/vector016.info b/extlibs/tinydtls/sha2/testvectors/vector016.info new file mode 100644 index 0000000..effb114 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector016.info @@ -0,0 +1,23 @@ +DESCRIPTION: + This test vector came from Brian LaMacchia in his e-mail + message containing several samples of output from his SHA-256 + and SHA-512 implementations. My own implementations match + his output exactly. The input data data set is the string + "Rijndael is AES" repeated 1024 times. + + (Total length of test vector data: 15360) + +FILE: + vector016.dat + +SHA256: + 80fced5a97176a5009207cd119551b42c5b51ceb445230d02ecc2663bbfb483a + +SHA384: + aa1e77c094e5ce6db81a1add4c095201d020b7f8885a4333218da3b799b9fc42 + f00d60cd438a1724ae03bd7b515b739b + +SHA512: + fae25ec70bcb3bbdef9698b9d579da49db68318dbdf18c021d1f76aaceff9628 + 38873235597e7cce0c68aabc610e0deb79b13a01c302abc108e459ddfbe9bee8 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector017.dat b/extlibs/tinydtls/sha2/testvectors/vector017.dat new file mode 100644 index 0000000..4272d97 Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector017.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector017.info b/extlibs/tinydtls/sha2/testvectors/vector017.info new file mode 100644 index 0000000..5d6c632 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector017.info @@ -0,0 +1,32 @@ +DESCRIPTION: + Rogier van de Pol notified me that my implementation differed + with several others on several test data sets he had tested + against. This test vector data set is one Rogier provided + to me that highlighted an off-by-one bug in my implementation + that affected SHA-256/384/512 hashes where the data set length + was of a certain length. In the case of SHA512 or SHA384, if + the data length after subtracting 111 was an even multiple of + 128 bytes, the bug surfaced. In the case of SHA256, after + subtracting 55, the remaining length was an even multiple of 64, + the bug surfaced. The fix was simple. In SHA512_Last() and in + SHA256_Final() functions, I simply replaced a single "<" test + with a "<=" test. + + Thanks, Rogier! + + (Total length of test vector data: 12271) + +FILE: + vector017.dat + +SHA256: + 88ee6ada861083094f4c64b373657e178d88ef0a4674fce6e4e1d84e3b176afb + +SHA384: + 78cc6402a29eb984b8f8f888ab0102cabe7c06f0b9570e3d8d744c969db14397 + f58ecd14e70f324bf12d8dd4cd1ad3b2 + +SHA512: + 211bec83fbca249c53668802b857a9889428dc5120f34b3eac1603f13d1b4796 + 5c387b39ef6af15b3a44c5e7b6bbb6c1096a677dc98fc8f472737540a332f378 + diff --git a/extlibs/tinydtls/sha2/testvectors/vector018.dat b/extlibs/tinydtls/sha2/testvectors/vector018.dat new file mode 100644 index 0000000..cc8a8d1 Binary files /dev/null and b/extlibs/tinydtls/sha2/testvectors/vector018.dat differ diff --git a/extlibs/tinydtls/sha2/testvectors/vector018.info b/extlibs/tinydtls/sha2/testvectors/vector018.info new file mode 100644 index 0000000..7ee3444 --- /dev/null +++ b/extlibs/tinydtls/sha2/testvectors/vector018.info @@ -0,0 +1,26 @@ +DESCRIPTION: + I added this vector after fixing a bug first discovered by + Rogier van de Pol. The length of this data set is designed to + test for that bug or similar bugs in SHA-256 hashes. The bug + was an off-by-one bug where I used a "<" test instead of a "<=" + test in SHA256_Final(). Whenever data set lengths were an even + multiple of 64 after subtracting 55, the bug showed up. The + fix was easy, once the problem was fully diagnosed. + + Thanks, Rogier! + + (Total length of test vector data: 1079) + +FILE: + vector018.dat + +SHA256: + 5a2e925a7f8399fa63a20a1524ae83a7e3c48452f9af4df493c8c51311b04520 + +SHA384: + 72ec26cc742bc5fb1ef82541c9cadcf01a15c8104650d305f24ec8b006d7428e + 8ebe2bb320a465dbdd5c6326bbd8c9ad + +SHA512: + ebad464e6d9f1df7e8aadff69f52db40a001b253fbf65a018f29974dcc7fbf8e + 58b69e247975fbadb4153d7289357c9b6212752d0ab67dd3d9bbc0bb908aa98c diff --git a/extlibs/tinydtls/state.h b/extlibs/tinydtls/state.h new file mode 100644 index 0000000..72df125 --- /dev/null +++ b/extlibs/tinydtls/state.h @@ -0,0 +1,64 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2013 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file state.h + * @brief state information for DTLS FSM + */ + +#ifndef _DTLS_STATE_H_ +#define _DTLS_STATE_H_ + +#include +#include + +#include "global.h" +#include "hmac.h" + +typedef enum { + DTLS_STATE_INIT = 0, DTLS_STATE_WAIT_CLIENTHELLO, DTLS_STATE_WAIT_CLIENTCERTIFICATE, + DTLS_STATE_WAIT_CLIENTKEYEXCHANGE, DTLS_STATE_WAIT_CERTIFICATEVERIFY, + DTLS_STATE_WAIT_CHANGECIPHERSPEC, + DTLS_STATE_WAIT_FINISHED, DTLS_STATE_FINISHED, + /* client states */ + DTLS_STATE_CLIENTHELLO, DTLS_STATE_WAIT_SERVERCERTIFICATE, DTLS_STATE_WAIT_SERVERKEYEXCHANGE, + DTLS_STATE_WAIT_SERVERHELLODONE, + + DTLS_STATE_CONNECTED, + DTLS_STATE_CLOSING, + DTLS_STATE_CLOSED +} dtls_state_t; + +typedef struct { + uint16_t mseq_s; /**< send handshake message sequence number counter */ + uint16_t mseq_r; /**< received handshake message sequence number counter */ + + /** pending config that is updated during handshake */ + /* FIXME: dtls_security_parameters_t pending_config; */ + + /* temporary storage for the final handshake hash */ + dtls_hash_ctx hs_hash; +} dtls_hs_state_t; +#endif /* _DTLS_STATE_H_ */ diff --git a/extlibs/tinydtls/t_list.h b/extlibs/tinydtls/t_list.h new file mode 100644 index 0000000..eb72991 --- /dev/null +++ b/extlibs/tinydtls/t_list.h @@ -0,0 +1,147 @@ +/* t_list -- tinydtls lists + * + * Copyright (C) 2012 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file t_list.h + * @brief Wrappers for list structures and functions + */ + +#ifndef _DTLS_LIST_H_ +#define _DTLS_LIST_H_ + +#include "tinydtls.h" + +#ifndef WITH_CONTIKI +#include "uthash.h" +#include "utlist.h" + +/* We define list structures and utility functions to be compatible + * with Contiki list structures. The Contiki list API is part of the + * Contiki operating system, and therefore the following licensing + * terms apply (taken from contiki/core/lib/list.h): + * + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * 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 above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $ Id: list.h,v 1.5 2010/09/13 13:31:00 adamdunkels Exp $ + */ + +typedef void **list_t; +struct list { + struct list *next; +}; + +#define LIST_CONCAT(s1, s2) s1##s2 + +#define LIST_STRUCT(name) \ + void *LIST_CONCAT(name, _list); \ + list_t name + +#define LIST_STRUCT_INIT(struct_ptr, name) { \ + (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ + (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ + } + +static inline void * +list_head(list_t list) { + return *list; +} + +static inline void +list_remove(list_t list, void *item) { + LL_DELETE(*(struct list **)list, (struct list *)item); +} + +static inline void +list_add(list_t list, void *item) { + list_remove(list, item); + LL_APPEND(*(struct list **)list, (struct list *)item); +} + +static inline void +list_push(list_t list, void *item) { + LL_PREPEND(*(struct list **)list, (struct list *)item); +} + +static inline void * +list_pop(list_t list) { + struct list *l; + l = *list; + if(l) + list_remove(list, l); + + return l; +} + +static inline void +list_insert(list_t list, void *previtem, void *newitem) { + if(previtem == NULL) { + list_push(list, newitem); + } else { + ((struct list *)newitem)->next = ((struct list *)previtem)->next; + ((struct list *)previtem)->next = newitem; + } +} + +static inline void * +list_item_next(void *item) +{ + return item == NULL? NULL: ((struct list *)item)->next; +} + +#else /* WITH_CONTIKI */ +#include "list.h" +#endif /* WITH_CONTIKI */ + +#endif /* _DTLS_LIST_H_ */ + diff --git a/extlibs/tinydtls/tests/Makefile.in b/extlibs/tinydtls/tests/Makefile.in new file mode 100644 index 0000000..3a50695 --- /dev/null +++ b/extlibs/tinydtls/tests/Makefile.in @@ -0,0 +1,84 @@ +# Makefile for tinydtls +# +# Copyright (C) 2011 Olaf Bergmann +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, copy, +# modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# the library's version +VERSION:=@PACKAGE_VERSION@ + +# tools +@SET_MAKE@ +SHELL = /bin/sh +MKDIR = mkdir + +abs_builddir = @abs_builddir@ +top_builddir = @top_builddir@ +top_srcdir:= @top_srcdir@ + +# files and flags +SOURCES:= dtls-server.c ccm-test.c prf-test.c \ + dtls-client.c + #cbc_aes128-test.c #dsrv-test.c +OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) +PROGRAMS:= $(patsubst %.c, %, $(SOURCES)) +HEADERS:= +CFLAGS:=-Wall @CFLAGS@ +CPPFLAGS:=-I$(top_srcdir) @CPPFLAGS@ +LDFLAGS:=-L$(top_builddir) +LDLIBS:=-ltinydtls @LIBS@ +DISTDIR=$(top_builddir)/@PACKAGE_TARNAME@-@PACKAGE_VERSION@ +FILES:=Makefile.in $(SOURCES) ccm-testdata.c #cbc_aes128-testdata.c + +.PHONY: all dirs clean distclean .gitignore doc + +.SUFFIXES: +.SUFFIXES: .c .o + +all: $(PROGRAMS) + +check: + echo DISTDIR: $(DISTDIR) + echo top_builddir: $(top_builddir) + +clean: + @rm -f $(PROGRAMS) main.o $(LIB) $(OBJECTS) + for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir clean ; \ + done + +doc: + $(MAKE) -C doc + +distclean: clean + @rm -rf $(DISTDIR) + @rm -f *~ $(DISTDIR).tar.gz + +dist: $(FILES) + test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests + cp $(FILES) $(DISTDIR)/tests + +# this directory contains no installation candidates +install: + : + +.gitignore: + echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/extlibs/tinydtls/tests/cbc_aes128-test.c b/extlibs/tinydtls/tests/cbc_aes128-test.c new file mode 100644 index 0000000..1f91920 --- /dev/null +++ b/extlibs/tinydtls/tests/cbc_aes128-test.c @@ -0,0 +1,60 @@ +#include +#include +#include + +#include "debug.h" +#include "numeric.h" +#include "crypto.h" + +#include "cbc_aes128-testdata.c" + +void +dump(unsigned char *buf, size_t len) { + size_t i = 0; + while (i < len) { + printf("%02x ", buf[i++]); + if (i % 4 == 0) + printf(" "); + if (i % 16 == 0) + printf("\n\t"); + } + printf("\n"); +} + +int main(int argc, char **argv) { + int len, n; + + for (n = 0; n < sizeof(data)/sizeof(struct test_vector); ++n) { + dtls_cipher_context_t *cipher; + + cipher = dtls_new_cipher(&ciphers[AES128], + data[n].key, + sizeof(data[n].key)); + + if (!cipher) { + fprintf(stderr, "cannot set key\n"); + exit(-1); + } + + dtls_init_cipher(cipher, data[n].nonce, sizeof(data[n].nonce)); + + if (data[n].M == 0) + len = dtls_encrypt(cipher, data[n].msg, data[n].lm); + else + len = dtls_decrypt(cipher, data[n].msg, data[n].lm); + + printf("Packet Vector #%d ", n+1); + if (len != data[n].r_lm + || memcmp(data[n].msg, data[n].result, len)) + printf("FAILED, "); + else + printf("OK, "); + + printf("result is (total length = %d):\n\t", (int)len); + dump(data[n].msg, len); + + free(cipher); + } + + return 0; +} diff --git a/extlibs/tinydtls/tests/cbc_aes128-testdata.c b/extlibs/tinydtls/tests/cbc_aes128-testdata.c new file mode 100644 index 0000000..0791679 --- /dev/null +++ b/extlibs/tinydtls/tests/cbc_aes128-testdata.c @@ -0,0 +1,72 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* test vectors from Appendix F.2.{1,2} of NIST SP 800-38A, ed. 2001 */ + +struct test_vector { + size_t M; /* mode: 0 == encrypt, 1 == decrypt */ + size_t lm; /* overall message length */ + size_t la; /* not used */ + unsigned char key[AES_BLKLEN]; + unsigned char nonce[AES_BLKLEN]; + unsigned char msg[2000]; + size_t r_lm; /* overall result length */ + unsigned char result[2000]; /* result */ +}; + +struct test_vector data[] = { + /* F.2.1 (encrypt) */ + { 0, 4 * AES_BLKLEN, 0, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, /* AES key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* Nonce */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, /* msg */ + 4 * AES_BLKLEN, /* length of result */ + { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 + } /* result */ + }, + + /* F.2.2 (decrypt) */ + { 1, 4 * AES_BLKLEN, 0, + { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, /* AES key */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* Nonce */ + { 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d, + 0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee, 0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2, + 0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b, 0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16, + 0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09, 0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7 + }, /* msg */ + 4 * AES_BLKLEN, /* length of result */ + { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 + } /* result */ + } +}; diff --git a/extlibs/tinydtls/tests/ccm-test.c b/extlibs/tinydtls/tests/ccm-test.c new file mode 100644 index 0000000..cbb7d2a --- /dev/null +++ b/extlibs/tinydtls/tests/ccm-test.c @@ -0,0 +1,96 @@ +#include +#include +#include +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef WITH_CONTIKI +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#endif /* WITH_CONTIKI */ + +//#include "debug.h" +#include "numeric.h" +#include "ccm.h" + +#include "ccm-testdata.c" + +#ifndef HAVE_FLS +int fls(unsigned int i) { + int n; + for (n = 0; i; n++) + i >>= 1; + return n; +} +#endif + +void +dump(unsigned char *buf, size_t len) { + size_t i = 0; + while (i < len) { + printf("%02x ", buf[i++]); + if (i % 4 == 0) + printf(" "); + if (i % 16 == 0) + printf("\n\t"); + } + printf("\n"); +} + +#ifdef WITH_CONTIKI +PROCESS(ccm_test_process, "CCM test process"); +AUTOSTART_PROCESSES(&ccm_test_process); +PROCESS_THREAD(ccm_test_process, ev, d) +{ +#else /* WITH_CONTIKI */ +int main(int argc, char **argv) { +#endif /* WITH_CONTIKI */ + long int len; + int n; + + rijndael_ctx ctx; + +#ifdef WITH_CONTIKI + PROCESS_BEGIN(); +#endif /* WITH_CONTIKI */ + + for (n = 0; n < sizeof(data)/sizeof(struct test_vector); ++n) { + + if (rijndael_set_key_enc_only(&ctx, data[n].key, 8*sizeof(data[n].key)) < 0) { + fprintf(stderr, "cannot set key\n"); + return -1; + } + + len = dtls_ccm_encrypt_message(&ctx, data[n].M, data[n].L, data[n].nonce, + data[n].msg + data[n].la, + data[n].lm - data[n].la, + data[n].msg, data[n].la); + + len += + data[n].la; + printf("Packet Vector #%d ", n+1); + if (len != data[n].r_lm || memcmp(data[n].msg, data[n].result, len)) + printf("FAILED, "); + else + printf("OK, "); + + printf("result is (total length = %lu):\n\t", len); + dump(data[n].msg, len); + + len = dtls_ccm_decrypt_message(&ctx, data[n].M, data[n].L, data[n].nonce, + data[n].msg + data[n].la, len - data[n].la, + data[n].msg, data[n].la); + + if (len < 0) + printf("Packet Vector #%d: cannot decrypt message\n", n+1); + else + printf("\t*** MAC verified (total length = %lu) ***\n", len + data[n].la); + } + +#ifdef WITH_CONTIKI + PROCESS_END(); +#else /* WITH_CONTIKI */ + return 0; +#endif /* WITH_CONTIKI */ +} diff --git a/extlibs/tinydtls/tests/ccm-testdata.c b/extlibs/tinydtls/tests/ccm-testdata.c new file mode 100644 index 0000000..f0da4ae --- /dev/null +++ b/extlibs/tinydtls/tests/ccm-testdata.c @@ -0,0 +1,395 @@ +/* dtls -- a very basic DTLS implementation + * + * Copyright (C) 2011 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* test vectors from RFC 3610 */ + +struct test_vector { + size_t M, L; + size_t lm; /* overall message length */ + size_t la; /* number of bytes additional data */ + unsigned char key[DTLS_CCM_BLOCKSIZE]; + unsigned char nonce[DTLS_CCM_BLOCKSIZE]; + unsigned char msg[200]; + size_t r_lm; /* overall result length */ + unsigned char result[200]; /* result */ +}; + +struct test_vector data[] = { + /* #1 */ + { 8, 2, 31, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ + 39, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84, 0x17, 0xE8, 0xD1, 0x2C, 0xFD, 0xF9, 0x26, 0xE0} /* result */ + }, + + /* #2 */ + { 8, 2, 32, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ + 40, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x72, 0xC9, 0x1A, 0x36, 0xE1, 0x35, 0xF8, 0xCF, 0x29, 0x1C, 0xA8, 0x94, 0x08, 0x5C, 0x87, 0xE3, 0xCC, 0x15, 0xC4, 0x39, 0xC9, 0xE4, 0x3A, 0x3B, 0xA0, 0x91, 0xD5, 0x6E, 0x10, 0x40, 0x09, 0x16} /* result */ + }, + + /* #3 */ + { 8, 2, 33, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x05, 0x04, 0x03, 0x02, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ + 41, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x51, 0xB1, 0xE5, 0xF4, 0x4A, 0x19, 0x7D, 0x1D, 0xA4, 0x6B, 0x0F, 0x8E, 0x2D, 0x28, 0x2A, 0xE8, 0x71, 0xE8, 0x38, 0xBB, 0x64, 0xDA, 0x85, 0x96, 0x57, 0x4A, 0xDA, 0xA7, 0x6F, 0xBD, 0x9F, 0xB0, 0xC5} /* result */ + }, + + /* #4 */ + { 8, 2, 31, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ + 39, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, 0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, 0xCD, 0xAC, 0x8C, 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1} /* result */ + }, + + /* #5 */ + { 8, 2, 32, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x07, 0x06, 0x05, 0x04, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ + 40, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xDC, 0xF1, 0xFB, 0x7B, 0x5D, 0x9E, 0x23, 0xFB, 0x9D, 0x4E, 0x13, 0x12, 0x53, 0x65, 0x8A, 0xD8, 0x6E, 0xBD, 0xCA, 0x3E, 0x51, 0xE8, 0x3F, 0x07, 0x7D, 0x9C, 0x2D, 0x93} /* result */ + }, + + /* #6 */ + { 8, 2, 33, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ + 41, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x6F, 0xC1, 0xB0, 0x11, 0xF0, 0x06, 0x56, 0x8B, 0x51, 0x71, 0xA4, 0x2D, 0x95, 0x3D, 0x46, 0x9B, 0x25, 0x70, 0xA4, 0xBD, 0x87, 0x40, 0x5A, 0x04, 0x43, 0xAC, 0x91, 0xCB, 0x94} /* result */ + }, + + /* #7 */ + { 10, 2, 31, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x09, 0x08, 0x07, 0x06, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ + 41, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x35, 0xD1, 0xB2, 0xC9, 0x5F, 0x41, 0xD5, 0xD1, 0xD4, 0xFE, 0xC1, 0x85, 0xD1, 0x66, 0xB8, 0x09, 0x4E, 0x99, 0x9D, 0xFE, 0xD9, 0x6C, 0x04, 0x8C, 0x56, 0x60, 0x2C, 0x97, 0xAC, 0xBB, 0x74, 0x90} /* result */ + }, + + /* #8 */ + { 10, 2, 32, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x0A, 0x09, 0x08, 0x07, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ + 42, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x7B, 0x75, 0x39, 0x9A, 0xC0, 0x83, 0x1D, 0xD2, 0xF0, 0xBB, 0xD7, 0x58, 0x79, 0xA2, 0xFD, 0x8F, 0x6C, 0xAE, 0x6B, 0x6C, 0xD9, 0xB7, 0xDB, 0x24, 0xC1, 0x7B, 0x44, 0x33, 0xF4, 0x34, 0x96, 0x3F, 0x34, 0xB4} /* result */ + }, + + /* #9 */ + { 10, 2, 33, 8, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x0B, 0x0A, 0x09, 0x08, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ + 43, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x82, 0x53, 0x1A, 0x60, 0xCC, 0x24, 0x94, 0x5A, 0x4B, 0x82, 0x79, 0x18, 0x1A, 0xB5, 0xC8, 0x4D, 0xF2, 0x1C, 0xE7, 0xF9, 0xB7, 0x3F, 0x42, 0xE1, 0x97, 0xEA, 0x9C, 0x07, 0xE5, 0x6B, 0x5E, 0xB1, 0x7E, 0x5F, 0x4E} /* result */ + }, + + /* #10 */ + { 10, 2, 31, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x0C, 0x0B, 0x0A, 0x09, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E}, /* msg */ + 41, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x07, 0x34, 0x25, 0x94, 0x15, 0x77, 0x85, 0x15, 0x2B, 0x07, 0x40, 0x98, 0x33, 0x0A, 0xBB, 0x14, 0x1B, 0x94, 0x7B, 0x56, 0x6A, 0xA9, 0x40, 0x6B, 0x4D, 0x99, 0x99, 0x88, 0xDD} /* result */ + }, + + /* #11 */ + { 10, 2, 32, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x0D, 0x0C, 0x0B, 0x0A, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, /* msg */ + 42, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x67, 0x6B, 0xB2, 0x03, 0x80, 0xB0, 0xE3, 0x01, 0xE8, 0xAB, 0x79, 0x59, 0x0A, 0x39, 0x6D, 0xA7, 0x8B, 0x83, 0x49, 0x34, 0xF5, 0x3A, 0xA2, 0xE9, 0x10, 0x7A, 0x8B, 0x6C, 0x02, 0x2C} /* result */ + }, + + /* #12 */ + { 10, 2, 33, 12, + { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, /* AES key */ + { 0x00, 0x00, 0x00, 0x0E, 0x0D, 0x0C, 0x0B, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}, /* Nonce */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}, /* msg */ + 43, /* length of result */ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xC0, 0xFF, 0xA0, 0xD6, 0xF0, 0x5B, 0xDB, 0x67, 0xF2, 0x4D, 0x43, 0xA4, 0x33, 0x8D, 0x2A, 0xA4, 0xBE, 0xD7, 0xB2, 0x0E, 0x43, 0xCD, 0x1A, 0xA3, 0x16, 0x62, 0xE7, 0xAD, 0x65, 0xD6, 0xDB} /* result */ + }, + + /* #13 */ + { 8, 2, 31, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x41, 0x2B, 0x4E, 0xA9, 0xCD, 0xBE, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, 0x08, 0xE8, 0xCF, 0x97, 0xD8, 0x20, 0xEA, 0x25, 0x84, 0x60, 0xE9, 0x6A, 0xD9, 0xCF, 0x52, 0x89, 0x05, 0x4D, 0x89, 0x5C, 0xEA, 0xC4, 0x7C}, /* msg */ + 39, /* length of result */ + { 0x0B, 0xE1, 0xA8, 0x8B, 0xAC, 0xE0, 0x18, 0xB1, 0x4C, 0xB9, 0x7F, 0x86, 0xA2, 0xA4, 0x68, 0x9A, 0x87, 0x79, 0x47, 0xAB, 0x80, 0x91, 0xEF, 0x53, 0x86, 0xA6, 0xFF, 0xBD, 0xD0, 0x80, 0xF8, 0xE7, 0x8C, 0xF7, 0xCB, 0x0C, 0xDD, 0xD7, 0xB3} /* result */ + }, + + /* #14 */ + { 8, 2, 32, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x33, 0x56, 0x8E, 0xF7, 0xB2, 0x63, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, 0x90, 0x20, 0xEA, 0x6F, 0x91, 0xBD, 0xD8, 0x5A, 0xFA, 0x00, 0x39, 0xBA, 0x4B, 0xAF, 0xF9, 0xBF, 0xB7, 0x9C, 0x70, 0x28, 0x94, 0x9C, 0xD0, 0xEC}, /* msg */ + 40, /* length of result */ + { 0x63, 0x01, 0x8F, 0x76, 0xDC, 0x8A, 0x1B, 0xCB, 0x4C, 0xCB, 0x1E, 0x7C, 0xA9, 0x81, 0xBE, 0xFA, 0xA0, 0x72, 0x6C, 0x55, 0xD3, 0x78, 0x06, 0x12, 0x98, 0xC8, 0x5C, 0x92, 0x81, 0x4A, 0xBC, 0x33, 0xC5, 0x2E, 0xE8, 0x1D, 0x7D, 0x77, 0xC0, 0x8A} /* result */ + }, + + /* #15 */ + { 8, 2, 33, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x10, 0x3F, 0xE4, 0x13, 0x36, 0x71, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, 0xB9, 0x16, 0xE0, 0xEA, 0xCC, 0x1C, 0x00, 0xD7, 0xDC, 0xEC, 0x68, 0xEC, 0x0B, 0x3B, 0xBB, 0x1A, 0x02, 0xDE, 0x8A, 0x2D, 0x1A, 0xA3, 0x46, 0x13, 0x2E}, /* msg */ + 41, /* length of result */ + { 0xAA, 0x6C, 0xFA, 0x36, 0xCA, 0xE8, 0x6B, 0x40, 0xB1, 0xD2, 0x3A, 0x22, 0x20, 0xDD, 0xC0, 0xAC, 0x90, 0x0D, 0x9A, 0xA0, 0x3C, 0x61, 0xFC, 0xF4, 0xA5, 0x59, 0xA4, 0x41, 0x77, 0x67, 0x08, 0x97, 0x08, 0xA7, 0x76, 0x79, 0x6E, 0xDB, 0x72, 0x35, 0x06} /* result */ + }, + + /* #16 */ + { 8, 2, 31, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x76, 0x4C, 0x63, 0xB8, 0x05, 0x8E, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, 0xF0, 0x49, 0xC2, 0x44, 0x12, 0xDA, 0xAC, 0x56, 0x30, 0xEF, 0xA5, 0x39, 0x6F, 0x77, 0x0C, 0xE1, 0xA6, 0x6B, 0x21, 0xF7, 0xB2, 0x10, 0x1C}, /* msg */ + 39, /* length of result */ + { 0xD0, 0xD0, 0x73, 0x5C, 0x53, 0x1E, 0x1B, 0xEC, 0xF0, 0x49, 0xC2, 0x44, 0x14, 0xD2, 0x53, 0xC3, 0x96, 0x7B, 0x70, 0x60, 0x9B, 0x7C, 0xBB, 0x7C, 0x49, 0x91, 0x60, 0x28, 0x32, 0x45, 0x26, 0x9A, 0x6F, 0x49, 0x97, 0x5B, 0xCA, 0xDE, 0xAF} /* result */ + }, + + /* #17 */ + { 8, 2, 32, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0xF8, 0xB6, 0x78, 0x09, 0x4E, 0x3B, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, 0x58, 0x99, 0xBC, 0xAE, 0xE8, 0x8B, 0x6A, 0x46, 0xC7, 0x8D, 0x63, 0xE5, 0x2E, 0xB8, 0xC5, 0x46, 0xEF, 0xB5, 0xDE, 0x6F, 0x75, 0xE9, 0xCC, 0x0D}, /* msg */ + 40, /* length of result */ + { 0x77, 0xB6, 0x0F, 0x01, 0x1C, 0x03, 0xE1, 0x52, 0x58, 0x99, 0xBC, 0xAE, 0x55, 0x45, 0xFF, 0x1A, 0x08, 0x5E, 0xE2, 0xEF, 0xBF, 0x52, 0xB2, 0xE0, 0x4B, 0xEE, 0x1E, 0x23, 0x36, 0xC7, 0x3E, 0x3F, 0x76, 0x2C, 0x0C, 0x77, 0x44, 0xFE, 0x7E, 0x3C} /* result */ + }, + + /* #18 */ + { 8, 2, 33, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0xD5, 0x60, 0x91, 0x2D, 0x3F, 0x70, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, 0x20, 0xEA, 0x60, 0xC0, 0x64, 0x35, 0xAC, 0xBA, 0xFB, 0x11, 0xA8, 0x2E, 0x2F, 0x07, 0x1D, 0x7C, 0xA4, 0xA5, 0xEB, 0xD9, 0x3A, 0x80, 0x3B, 0xA8, 0x7F}, /* msg */ + 41, /* length of result */ + { 0xCD, 0x90, 0x44, 0xD2, 0xB7, 0x1F, 0xDB, 0x81, 0x20, 0xEA, 0x60, 0xC0, 0x00, 0x97, 0x69, 0xEC, 0xAB, 0xDF, 0x48, 0x62, 0x55, 0x94, 0xC5, 0x92, 0x51, 0xE6, 0x03, 0x57, 0x22, 0x67, 0x5E, 0x04, 0xC8, 0x47, 0x09, 0x9E, 0x5A, 0xE0, 0x70, 0x45, 0x51} /* result */ + }, + + /* #19 */ + { 10, 2, 31, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x42, 0xFF, 0xF8, 0xF1, 0x95, 0x1C, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, 0x8A, 0x19, 0xB9, 0x50, 0xBC, 0xF7, 0x1A, 0x01, 0x8E, 0x5E, 0x67, 0x01, 0xC9, 0x17, 0x87, 0x65, 0x98, 0x09, 0xD6, 0x7D, 0xBE, 0xDD, 0x18}, /* msg */ + 41, /* length of result */ + { 0xD8, 0x5B, 0xC7, 0xE6, 0x9F, 0x94, 0x4F, 0xB8, 0xBC, 0x21, 0x8D, 0xAA, 0x94, 0x74, 0x27, 0xB6, 0xDB, 0x38, 0x6A, 0x99, 0xAC, 0x1A, 0xEF, 0x23, 0xAD, 0xE0, 0xB5, 0x29, 0x39, 0xCB, 0x6A, 0x63, 0x7C, 0xF9, 0xBE, 0xC2, 0x40, 0x88, 0x97, 0xC6, 0xBA} /* result */ + }, + + /* #20 */ + { 10, 2, 32, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x92, 0x0F, 0x40, 0xE5, 0x6C, 0xDC, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, 0x17, 0x61, 0x43, 0x3C, 0x37, 0xC5, 0xA3, 0x5F, 0xC1, 0xF3, 0x9F, 0x40, 0x63, 0x02, 0xEB, 0x90, 0x7C, 0x61, 0x63, 0xBE, 0x38, 0xC9, 0x84, 0x37}, /* msg */ + 42, /* length of result */ + { 0x74, 0xA0, 0xEB, 0xC9, 0x06, 0x9F, 0x5B, 0x37, 0x58, 0x10, 0xE6, 0xFD, 0x25, 0x87, 0x40, 0x22, 0xE8, 0x03, 0x61, 0xA4, 0x78, 0xE3, 0xE9, 0xCF, 0x48, 0x4A, 0xB0, 0x4F, 0x44, 0x7E, 0xFF, 0xF6, 0xF0, 0xA4, 0x77, 0xCC, 0x2F, 0xC9, 0xBF, 0x54, 0x89, 0x44} /* result */ + }, + + /* #21 */ + { 10, 2, 33, 8, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x27, 0xCA, 0x0C, 0x71, 0x20, 0xBC, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, 0xA4, 0x34, 0xA8, 0xE5, 0x85, 0x00, 0xC6, 0xE4, 0x15, 0x30, 0x53, 0x88, 0x62, 0xD6, 0x86, 0xEA, 0x9E, 0x81, 0x30, 0x1B, 0x5A, 0xE4, 0x22, 0x6B, 0xFA}, /* msg */ + 43, /* length of result */ + { 0x44, 0xA3, 0xAA, 0x3A, 0xAE, 0x64, 0x75, 0xCA, 0xF2, 0xBE, 0xED, 0x7B, 0xC5, 0x09, 0x8E, 0x83, 0xFE, 0xB5, 0xB3, 0x16, 0x08, 0xF8, 0xE2, 0x9C, 0x38, 0x81, 0x9A, 0x89, 0xC8, 0xE7, 0x76, 0xF1, 0x54, 0x4D, 0x41, 0x51, 0xA4, 0xED, 0x3A, 0x8B, 0x87, 0xB9, 0xCE} /* result */ + }, + + /* #22 */ + { 10, 2, 31, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x5B, 0x8C, 0xCB, 0xCD, 0x9A, 0xF8, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70, 0xB9, 0x6B, 0x49, 0xE2, 0x1D, 0x62, 0x17, 0x41, 0x63, 0x28, 0x75, 0xDB, 0x7F, 0x6C, 0x92, 0x43, 0xD2, 0xD7, 0xC2}, /* msg */ + 41, /* length of result */ + { 0xEC, 0x46, 0xBB, 0x63, 0xB0, 0x25, 0x20, 0xC3, 0x3C, 0x49, 0xFD, 0x70, 0x31, 0xD7, 0x50, 0xA0, 0x9D, 0xA3, 0xED, 0x7F, 0xDD, 0xD4, 0x9A, 0x20, 0x32, 0xAA, 0xBF, 0x17, 0xEC, 0x8E, 0xBF, 0x7D, 0x22, 0xC8, 0x08, 0x8C, 0x66, 0x6B, 0xE5, 0xC1, 0x97} /* result */ + }, + + /* #23 */ + { 10, 2, 32, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x3E, 0xBE, 0x94, 0x04, 0x4B, 0x9A, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, 0x27, 0xE8, 0x5E, 0x71, 0xE2, 0xFC, 0xFB, 0xB8, 0x80, 0x44, 0x2C, 0x73, 0x1B, 0xF9, 0x51, 0x67, 0xC8, 0xFF, 0xD7, 0x89, 0x5E, 0x33, 0x70, 0x76}, /* msg */ + 42, /* length of result */ + { 0x47, 0xA6, 0x5A, 0xC7, 0x8B, 0x3D, 0x59, 0x42, 0x27, 0xE8, 0x5E, 0x71, 0xE8, 0x82, 0xF1, 0xDB, 0xD3, 0x8C, 0xE3, 0xED, 0xA7, 0xC2, 0x3F, 0x04, 0xDD, 0x65, 0x07, 0x1E, 0xB4, 0x13, 0x42, 0xAC, 0xDF, 0x7E, 0x00, 0xDC, 0xCE, 0xC7, 0xAE, 0x52, 0x98, 0x7D} /* result */ + }, + + /* #24 */ + { 10, 2, 33, 12, + { 0xD7, 0x82, 0x8D, 0x13, 0xB2, 0xB0, 0xBD, 0xC3, 0x25, 0xA7, 0x62, 0x36, 0xDF, 0x93, 0xCC, 0x6B}, /* AES key */ + { 0x00, 0x8D, 0x49, 0x3B, 0x30, 0xAE, 0x8B, 0x3C, 0x96, 0x96, 0x76, 0x6C, 0xFA}, /* Nonce */ + { 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, 0x34, 0xAB, 0x60, 0x59, 0xAB, 0xF2, 0x1C, 0x0B, 0x02, 0xFE, 0xB8, 0x8F, 0x85, 0x6D, 0xF4, 0xA3, 0x73, 0x81, 0xBC, 0xE3, 0xCC, 0x12, 0x85, 0x17, 0xD4}, /* msg */ + 43, /* length of result */ + { 0x6E, 0x37, 0xA6, 0xEF, 0x54, 0x6D, 0x95, 0x5D, 0x34, 0xAB, 0x60, 0x59, 0xF3, 0x29, 0x05, 0xB8, 0x8A, 0x64, 0x1B, 0x04, 0xB9, 0xC9, 0xFF, 0xB5, 0x8C, 0xC3, 0x90, 0x90, 0x0F, 0x3D, 0xA1, 0x2A, 0xB1, 0x6D, 0xCE, 0x9E, 0x82, 0xEF, 0xA1, 0x6D, 0xA6, 0x20, 0x59} /* result */ + }, + + /* #25 */ + /* Cipher: AES-128 M=16 L=2 K_LEN=1 N_LEN=13 K=0x00 N=0x00000000000000000000000000 */ + { 16, 2, 0, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* AES key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Nonce */ + { }, /* msg */ + 16, /* length of result */ + { 0x8b, 0x60, 0xab, 0xcd, 0x60, 0x43, 0x81, 0x0b, + 0xa3, 0x78, 0xa0, 0x1d, 0x4a, 0x29, 0x83, 0x0b + } /* result */ + }, + + /* #26 */ + /* Cipher: AES-128 M=16 L=2 K_LEN=1 N_LEN=13 K=0x00 N=0x00000000000000000000000000 */ + { 16, 2, 37, 0, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* AES key */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, /* Nonce */ + { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, + 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, + 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, + 0x43, 0x43, 0x4d, 0x2e, 0x0a + }, /* msg */ + 53, /* length of result */ + { 0x90, 0x11, 0x9c, 0x2d, 0x6b, 0xf9, 0xe9, 0x05, + 0x3e, 0x0b, 0x44, 0x56, 0xca, 0xc8, 0xb6, 0x1a, + 0x00, 0x57, 0xa9, 0x8b, 0x6b, 0x69, 0x09, 0x7e, + 0x8e, 0x50, 0x50, 0x63, 0x50, 0x58, 0x0f, 0x78, + 0x75, 0x69, 0x6e, 0x9f, 0x3d, 0x63, 0x93, 0xe7, + 0x7a, 0x84, 0xe9, 0x9f, 0x11, 0x93, 0x95, 0xa0, + 0x9a, 0xef, 0x0d, 0xa0, 0xed + } /* result */ + }, + + /* #27 */ + /* Cipher: AES-128 M=8 L=5 K_LEN=16 N_LEN=10 K=0x001234567890abcdefdcaffeed3921ee N=0x00112233445566778899 */ + { 8, 5, 0, 0, + { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99 }, /* Nonce */ + { }, /* msg */ + 8, /* length of result */ + { 0xb1, 0x33, 0x51, 0xc8, 0xb3, 0xd5, 0x10, 0xa7 } /* result */ + }, + + /* #28 */ + /* Cipher: AES-128 M=8 L=5 K_LEN=16 N_LEN=10 K=0x001234567890abcdefdcaffeed3921ee N=0x00112233445566778899 */ + { 8, 5, 37, 0, + { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99 }, /* Nonce */ + { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, + 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, + 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, + 0x43, 0x43, 0x4d, 0x2e, 0x0a + }, /* msg */ + 45, /* length of result */ + { 0x44, 0x7a, 0x82, 0x70, 0x1d, 0xd0, 0x35, 0x7b, + 0x68, 0xf7, 0x35, 0x4d, 0xbf, 0xd9, 0x16, 0x15, + 0x97, 0x41, 0x3d, 0x1e, 0x89, 0xc1, 0x25, 0xe7, + 0xd6, 0xa7, 0xde, 0x90, 0x1e, 0xf1, 0x69, 0x69, + 0x9f, 0xce, 0x40, 0xdc, 0xf0, 0xd1, 0x74, 0x53, + 0x2c, 0xa3, 0xb0, 0xcf, 0xb9 + } /* result */ + }, + + /* #29 */ + /* Cipher: AES-128 M=14 L=3 K_LEN=16 N_LEN=12 K=0x001234567890abcdefdcaffeed3921ee N=0x001122334455667788990000 */ + { 14, 3, 0, 0, + { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0x00, 0x00 }, /* Nonce */ + { }, /* msg */ + 14, /* length of result */ + { 0xa4, 0x06, 0xa4, 0x23, 0x93, 0x3d, 0xa0, 0xca, + 0xb5, 0x90, 0xdb, 0x69, 0x69, 0x33 } /* result */ + }, + + /* #30 */ + /* Cipher: AES-128 M=14 L=3 K_LEN=16 N_LEN=12 K=0x001234567890abcdefdcaffeed3921ee N=0x001122334455667788990000 */ + { 14, 3, 37, 0, + { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + 0xef, 0xdc, 0xaf, 0xfe, 0xed, 0x39, 0x21, 0xee }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0x00, 0x00 }, /* Nonce */ + { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, + 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, + 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, + 0x43, 0x43, 0x4d, 0x2e, 0x0a + }, /* msg */ + 51, + { 0x60, 0xaf, 0x87, 0x67, 0x4d, 0x9d, 0x54, 0x17, + 0x16, 0xc0, 0x29, 0x10, 0x7e, 0x3e, 0x34, 0x93, + 0x78, 0xe8, 0xd3, 0xc8, 0xc1, 0x03, 0x4f, 0xd6, + 0xf5, 0x3b, 0xaf, 0xd3, 0xf0, 0xd7, 0x0b, 0xdd, + 0x63, 0x93, 0xed, 0xf2, 0xb2, 0x72, 0xdc, 0xae, + 0x7c, 0xa0, 0x01, 0xdb, 0x56, 0x2a, 0x06, 0xb6, + 0xe9, 0xcf, 0x3c } /* result */ + }, + + /* #31 */ + /* Cipher: AES-128 M=8 L=5 K_LEN=6 N_LEN=10 K=0x11223344aabb N=0x00112233445566778899 */ + { 8, 5, 0, 0, + { 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99 }, /* Nonce */ + { }, /* msg */ + 8, + { 0x28, 0x15, 0xfe, 0x81, 0xdd, 0xc3, 0x79, 0x04 } /* result */ + }, + + /* #32 */ + /* Cipher: AES-128 M=8 L=5 K_LEN=6 N_LEN=10 K=0x11223344aabb N=0x00112233445566778899 */ + + { 8, 5, 37, 0, + { 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb }, /* AES key */ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99 }, /* Nonce */ + { 0x45, 0x69, 0x6e, 0x20, 0x6b, 0x6c, 0x65, 0x69, + 0x6e, 0x65, 0x72, 0x20, 0x54, 0x65, 0x78, 0x74, + 0x0a, 0x7a, 0x75, 0x6d, 0x20, 0x54, 0x65, 0x73, + 0x74, 0x65, 0x6e, 0x20, 0x76, 0x6f, 0x6e, 0x20, + 0x43, 0x43, 0x4d, 0x2e, 0x0a + }, /* msg */ + 45, + { 0xdb, 0x31, 0x55, 0x9d, 0xab, 0x70, 0xdc, 0x62, + 0xd7, 0x76, 0x41, 0xb2, 0x14, 0x9e, 0x9c, 0x26, + 0x70, 0x61, 0xea, 0x36, 0xf8, 0x0e, 0xdf, 0x19, + 0xa6, 0xc7, 0x46, 0x3d, 0x5a, 0xc3, 0x0a, 0x73, + 0x14, 0x96, 0xa4, 0x84, 0x7f, 0x37, 0x55, 0x42, + 0xce, 0x7e, 0xf9, 0x3b, 0xe5 } /* result */ + } +}; diff --git a/extlibs/tinydtls/tests/dsrv-test.c b/extlibs/tinydtls/tests/dsrv-test.c new file mode 100644 index 0000000..e7b44a9 --- /dev/null +++ b/extlibs/tinydtls/tests/dsrv-test.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "dsrv.h" + +void +handle_read(struct dsrv_context_t *ctx) { + int len; + static char buf[200]; + struct sockaddr_storage src; + socklen_t srclen = sizeof(src); + int fd = dsrv_get_fd(ctx, DSRV_READ); + + len = recvfrom(fd, buf, sizeof(buf), 0, + (struct sockaddr *)&src, &srclen); + + if (len < 0) { + perror("recvfrom"); + } else { + printf("read %d bytes: '%*s'\n", len, len, buf); + if (dsrv_sendto(ctx, (struct sockaddr *)&src, srclen, 0, buf, len) + == NULL) { + fprintf(stderr, "cannot add packet to sendqueue\n"); + } + } +} + +int +handle_write(struct dsrv_context_t *ctx) { + struct packet_t *p; + int fd = dsrv_get_fd(ctx, DSRV_WRITE); + int len; + + p = ctx->rq ? nq_peek(ctx->wq) : NULL; + + if (!p) + return -1; + + len = sendto(fd, p->buf, p->len, 0, p->raddr, p->rlen); + + if (len < 0) + perror("sendto"); + else + nq_pop(ctx->wq); + + return len; +} + +int main(int argc, char **argv) { + +#if 1 + struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 }; +#else + struct sockaddr_in listen_addr = { AF_INET, htons(20220), { htonl(0x7f000001) } }; +#endif + fd_set rfds, wfds; + struct timeval timeout; + struct dsrv_context_t *ctx; + int result; + + ctx = dsrv_new_context((struct sockaddr *)&listen_addr, sizeof(listen_addr), + 200,200); + + if (!ctx) { + fprintf(stderr, "E: cannot create server context\n"); + return -1; + } + + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + dsrv_prepare(ctx, &rfds, DSRV_READ); + dsrv_prepare(ctx, &wfds, DSRV_WRITE); + +#if 0 + timeout.tv_sec = 0; + timeout.tv_usec = dsrv_get_timeout(ctx); +#else + timeout.tv_sec = 5; + timeout.tv_usec = 0; +#endif + + result = select( FD_SETSIZE, &rfds, &wfds, 0, &timeout); + + if (result < 0) { /* error */ + if (errno != EINTR) + perror("select"); + } else if (result == 0) { /* timeout */ + printf("."); + } else { /* ok */ + if (dsrv_check(ctx, &wfds, DSRV_WRITE)) + handle_write(ctx); + else if (dsrv_check(ctx, &rfds, DSRV_READ)) + handle_read(ctx); + } + } + + dsrv_close(ctx); + dsrv_free_context(ctx); + + return 0; +} diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c new file mode 100644 index 0000000..1c48c1a --- /dev/null +++ b/extlibs/tinydtls/tests/dtls-client.c @@ -0,0 +1,544 @@ +#include "tinydtls.h" + +/* This is needed for apple */ +#define __APPLE_USE_RFC_3542 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "debug.h" +#include "dtls.h" + +#define DEFAULT_PORT 20220 + +#define PSK_CLIENT_IDENTITY "Client_identity" +#define PSK_SERVER_IDENTITY "Server_identity" +#define PSK_DEFAULT_KEY "secretPSK" +#define PSK_OPTIONS "i:s:k:" + +#ifdef __GNUC__ +#define UNUSED_PARAM __attribute__((unused)) +#else +#define UNUSED_PARAM +#endif /* __GNUC__ */ + +static char buf[200]; +static size_t len = 0; + +typedef struct { + size_t length; /* length of string */ + unsigned char *s; /* string data */ +} dtls_str; + +static dtls_str output_file = { 0, NULL }; /* output file name */ + +static dtls_context_t *dtls_context = NULL; +static dtls_context_t *orig_dtls_context = NULL; + + +static const unsigned char ecdsa_priv_key[] = { + 0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14, + 0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14, + 0x89, 0x6A, 0x33, 0xBB, 0xAD, 0x72, 0x94, 0xCA, + 0x40, 0x14, 0x55, 0xA1, 0x94, 0xA9, 0x49, 0xFA}; + +static const unsigned char ecdsa_pub_key_x[] = { + 0x36, 0xDF, 0xE2, 0xC6, 0xF9, 0xF2, 0xED, 0x29, + 0xDA, 0x0A, 0x9A, 0x8F, 0x62, 0x68, 0x4E, 0x91, + 0x63, 0x75, 0xBA, 0x10, 0x30, 0x0C, 0x28, 0xC5, + 0xE4, 0x7C, 0xFB, 0xF2, 0x5F, 0xA5, 0x8F, 0x52}; + +static const unsigned char ecdsa_pub_key_y[] = { + 0x71, 0xA0, 0xD4, 0xFC, 0xDE, 0x1A, 0xB8, 0x78, + 0x5A, 0x3C, 0x78, 0x69, 0x35, 0xA7, 0xCF, 0xAB, + 0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B, + 0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29}; + +#ifdef DTLS_PSK +ssize_t +read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) { + FILE *f; + ssize_t result = 0; + + f = fopen(arg, "r"); + if (f == NULL) + return -1; + + while (!feof(f)) { + size_t bytes_read; + bytes_read = fread(buf, 1, max_buf_len, f); + if (ferror(f)) { + result = -1; + break; + } + + buf += bytes_read; + result += bytes_read; + max_buf_len -= bytes_read; + } + + fclose(f); + return result; +} + +/* The PSK information for DTLS */ +#define PSK_ID_MAXLEN 256 +#define PSK_MAXLEN 256 +static unsigned char psk_client_id[PSK_ID_MAXLEN]; +static size_t psk_client_id_length = 0; +static unsigned char psk_server_id[PSK_ID_MAXLEN]; +static size_t psk_server_id_length = 0; +static unsigned char psk_key[PSK_MAXLEN]; +static size_t psk_key_length = 0; + +/* This function is the "key store" for tinyDTLS. It is called to + * retrieve a key for the given identity within this particular + * session. */ +static int +get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM, + const session_t *session UNUSED_PARAM, + dtls_credentials_type_t type, + const unsigned char *id, size_t id_len, + unsigned char *result, size_t result_length) { + + switch (type) { + case DTLS_PSK_IDENTITY: + if (id_len) { + dtls_debug("got psk_identity_hint: '%.*s'\n", id_len, id); + } + + if (result_length < psk_client_id_length) { + dtls_warn("cannot set psk_identity -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_client_id, psk_client_id_length); + return psk_client_id_length; + case DTLS_PSK_KEY: + if (id_len != psk_server_id_length || memcmp(psk_server_id, id, id_len) != 0) { + dtls_warn("PSK for unknown id requested, exiting\n"); + return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER); + } else if (result_length < psk_key_length) { + dtls_warn("cannot set psk -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk_key, psk_key_length); + return psk_key_length; + default: + dtls_warn("unsupported request type: %d\n", type); + } + + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); +} +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC +static int +get_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecdsa_key_t **result) { + static const dtls_ecdsa_key_t ecdsa_key = { + .curve = DTLS_ECDH_CURVE_SECP256R1, + .priv_key = ecdsa_priv_key, + .pub_key_x = ecdsa_pub_key_x, + .pub_key_y = ecdsa_pub_key_y + }; + + *result = &ecdsa_key; + return 0; +} + +static int +verify_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char *other_pub_x, + const unsigned char *other_pub_y, + size_t key_size) { + return 0; +} +#endif /* DTLS_ECC */ + +static void +try_send(struct dtls_context_t *ctx, session_t *dst) { + int res; + res = dtls_write(ctx, dst, (uint8 *)buf, len); + if (res >= 0) { + memmove(buf, buf + res, len - res); + len -= res; + } +} + +static void +handle_stdin() { + if (fgets(buf + len, sizeof(buf) - len, stdin)) + len += strlen(buf + len); +} + +static int +read_from_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + size_t i; + for (i = 0; i < len; i++) + printf("%c", data[i]); + return 0; +} + +static int +send_to_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + + int fd = *(int *)dtls_get_app_data(ctx); + return sendto(fd, data, len, MSG_DONTWAIT, + &session->addr.sa, session->size); +} + +static int +dtls_handle_read(struct dtls_context_t *ctx) { + int fd; + session_t session; +#define MAX_READ_BUF 2000 + static uint8 buf[MAX_READ_BUF]; + int len; + + fd = *(int *)dtls_get_app_data(ctx); + + if (!fd) + return -1; + + memset(&session, 0, sizeof(session_t)); + session.size = sizeof(session.addr); + len = recvfrom(fd, buf, MAX_READ_BUF, 0, + &session.addr.sa, &session.size); + + if (len < 0) { + perror("recvfrom"); + return -1; + } else { + dtls_dsrv_log_addr(DTLS_LOG_DEBUG, "peer", &session); + dtls_debug_dump("bytes from peer", buf, len); + } + + return dtls_handle_message(ctx, &session, buf, len); +} + +static void dtls_handle_signal(int sig) +{ + dtls_free_context(dtls_context); + dtls_free_context(orig_dtls_context); + signal(sig, SIG_DFL); + kill(getpid(), sig); +} + +/* stolen from libcoap: */ +static int +resolve_address(const char *server, struct sockaddr *dst) { + + struct addrinfo *res, *ainfo; + struct addrinfo hints; + static char addrstr[256]; + int error; + + memset(addrstr, 0, sizeof(addrstr)); + if (server && strlen(server) > 0) + memcpy(addrstr, server, strlen(server)); + else + memcpy(addrstr, "localhost", 9); + + memset ((char *)&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_family = AF_UNSPEC; + + error = getaddrinfo(addrstr, "", &hints, &res); + + if (error != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); + return error; + } + + for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { + + switch (ainfo->ai_family) { + case AF_INET6: + case AF_INET: + + memcpy(dst, ainfo->ai_addr, ainfo->ai_addrlen); + return ainfo->ai_addrlen; + default: + ; + } + } + + freeaddrinfo(res); + return -1; +} + +/*---------------------------------------------------------------------------*/ +static void +usage( const char *program, const char *version) { + const char *p; + + p = strrchr( program, '/' ); + if ( p ) + program = ++p; + + fprintf(stderr, "%s v%s -- DTLS client implementation\n" + "(c) 2011-2014 Olaf Bergmann \n\n" +#ifdef DTLS_PSK + "usage: %s [-i file] [-s file] [-k file] [-o file] [-p port] [-v num] addr [port]\n" +#else /* DTLS_PSK */ + "usage: %s [-o file] [-p port] [-v num] addr [port]\n" +#endif /* DTLS_PSK */ +#ifdef DTLS_PSK + "\t-i file\t\tread PSK Client identity from file\n" + "\t-s file\t\tread PSK Server identity from file\n" + "\t-k file\t\tread pre-shared key from file\n" +#endif /* DTLS_PSK */ + "\t-o file\t\toutput received data to this file (use '-' for STDOUT)\n" + "\t-p port\t\tlisten on specified port (default is %d)\n" + "\t-v num\t\tverbosity level (default: 3)\n", + program, version, program, DEFAULT_PORT); +} + +static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, +#ifdef DTLS_PSK + .get_psk_info = get_psk_info, +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + .get_ecdsa_key = get_ecdsa_key, + .verify_ecdsa_key = verify_ecdsa_key +#endif /* DTLS_ECC */ +}; + +#define DTLS_CLIENT_CMD_CLOSE "client:close" +#define DTLS_CLIENT_CMD_RENEGOTIATE "client:renegotiate" + +/* As per RFC 6347 section 4.2.8, DTLS Server should support requests + * from clients who have silently abandoned the existing association + * and initiated a new handshake request by sending a ClientHello. + * Below command tests this feature. + */ +#define DTLS_CLIENT_CMD_REHANDSHAKE "client:rehandshake" +int +main(int argc, char **argv) { + fd_set rfds, wfds; + struct timeval timeout; + unsigned short port = DEFAULT_PORT; + char port_str[NI_MAXSERV] = "0"; + log_t log_level = DTLS_LOG_WARN; + int fd, result; + int on = 1; + int opt, res; + session_t dst; + + dtls_init(); + snprintf(port_str, sizeof(port_str), "%d", port); + +#ifdef DTLS_PSK + psk_client_id_length = strlen(PSK_CLIENT_IDENTITY); + psk_server_id_length = strlen(PSK_SERVER_IDENTITY); + psk_key_length = strlen(PSK_DEFAULT_KEY); + memcpy(psk_client_id, PSK_CLIENT_IDENTITY, psk_client_id_length); + memcpy(psk_server_id, PSK_SERVER_IDENTITY, psk_server_id_length); + memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length); +#endif /* DTLS_PSK */ + + while ((opt = getopt(argc, argv, "p:o:v:" PSK_OPTIONS)) != -1) { + switch (opt) { +#ifdef DTLS_PSK + case 'i' : { + ssize_t result = read_from_file(optarg, psk_client_id, PSK_ID_MAXLEN); + if (result < 0) { + dtls_warn("cannot read Client PSK identity\n"); + } else { + psk_client_id_length = result; + } + break; + } + case 's' : { + ssize_t result = read_from_file(optarg, psk_server_id, PSK_ID_MAXLEN); + if (result < 0) { + dtls_warn("cannot read Server PSK identity\n"); + } else { + psk_server_id_length = result; + } + break; + } + case 'k' : { + ssize_t result = read_from_file(optarg, psk_key, PSK_MAXLEN); + if (result < 0) { + dtls_warn("cannot read PSK\n"); + } else { + psk_key_length = result; + } + break; + } +#endif /* DTLS_PSK */ + case 'p' : + strncpy(port_str, optarg, NI_MAXSERV-1); + port_str[NI_MAXSERV - 1] = '\0'; + break; + case 'o' : + output_file.length = strlen(optarg); + output_file.s = (unsigned char *)malloc(output_file.length + 1); + + if (!output_file.s) { + dtls_crit("cannot set output file: insufficient memory\n"); + exit(-1); + } else { + /* copy filename including trailing zero */ + memcpy(output_file.s, optarg, output_file.length + 1); + } + break; + case 'v' : + log_level = strtol(optarg, NULL, 10); + break; + default: + usage(argv[0], dtls_package_version()); + exit(1); + } + } + + dtls_set_log_level(log_level); + + if (argc <= optind) { + usage(argv[0], dtls_package_version()); + exit(1); + } + + memset(&dst, 0, sizeof(session_t)); + /* resolve destination address where server should be sent */ + res = resolve_address(argv[optind++], &dst.addr.sa); + if (res < 0) { + dtls_emerg("failed to resolve address\n"); + exit(-1); + } + dst.size = res; + + /* use port number from command line when specified or the listen + port, otherwise */ + dst.addr.sin.sin_port = htons(atoi(optind < argc ? argv[optind++] : port_str)); + + + /* init socket and set it to non-blocking */ + fd = socket(dst.addr.sa.sa_family, SOCK_DGRAM, 0); + + if (fd < 0) { + dtls_alert("socket: %s\n", strerror(errno)); + return 0; + } + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { + dtls_alert("setsockopt SO_REUSEADDR: %s\n", strerror(errno)); + } +#if 0 + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + dtls_alert("fcntl: %s\n", strerror(errno)); + goto error; + } +#endif + on = 1; +#ifdef IPV6_RECVPKTINFO + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { +#else /* IPV6_RECVPKTINFO */ + if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { +#endif /* IPV6_RECVPKTINFO */ + dtls_alert("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); + } + + if (signal(SIGINT, dtls_handle_signal) == SIG_ERR) { + dtls_alert("An error occurred while setting a signal handler.\n"); + return EXIT_FAILURE; + } + + dtls_context = dtls_new_context(&fd); + if (!dtls_context) { + dtls_emerg("cannot create context\n"); + exit(-1); + } + + dtls_set_handler(dtls_context, &cb); + + dtls_connect(dtls_context, &dst); + + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + FD_SET(fileno(stdin), &rfds); + FD_SET(fd, &rfds); + /* FD_SET(fd, &wfds); */ + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + result = select(fd+1, &rfds, &wfds, 0, &timeout); + + if (result < 0) { /* error */ + if (errno != EINTR) + perror("select"); + } else if (result == 0) { /* timeout */ + } else { /* ok */ + if (FD_ISSET(fd, &wfds)) + /* FIXME */; + else if (FD_ISSET(fd, &rfds)) + dtls_handle_read(dtls_context); + else if (FD_ISSET(fileno(stdin), &rfds)) + handle_stdin(); + } + + if (len) { + if (len >= strlen(DTLS_CLIENT_CMD_CLOSE) && + !memcmp(buf, DTLS_CLIENT_CMD_CLOSE, strlen(DTLS_CLIENT_CMD_CLOSE))) { + printf("client: closing connection\n"); + dtls_close(dtls_context, &dst); + len = 0; + } else if (len >= strlen(DTLS_CLIENT_CMD_RENEGOTIATE) && + !memcmp(buf, DTLS_CLIENT_CMD_RENEGOTIATE, strlen(DTLS_CLIENT_CMD_RENEGOTIATE))) { + printf("client: renegotiate connection\n"); + dtls_renegotiate(dtls_context, &dst); + len = 0; + } else if (len >= strlen(DTLS_CLIENT_CMD_REHANDSHAKE) && + !memcmp(buf, DTLS_CLIENT_CMD_REHANDSHAKE, strlen(DTLS_CLIENT_CMD_REHANDSHAKE))) { + printf("client: rehandshake connection\n"); + if (orig_dtls_context == NULL) { + /* Cache the current context. We cannot free the current context as it will notify + * the Server to close the connection (which we do not want). + */ + orig_dtls_context = dtls_context; + /* Now, Create a new context and attempt to initiate a handshake. */ + dtls_context = dtls_new_context(&fd); + if (!dtls_context) { + dtls_emerg("cannot create context\n"); + exit(-1); + } + dtls_set_handler(dtls_context, &cb); + dtls_connect(dtls_context, &dst); + } + len = 0; + } else { + try_send(dtls_context, &dst); + } + } + } + + dtls_free_context(dtls_context); + dtls_free_context(orig_dtls_context); + exit(0); +} + diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c new file mode 100644 index 0000000..ae1283e --- /dev/null +++ b/extlibs/tinydtls/tests/dtls-server.c @@ -0,0 +1,381 @@ + +/* This is needed for apple */ +#define __APPLE_USE_RFC_3542 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tinydtls.h" +#include "dtls.h" +#include "debug.h" + +#define DEFAULT_PORT 20220 + +static const unsigned char ecdsa_priv_key[] = { + 0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05, + 0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF, + 0xC7, 0xF1, 0xCD, 0x74, 0x83, 0x8F, 0x75, 0x70, + 0xC8, 0x07, 0x2D, 0x0A, 0x76, 0x26, 0x1B, 0xD4}; + +static const unsigned char ecdsa_pub_key_x[] = { + 0xD0, 0x55, 0xEE, 0x14, 0x08, 0x4D, 0x6E, 0x06, + 0x15, 0x59, 0x9D, 0xB5, 0x83, 0x91, 0x3E, 0x4A, + 0x3E, 0x45, 0x26, 0xA2, 0x70, 0x4D, 0x61, 0xF2, + 0x7A, 0x4C, 0xCF, 0xBA, 0x97, 0x58, 0xEF, 0x9A}; + +static const unsigned char ecdsa_pub_key_y[] = { + 0xB4, 0x18, 0xB6, 0x4A, 0xFE, 0x80, 0x30, 0xDA, + 0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31, + 0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D, + 0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70}; + +#if 0 +/* SIGINT handler: set quit to 1 for graceful termination */ +void +handle_sigint(int signum) { + dsrv_stop(dsrv_get_context()); +} +#endif + +#ifdef DTLS_PSK + +#define PSK_SERVER_HINT "Server_identity" + +/* This function is the "key store" for tinyDTLS. It is called to + * retrieve a key for the given identity within this particular + * session. */ +static int +get_psk_info(struct dtls_context_t *ctx, const session_t *session, + dtls_credentials_type_t type, + const unsigned char *id, size_t id_len, + unsigned char *result, size_t result_length) { + + struct keymap_t { + unsigned char *id; + size_t id_length; + unsigned char *key; + size_t key_length; + } psk[3] = { + { (unsigned char *)"Client_identity", 15, + (unsigned char *)"secretPSK", 9 }, + { (unsigned char *)"default identity", 16, + (unsigned char *)"\x11\x22\x33", 3 }, + { (unsigned char *)"\0", 2, + (unsigned char *)"", 1 } + }; + + switch (type) { + case DTLS_PSK_HINT: + if (result_length < strlen(PSK_SERVER_HINT)) { + dtls_warn("cannot set psk_hint -- buffer too small\n"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, PSK_SERVER_HINT, strlen(PSK_SERVER_HINT)); + return strlen(PSK_SERVER_HINT); + + case DTLS_PSK_KEY: + if (id) { + int i; + for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) { + if (id_len == psk[i].id_length && memcmp(id, psk[i].id, id_len) == 0) { + if (result_length < psk[i].key_length) { + dtls_warn("buffer too small for PSK"); + return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR); + } + + memcpy(result, psk[i].key, psk[i].key_length); + return psk[i].key_length; + } + } + } + break; + + default: + dtls_warn("unsupported request type: %d\n", type); + } + + return dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR); +} + +#endif /* DTLS_PSK */ + +#ifdef DTLS_ECC +static int +get_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const dtls_ecdsa_key_t **result) { + static const dtls_ecdsa_key_t ecdsa_key = { + .curve = DTLS_ECDH_CURVE_SECP256R1, + .priv_key = ecdsa_priv_key, + .pub_key_x = ecdsa_pub_key_x, + .pub_key_y = ecdsa_pub_key_y + }; + + *result = &ecdsa_key; + return 0; +} + +static int +verify_ecdsa_key(struct dtls_context_t *ctx, + const session_t *session, + const unsigned char *other_pub_x, + const unsigned char *other_pub_y, + size_t key_size) { + return 0; +} +#endif /* DTLS_ECC */ + +#define DTLS_SERVER_CMD_CLOSE "server:close" +#define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate" + +static int +read_from_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + size_t i; + for (i = 0; i < len; i++) + printf("%c", data[i]); + if (len >= strlen(DTLS_SERVER_CMD_CLOSE) && + !memcmp(data, DTLS_SERVER_CMD_CLOSE, strlen(DTLS_SERVER_CMD_CLOSE))) { + printf("server: closing connection\n"); + dtls_close(ctx, session); + return len; + } else if (len >= strlen(DTLS_SERVER_CMD_RENEGOTIATE) && + !memcmp(data, DTLS_SERVER_CMD_RENEGOTIATE, strlen(DTLS_SERVER_CMD_RENEGOTIATE))) { + printf("server: renegotiate connection\n"); + dtls_renegotiate(ctx, session); + return len; + } + + return dtls_write(ctx, session, data, len); +} + +static int +send_to_peer(struct dtls_context_t *ctx, + session_t *session, uint8 *data, size_t len) { + + int fd = *(int *)dtls_get_app_data(ctx); + return sendto(fd, data, len, MSG_DONTWAIT, + &session->addr.sa, session->size); +} + +static int +dtls_handle_read(struct dtls_context_t *ctx) { + int *fd; + session_t session; + static uint8 buf[DTLS_MAX_BUF]; + int len; + + fd = dtls_get_app_data(ctx); + + assert(fd); + + memset(&session, 0, sizeof(session_t)); + session.size = sizeof(session.addr); + len = recvfrom(*fd, buf, sizeof(buf), MSG_TRUNC, + &session.addr.sa, &session.size); + + if (len < 0) { + perror("recvfrom"); + return -1; + } else { + dtls_debug("got %d bytes from port %d\n", len, + ntohs(session.addr.sin6.sin6_port)); + if (sizeof(buf) < len) { + dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf)); + } + } + + return dtls_handle_message(ctx, &session, buf, len); +} + +static int +resolve_address(const char *server, struct sockaddr *dst) { + + struct addrinfo *res, *ainfo; + struct addrinfo hints; + static char addrstr[256]; + int error; + + memset(addrstr, 0, sizeof(addrstr)); + if (server && strlen(server) > 0) + memcpy(addrstr, server, strlen(server)); + else + memcpy(addrstr, "localhost", 9); + + memset ((char *)&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_family = AF_UNSPEC; + + error = getaddrinfo(addrstr, "", &hints, &res); + + if (error != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); + return error; + } + + for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { + + switch (ainfo->ai_family) { + case AF_INET6: + + memcpy(dst, ainfo->ai_addr, ainfo->ai_addrlen); + return ainfo->ai_addrlen; + default: + ; + } + } + + freeaddrinfo(res); + return -1; +} + +static void +usage(const char *program, const char *version) { + const char *p; + + p = strrchr( program, '/' ); + if ( p ) + program = ++p; + + fprintf(stderr, "%s v%s -- DTLS server implementation\n" + "(c) 2011-2014 Olaf Bergmann \n\n" + "usage: %s [-A address] [-p port] [-v num]\n" + "\t-A address\t\tlisten on specified address (default is ::)\n" + "\t-p port\t\tlisten on specified port (default is %d)\n" + "\t-v num\t\tverbosity level (default: 3)\n", + program, version, program, DEFAULT_PORT); +} + +static dtls_handler_t cb = { + .write = send_to_peer, + .read = read_from_peer, + .event = NULL, +#ifdef DTLS_PSK + .get_psk_info = get_psk_info, +#endif /* DTLS_PSK */ +#ifdef DTLS_ECC + .get_ecdsa_key = get_ecdsa_key, + .verify_ecdsa_key = verify_ecdsa_key +#endif /* DTLS_ECC */ +}; + +int +main(int argc, char **argv) { + dtls_context_t *the_context = NULL; + log_t log_level = DTLS_LOG_WARN; + fd_set rfds, wfds; + struct timeval timeout; + int fd, opt, result; + int on = 1; + struct sockaddr_in6 listen_addr; + + memset(&listen_addr, 0, sizeof(struct sockaddr_in6)); + + /* fill extra field for 4.4BSD-based systems (see RFC 3493, section 3.4) */ +#if defined(SIN6_LEN) || defined(HAVE_SOCKADDR_IN6_SIN6_LEN) + listen_addr.sin6_len = sizeof(struct sockaddr_in6); +#endif + + listen_addr.sin6_family = AF_INET6; + listen_addr.sin6_port = htons(DEFAULT_PORT); + listen_addr.sin6_addr = in6addr_any; + + while ((opt = getopt(argc, argv, "A:p:v:")) != -1) { + switch (opt) { + case 'A' : + if (resolve_address(optarg, (struct sockaddr *)&listen_addr) < 0) { + fprintf(stderr, "cannot resolve address\n"); + exit(-1); + } + break; + case 'p' : + listen_addr.sin6_port = htons(atoi(optarg)); + break; + case 'v' : + log_level = strtol(optarg, NULL, 10); + break; + default: + usage(argv[0], dtls_package_version()); + exit(1); + } + } + + dtls_set_log_level(log_level); + + /* init socket and set it to non-blocking */ + fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0); + + if (fd < 0) { + dtls_alert("socket: %s\n", strerror(errno)); + return 0; + } + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) { + dtls_alert("setsockopt SO_REUSEADDR: %s\n", strerror(errno)); + } +#if 0 + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { + dtls_alert("fcntl: %s\n", strerror(errno)); + goto error; + } +#endif + on = 1; +#ifdef IPV6_RECVPKTINFO + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) { +#else /* IPV6_RECVPKTINFO */ + if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on) ) < 0) { +#endif /* IPV6_RECVPKTINFO */ + dtls_alert("setsockopt IPV6_PKTINFO: %s\n", strerror(errno)); + } + + if (bind(fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0) { + dtls_alert("bind: %s\n", strerror(errno)); + goto error; + } + + dtls_init(); + + the_context = dtls_new_context(&fd); + + dtls_set_handler(the_context, &cb); + + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + FD_SET(fd, &rfds); + /* FD_SET(fd, &wfds); */ + + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + result = select( fd+1, &rfds, &wfds, 0, &timeout); + + if (result < 0) { /* error */ + if (errno != EINTR) + perror("select"); + } else if (result == 0) { /* timeout */ + } else { /* ok */ + if (FD_ISSET(fd, &wfds)) + ; + else if (FD_ISSET(fd, &rfds)) { + dtls_handle_read(the_context); + } + } + } + + error: + dtls_free_context(the_context); + exit(0); +} diff --git a/extlibs/tinydtls/tests/netq-test.c b/extlibs/tinydtls/tests/netq-test.c new file mode 100644 index 0000000..d0dc66f --- /dev/null +++ b/extlibs/tinydtls/tests/netq-test.c @@ -0,0 +1,103 @@ +#include +#include + +#include "netq.h" + +#ifndef NDEBUG +extern void nq_dump(struct netq_t *); +#endif + +int main(int argc, char **argv) { +#ifndef NDEBUG + struct netq_t *nq; + + struct sockaddr_in6 dst = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 }; + struct packet_t *p; + + char *pkt[20] = { + "Packet #1", + "This is packet #2", + "The third packet #3 is the largest", + "Packet #4", + "Packet #5", + "Packet #6", + "Packet #7" + }; + + nq = nq_new(200); + + if (!nq) { + fprintf(stderr, "E: cannot create network packet queue\n"); + return -1; + } + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[0], strlen(pkt[0]))) { + fprintf(stderr, "E: cannot add packet #1\n"); + } + + nq_dump(nq); + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[1], strlen(pkt[1]))) { + fprintf(stderr, "E: cannot add packet #2\n"); + } + + nq_dump(nq); + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[2], strlen(pkt[2]))) { + fprintf(stderr, "E: cannot add packet #3\n"); + } + + nq_dump(nq); + + p = nq_pop(nq); + if (!p) { + fprintf(stderr, "E: no packet\n"); + } + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[3], strlen(pkt[3]))) { + fprintf(stderr, "E: cannot add packet #4\n"); + } + + nq_dump(nq); + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[4], strlen(pkt[4]))) { + fprintf(stderr, "E: cannot add packet #5\n"); + } + + nq_dump(nq); + + p = nq_pop(nq); + if (!p) { + fprintf(stderr, "E: no packet\n"); + } + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[5], strlen(pkt[5]))) { + fprintf(stderr, "E: cannot add packet #6\n"); + } + + nq_dump(nq); + + p = nq_pop(nq); + p = nq_pop(nq); + p = nq_pop(nq); + p = nq_pop(nq); + p = nq_pop(nq); + p = nq_pop(nq); + p = nq_pop(nq); + + if (!nq_new_packet(nq, (struct sockaddr *)&dst, sizeof(dst), + 0, pkt[6], strlen(pkt[6]))) { + fprintf(stderr, "E: cannot add packet #7\n"); + } + + nq_dump(nq); +#endif + + return 0; +} diff --git a/extlibs/tinydtls/tests/pcap.c b/extlibs/tinydtls/tests/pcap.c new file mode 100644 index 0000000..7534c5f --- /dev/null +++ b/extlibs/tinydtls/tests/pcap.c @@ -0,0 +1,478 @@ +#include +#include +#include +#include + +#include "tinydtls.h" +#include "debug.h" +#include "dtls.h" + +#define TRANSPORT_HEADER_SIZE (14+20+8) /* Ethernet + IP + UDP */ + +/* the pre_master_secret is generated from the PSK at startup */ +unsigned char pre_master_secret[60]; +size_t pre_master_len = 0; + +unsigned char master_secret[DTLS_MASTER_SECRET_LENGTH]; +size_t master_secret_len = 0; + +dtls_security_parameters_t security_params[2]; +int config = 0; +unsigned int epoch[2] = { 0, 0 }; + +#if DTLS_VERSION == 0xfeff +dtls_hash_t hs_hash[2]; +#elif DTLS_VERSION == 0xfefd +dtls_hash_t hs_hash[1]; +#endif + +static inline void +update_hash(uint8 *record, size_t rlength, + uint8 *data, size_t data_length) { + int i; + + if (!hs_hash[0]) + return; + + for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i) { + dtls_hash_update(hs_hash[i], data, data_length); + } +} + +static inline void +finalize_hash(uint8 *buf) { +#if DTLS_VERSION == 0xfeff + unsigned char statebuf[sizeof(md5_state_t) + sizeof(SHA_CTX)]; +#elif DTLS_VERSION == 0xfefd + unsigned char statebuf[sizeof(SHA256_CTX)]; +#endif + + if (!hs_hash[0]) + return; + + /* temporarily store hash status for roll-back after finalize */ +#if DTLS_VERSION == 0xfeff + memcpy(statebuf, hs_hash[0], sizeof(md5_state_t)); + memcpy(statebuf + sizeof(md5_state_t), + hs_hash[1], + sizeof(SHA_CTX)); +#elif DTLS_VERSION == 0xfefd + memcpy(statebuf, hs_hash[0], sizeof(statebuf)); +#endif + + dtls_hash_finalize(buf, hs_hash[0]); +#if DTLS_VERSION == 0xfeff + dtls_hash_finalize(buf + 16, hs_hash[1]); +#endif + + /* restore hash status */ +#if DTLS_VERSION == 0xfeff + memcpy(hs_hash[0], statebuf, sizeof(md5_state_t)); + memcpy(hs_hash[1], + statebuf + sizeof(md5_state_t), + sizeof(SHA_CTX)); +#elif DTLS_VERSION == 0xfefd + memcpy(hs_hash[0], statebuf, sizeof(statebuf)); +#endif +} + +static inline void +clear_hash() { + int i; + + for (i = 0; i < sizeof(hs_hash) / sizeof(dtls_hash_t *); ++i) + free(hs_hash[i]); + memset(hs_hash, 0, sizeof(hs_hash)); +} + +#undef CURRENT_CONFIG +#undef OTHER_CONFIG +#undef SWITCH_CONFIG +#define CURRENT_CONFIG (&security_params[config]) +#define OTHER_CONFIG (&security_params[!(config & 0x01)]) +#define SWITCH_CONFIG (config = !(config & 0x01)) + +int +pcap_verify(dtls_security_parameters_t *sec, + int is_client, + const unsigned char *record, size_t record_length, + const unsigned char *cleartext, size_t cleartext_length) { + + unsigned char mac[DTLS_HMAC_MAX]; + dtls_hmac_context_t hmac_ctx; + int ok; + + if (cleartext_length < dtls_kb_digest_size(sec)) + return 0; + + dtls_hmac_init(&hmac_ctx, + is_client + ? dtls_kb_client_mac_secret(sec) + : dtls_kb_server_mac_secret(sec), + dtls_kb_mac_secret_size(sec)); + + cleartext_length -= dtls_kb_digest_size(sec); + + /* calculate MAC even if padding is wrong */ + dtls_mac(&hmac_ctx, + record, /* the pre-filled record header */ + cleartext, cleartext_length, + mac); + + ok = memcmp(mac, cleartext + cleartext_length, + dtls_kb_digest_size(sec)) == 0; +#ifndef NDEBUG + printf("MAC (%s): ", ok ? "valid" : "invalid"); + dump(mac, dtls_kb_digest_size(sec)); + printf("\n"); +#endif + return ok; +} + +int +decrypt_verify(int is_client, const uint8 *packet, size_t length, + uint8 **cleartext, size_t *clen) { + int res, ok = 0; + dtls_cipher_context_t *cipher; + + static unsigned char buf[1000]; + + switch (CURRENT_CONFIG->cipher) { + case AES128: /* TLS_PSK_WITH_AES128_CBC_SHA */ + *cleartext = buf; + *clen = length - sizeof(dtls_record_header_t); + + if (is_client) + cipher = CURRENT_CONFIG->read_cipher; + else + cipher = CURRENT_CONFIG->write_cipher; + + res = dtls_decrypt(cipher, + (uint8 *)packet + sizeof(dtls_record_header_t), *clen, + buf, NULL, 0); + + if (res < 0) { + warn("decryption failed!\n"); + } else { + ok = pcap_verify(CURRENT_CONFIG, is_client, (uint8 *)packet, length, + *cleartext, res); + + if (ok) + *clen = res - dtls_kb_digest_size(CURRENT_CONFIG); + } + break; + default: /* no cipher suite selected */ + *cleartext = (uint8 *)packet + sizeof(dtls_record_header_t); + *clen = length - sizeof(dtls_record_header_t); + + ok = 1; + } + + if (ok) + printf("verify OK\n"); + else + printf("verification failed!\n"); + return ok; +} + +#define SKIP_ETH_HEADER(M,L) \ + if ((L) < 14) \ + return; \ + else { \ + (M) += 14; \ + (L) -= 14; \ + } + +#define SKIP_IP_HEADER(M,L) \ + if (((M)[0] & 0xF0) == 0x40) { /* IPv4 */ \ + (M) += (M[0] & 0x0F) * 4; \ + (L) -= (M[0] & 0x0F) * 4; \ + } else \ + if (((M)[0] & 0xF0) == 0x60) { /* IPv6 */ \ + (M) += 40; \ + (L) -= 40; \ + } + +#define SKIP_UDP_HEADER(M,L) { \ + (M) += 8; \ + (L) -= 8; \ + } + +void +handle_packet(const u_char *packet, int length) { + static int n = 0; + static unsigned char initial_hello[] = { + 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + uint8 *data; + size_t data_length, rlen; + int i, res; +#if DTLS_VERSION == 0xfeff +#ifndef SHA1_DIGEST_LENGTH +#define SHA1_DIGEST_LENGTH 20 +#endif + uint8 hash_buf[16 + SHA1_DIGEST_LENGTH]; +#elif DTLS_VERSION == 0xfefd + uint8 hash_buf[SHA256_DIGEST_LENGTH]; +#endif +#define verify_data_length 12 + int is_client; + n++; + + SKIP_ETH_HEADER(packet, length); + SKIP_IP_HEADER(packet, length); + + /* determine from port if this is a client */ + is_client = dtls_uint16_to_int(packet) != 20220; + + SKIP_UDP_HEADER(packet, length); + + while (length) { + rlen = dtls_uint16_to_int(packet + 11) + sizeof(dtls_record_header_t); + + if (!rlen) { + fprintf(stderr, "invalid length!\n"); + return; + } + + /* skip packet if it is from a different epoch */ + if (dtls_uint16_to_int(packet + 3) != epoch[is_client]) + goto next; + + res = decrypt_verify(is_client, packet, rlen, + &data, &data_length); + + if (res <= 0) + goto next; + + printf("packet %d (from %s):\n", n, is_client ? "client" : "server"); + hexdump(packet, sizeof(dtls_record_header_t)); + printf("\n"); + hexdump(data, data_length); + printf("\n"); + + if (packet[0] == 22 && data[0] == 1) { /* ClientHello */ + if (memcmp(packet, initial_hello, sizeof(initial_hello)) == 0) + goto next; + + memcpy(dtls_kb_client_iv(OTHER_CONFIG), data + 14, 32); + + clear_hash(); +#if DTLS_VERSION == 0xfeff + hs_hash[0] = dtls_new_hash(HASH_MD5); + hs_hash[1] = dtls_new_hash(HASH_SHA1); + + hs_hash[0]->init(hs_hash[0]->data); + hs_hash[1]->init(hs_hash[1]->data); +#elif DTLS_VERSION == 0xfefd + dtls_hash_init(hs_hash[0]); +#endif + } + + if (packet[0] == 22 && data[0] == 2) { /* ServerHello */ + memcpy(dtls_kb_server_iv(OTHER_CONFIG), data + 14, 32); + /* FIXME: search in ciphers */ + OTHER_CONFIG->cipher = TLS_PSK_WITH_AES_128_CCM_8; + } + + if (packet[0] == 20 && data[0] == 1) { /* ChangeCipherSpec */ + printf("client random: "); + dump(dtls_kb_client_iv(OTHER_CONFIG), 32); + printf("\nserver random: "); + dump(dtls_kb_server_iv(OTHER_CONFIG), 32); + printf("\n"); + master_secret_len = + dtls_prf(pre_master_secret, pre_master_len, + (unsigned char *)"master secret", 13, + dtls_kb_client_iv(OTHER_CONFIG), 32, + dtls_kb_server_iv(OTHER_CONFIG), 32, + master_secret, DTLS_MASTER_SECRET_LENGTH); + + printf("master_secret:\n "); + for(i = 0; i < master_secret_len; i++) + printf("%02x", master_secret[i]); + printf("\n"); + + /* create key_block from master_secret + * key_block = PRF(master_secret, + "key expansion" + server_random + client_random) */ + dtls_prf(master_secret, master_secret_len, + (unsigned char *)"key expansion", 13, + dtls_kb_server_iv(OTHER_CONFIG), 32, + dtls_kb_client_iv(OTHER_CONFIG), 32, + OTHER_CONFIG->key_block, + dtls_kb_size(OTHER_CONFIG)); + + OTHER_CONFIG->read_cipher = + dtls_cipher_new(OTHER_CONFIG->cipher, + dtls_kb_client_write_key(OTHER_CONFIG), + dtls_kb_key_size(OTHER_CONFIG)); + + if (!OTHER_CONFIG->read_cipher) { + warn("cannot create read cipher\n"); + } else { + dtls_cipher_set_iv(OTHER_CONFIG->read_cipher, + dtls_kb_client_iv(OTHER_CONFIG), + dtls_kb_iv_size(OTHER_CONFIG)); + } + + OTHER_CONFIG->write_cipher = + dtls_cipher_new(OTHER_CONFIG->cipher, + dtls_kb_server_write_key(OTHER_CONFIG), + dtls_kb_key_size(OTHER_CONFIG)); + + if (!OTHER_CONFIG->write_cipher) { + warn("cannot create write cipher\n"); + } else { + dtls_cipher_set_iv(OTHER_CONFIG->write_cipher, + dtls_kb_server_iv(OTHER_CONFIG), + dtls_kb_iv_size(OTHER_CONFIG)); + } + + /* if (is_client) */ + SWITCH_CONFIG; + epoch[is_client]++; + + printf("key_block:\n"); + printf(" client_MAC_secret:\t"); + dump(dtls_kb_client_mac_secret(CURRENT_CONFIG), + dtls_kb_mac_secret_size(CURRENT_CONFIG)); + printf("\n"); + + printf(" server_MAC_secret:\t"); + dump(dtls_kb_server_mac_secret(CURRENT_CONFIG), + dtls_kb_mac_secret_size(CURRENT_CONFIG)); + printf("\n"); + + printf(" client_write_key:\t"); + dump(dtls_kb_client_write_key(CURRENT_CONFIG), + dtls_kb_key_size(CURRENT_CONFIG)); + printf("\n"); + + printf(" server_write_key:\t"); + dump(dtls_kb_server_write_key(CURRENT_CONFIG), + dtls_kb_key_size(CURRENT_CONFIG)); + printf("\n"); + + printf(" client_IV:\t\t"); + dump(dtls_kb_client_iv(CURRENT_CONFIG), + dtls_kb_iv_size(CURRENT_CONFIG)); + printf("\n"); + + printf(" server_IV:\t\t"); + dump(dtls_kb_server_iv(CURRENT_CONFIG), + dtls_kb_iv_size(CURRENT_CONFIG)); + printf("\n"); + + } + + if (packet[0] == 22) { + if (data[0] == 20) { /* Finished */ + finalize_hash(hash_buf); + /* clear_hash(); */ + + update_hash((unsigned char *)packet, sizeof(dtls_record_header_t), + data, data_length); + + dtls_prf(master_secret, master_secret_len, + is_client + ? (unsigned char *)"client finished" + : (unsigned char *)"server finished" + , 15, + hash_buf, sizeof(hash_buf), + NULL, 0, + data + sizeof(dtls_handshake_header_t), + verify_data_length); + printf("verify_data:\n"); + dump(data, data_length); + printf("\n"); + } else { + update_hash((unsigned char *)packet, sizeof(dtls_record_header_t), + data, data_length); + } + } + + if (packet[0] == 23) { /* Application Data */ + printf("Application Data:\n"); + dump(data, data_length); + printf("\n"); + } + + next: + length -= rlen; + packet += rlen; + } +} + +void init() { + memset(security_params, 0, sizeof(security_params)); + CURRENT_CONFIG->cipher = -1; + + memset(hs_hash, 0, sizeof(hs_hash)); + + /* set pre_master_secret to default if no PSK was given */ + if (!pre_master_len) { + /* unsigned char psk[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; */ + pre_master_len = + dtls_pre_master_secret((unsigned char *)"secretPSK", 9, + pre_master_secret); + } +} + +int main(int argc, char **argv) { + pcap_t *pcap; + char errbuf[PCAP_ERRBUF_SIZE]; + struct pcap_pkthdr *pkthdr; + const u_char *packet; + int res = 0; + int c, option_index = 0; + + static struct option opts[] = { + { "psk", 1, 0, 'p' }, + { 0, 0, 0, 0 } + }; + + /* handle command line options */ + while (1) { + c = getopt_long(argc, argv, "p:", opts, &option_index); + if (c == -1) + break; + + switch (c) { + case 'p': + pre_master_len = dtls_pre_master_secret((unsigned char *)optarg, + strlen(optarg), pre_master_secret); + break; + } + } + + if (argc <= optind) { + fprintf(stderr, "usage: %s [-p|--psk PSK] pcapfile\n", argv[0]); + return -1; + } + + init(); + + pcap = pcap_open_offline(argv[optind], errbuf); + if (!pcap) { + fprintf(stderr, "pcap_open_offline: %s\n", errbuf); + return -2; + } + + for (;;) { + res = pcap_next_ex(pcap, &pkthdr, &packet); + + switch(res) { + case -2: goto done; + case -1: pcap_perror(pcap, "read packet"); break; + case 1: handle_packet(packet, pkthdr->caplen); break; + default: + ; + } + } + done: + + pcap_close(pcap); + + return 0; +} diff --git a/extlibs/tinydtls/tests/prf-test.c b/extlibs/tinydtls/tests/prf-test.c new file mode 100644 index 0000000..d8d83d9 --- /dev/null +++ b/extlibs/tinydtls/tests/prf-test.c @@ -0,0 +1,31 @@ +#include + +#include "tinydtls.h" +#include "debug.h" +#include "global.h" +#include "crypto.h" + +int +main() { + /* see http://www.ietf.org/mail-archive/web/tls/current/msg03416.html */ + unsigned char key[] = { 0x9b, 0xbe, 0x43, 0x6b, 0xa9, 0x40, 0xf0, 0x17, + 0xb1, 0x76, 0x52, 0x84, 0x9a, 0x71, 0xdb, 0x35 }; + unsigned char label[] = { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c}; + unsigned char random1[] = { 0xa0, 0xba, 0x9f, 0x93, 0x6c, 0xda, 0x31, 0x18}; + unsigned char random2[] = {0x27, 0xa6, 0xf7, 0x96, 0xff, 0xd5, 0x19, 0x8c + }; + unsigned char buf[200]; + size_t result; + + result = dtls_prf(key, sizeof(key), + label, sizeof(label), + random1, sizeof(random1), + random2, sizeof(random2), + buf, 100); + + printf("PRF yields %zu bytes of random data:\n", result); + hexdump(buf, result); + printf("\n"); + return 0; +} diff --git a/extlibs/tinydtls/tests/secure-server.c b/extlibs/tinydtls/tests/secure-server.c new file mode 100644 index 0000000..6ba5258 --- /dev/null +++ b/extlibs/tinydtls/tests/secure-server.c @@ -0,0 +1,862 @@ +/* secure-server -- A (broken) DTLS server example + * + * Copyright (C) 2011 Olaf Bergmann + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef WITH_DTLS +#define SERVER_CERT_PEM "./server-cert.pem" +#define SERVER_KEY_PEM "./server-key.pem" +#define CA_CERT_PEM "./ca-cert.pem" +#endif + +#ifdef HAVE_ASSERT_H +# include +#else +# define assert(x) +#endif /* HAVE_ASSERT_H */ + +static int quit=0; + +/* SIGINT handler: set quit to 1 for graceful termination */ +void +handle_sigint(int signum) { + quit = 1; +} + +int +check_connect(int sockfd, char *buf, int buflen, + struct sockaddr *src, int *ifindex) { + + /* for some reason, the definition in netinet/in.h is not exported */ +#ifndef IN6_PKTINFO + struct in6_pktinfo + { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ + }; +#endif + + size_t bytes; + + struct iovec iov[1] = { {buf, buflen} }; + char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + struct in6_pktinfo *p = NULL; + + struct msghdr msg = { 0 }; + struct cmsghdr *cmsg; + + msg.msg_name = src; + msg.msg_namelen = sizeof(struct sockaddr_in6); + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + + bytes = recvmsg(sockfd, &msg, MSG_DONTWAIT | MSG_PEEK); + if (bytes < 0) { + perror("recvmsg"); + return bytes; + } + + /* TODO: handle msg.msg_flags & MSG_TRUNC */ + if (msg.msg_flags & MSG_CTRUNC) { + fprintf(stderr, "control was truncated!\n"); + return -1; + } + + if (ifindex) { + /* Here we try to retrieve the interface index where the packet was received */ + *ifindex = 0; + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) { + p = (struct in6_pktinfo *)(CMSG_DATA(cmsg)); + *ifindex = p->ipi6_ifindex; + break; + } + } + } + + return bytes; +} + +typedef enum { UNKNOWN=0, DTLS=1 } protocol_t; + +protocol_t +demux_protocol(const char *buf, int len) { + return DTLS; +} + +#ifdef WITH_DTLS +typedef enum { + PEER_ST_ESTABLISHED, PEER_ST_PENDING, PEER_ST_CLOSED + } peer_state_t; +typedef struct { + peer_state_t state; + unsigned long h; + SSL *ssl; +} ssl_peer_t; + +#define MAX_SSL_PENDING 2 /* must be less than MAX_SSL_PEERS */ +#define MAX_SSL_PEERS 10 /* MAX_SSL_PENDING of these might be pending */ +ssl_peer_t *ssl_peer_storage[MAX_SSL_PEERS]; +static int pending = 0; + +void +check_peers() { +typedef struct bio_dgram_data_st + { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; + } bio_dgram_data; + + struct sockaddr_in6 peer; + int i; + BIO *bio; + for (i = 0; i < MAX_SSL_PEERS; i++) { + if (ssl_peer_storage[i]) { + if (!ssl_peer_storage[i]->ssl) + fprintf(stderr, "invalid SSL object for peer %d!\n",i); + else { + bio = SSL_get_rbio(ssl_peer_storage[i]->ssl); + if (bio) { + (void) BIO_dgram_get_peer(bio, (struct sockaddr *)&peer); + if (peer.sin6_port && ssl_peer_storage[i]->h != ntohs(peer.sin6_port)) { + fprintf(stderr, " bio %p: port differs from hash: %d != %d! (%sconnected)\n", bio, + ssl_peer_storage[i]->h, + ntohs(((struct sockaddr_in6 *)&peer)->sin6_port), + ((bio_dgram_data *)bio->ptr)->connected ? "" : "not "); + } + + } + } + } + } +} + +/** Creates a hash value from the first num bytes of s, taking init as + * initialization value. */ +static inline unsigned long +_hash(unsigned long init, const char *s, int num) { + int c; + + while (num--) + while ( (c = *s++) ) { + init = ((init << 7) + init) + c; + } + + return init; +} + +static inline unsigned long +hash_peer(const struct sockaddr *peer, int ifindex) { + unsigned long h; + + /* initialize hash value to interface index */ + h = _hash(0, (char *)&ifindex, sizeof(int)); + +#define CAST(TYPE,VAR) ((TYPE)VAR) + + assert(peer); + switch (peer->sa_family) { + case AF_INET: + return ntohs(CAST(const struct sockaddr_in *, peer)->sin_port); + h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_addr, + sizeof(struct in_addr)); + h = _hash(h, (char *) &CAST(const struct sockaddr_in *, peer)->sin_port, + sizeof(in_port_t)); + break; + case AF_INET6: + return ntohs(CAST(const struct sockaddr_in6 *, peer)->sin6_port); + h = _hash(h, + (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_addr, + sizeof(struct in6_addr)); + h = _hash(h, + (char *) &CAST(const struct sockaddr_in6 *, peer)->sin6_port, + sizeof(in_port_t)); + break; + default: + /* last resort */ + h = _hash(h, (char *)peer, sizeof(struct sockaddr)); + } + + return 42; + return h; +} + +/* Returns index of peer object for specified address/ifindex pair. */ +int +get_index_of_peer(const struct sockaddr *peer, int ifindex) { + unsigned long h; + int idx; +#ifndef NDEBUG + char addr[INET6_ADDRSTRLEN]; + char port[6]; +#endif + + if (!peer) + return -1; + + h = hash_peer(peer,ifindex); + + for (idx = 0; idx < MAX_SSL_PEERS; idx++) { + if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->h == h) { +#ifndef NDEBUG + getnameinfo((struct sockaddr *)peer, sizeof(struct sockaddr_in6), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + + fprintf(stderr, "get_index_of_peer: [%s]:%s => %lu\n", + addr, port, h); +#endif + return idx; + } + } + return -1; +} + +SSL * +get_ssl(SSL_CTX *ctx, int sockfd, struct sockaddr *src, int ifindex) { + int idx; + BIO *bio; + SSL *ssl; +#ifndef NDEBUG + struct sockaddr_storage peer; + char addr[INET6_ADDRSTRLEN]; + char port[6]; + int i; +#endif + + idx = get_index_of_peer(src,ifindex); + if (idx >= 0) { + fprintf(stderr,"found peer %d ",idx); + switch (ssl_peer_storage[idx]->state) { + case PEER_ST_ESTABLISHED: fprintf(stderr,"established\n"); break; + case PEER_ST_PENDING: fprintf(stderr,"pending\n"); break; + case PEER_ST_CLOSED: fprintf(stderr,"closed\n"); break; + default: + OPENSSL_assert(0); + } + +#ifndef NDEBUG + memset(&peer, 0, sizeof(peer)); + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer); + + getnameinfo((struct sockaddr *)&peer, sizeof(peer), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + + fprintf(stderr," [%s]:%s \n", addr, port); +#endif + return ssl_peer_storage[idx]->ssl; + } + + /* none found, create new if sufficient space available */ + if (pending < MAX_SSL_PENDING) { + for (idx = 0; idx < MAX_SSL_PEERS; idx++) { + if (ssl_peer_storage[idx] == NULL) { /* found space */ + ssl = SSL_new(ctx); + + if (ssl) { + bio = BIO_new_dgram(sockfd, BIO_NOCLOSE); + if (!bio) { + SSL_free(ssl); + return NULL; + } + + SSL_set_bio(ssl, bio, bio); + SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); + + SSL_set_accept_state(ssl); + ssl_peer_storage[idx] = (ssl_peer_t *) malloc(sizeof(ssl_peer_t)); + if (!ssl_peer_storage[idx]) { + SSL_free(ssl); + return NULL; + } + ssl_peer_storage[idx]->state = PEER_ST_PENDING; + ssl_peer_storage[idx]->h = hash_peer(src,ifindex); + ssl_peer_storage[idx]->ssl = ssl; + + pending++; + + fprintf(stderr, + "created new SSL peer %d for ssl object %p (storage: %p)\n", + idx, ssl, ssl_peer_storage[idx]); +#ifndef NDEBUG + if (getnameinfo((struct sockaddr *)&src, sizeof(src), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV) != 0) { + perror("getnameinfo"); + fprintf(stderr, "port was %u\n", ntohs(((struct sockaddr_in6 *)src)->sin6_port)); + } else { + fprintf(stderr," [%s]:%s \n", addr, port); + } +#endif + OPENSSL_assert(ssl_peer_storage[idx]->ssl == ssl); + fprintf(stderr,"%d objects pending\n", pending); + check_peers(); + return ssl; + } + } + } + } else { + fprintf(stderr, "too many pending SSL objects\n"); + return NULL; + } + + fprintf(stderr, "too many peers\n"); + return NULL; +} + +/** Deletes peer stored at index idx and frees allocated memory. */ +static inline void +delete_peer(int idx) { + if (idx < 0 || !ssl_peer_storage[idx]) + return; + + if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) + pending--; + + OPENSSL_assert(ssl_peer_storage[idx]->ssl); + SSL_free(ssl_peer_storage[idx]->ssl); + + free(ssl_peer_storage[idx]); + ssl_peer_storage[idx] = NULL; + + printf("deleted peer %d\n",idx); +} + +/** Deletes all closed objects from ssl_peer_storage. */ +void +remove_closed() { + int idx; + + for (idx = 0; idx < MAX_SSL_PEERS; idx++) + if (ssl_peer_storage[idx] + && ssl_peer_storage[idx]->state == PEER_ST_CLOSED) + delete_peer(idx); +} + +#define min(a,b) ((a) < (b) ? (a) : (b)) + +unsigned int +psk_server_callback(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len) { + static char keybuf[] = "secretPSK"; + + printf("psk_server_callback: check identity of client %s\n", identity); + memcpy(psk, keybuf, min(strlen(keybuf), max_psk_len)); + + return min(strlen(keybuf), max_psk_len); +} + +#endif + +#ifdef WITH_DTLS +/** + * This function tracks the status changes from libssl to manage local + * object state. + */ +void +info_callback(const SSL *ssl, int where, int ret) { + int idx, i; + struct sockaddr_storage peer; + struct sockaddr_storage peer2; + char addr[INET6_ADDRSTRLEN]; + char port[6]; + + if (where & SSL_CB_LOOP) /* do not care for intermediary states */ + return; + + memset(&peer, 0, sizeof(peer)); + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + /* lookup SSL object */ /* FIXME: need to get the ifindex */ + idx = get_index_of_peer((struct sockaddr *)&peer, 0); + + if (idx >= 0) + fprintf(stderr, "info_callback: assert: %d < 0 || %p == %p (storage: %p)\n", + idx, ssl, ssl_peer_storage[idx]->ssl, ssl_peer_storage[idx]); + if (idx >= 0 && ssl != ssl_peer_storage[idx]->ssl) { + getnameinfo((struct sockaddr *)&peer, sizeof(peer), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + + fprintf(stderr," ssl: [%s]:%s ", addr, port); + + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[idx]->ssl), &peer2); + getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + + fprintf(stderr," ssl_peer_storage[idx]->ssl: [%s]:%s\n", addr, port); + + fprintf(stderr, " hash:%lu h: %lu\n", + hash_peer((const struct sockaddr *)&peer, 0), + ssl_peer_storage[idx]->h); + + for (i = 0; i < MAX_SSL_PEERS; i++) { + if (ssl_peer_storage[i]) { + fprintf(stderr, "%02d: %p ssl: %p ", + i, ssl_peer_storage[i] ,ssl_peer_storage[i]->ssl); + + (void) BIO_dgram_get_peer(SSL_get_rbio(ssl_peer_storage[i]->ssl), &peer2); + getnameinfo((struct sockaddr *)&peer2, sizeof(peer2), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + + fprintf(stderr," peer: [%s]:%s h: %lu\n", addr, port, ssl_peer_storage[i]->h); + } + } + fprintf(stderr, "***** ASSERT FAILED ******\n"); + + memset(&peer, 0, sizeof(peer)); + (void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer); + + idx = get_index_of_peer((struct sockaddr *)&peer, 0); + fprintf(stderr, " get_index_of_peer for wbio returns %d, type is %04x\n", + idx, where); + } +#if 1 + check_peers(); + OPENSSL_assert((idx < 0) || (ssl == ssl_peer_storage[idx]->ssl)); +#endif + + if (where & SSL_CB_ALERT) { +#ifndef NDEBUG + if (ret != 0) + fprintf(stderr,"%s:%s:%s\n", SSL_alert_type_string(ret), + SSL_alert_desc_string(ret), SSL_alert_desc_string_long(ret)); +#endif + + /* examine alert type */ + switch (*SSL_alert_type_string(ret)) { + case 'F': + /* move SSL object from pending to close */ + if (idx >= 0) { + ssl_peer_storage[idx]->state = PEER_ST_CLOSED; + pending--; + } + break; + case 'W': + if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) { + if (where == SSL_CB_WRITE_ALERT) + fprintf(stderr,"sent CLOSE_NOTIFY\n"); + else /* received CN */ + fprintf(stderr,"received CLOSE_NOTIFY\n"); + } + break; + default: /* handle unknown alert types */ +#ifndef NDEBUG + printf("not handled!\n"); +#endif + } + } + + if (where & SSL_CB_HANDSHAKE_DONE) { + /* move SSL object from pending to established */ + printf("HANDSHAKE_DONE "); + if (idx >= 0) { + + if (ssl_peer_storage[idx]->state == PEER_ST_PENDING) { + ssl_peer_storage[idx]->state = PEER_ST_ESTABLISHED; + pending--; + printf("moved SSL object %d to ESTABLISHED\n", idx); + printf("%d objects pending\n", pending); + } else { +#ifndef NDEBUG + printf("huh, object %d was not pending? (%d)\n", idx, + ssl_peer_storage[idx]->state); +#endif + } + return; + } + return; + } + + return; +} +#endif + +#ifdef WITH_DTLS +/* checks if ssl object was closed and can be removed */ +int +check_close(SSL *ssl) { + int res, err, idx; + struct sockaddr_storage peer; + + memset(&peer, 0, sizeof(peer)); + (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); + + res = 0; + if (SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) { + printf("SSL_RECEIVED_SHUTDOWN\n"); + res = SSL_shutdown(ssl); + if (res == 0) { + printf("must call SSL_shutdown again\n"); + res = SSL_shutdown(ssl); + } + if (res < 0) { + err = SSL_get_error(ssl,res); + fprintf(stderr, "shutdown: SSL error %d: %s\n", err, + ERR_error_string(err, NULL)); + } + + /* we can close the SSL object anyway */ + /* FIXME: need to get ifindex from somewhere */ + idx = get_index_of_peer((struct sockaddr *)&peer, 0); + OPENSSL_assert(idx < 0 || ssl == ssl_peer_storage[idx]->ssl); + if (idx >= 0) { + ssl_peer_storage[idx]->state = PEER_ST_CLOSED; + printf("moved SSL object %d to CLOSED\n",idx); + } + } + + return res; +} + +int +check_timeout() { + int i, result, err; + + for (i = 0; i < MAX_SSL_PEERS; i++) { + if (ssl_peer_storage[i]) { + OPENSSL_assert(ssl_peer_storage[i]->ssl); + result = DTLSv1_handle_timeout(ssl_peer_storage[i]->ssl); + if (result < 0) { + err = SSL_get_error(ssl_peer_storage[i]->ssl,result); + fprintf(stderr, "dtls1_handle_timeout (%d): %s\n", + err, ERR_error_string(err, NULL)); + } + } + } + + /* remove outdated obbjects? */ + + return 0; +} +#endif /* WITH_DTLS */ + +int +_read(SSL_CTX *ctx, int sockfd) { + char buf[2000]; + struct sockaddr_in6 src; + int len, ifindex, i; + char addr[INET6_ADDRSTRLEN]; + char port[6]; + socklen_t sz = sizeof(struct sockaddr_in6); +#ifdef WITH_DTLS + SSL *ssl; + int err; +#endif + + /* Retrieve remote address and interface index as well as the first + few bytes of the message to demultiplex protocols. */ + memset(&src, 0, sizeof(struct sockaddr_in6)); + len = check_connect(sockfd, buf, 4, (struct sockaddr *)&src, &ifindex); + + if (len < 0) /* error */ + return len; + +#ifndef NDEBUG + fprintf(stderr,"received packet"); + + if (getnameinfo((struct sockaddr *)&src, sizeof(src), + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV) == 0) + fprintf(stderr," from [%s]:%s", addr, port); + + fprintf(stderr," on interface %d\n", ifindex); +#endif + + switch (demux_protocol(buf, len)) { +#ifdef WITH_DTLS + case DTLS : + ssl = get_ssl(ctx, sockfd, (struct sockaddr *)&src, ifindex); + if (!ssl) { + fprintf(stderr, "cannot create new SSL object\n"); + /* return recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT);*/ + len = recvfrom(sockfd, buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr *)&src, &sz); + getnameinfo((struct sockaddr *)&src, sz, + addr, sizeof(addr), port, sizeof(port), + NI_NUMERICHOST | NI_NUMERICSERV); + printf("discarded %d bytes from [%s]:%s\n", len, addr, port); + return len; + } + len = SSL_read(ssl, buf, sizeof(buf)); + break; +#endif + case UNKNOWN: + default : + len = recv(sockfd, buf, sizeof(buf), MSG_DONTWAIT); + } + + if (len > 0) { + printf("here is the data:\n"); + for (i=0; i 0) { /* read from socket */ + if ( FD_ISSET( sockfd, &fds[READ]) ) { + _read(ctx, sockfd); /* read received data */ + } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */ + _write(ctx, sockfd); /* write data */ + } + } else { /* timeout */ + check_timeout(); + } + remove_closed(); + } + + end: +#ifdef WITH_DTLS + for (idx = 0; idx < MAX_SSL_PEERS; idx++) { + if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) { + if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED) + SSL_shutdown(ssl_peer_storage[idx]->ssl); + SSL_free(ssl_peer_storage[idx]->ssl); + } + } + + SSL_CTX_free(ctx); +#endif + close(sockfd); /* don't care if we close stdin at this point */ + return res; +} diff --git a/extlibs/tinydtls/tinydtls.h b/extlibs/tinydtls/tinydtls.h new file mode 100644 index 0000000..3fa228a --- /dev/null +++ b/extlibs/tinydtls/tinydtls.h @@ -0,0 +1,45 @@ +/* tinydtls.h. Generated from tinydtls.h.in by configure. */ +/* tinydtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file tinydtls.h + * @brief public tinydtls API + */ + +#ifndef _DTLS_TINYDTLS_H_ +#define _DTLS_TINYDTLS_H_ + +/** Defined to 1 if tinydtls is built with support for ECC */ +/* #undef DTLS_ECC */ + +/** Defined to 1 if tinydtls is built with support for PSK */ +#define DTLS_PSK 1 + +/** Defined to 1 if tinydtls is built for Contiki OS */ +/* #undef WITH_CONTIKI */ + +#endif /* _DTLS_TINYDTLS_H_ */ diff --git a/extlibs/tinydtls/tinydtls.h.in b/extlibs/tinydtls/tinydtls.h.in new file mode 100644 index 0000000..a2e6685 --- /dev/null +++ b/extlibs/tinydtls/tinydtls.h.in @@ -0,0 +1,44 @@ +/* tinydtls -- a very basic DTLS implementation + * + * Copyright (C) 2011--2014 Olaf Bergmann + * Copyright (C) 2013 Hauke Mehrtens + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file tinydtls.h + * @brief public tinydtls API + */ + +#ifndef _DTLS_TINYDTLS_H_ +#define _DTLS_TINYDTLS_H_ + +/** Defined to 1 if tinydtls is built with support for ECC */ +#undef DTLS_ECC + +/** Defined to 1 if tinydtls is built with support for PSK */ +#undef DTLS_PSK + +/** Defined to 1 if tinydtls is built for Contiki OS */ +#undef WITH_CONTIKI + +#endif /* _DTLS_TINYDTLS_H_ */ diff --git a/extlibs/tinydtls/uthash.h b/extlibs/tinydtls/uthash.h new file mode 100644 index 0000000..786c956 --- /dev/null +++ b/extlibs/tinydtls/uthash.h @@ -0,0 +1,972 @@ +/* +Copyright (c) 2003-2010, Troy D. Hanson http://uthash.sourceforge.net +All rights reserved. + +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. + +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. +*/ + +#ifndef _DTLS_UTHASH_H +#define _DTLS_UTHASH_H + +#include /* memcmp,strlen */ +#include /* ptrdiff_t */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on win32 */ +#ifdef _MSC_VER +typedef unsigned int uint32_t; +#else +#include /* uint32_t */ +#endif + +#define UTHASH_VERSION 1.9.3 + +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ + +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_bkt,_hf_hashv; \ + out=NULL; \ + if (head) { \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0); + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0); + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)keyptr; \ + (add)->hh.keylen = keylen_in; \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + unsigned _hd_bkt; \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((char*)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield,strlen(add->strfield),add) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + unsigned _bkt_i; \ + unsigned _count, _bkt_count; \ + char *_prev; \ + struct UT_hash_handle *_thh; \ + if (head) { \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %d, actual %d\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6 */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) + +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) \ + hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ + bkt = hashv & (num_bkts-1); \ +} while(0); + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + char *_hj_key=(char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = keylen; \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + char *_sfh_key=(char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0); + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * So MurmurHash comes in two versions, the faster unaligned one and the slower + * aligned one. We only use the faster one on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__)) +#define HASH_MUR HASH_MUR_UNALIGNED +#else +#define HASH_MUR HASH_MUR_ALIGNED +#endif + +/* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */ +#define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const unsigned int _mur_m = 0x5bd1e995; \ + const int _mur_r = 24; \ + hashv = 0xcafebabe ^ keylen; \ + char *_mur_key = (char *)(key); \ + uint32_t _mur_tmp, _mur_len = keylen; \ + \ + for (;_mur_len >= 4; _mur_len-=4) { \ + _mur_tmp = *(uint32_t *)_mur_key; \ + _mur_tmp *= _mur_m; \ + _mur_tmp ^= _mur_tmp >> _mur_r; \ + _mur_tmp *= _mur_m; \ + hashv *= _mur_m; \ + hashv ^= _mur_tmp; \ + _mur_key += 4; \ + } \ + \ + switch(_mur_len) \ + { \ + case 3: hashv ^= _mur_key[2] << 16; \ + case 2: hashv ^= _mur_key[1] << 8; \ + case 1: hashv ^= _mur_key[0]; \ + hashv *= _mur_m; \ + }; \ + \ + hashv ^= hashv >> 13; \ + hashv *= _mur_m; \ + hashv ^= hashv >> 15; \ + \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */ +#define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const unsigned int _mur_m = 0x5bd1e995; \ + const int _mur_r = 24; \ + hashv = 0xcafebabe ^ (keylen); \ + char *_mur_key = (char *)(key); \ + uint32_t _mur_len = keylen; \ + int _mur_align = (int)_mur_key & 3; \ + \ + if (_mur_align && (_mur_len >= 4)) { \ + unsigned _mur_t = 0, _mur_d = 0; \ + switch(_mur_align) { \ + case 1: _mur_t |= _mur_key[2] << 16; \ + case 2: _mur_t |= _mur_key[1] << 8; \ + case 3: _mur_t |= _mur_key[0]; \ + } \ + _mur_t <<= (8 * _mur_align); \ + _mur_key += 4-_mur_align; \ + _mur_len -= 4-_mur_align; \ + int _mur_sl = 8 * (4-_mur_align); \ + int _mur_sr = 8 * _mur_align; \ + \ + for (;_mur_len >= 4; _mur_len-=4) { \ + _mur_d = *(unsigned *)_mur_key; \ + _mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ + unsigned _mur_k = _mur_t; \ + _mur_k *= _mur_m; \ + _mur_k ^= _mur_k >> _mur_r; \ + _mur_k *= _mur_m; \ + hashv *= _mur_m; \ + hashv ^= _mur_k; \ + _mur_t = _mur_d; \ + _mur_key += 4; \ + } \ + _mur_d = 0; \ + if(_mur_len >= _mur_align) { \ + switch(_mur_align) { \ + case 3: _mur_d |= _mur_key[2] << 16; \ + case 2: _mur_d |= _mur_key[1] << 8; \ + case 1: _mur_d |= _mur_key[0]; \ + } \ + unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ + _mur_k *= _mur_m; \ + _mur_k ^= _mur_k >> _mur_r; \ + _mur_k *= _mur_m; \ + hashv *= _mur_m; \ + hashv ^= _mur_k; \ + _mur_k += _mur_align; \ + _mur_len -= _mur_align; \ + \ + switch(_mur_len) \ + { \ + case 3: hashv ^= _mur_key[2] << 16; \ + case 2: hashv ^= _mur_key[1] << 8; \ + case 1: hashv ^= _mur_key[0]; \ + hashv *= _mur_m; \ + } \ + } else { \ + switch(_mur_len) \ + { \ + case 3: _mur_d ^= _mur_key[2] << 16; \ + case 2: _mur_d ^= _mur_key[1] << 8; \ + case 1: _mur_d ^= _mur_key[0]; \ + case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ + hashv *= _mur_m; \ + } \ + } \ + \ + hashv ^= hashv >> 13; \ + hashv *= _mur_m; \ + hashv ^= hashv >> 15; \ + } else { \ + for (;_mur_len >= 4; _mur_len-=4) { \ + unsigned _mur_k = *(unsigned*)_mur_key; \ + _mur_k *= _mur_m; \ + _mur_k ^= _mur_k >> _mur_r; \ + _mur_k *= _mur_m; \ + hashv *= _mur_m; \ + hashv ^= _mur_k; \ + _mur_key += 4; \ + } \ + switch(_mur_len) \ + { \ + case 3: hashv ^= _mur_key[2] << 16; \ + case 2: hashv ^= _mur_key[1] << 8; \ + case 1: hashv ^= _mur_key[0]; \ + hashv *= _mur_m; \ + } \ + \ + hashv ^= hashv >> 13; \ + hashv *= _mur_m; \ + hashv ^= hashv >> 15; \ + } \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if (out->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + _hs_tail->next = NULL; \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket { + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table { + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle { + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* _DTLS_UTHASH_H */ diff --git a/extlibs/tinydtls/utlist.h b/extlibs/tinydtls/utlist.h new file mode 100644 index 0000000..8b03b6b --- /dev/null +++ b/extlibs/tinydtls/utlist.h @@ -0,0 +1,490 @@ +/* +Copyright (c) 2007-2010, Troy D. Hanson http://uthash.sourceforge.net +All rights reserved. + +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. + +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. +*/ + +#ifndef _DTLS_UTLIST_H +#define _DTLS_UTLIST_H + +#define UTLIST_VERSION 1.9.1 + +/* + * This file contains macros to manipulate singly and doubly-linked lists. + * + * 1. LL_ macros: singly-linked lists. + * 2. DL_ macros: doubly-linked lists. + * 3. CDL_ macros: circular doubly-linked lists. + * + * To use singly-linked lists, your structure must have a "next" pointer. + * To use doubly-linked lists, your structure must "prev" and "next" pointers. + * Either way, the pointer to the head of the list must be initialized to NULL. + * + * ----------------.EXAMPLE ------------------------- + * struct item { + * int id; + * struct item *prev, *next; + * } + * + * struct item *list = NULL: + * + * int main() { + * struct item *item; + * ... allocate and populate item ... + * DL_APPEND(list, item); + * } + * -------------------------------------------------- + * + * For doubly-linked lists, the append and delete macros are O(1) + * For singly-linked lists, append and delete are O(n) but prepend is O(1) + * The sort macro is O(n log(n)) for all types of single/double/circular lists. + */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ code), this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && __cplusplus /* VS2010 and newer in C++ mode */ +#define LDECLTYPE(x) decltype(x) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define LDECLTYPE(x) char* +#endif +#else /* GNU, Sun and other compilers */ +#define LDECLTYPE(x) __typeof(x) +#endif + +/* for VS2008 we use some workarounds to get around the lack of decltype, + * namely, we always reassign our tmp variable to the list head if we need + * to dereference its prev/next pointers, and save/restore the real head.*/ +#ifdef NO_DECLTYPE +#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } +#define _NEXT(elt,list) ((char*)((list)->next)) +#define _NEXTASGN(elt,list,to) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +#define _PREV(elt,list) ((char*)((list)->prev)) +#define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } +#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } +#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +#else +#define _SV(elt,list) +#define _NEXT(elt,list) ((elt)->next) +#define _NEXTASGN(elt,list,to) ((elt)->next)=(to) +#define _PREV(elt,list) ((elt)->prev) +#define _PREVASGN(elt,list,to) ((elt)->prev)=(to) +#define _RS(list) +#define _CASTASGN(a,b) (a)=(b) +#endif + +/****************************************************************************** + * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * + * Unwieldy variable names used here to avoid shadowing passed-in variables. * + *****************************************************************************/ +#define LL_SORT(list, cmp) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } else _tmp=NULL; /* quiet gcc unused variable warning */ \ +} while (0) + +#define DL_SORT(list, cmp) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev, _ls_tail); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } else _tmp=NULL; /* quiet gcc unused variable warning */ \ +} while (0) + +#define CDL_SORT(list, cmp) \ +do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + LDECLTYPE(list) _ls_oldhead; \ + LDECLTYPE(list) _tmp; \ + LDECLTYPE(list) _tmp2; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p,list); \ + _CASTASGN(_ls_oldhead,list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q,list); \ + if (_NEXT(_ls_q,list) == _ls_oldhead) { \ + _ls_q = NULL; \ + } else { \ + _ls_q = _NEXT(_ls_q,list); \ + } \ + _RS(list); \ + if (!_ls_q) break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else if (cmp(_ls_p,_ls_q) <= 0) { \ + _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = _NEXT(_ls_p,list); _RS(list); _ls_psize--; \ + if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ + } else { \ + _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list); _RS(list); _ls_qsize--; \ + if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e); _RS(list); \ + } else { \ + _CASTASGN(list,_ls_e); \ + } \ + _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail); _RS(list); \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + _CASTASGN(list->prev,_ls_tail); \ + _CASTASGN(_tmp2,list); \ + _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp2); _RS(list); \ + if (_ls_nmerges <= 1) { \ + _ls_looping=0; \ + } \ + _ls_insize *= 2; \ + } \ + } else _tmp=NULL; /* quiet gcc unused variable warning */ \ +} while (0) + +/****************************************************************************** + * singly linked list macros (non-circular) * + *****************************************************************************/ +#define LL_PREPEND(head,add) \ +do { \ + (add)->next = head; \ + head = add; \ +} while (0) + +#define LL_APPEND(head,add) \ +do { \ + LDECLTYPE(head) _tmp; \ + (add)->next=NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { _tmp = _tmp->next; } \ + _tmp->next=(add); \ + } else { \ + (head)=(add); \ + } \ +} while (0) + +#define LL_DELETE(head,del) \ +do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ +} while (0) + +/* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ +#define LL_APPEND_VS2008(head,add) \ +do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { (add)->next = (add)->next->next; } \ + (add)->next->next=(add); \ + } else { \ + (head)=(add); \ + } \ + (add)->next=NULL; \ +} while (0) + +#define LL_DELETE_VS2008(head,del) \ +do { \ + if ((head) == (del)) { \ + (head)=(head)->next; \ + } else { \ + char *_tmp = (char*)(head); \ + while (head->next && (head->next != (del))) { \ + head = head->next; \ + } \ + if (head->next) { \ + head->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char**)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ +} while (0) +#ifdef NO_DECLTYPE +#undef LL_APPEND +#define LL_APPEND LL_APPEND_VS2008 +#undef LL_DELETE +#define LL_DELETE LL_DELETE_VS2008 +#endif +/* end VS2008 replacements */ + +#define LL_FOREACH(head,el) \ + for(el=head;el;el=el->next) + +#define LL_FOREACH_SAFE(head,el,tmp) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head,out,field,val) \ +do { \ + LL_FOREACH(head,out) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define LL_SEARCH(head,out,elt,cmp) \ +do { \ + LL_FOREACH(head,out) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +/****************************************************************************** + * doubly linked list macros (non-circular) * + *****************************************************************************/ +#define DL_PREPEND(head,add) \ +do { \ + (add)->next = head; \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev = (add); \ + } else { \ + (add)->prev = (add); \ + } \ + (head) = (add); \ +} while (0) + +#define DL_APPEND(head,add) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (head)->prev->next = (add); \ + (head)->prev = (add); \ + (add)->next = NULL; \ + } else { \ + (head)=(add); \ + (head)->prev = (head); \ + (head)->next = NULL; \ + } \ +} while (0); + +#define DL_DELETE(head,del) \ +do { \ + if ((del)->prev == (del)) { \ + (head)=NULL; \ + } else if ((del)==(head)) { \ + (del)->next->prev = (del)->prev; \ + (head) = (del)->next; \ + } else { \ + (del)->prev->next = (del)->next; \ + if ((del)->next) { \ + (del)->next->prev = (del)->prev; \ + } else { \ + (head)->prev = (del)->prev; \ + } \ + } \ +} while (0); + + +#define DL_FOREACH(head,el) \ + for(el=head;el;el=el->next) + +/* this version is safe for deleting the elements during iteration */ +#define DL_FOREACH_SAFE(head,el,tmp) \ + for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) + +/* these are identical to their singly-linked list counterparts */ +#define DL_SEARCH_SCALAR LL_SEARCH_SCALAR +#define DL_SEARCH LL_SEARCH + +/****************************************************************************** + * circular doubly linked list macros * + *****************************************************************************/ +#define CDL_PREPEND(head,add) \ +do { \ + if (head) { \ + (add)->prev = (head)->prev; \ + (add)->next = (head); \ + (head)->prev = (add); \ + (add)->prev->next = (add); \ + } else { \ + (add)->prev = (add); \ + (add)->next = (add); \ + } \ +(head)=(add); \ +} while (0) + +#define CDL_DELETE(head,del) \ +do { \ + if ( ((head)==(del)) && ((head)->next == (head))) { \ + (head) = 0L; \ + } else { \ + (del)->next->prev = (del)->prev; \ + (del)->prev->next = (del)->next; \ + if ((del) == (head)) (head)=(del)->next; \ + } \ +} while (0); + +#define CDL_FOREACH(head,el) \ + for(el=head;el;el=(el->next==head ? 0L : el->next)) + +#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ + for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ + (el) && ((tmp2)=(el)->next, 1); \ + ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) + +#define CDL_SEARCH_SCALAR(head,out,field,val) \ +do { \ + CDL_FOREACH(head,out) { \ + if ((out)->field == (val)) break; \ + } \ +} while(0) + +#define CDL_SEARCH(head,out,elt,cmp) \ +do { \ + CDL_FOREACH(head,out) { \ + if ((cmp(out,elt))==0) break; \ + } \ +} while(0) + +#endif /* _DTLS_UTLIST_H */ + diff --git a/extra_options.scons b/extra_options.scons index dc2e48e..6cd51b7 100644 --- a/extra_options.scons +++ b/extra_options.scons @@ -1,3 +1,23 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ###################################################################### # This script manages extra build options # @@ -11,25 +31,4 @@ target_os = env.get('TARGET_OS') target_arch = env.get('TARGET_ARCH') src_dir = env.get('SRC_DIR') -if target_os == 'arduino': - # Add 'NET' build option, let user select board network connection type - vars = Variables() - vars.Add(EnumVariable('NET', 'Network connection type', 'Ethernet', ['Ethernet', 'Wifi'])) - vars.Update(env) - Help(vars.GenerateHelpText(env)) - -# check 'cereal' library, temporarily put it here -if not os.path.exists(src_dir + '/extlibs/cereal'): - print ''' -*********************************** Error: ************************************** -* 'Cereal' library doesn't exist. please download cereal to extlibs directory * -* add apply the patch as following: * -* $ git clone https://github.com/USCiLab/cereal.git /extlibs/cereal* -* $ cd /extlibs/cereal * -* $ git reset --hard 7121e91e6ab8c3e6a6516d9d9c3e6804e6f65245 * -* $ git apply ../../resource/patches/cereal_gcc46.patch * -********************************************************************************* -''' - Exit(1) -else: - env.AppendUnique(CPPPATH = [src_dir + '/extlibs/cereal/include']) +env.SConscript('extlibs/cereal/SConscript') diff --git a/gbsbuild.sh b/gbsbuild.sh new file mode 100644 index 0000000..d4542f0 --- /dev/null +++ b/gbsbuild.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +spec=`ls tools/tizen/*.spec` +version=`rpm --query --queryformat '%{version}\n' --specfile $spec` + +name=`echo $name|cut -d" " -f 1` +version=`echo $version|cut -d" " -f 1` + +name=iotivity + +rm -rf $name-$version + +builddir=`pwd` +sourcedir=`pwd` + +echo `pwd` + +mkdir ./tmp +mkdir ./tmp/extlibs/ +mkdir ./tmp/packaging +cp -R ./build_common $sourcedir/tmp +cp -R ./examples $sourcedir/tmp +cp -R ./extlibs/cereal $sourcedir/tmp/extlibs +cp -R ./extlibs/cjson $sourcedir/tmp/extlibs +cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs +cp -R ./extlibs/timer $sourcedir/tmp/extlibs +cp -R ./extlibs/rapidxml $sourcedir/tmp/extlibs +cp -R ./resource $sourcedir/tmp +cp -R ./service $sourcedir/tmp +cp ./extra_options.scons $sourcedir/tmp +cp ./tools/tizen/*.spec ./tmp/packaging +cp ./SConstruct ./tmp +cp ./tools/tizen/*.rpm ./tmp +cp ./tools/tizen/.gbs.conf ./tmp +cd $sourcedir/tmp + +echo `pwd` +rm -rf ./extlibs/cereal/cereal/.git* + +# Initialize Git repository +if [ ! -d .git ]; then + git init ./ + git config user.email "you@example.com" + git config user.name "Your Name" + git add ./ + git commit -m "Initial commit" +fi + +echo "Calling core gbs build command" +gbscommand="gbs build -A armv7l -B ~/GBS-ROOT --include-all --repository ./" +echo $gbscommand +if eval $gbscommand; then + echo "Build is successful" +else + echo "Build failed!" +fi + +cd $sourcedir +rm -rf $sourcedir/tmp diff --git a/resource/README.setup.txt b/resource/README.setup.txt deleted file mode 100644 index d248d66..0000000 --- a/resource/README.setup.txt +++ /dev/null @@ -1,266 +0,0 @@ -****************************************************************** - - Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. - --=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - - 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. - --=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -=============================================================================== -== NOTICE - Transition to SCONS == -=============================================================================== - -The IoTivity build system is transitioning to SCONS. Although the -makefiles are still available (until v1.0) and some developers are -still using them, they are currently no longer supported. To learn more -about building using SCONS see Readme.scons.txt in the repository root -directory. The build steps used in continuous integration can be found -in auto_build.sh which is also in the the repository root directory. - -=============================================================================== -== Rich Stack & Lite Stack == -=============================================================================== - -The OIC-RESOURCE repository (referred as "") contains two SDKs -with underlying code (i.e. "stack"). The two SDKs are referred to as "Rich SDK" -(or "C++ SDK") and "Lite SDK" (or "C SDK"). The associated stacks are referred -to as "Rich Stack" (or "C++ Stack") and "Lite Stack" (or "C Stack"), -respectively. The Rich Stack-SDK pair requires that the Lite Stack-SDK pair is -built under it. - -For a list of artifact locations for all possible build processes in the -OIC-RESOURCE repository, please refer to: -/artifact_output_locations.txt. - -=============================================================================== - -The Rich Stack is intended ONLY for Linux Ubuntu 12.04 operating system. -To build Rich Stack, please follow these requirements: -- GCC compiler version is 4.6 -- Pre-install the "gnu-libc" libraries package. -- You have pre-built the Lite Stack for Linux Ubuntu 12.04. -- You have installed and pre-built Boost 1.54. -- To compile Rich Unit Tests, you must have Google Test 1.7.0 and must also - create/append "local.properties" file at /csdk/ with the - following specified: - - GTEST_DIR= - -The Lite Stack is intended ONLY for Linux Ubuntu 12.04, Arduino ATMega 2560 with -Arduino Framework 1.0.5, and Arduino Due with Arduino Framework 1.5.7. -Tip: Use Cutecom in Ubuntu 12.04 to view logs from Arduino ATMega 2560 and -Arduino Due. - -To build Lite Stack, please follow these requirements for Linux Ubuntu 12.04: -- GCC compiler version is 4.6 -- Pre-install the "gnu-libc" libraries package. - -To build Lite Stack, please follow these requirements for Arduino ATMega 2560: -- Arduino Framework 1.0.5 is installed. (Newer versions of the Arduino - Framework for Arduino ATMega 2560 have not been tested.) -- AVR-GCC compiler version is 4.5.3 (Distributed with Arduino 1.0.5, no further - action necessary if framework was obtained from - http://arduino.cc/en/Main/OldSoftwareReleases. Note: Frameworks obtained from - apt-get have had different compiler versions.) -- Unzip the Time Library from here to your Arduino Directory Structure: - http://playground.arduino.cc/code/time -- Apply patch "arduino-1.0.5_linux.patch" at - /tools/arduino/patches to your Arduino Directory Structure at - location . -- Create/Append "local.properties" file at location - /resource/csdk/ with the following specified: - - ARDUINO_DIR := - ARDUINO_TOOLS_DIR := $(ARDUINO_DIR)/hardware/tools/avr/bin - -To build Lite Stack, please follow these requirements for Arduino Due: -- Arduino Framework 1.5.7 is installed. (Newer versions of the Arduino - Framework for Arduino Due have not been tested.) -- AVR-GCC compiler version is 4.8.3 (Distributed with Arduino 1.5.7, no further - action necessary if framework was obtained from - http://arduino.cc/en/Main/OldSoftwareReleases. Note: Frameworks obtained from - apt-get have had different compiler versions.) -- Unzip the Time Library from here to your Arduino Directory Structure: - http://www.pjrc.com/teensy/td_libs_Time.html -- Apply patch "arduino-1.5.7_linux.patch" at - /tools/arduino/patches to your Arduino Directory Structure at - location . -- Create/Append "local.properties" file at location - /resource/csdk/ with the following specified: - - ARDUINO_DIR := - ARDUINO_TOOLS_DIR := $(ARDUINO_DIR)/hardware/tools/avr/bin - -Note: If you are building Unit Tests for Linux, building for Arduino Mega, and -building for Arduino Due you may find it useful to set the "local.properties" -file to look like this: - -GTEST_DIR= - -ifeq ($(PLATFORM), arduinomega) - #Location of arduino sdk for Arduino Mega - ARDUINO_DIR := - ARDUINO_TOOLS_DIR := $(ARDUINO_DIR)/hardware/tools/avr/bin -else - #Location of arduino sdk for Arduino Due - ARDUINO_DIR := - ARDUINO_TOOLS_DIR := $(ARDUINO_DIR)/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin -endif - -=============================================================================== - -Instructions for Common Build Processes: - -NOTE: 'GNU Make' is required to utilize the build script at location: -/buildScript.mk. - -======================================= -== All Targets - Linux, ATMega & Due == -======================================= - -- All Modules, including OCICUC, in Release & Debug (Lite Stack, Lite Unit - Tests, Lite Examples, Rich Stack, Rich Unit Tests, Rich Examples, Rich - OCICUC) for linux, Arduino ATMega 2560 with Ethernet Shield, Arduino ATMega - ATMega 2560 with WiFi Shield, Arduino Due with Ethernet Shield and Arduino - Due with WiFi Shield: - (This will be what is used on the Build Server(s) to limit regression.) - - make -f buildScript.mk all_dev - -======================================= -== All Targets - Linux & ATMega 2560 == -======================================= - -- All Modules in Release (Lite Stack, Lite Unit Tests, Lite Examples, Rich - Stack, Rich Unit Tests, Rich Examples) for Linux & Arduino ATMega 2560 with - Ethernet Shield: - - make -f buildScript.mk all - -- All Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples, Rich Stack, - Rich Examples) for Linux & Arduino ATMega 2560 with Ethernet Shield: - - make -f buildScript.mk all_debug - -======================================= -== All Targets - Linux & Due == -======================================= - -- All Modules in Release (Lite Stack, Lite Unit Tests, Lite Examples, Rich - Stack, Rich Unit Tests, Rich Examples) for Linux & Arduino Due with Ethernet - Shield: - - make -f buildScript.mk complement - -- All Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples, Rich Stack, - Rich Unit Tests, Rich Examples) for Linux & Arduino Due with Ethernet Shield: - - make -f buildScript.mk complement_debug - -======================================= -== All Targets - Linux Only == -======================================= - -- All Modules, without OCICUC, in Release (Lite Stack, Lite Unit Tests, Lite - Examples, Rich Stack, Rich Unit Tests, Rich Examples) for linux: - - make -f buildScript.mk linux - -- All Modules, without OCICUC, in Debug (Lite Stack, Lite Unit Tests, Lite - Examples, Rich Stack, Rich Unit Tests, Rich Examples) for linux: - - make -f buildScript.mk linux_debug - -- All Rich Stack Modules in Release, without OCICUC, (Lite Stack, Rich Stack, - Rich Unit Tests, Rich Examples) for Linux: - - make -f buildScript.mk linux_ub - -- All Rich Stack Modules in Debug, without OCICUC, (Lite Stack, Rich Stack, - Rich Unit Tests, Rich Examples) for Linux: - - make -f buildScript.mk linux_ub_debug - -- All Rich Stack Modules, including OCICUC, in Release & Debug (Lite Stack, - Rich Stack, Rich Unit Tests, Rich Examples, Rich OCICUC) for linux: - - make -f buildScript.mk linux_ub_dev - -- All Lite Stack Modules in Release (Lite Stack, Lite Unit Tests, Lite - Examples) for Linux: - - make -f buildScript.mk linux_tb - -- All Lite Stack Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples) - for Linux: - - make -f buildScript.mk linux_tb_debug - -======================================= -== All Targets - Mega Only == -======================================= - -- All Lite Stack Modules in Release (Lite Stack, Lite Unit Tests, Lite - Examples) for Arduino ATMega 2560 with Ethernet Shield: - - make -f buildScript.mk arduinomega - -- All Lite Stack Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples) - for Arduino ATMega 2560 with Ethernet Shield: - - make -f buildScript.mk arduinomega_debug - -- All Lite Stack Modules in Release (Lite Stack, Lite Unit Tests, Lite - Examples) for Arduino ATMega 2560 with WiFi Shield: - - make -f buildScript.mk arduinomega_wifi - -- All Lite Stack Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples) - for Arduino ATMega 2560 with WiFi Shield: - - make -f buildScript.mk arduinomega_wifi_debug - -======================================= -== All Targets - Due Only == -======================================= - -- All Lite Stack Modules in Release (Lite Stack, Lite Unit Tests, Lite - Examples) for Arduino Due with Ethernet Shield: - - make -f buildScript.mk arduinodue_all - -- All Lite Stack Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples) - Examples) for Arduino Due with Ethernet Shield: - - make -f buildScript.mk arduinodue_all_debug - -- All Lite Stack Modules in Release (Lite Stack, Lite Unit Tests, Lite - Examples) for Arduino Due with WiFi Shield: - - make -f buildScript.mk arduinodue_wifi - -- All Lite Stack Modules in Debug (Lite Stack, Lite Unit Tests, Lite Examples) - for Arduino Due with WiFi Shield: - - make -f buildScript.mk arduinodue_wifi_debug - -======================================= -== Clean All Targets == -======================================= - -- Clean All: - - make -f buildScript.mk clean - diff --git a/resource/SConscript b/resource/SConscript index e1ad14e..9f96e77 100644 --- a/resource/SConscript +++ b/resource/SConscript @@ -1,29 +1,74 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ## # 'resource' sub-project main build script # ## +import os + Import('env') target_os = env.get('TARGET_OS') +src_dir = env.get('SRC_DIR') + +if target_os not in ['arduino', 'darwin', 'ios', 'android']: + env.AppendUnique(LIBS=['rt']) # Build libcoap -SConscript('csdk/libcoap/SConscript') +SConscript('csdk/connectivity/lib/libcoap-4.1.1/SConscript') + +# Build connectivity +SConscript('csdk/connectivity/SConscript') # Build liboctbstack SConscript('csdk/SConscript') -if target_os == 'android': - SConscript('android/SConscript') - -if target_os != 'arduino': +if target_os not in ['arduino','darwin']: # Build liboc_logger SConscript('oc_logger/SConscript') # Build liboc SConscript('src/SConscript') +if target_os not in ['arduino','darwin', 'android']: # Build examples SConscript('examples/SConscript') -else: - SConscript('csdk/stack/samples/arduino/SimpleClientServer/ocserver/SConscript') \ No newline at end of file + +if target_os == 'linux': + # Build C Samples + SConscript('csdk/stack/samples/linux/SimpleClientServer/SConscript') + + # Build secure samples + SConscript('csdk/stack/samples/linux/secure/SConscript') + + # Build C/C++ unit tests + SConscript('unit_tests.scons') + +elif target_os == 'darwin': + # Build linux samples for now. + SConscript('csdk/stack/samples/linux/SimpleClientServer/SConscript') + + # Build C stack's unit tests. + SConscript('unit_tests.scons') + +elif target_os == 'arduino': + SConscript('csdk/stack/samples/arduino/SimpleClientServer/ocserver/SConscript') diff --git a/resource/android/OCAndroid.cpp b/resource/android/OCAndroid.cpp index a43d578..46850cd 100644 --- a/resource/android/OCAndroid.cpp +++ b/resource/android/OCAndroid.cpp @@ -82,23 +82,54 @@ namespace std { return ret; } - std::string to_string(int t) { - std::ostringstream os; - os << t; - return os.str(); + #define TO_STRING(_t) { \ + std::ostringstream os; \ + os << _t; \ + return os.str(); \ + } \ + + std::string to_string(int val) + { + TO_STRING(val) + } + + std::string to_string(long val) + { + TO_STRING(val) + } + + std::string to_string(long long val) + { + TO_STRING(val) + } + + std::string to_string(unsigned val) + { + TO_STRING(val) + } + + std::string to_string(unsigned long val) + { + TO_STRING(val) + } + + std::string to_string(unsigned long long val) + { + TO_STRING(val) } - std::string to_string(double t) { - std::ostringstream os; - os << t; - return os.str(); + std::string to_string(float val) + { + TO_STRING(val) } - std::string to_string(uint32_t t) + std::string to_string(double val) { - std::ostringstream os; - os << t; - return os.str(); + TO_STRING(val) } + std::string to_string(long double val) + { + TO_STRING(val) + } } // std diff --git a/resource/android/SConscript b/resource/android/SConscript index 35e3616..d7bce9f 100644 --- a/resource/android/SConscript +++ b/resource/android/SConscript @@ -3,11 +3,7 @@ ## Import('env') -# Add third party libraries -lib_env = env.Clone() -#SConscript(env.get('SRC_DIR') + '/resource/third_party_libs.scons', 'lib_env') - -compatibilitylib_env = lib_env.Clone() +compatibilitylib_env = env.Clone() ###################################################################### # Build flags ###################################################################### @@ -17,8 +13,7 @@ target_os = env.get('TARGET_OS') if target_os == 'android': compatibilitylib_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions']) - #oclib_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) - compatibilitylib_env.AppendUnique(LIBS = ['gnustl_static']) + compatibilitylib_env.AppendUnique(LIBS = ['gnustl_shared']) ###################################################################### # Source files and Targets diff --git a/resource/artifact_output_locations.txt b/resource/artifact_output_locations.txt index d9234a0..72b2ca5 100644 --- a/resource/artifact_output_locations.txt +++ b/resource/artifact_output_locations.txt @@ -33,10 +33,8 @@ Please refer to the readme file at /README for more information. TB Stack: release: - /csdk/libcoap/linux/release/libcoap.a /csdk/linux/release/liboctbstack.a debug: - /csdk/libcoap/linux/debug/libcoap.a /csdk/linux/debug/liboctbstack.a TB Unit Tests: @@ -95,7 +93,7 @@ UB OCICUC: /examples/ocicuc/client /examples/ocicuc/monoprocess /examples/ocicuc/server - + =============================================================================== ==== Arduino ATMega 2560 - Release & Debug - Ethernet Shield ==== @@ -104,10 +102,8 @@ UB OCICUC: TB Stack: Ethernet Shield: release: - /csdk/libcoap/arduinomega/ethernet_shield/release/libcoap.a /csdk/arduinomega/ethernet_shield/release/liboctbstack.a debug: - /csdk/libcoap/arduinomega/ethernet_shield/debug/libcoap.a /csdk/arduinomega/ethernet_shield/debug/liboctbstack.a TB Examples: @@ -124,10 +120,8 @@ TB Examples: TB Stack: WiFi Shield: release: - /csdk/libcoap/arduinomega/wifi_shield/release/libcoap.a /csdk/arduinomega/wifi_shield/release/liboctbstack.a debug: - /csdk/libcoap/arduinomega/wifi_shield/debug/libcoap.a /csdk/arduinomega/wifi_shield/debug/liboctbstack.a TB Examples: @@ -144,10 +138,8 @@ TB Examples: TB Stack: Ethernet Shield: release: - /csdk/libcoap/arduinodue/ethernet_shield/release/libcoap.a /csdk/arduinodue/ethernet_shield/release/liboctbstack.a debug: - /csdk/libcoap/arduinodue/ethernet_shield/debug/libcoap.a /csdk/arduinodue/ethernet_shield/debug/liboctbstack.a TB Examples: @@ -164,10 +156,8 @@ TB Examples: TB Stack: WiFi Shield: release: - /csdk/libcoap/arduinodue/wifi_shield/release/libcoap.a /csdk/arduinodue/wifi_shield/release/liboctbstack.a debug: - /csdk/libcoap/arduinodue/wifi_shield/debug/libcoap.a /csdk/arduinodue/wifi_shield/debug/liboctbstack.a TB Examples: @@ -189,3 +179,4 @@ TB Examples: + diff --git a/resource/buildScript.mk b/resource/buildScript.mk deleted file mode 100644 index 64afad1..0000000 --- a/resource/buildScript.mk +++ /dev/null @@ -1,531 +0,0 @@ -# //****************************************************************** -# // -# // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. -# // -# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# // -# // 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. -# // -# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -# - -# This makefile build-script requires the following for each platform: -# Note: Refer to READMEs at "/" & "/csdk/" for -# more information. -# -# Linux: -# OS: Ubuntu 12.04 -# GCC Version: 4.6.1 -# -# Arduino ATMega 2560: -# Framework Version: Arduino 1.0.5 -# AVR-GCC Version: 4.5.3 -# -# Arduino Due: -# Framework Version: Arduino 1.5.7 -# AVR-GCC Version: 4.8.3 - -# Header Description: -# ====NAME/TITLE - BUILD TYPE - OUT DIRECTORY==== - -############################################################################### -#### TB Stack, TB Unit Tests, TB Examples, UB Stack, #### -#### & UB Examples - Linux & Arduino Mega #### -#### Note: Default "all" target builds Release only "all" of Linux & #### -#### Release only "all" of Arduino Mega with Ethernet Shield. #### -############################################################################### - -all: all_release - -all_all: all_release all_debug - -dev: linux_ub_dev arduinomega_all_dev - -all_release: linux_release arduinomega_release - -all_debug: linux_debug arduinomega_debug - -############################################################################### -#### TB Stack, TB Unit Tests, TB Examples, UB Stack, #### -#### & UB Examples - Linux & Arduino Due #### -#### Note: Default "all" target builds Release only "all" of Linux & #### -#### Release only "all" of Arduino Due with Ethernet Shield. #### -############################################################################### - -complement: complement_release - -complement_all: complement_release complement_debug - -complement_dev: linux_ub_dev arduinodue_all_dev - -complement_release: linux_release arduinodue_release - -complement_debug: linux_debug arduinodue_debug - -############################################################################### -#### TB Stack, TB Unit Tests, TB Examples, UB Stack, UB Examples, #### -#### & OCICUC - Linux, Arduino Mega and Arduino Due #### -#### Note: The "all_dev" target is intended for use on the build #### -#### server(s). This includes "all" targets for Release & Debug for #### -#### Linux, "all" Release & Debug for Arduino Mega with Ethernet #### -#### Shield & WiFi Shield, and "all" Release & Debug for Arduino #### -#### Due with Ethernet Shield & Wifi Shield. #### -############################################################################### - -all_dev: linux_ub_dev arduinomega_all_dev arduinodue_all_dev - -############################################################################### -## TB Stack, TB Unit Tests, TB Examples, UB Stack, & UB Examples - Linux Only # -############################################################################### - -linux: linux_tb_release - -linux_all: linux_release linux_debug - -linux_release: linux_tb_release linux_ub_release - -linux_debug: linux_tb_debug linux_ub_debug - -############################################################################### -#### TB Stack, TB Unit Tests, & TB Examples - Linux Only #### -############################################################################### - -linux_tb: linux_tb_release - -linux_tb_all: linux_tb_release linux_tb_debug - -linux_tb_release: linux_tb_stack_release linux_tb_unittests_release linux_tb_examples_release - -linux_tb_debug: linux_tb_stack_debug linux_tb_unittests_debug linux_tb_examples_debug - -############################################################################### -#### UB Stack, TB Stack, & UB Examples - Linux Only #### -############################################################################### - -linux_ub: linux_ub_release - -linux_ub_all: linux_ub_release linux_ub_debug - -linux_ub_release: linux_tb_stack_release linux_ub_unittests_release linux_ub_stack_release linux_ub_examples_release - -linux_ub_debug: linux_tb_stack_debug linux_ub_unittests_debug linux_ub_stack_debug linux_ub_examples_debug - -############################################################################### -#### TB Stack - Linux Only #### -############################################################################### - -linux_tb_stack: linux_tb_stack_release - -linux_tb_stack_all: linux_tb_stack_release linux_tb_stack_debug - -linux_tb_stack_debug: - @echo "=====BUILD LIBCOAP FOR LINUX - DEBUG - /csdk/libcoap/linux/debug/=====" - $(MAKE) -C csdk/libcoap "BUILD=debug" "PLATFORM=linux" - @echo "=====BUILD TB STACK FOR LINUX - DEBUG - /csdk/linux/debug/=====" - $(MAKE) -C csdk/ "buildScript_all" "BUILD=debug" "PLATFORM=linux" - -linux_tb_stack_release: - @echo "=====BUILD LIBCOAP FOR LINUX - RELEASE - /csdk/libcoap/linux/release/=====" - $(MAKE) -C csdk/libcoap "BUILD=release" "PLATFORM=linux" - @echo "=====BUILD TB STACK FOR LINUX - RELEASE - /csdk/linux/release/=====" - $(MAKE) -C csdk/ "buildScript_all" "BUILD=release" "PLATFORM=linux" - -############################################################################### -#### TB Unit Tests - Linux Only #### -############################################################################### - -linux_tb_unittests: linux_tb_unittests_release - -linux_tb_unittests_all: linux_tb_unittests_release linux_tb_unittests_debug - -linux_tb_unittests_release: linux_tb_stack_release - @echo "=====BUILD TB UNITTESTS FOR LINUX - RELEASE - /csdk/stack/test/linux/release/=====" - $(MAKE) -C csdk/stack/test/linux/ "BUILD=release" - -linux_tb_unittests_debug: linux_tb_stack_debug - @echo "=====BUILD TB UNITTESTS FOR LINUX - DEBUG - /csdk/stack/test/linux/debug/=====" - $(MAKE) -C csdk/stack/test/linux/ "BUILD=debug" - -############################################################################### -#### TB Examples - Linux Only #### -############################################################################### - -linux_tb_examples: linux_tb_stack_release linux_tb_examples_release - -linux_tb_examples_all: linux_tb_stack_release linux_tb_examples_debug - -linux_tb_examples_release: linux_tb_stack_release - @echo "=====BUILD TB SAMPLE APPS FOR LINUX - RELEASE - /csdk/stack/samples/linux/SimpleClientServer/release/=====" - $(MAKE) -C csdk/stack/samples/linux/SimpleClientServer "PLATFORM=linux" "BUILD=release" - $(MAKE) -C csdk/stack/samples/linux/secure "PLATFORM=linux" "BUILD=release" - -linux_tb_examples_debug: linux_tb_stack_debug - @echo "=====BUILD TB SAMPLE APPS FOR LINUX - DEBUG - /csdk/stack/samples/linux/SimpleClientServer/debug/=====" - $(MAKE) -C csdk/stack/samples/linux/SimpleClientServer "PLATFORM=linux" "BUILD=debug" - $(MAKE) -C csdk/stack/samples/linux/secure "PLATFORM=linux" "BUILD=debug" - -############################################################################### -#### UB Stack (& TB Stack as prerequisite) - Linux Only #### -############################################################################### - -linux_ub_stack: linux_ub_stack_release - -linux_ub_stack_all: linux_ub_stack_release linux_ub_stack_debug - -linux_ub_stack_release: linux_tb_stack_release - @echo "=====BUILD UB STACK FOR LINUX - RELEASE - /release/=====" - $(MAKE) -C ./ "buildScript_all" "BUILD=release" - -linux_ub_stack_debug: linux_tb_stack_debug - @echo "=====BUILD UB STACK FOR LINUX - DEBUG - /debug/=====" - $(MAKE) -C ./ "buildScript_all" "BUILD=debug" - -############################################################################### -#### UB Unit Tests (& TB Stack as prequisite) - Linux Only #### -############################################################################### - -linux_ub_unittests: linux_ub_unittests_release - -linux_ub_unittests_all: linux_ub_unittests_release linux_ub_unittests_debug - -linux_ub_unittests_release: linux_ub_stack_release - @echo "=====BUILD UB UNIT TESTS FOR LINUX - RELEASE - /unittests/release=====" - $(MAKE) -C unittests/ "BUILD=release" - -linux_ub_unittests_debug: linux_ub_stack_debug - @echo "=====BUILD UB UNIT TESTS FOR LINUX - DEBUG - /unittests/debug=====" - $(MAKE) -C unittests/ "BUILD=debug" - -############################################################################### -#### UB Examples (& UB Stack as prerequisite) - Linux Only #### -############################################################################### - -linux_ub_examples: linux_ub_examples_release - -linux_ub_examples_all: linux_ub_examples_release linux_ub_examples_debug - -linux_ub_examples_release: linux_ub_stack_release - @echo "=====BUILD UB SAMPLE APPS FOR LINUX - RELEASE - /examples/release/=====" - $(MAKE) -C examples/ "buildScript_all" "BUILD=release" - -linux_ub_examples_debug: linux_ub_stack_debug - @echo "=====BUILD UB SAMPLE APPS FOR LINUX - DEBUG - /examples/debug/=====" - $(MAKE) -C examples/ "buildScript_all" "BUILD=debug" - -############################################################################### -#### TB Stack, TB Unit Tests, TB Examples, UB Stack, UB Examples, #### -#### UB Unit Tests, & OCICUC - Linux Only #### -############################################################################### - -linux_ub_dev: linux_ub_stack_all linux_ub_unittests_all linux_ub_examples_all linux_tb_examples_all - @echo "=====BUILD UB OCICUC - /examples/ocicuc/=====" - $(MAKE) -C examples/ocicuc/ - -############################################################################### -#TB Stack, TB Unit Tests, & TB Examples - Arduino Mega Only - Ethernet & WiFi # -############################################################################### - -arduinomega: arduinomega_release - -arduinomega_all: arduinomega_release arduinomega_debug - -arduinomega_all_dev: arduinomega_release_dev arduinomega_debug_dev - -arduinomega_release: arduinomega_ethernet_release - -arduinomega_debug: arduinomega_ethernet_debug - -arduinomega_release_dev: arduinomega_ethernet_release arduinomega_wifi_release - -arduinomega_debug_dev: arduinomega_ethernet_debug arduinomega_wifi_debug - -############################################################################### -## TB Stack, TB Unit Tests, & TB Examples - Arduino Mega Only - Ethernet Only # -############################################################################### - -arduinomega_ethernet: arduinomega_ethernet_release - -arduinomega_ethernet_all: arduinomega_ethernet_release arduinomega_ethernet_debug - -arduinomega_ethernet_release: arduinomega_stack_ethernet_release arduinomega_samples_ethernet_release - -arduinomega_ethernet_debug: arduinomega_stack_ethernet_debug arduinomega_samples_ethernet_debug - -############################################################################### -## TB Stack, TB Unit Tests, & TB Examples - Arduino Mega Only - Ethernet Only # -############################################################################### - -arduinomega_wifi: arduinomega_wifi_release - -arduinomega_wifi_all: arduinomega_wifi_release arduinomega_wifi_debug - -arduinomega_wifi_release: arduinomega_stack_wifi_release arduinomega_samples_wifi_release - -arduinomega_wifi_debug: arduinomega_stack_wifi_debug arduinomega_samples_wifi_debug - -############################################################################### -#### TB Stack - Arduino Mega Only - Ethernet Only #### -############################################################################### - -arduinomega_stack_ethernet: arduinomega_stack_ethernet_release - -arduinomega_stack_ethernet_all: arduinomega_stack_ethernet_release arduinomega_stack_ethernet_debug - -arduinomega_stack_ethernet_release: - @echo "=====BUILD C STACK FOR ARDUINO ATMEGA 2560 - RELEASE - ETHERNET SHIELD======" - @echo "=====BUILD LIBCOAP - RELEASE - /csdk/libcoap/arduinomega/ethernet_shield/release/=====" - $(MAKE) -C csdk/libcoap "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - @echo "=====BUILD TB STACK - RELEASE - /csdk/arduinomega/ethernet_shield/release/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - -arduinomega_stack_ethernet_debug: - @echo "=====BUILD C STACK FOR ARDUINO ATMEGA 2560 - DEBUG - ETHERNET SHIELD======" - @echo "=====BUILD LIBCOAP - DEBUG - /csdk/libcoap/arduinomega/ethernet_shield/debug/=====" - $(MAKE) -C csdk/libcoap "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - @echo "=====BUILD TB STACK - DEBUG - /csdk/arduinomega/ethernet_shield/debug/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - -############################################################################### -#### TB Stack - Arduino Mega Only - WiFi Only #### -############################################################################### - -arduinomega_stack_wifi: arduinomega_stack_wifi_release - -arduinomega_stack_wifi_all: arduinomega_stack_wifi_release arduinomega_stack_wifi_debug - -arduinomega_stack_wifi_release: - @echo "=====BUILD C STACK FOR ARDUINO ATMEGA 2560 - RELEASE - WiFi SHIELD======" - @echo "=====BUILD LIBCOAP - RELEASE - /csdk/libcoap/arduinomega/wifi_shield/release/=====" - $(MAKE) -C csdk/libcoap "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - @echo "=====BUILD TB STACK - RELEASE - /csdk/arduinomega/wifi_shield/release/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - -arduinomega_stack_wifi_debug: - @echo "=====BUILD C STACK FOR ARDUINO ATMEGA 2560 - DEBUG - WiFi SHIELD======" - @echo "=====BUILD LIBCOAP - DEBUG - /csdk/libcoap/arduinomega/wifi_shield/debug/=====" - $(MAKE) -C csdk/libcoap "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - @echo "=====BUILD TB STACK - DEBUG - /csdk/arduinomega/wifi_shield/debug/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - -############################################################################### -#### TB Examples - Arduino Mega Only - Ethernet Only #### -############################################################################### - -arduinomega_samples_ethernet: arduinomega_samples_ethernet_release - -arduinomega_samples_ethernet_all: arduinomega_samples_ethernet_release arduinomega_samples_ethernet_debug - -arduinomega_samples_ethernet_release: arduinomega_stack_ethernet_release - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO ATMEGA 2560 - RELEASE - ETHERNET SHIELD=====" - @echo "=====BUILD OCSERVER - RELEASE - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinomega/ethernet_shield/release/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - -arduinomega_samples_ethernet_debug: arduinomega_stack_ethernet_debug - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO ATMEGA 2560 - DEBUG - ETHERNET SHIELD=====" - @echo "=====BUILD OCSERVER - DEBUG - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinomega/ethernet_shield/debug/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=0" - -############################################################################### -#### TB Examples - Arduino Mega Only - WiFi Only #### -############################################################################### - -arduinomega_samples_wifi: arduinomega_samples_wifi_release - -arduinomega_samples_wifi_all: arduinomega_samples_wifi_release arduinomega_samples_wifi_debug - -arduinomega_samples_wifi_release: arduinomega_stack_wifi_release - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO ATMEGA 2560 - RELEASE - WIFI SHIELD=====" - @echo "=====BUILD OCSERVER - RELEASE - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinomega/wifi_shield/release/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=release" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - -arduinomega_samples_wifi_debug: arduinomega_stack_wifi_debug - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO ATMEGA 2560 - DEBUG - WIFI SHIELD=====" - @echo "=====BUILD OCSERVER - DEBUG - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinomega/wifi_shield/debug/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=debug" "PLATFORM=arduinomega" "ARDUINOWIFI=1" - - -############################################################################### -#TB Stack, TB Unit Tests, & TB Examples - Arduino Due Only - Ethernet & WiFi ## -############################################################################### - -arduinodue: arduinodue_release - -arduinodue_all: arduinodue_release arduinodue_debug - -arduinodue_all_dev: arduinodue_release_dev arduinodue_debug_dev - -arduinodue_release: arduinodue_ethernet_release - -arduinodue_debug: arduinodue_ethernet_debug - -arduinodue_release_dev: arduinodue_ethernet_release arduinodue_wifi_release - -arduinodue_debug_dev: arduinodue_ethernet_debug arduinodue_wifi_debug - -############################################################################### -## TB Stack, TB Unit Tests, & TB Examples - Arduino Due Only - Ethernet Only ## -############################################################################### - -arduinodue_ethernet: arduinodue_ethernet_release - -arduinodue_ethernet_all: arduinodue_ethernet_release arduinodue_ethernet_debug - -arduinodue_ethernet_release: arduinodue_stack_ethernet_release arduinodue_samples_ethernet_release - -arduinodue_ethernet_debug: arduinodue_stack_ethernet_debug arduinodue_samples_ethernet_debug - -############################################################################### -## TB Stack, TB Unit Tests, & TB Examples - Arduino Due Only - Ethernet Only ## -############################################################################### - -arduinodue_wifi: arduinodue_wifi_release - -arduinodue_wifi_all: arduinodue_wifi_release arduinodue_wifi_debug - -arduinodue_wifi_release: arduinodue_stack_wifi_release arduinodue_samples_wifi_release - -arduinodue_wifi_debug: arduinodue_stack_wifi_debug arduinodue_samples_wifi_debug - -############################################################################### -#### TB Stack - Arduino Due Only - Ethernet Only #### -############################################################################### - -arduinodue_stack_ethernet: arduinodue_stack_ethernet_release - -arduinodue_stack_ethernet_all: arduinodue_stack_ethernet_release arduinodue_stack_ethernet_debug - -arduinodue_stack_ethernet_release: - @echo "=====BUILD C STACK FOR ARDUINO DUE - RELEASE - ETHERNET SHIELD======" - @echo "=====BUILD LIBCOAP - RELEASE - /csdk/libcoap/arduinodue/ethernet_shield/release/=====" - $(MAKE) -C csdk/libcoap "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - @echo "=====BUILD TB STACK - RELEASE - /csdk/arduinodue/ethernet_shield/release/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - -arduinodue_stack_ethernet_debug: - @echo "=====BUILD C STACK FOR ARDUINO DUE - DEBUG - ETHERNET SHIELD======" - @echo "=====BUILD LIBCOAP - DEBUG - /csdk/libcoap/arduinodue/ethernet_shield/debug/=====" - $(MAKE) -C csdk/libcoap "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - @echo "=====BUILD TB STACK - DEBUG - /csdk/arduinodue/ethernet_shield/debug/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - -############################################################################### -#### TB Stack - Arduino Due Only - WiFi Only #### -############################################################################### - -arduinodue_stack_wifi: arduinodue_stack_wifi_release - -arduinodue_stack_wifi_all: arduinodue_stack_wifi_release arduinodue_stack_wifi_debug - -arduinodue_stack_wifi_release: - @echo "=====BUILD C STACK FOR ARDUINO DUE - RELEASE - WiFi SHIELD======" - @echo "=====BUILD LIBCOAP - RELEASE - /csdk/libcoap/arduinodue/wifi_shield/release/=====" - $(MAKE) -C csdk/libcoap "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - @echo "=====BUILD TB STACK - RELEASE - /csdk/arduinodue/wifi_shield/release/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - -arduinodue_stack_wifi_debug: - @echo "=====BUILD C STACK FOR ARDUINO DUE - DEBUG - WiFi SHIELD======" - @echo "=====BUILD LIBCOAP - DEBUG - /csdk/libcoap/arduinodue/wifi_shield/debug/=====" - $(MAKE) -C csdk/libcoap "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - @echo "=====BUILD TB STACK - DEBUG - /csdk/arduinodue/wifi_shield/debug/=====" - $(MAKE) -C csdk "buildScript_all" "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - -############################################################################### -#### TB Examples - Arduino Due Only - Ethernet Only #### -############################################################################### - -arduinodue_samples_ethernet: arduinodue_samples_ethernet_release - -arduinodue_samples_ethernet_all: arduinodue_samples_ethernet_release arduinodue_samples_ethernet_debug - -arduinodue_samples_ethernet_release: arduinodue_stack_ethernet_release - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO DUE - RELEASE - ETHERNET SHIELD=====" - @echo "=====BUILD OCSERVER - RELEASE - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinodue/ethernet_shield/release/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - -arduinodue_samples_ethernet_debug: arduinodue_stack_ethernet_debug - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO DUE - DEBUG - ETHERNET SHIELD=====" - @echo "=====BUILD OCSERVER - DEBUG - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinodue/ethernet_shield/debug/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=0" - -############################################################################### -#### TB Examples - Arduino Due Only - WiFi Only #### -############################################################################### - -arduinodue_samples_wifi: arduinodue_samples_wifi_release - -arduinodue_samples_wifi_all: arduinodue_samples_wifi_release arduinodue_samples_wifi_debug - -arduinodue_samples_wifi_release: arduinodue_stack_wifi_release - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO DUE - RELEASE - WIFI SHIELD=====" - @echo "=====BUILD OCSERVER - RELEASE - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinodue/wifi_shield/release/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=release" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - -arduinodue_samples_wifi_debug: arduinodue_stack_wifi_debug - @echo "=====BUILD TB SAMPLE APPS FOR ARDUINO DUE - DEBUG - WIFI SHIELD=====" - @echo "=====BUILD OCSERVER - DEBUG - /csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinodue/wifi_shield/debug/=====" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "BUILD=debug" "PLATFORM=arduinodue" "ARDUINOWIFI=1" - -############################################################################### -#### Clean All - Linux Only - Ethernet Only #### -############################################################################### - -linux_clean: - -rm -rf -C csdk/libcoap/linux - -rm -rf -C csdk/linux - $(MAKE) -C csdk/stack/test/linux "clean" - $(MAKE) -C csdk/stack/samples/linux/SimpleClientServer "clean" - $(MAKE) -C csdk/stack/samples/linux/secure "clean" - $(MAKE) -C . "clean" - -############################################################################### -#### Clean All - Arduino Mega Only - Ethernet & WiFi #### -############################################################################### - -arduinomega_clean: - -rm -rf csdk/libcoap/arduinomega - -rm -rf csdk/arduinomega - -rm -rf csdk/stack/test/arduino/arduinomega - -rm -rf csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinomega - -############################################################################### -#### Clean All - Arduino Due Only - Ethernet & WiFi #### -############################################################################### - -arduinodue_clean: - -rm -rf csdk/libcoap/arduinodue - -rm -rf csdk/arduinodue - -rm -rf csdk/stack/test/arduino/arduinodue - -rm -rf csdk/stack/samples/arduino/SimpleClientServer/ocserver/arduinodue - - -############################################################################### -#### Clean All - Linux, Arduino Mega & Arduino Due - Ethernet & WiFi #### -############################################################################### -clean: - $(MAKE) -C csdk "clean" "deepclean" - $(MAKE) -C csdk/stack/test/linux "clean" - $(MAKE) -C csdk/stack/samples/linux/SimpleClientServer "clean" - $(MAKE) -C csdk/stack/samples/linux/secure "clean" - $(MAKE) -C csdk/stack/samples/arduino/SimpleClientServer/ocserver "clean" - $(MAKE) -C . "clean" - $(MAKE) -C unittests/ "clean" - $(MAKE) -C examples/ "clean" - $(MAKE) -C oc_logger/ "clean" - -############################################################################### -### You must specify arduinomega or arduinodue when using an arduino target.### -############################################################################### -arduino: - $(error "You must specify "arduinomega" or "arduinodue" when trying to\ - build arduino targets.") diff --git a/resource/csdk/README b/resource/csdk/README deleted file mode 100644 index fb92438..0000000 --- a/resource/csdk/README +++ /dev/null @@ -1,62 +0,0 @@ -------------------------------------------------------------------------------- - NOTICE - Transition to SCONS -------------------------------------------------------------------------------- - -The IoTivity build system is transitioning to SCONS. Although the -makefiles are still available (until v1.0) and some developers are -still using them, they are currently no longer supported. To learn more -about building using SCONS see Readme.scons.txt in the repository root -directory. The build steps used in continuous integration can be found -in auto_build.sh which is also in the the repository root directory. - -------------------------------------------------------------------------------- -**Linux** -------------------------------------------------------------------------------- -To make octbstack.a in release mode: - - make - -To make octbstack.a in debug mode: - - make BUILD=debug - -------------------------------------------------------------------------------- -**Arduino** -------------------------------------------------------------------------------- -Touch (i.e. create) file named "local.properties" at this directory level with -the following definition(s): - - ARDUINO_DIR = /arduino-1.0.5 - ARDUINO_TOOLS_DIR = (location of avr-g++ and other avr tools) - -To make octbstack.a in release mode: - make PLATFORM=arduinomega (For Arduino Due, use ) - -To make octbstack.a in debug mode: - make PLATFORM=arduinomega BUILD=debug (For Arduino Due, use ) - -To make octbstack.a with Arduino WiFi Shield support: - make PLATFORM=arduinomega ARDUINOWIFI=1 (For Arduino Due, use ) - -Dependencies: - 1) Patch the Wiznet Ethernet library with the patch available at : - oic-utilities/tb/arduino_linux_ethernet_socket_cpp.patch - 2) Arduino builds are dependent on latest Time library. Download it from here: - http://www.pjrc.com/teensy/td_libs_Time.html - 3) Arduino Due has been tested with Arduino 1.5.7 framework. - 4) For Arduino Due, binary tools are located in: - /hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin - 5) For Arduino WiFi, update the WiFi shield with the firmware patches provided - by Intel. -------------------------------------------------------------------------------- -**Clean-Up** -------------------------------------------------------------------------------- -To clean only stack modules: - - make clean - -To clean stack modules and libcoap (i.e. networking) modules & its -dependencies: - - make deepclean - diff --git a/resource/csdk/SConscript b/resource/csdk/SConscript index 65d02a1..63e6462 100644 --- a/resource/csdk/SConscript +++ b/resource/csdk/SConscript @@ -1,7 +1,26 @@ +#****************************************************************** +# +# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +# +# 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. +# +#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ## # liboctbstack (share library) build script ## - Import('env') lib_env = env.Clone() @@ -21,15 +40,18 @@ if target_os == 'arduino': ###################################################################### liboctbstack_env.PrependUnique(CPPPATH = [ '../../extlibs/cjson/', - 'ocsocket/include', + '../../extlibs/timer/', 'logger/include', 'ocrandom/include', 'ocmalloc/include', - 'libcoap', - 'occoap/include', 'stack/include', 'stack/include/internal', - '../oc_logger/include' + '../oc_logger/include', + 'connectivity/lib/libcoap-4.1.1', + 'connectivity/inc', + 'connectivity/api', + 'security/include', + 'security/include/internal', ]) if target_os not in ['arduino', 'windows', 'winrt']: @@ -39,21 +61,33 @@ if target_os not in ['arduino', 'windows', 'winrt']: if target_os not in ['windows', 'winrt']: liboctbstack_env.AppendUnique(CFLAGS = ['-Wall']) -if target_os == 'android': - liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) - liboctbstack_env.AppendUnique(LIBS = ['coap', 'm']) +liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) + +if target_os in ['android', 'linux', 'tizen']: + liboctbstack_env.AppendUnique(LIBS = ['connectivity_abstraction']) +liboctbstack_env.AppendUnique(LIBS = ['coap', 'm']) + +if target_os == 'tizen': + liboctbstack_env.ParseConfig("pkg-config --cflags --libs uuid") + +if target_os not in ['android', 'arduino', 'windows', 'winrt']: + liboctbstack_env.AppendUnique(LIBS = ['pthread']) if target_os == 'arduino': liboctbstack_env.AppendUnique(CPPDEFINES = ['NDEBUG', 'WITH_ARDUINO']) -else: +elif target_os not in ['darwin','ios']: liboctbstack_env.AppendUnique(CFLAGS = ['-fPIC']) - if target_os in ['darwin', 'ios']: + env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE']) liboctbstack_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE']) liboctbstack_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) - liboctbstack_env.AppendUnique(LIBS = ['coap']) +if target_os not in ['arduino']: + liboctbstack_env.AppendUnique(LINKFLAGS = ['-Wl,--no-undefined']) + +if env.get('SECURED') == '1': + liboctbstack_env.AppendUnique(LIBS = ['tinydtls']) -if not env.get('RELEASE'): +if env.get('LOGGING'): liboctbstack_env.AppendUnique(CPPDEFINES = ['TB_LOG']) ###################################################################### @@ -62,18 +96,20 @@ if not env.get('RELEASE'): OCTBSTACK_SRC = 'stack/src/' liboctbstack_src = [ '../../extlibs/cjson/cJSON.c', - 'occoap/src/occoap.c', - 'occoap/src/occoaphelper.c', + '../../extlibs/timer/timer.c', OCTBSTACK_SRC + 'ocstack.c', OCTBSTACK_SRC + 'occlientcb.c', OCTBSTACK_SRC + 'ocresource.c', OCTBSTACK_SRC + 'ocobserve.c', - OCTBSTACK_SRC + 'ocserverrequest.c', + OCTBSTACK_SRC + 'ocserverrequest.c', OCTBSTACK_SRC + 'occollection.c', - OCTBSTACK_SRC + 'ocsecurity.c', - OCTBSTACK_SRC + 'oicgroup.c' + OCTBSTACK_SRC + 'oicgroup.c', + 'security/src/ocsecurity.c', + 'logger/src/logger.c', + 'ocrandom/src/ocrandom.c', + 'ocmalloc/src/ocmalloc.c' ] -if target_os == 'arduino': +if target_os in ['arduino','darwin','ios'] : static_liboctbstack = liboctbstack_env.StaticLibrary('octbstack', liboctbstack_src) liboctbstack_env.InstallTarget(static_liboctbstack, 'liboctbstack') else: @@ -81,4 +117,3 @@ else: shared_liboctbstack = liboctbstack_env.SharedLibrary('octbstack', liboctbstack_src) liboctbstack_env.InstallTarget([static_liboctbstack, shared_liboctbstack], 'liboctbstack') - diff --git a/resource/csdk/arduinomega.properties b/resource/csdk/arduinomega.properties index 2b76cee..58b46e8 100644 --- a/resource/csdk/arduinomega.properties +++ b/resource/csdk/arduinomega.properties @@ -1,22 +1,22 @@ #Source directories -SDIR_ARD_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino -SDIR_ARD_SPI = $(ARDUINO_DIR)/libraries/SPI -SDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet -SDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/utility -SDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi -SDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/utility +SDIR_ARD_CORE = $(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +SDIR_ARD_SPI = $(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI +SDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet/src +SDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/src/utility +SDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi/src +SDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/src/utility SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time/Time SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE):$(SDIR_ARD_SPI):$(SDIR_ARD_TIME) #include directories -INCD_ARD_CORE = -I$(ARDUINO_DIR)/hardware/arduino/cores/arduino -INCD_ARD_VARIANT = -I$(ARDUINO_DIR)/hardware/arduino/variants/mega -INCD_ARD_SPI = -I$(ARDUINO_DIR)/libraries/SPI -INCD_ARD_ETH = -I$(ARDUINO_DIR)/libraries/Ethernet -INCD_ARD_ETH_UTIL = -I$(ARDUINO_DIR)/libraries/Ethernet/utility -INCD_ARD_WIFI = -I$(ARDUINO_DIR)/libraries/WiFi -INCD_ARD_WIFI_UTIL = -I$(ARDUINO_DIR)/libraries/WiFi/utility +INCD_ARD_CORE = -I$(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +INCD_ARD_VARIANT = -I$(ARDUINO_DIR)/hardware/arduino/avr/variants/mega +INCD_ARD_SPI = -I$(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI +INCD_ARD_ETH = -I$(ARDUINO_DIR)/libraries/Ethernet/src +INCD_ARD_ETH_UTIL = -I$(ARDUINO_DIR)/libraries/Ethernet/src/utility +INCD_ARD_WIFI = -I$(ARDUINO_DIR)/libraries/WiFi/src +INCD_ARD_WIFI_UTIL = -I$(ARDUINO_DIR)/libraries/WiFi/src/utility INCD_ARD_TIME = -I$(ARDUINO_DIR)/libraries/Time/Time INC_DIR_PLATFORM = $(INCD_ARD_CORE) $(INCD_ARD_VARIANT) $(INCD_ARD_SPI) $(INCD_ARD_TIME) @@ -31,11 +31,12 @@ CC=$(ARDUINO_TOOLS_DIR)/avr-gcc AR=$(ARDUINO_TOOLS_DIR)/avr-ar RANLIB=$(ARDUINO_TOOLS_DIR)/avr-ranlib AVR_OBJCOPY=$(ARDUINO_TOOLS_DIR)/avr-objcopy -AVR_PROGRAMMER=$(ARDUINO_TOOLS_DIR)/../../avrdude +AVR_PROGRAMMER=$(ARDUINO_TOOLS_DIR)/avrdude #Needed object files -CORE_COBJ = WInterrupts.o wiring.o wiring_digital.o -CORE_CPPOBJ = main.o Stream.o WMath.o WString.o HardwareSerial.o Print.o SPI.o IPAddress.o +CORE_COBJ = hooks.o WInterrupts.o wiring.o wiring_digital.o wiring_analog.o wiring_shift.o wiring_pulse.o +CORE_CPPOBJ = CDC.o HardwareSerial.o HardwareSerial0.o HardwareSerial1.o HardwareSerial2.o HardwareSerial3.o IPAddress.o HID.o \ + main.o new.o Print.o Stream.o Tone.o USBCore.o WMath.o WString.o SPI.o ETH_CPPOBJ = Dhcp.o Dns.o Ethernet.o EthernetUdp.o ETH_UTIL_CPPOBJ = socket.o w5100.o WIFI_COBJ = WiFi.o WiFiClient.o WiFiServer.o WiFiUdp.o server_drv.o spi_drv.o wifi_drv.o diff --git a/resource/csdk/connectivity/RELEASE v0.1 b/resource/csdk/connectivity/RELEASE v0.1 deleted file mode 100644 index c1f3f27..0000000 --- a/resource/csdk/connectivity/RELEASE v0.1 +++ /dev/null @@ -1,69 +0,0 @@ -Project Name: IoTivity -Release Version No. / Label Name: CA_v0.1 -API Version: CA_v0.4 - -Release Description: -Connectivity Abstraction provides a unified approach to send different OIC messages across multiple transports. - -Scope of Release: -1. Supported APIs ( please check below APIs) -2. Samples to test Supported APIs. -3. OIC Coding guidelines followed based on the current CSDK source. -4. Multi-Threaded Connectivity abstraction -5. Executed Open Source Verification and Prevent analysis. - -The following Connectivity Abstraction API features are supported in this release: - -Supported APIs -CAInitialize() -CATerminate() -CAStartListeningServer() -CAStartDiscoveryServer() -CARegisterHandler() -CAhandleRequestResponse() -FindResource() -SendRequest() -SendResponse() -SelectNetwork() -UnselectNetwork() - -Non Supported APIs -SendNotification() -AdvertizeResource() -CAGenerateToken() -CADestryToken() -CAGetNetworkInfo() - -Type of Release: Source, -Platform OS: Ubuntu 12.0.4 and above: - -Connectivity: WIFI only -Preconditions: -1)gcc 4.6.3 and above. -2)glib library (sudo apt-get install libglib2.0-dev) -3)libcoap.a library ( do make @lib/libcoap-4.1.1) - -Known and Open Issues: -1) OIC Log, OIC malloc will be removed once name changes applied to OIC Bases code -2) Support only WIFI Interface. -3) URI length is 16 characters. - -Nature of Release: Partial - -How to Build: -Follow below steps to execute CA Client / server in different systems -Step 1: Build Libcoap library -Make File Location @connectivity\lib\libcoap-4.1.1 -Step 2: Build CA library -Make File Location @connectivity\build\linux -Step 3: Samples -Make File Location @connectivity\samples\linux - -NOTE: sample.sh script can be used @connectivity\samples\linux for 3 steps together - -Execution: -linux$ export LD_LIBRARY_PATH=../../build/out/ -linux$ ./out/sample_main - -Client Option : d, f, h Client -Server Option : s, h diff --git a/resource/csdk/connectivity/RELEASE v0.7 b/resource/csdk/connectivity/RELEASE v0.7 new file mode 100644 index 0000000..d3669a2 --- /dev/null +++ b/resource/csdk/connectivity/RELEASE v0.7 @@ -0,0 +1,97 @@ +Project Name: IoTivity +Release Version No: CA_v0.7 +API Version: CA_v0.8 + +Release Description: +Connectivity Abstraction provides a unified approach to send different OIC messages across multiple transports. + +Supported Platform OS: +1) Ubuntu 12.0.4 and above: + Connectivity : WIFI, ETHERNET + Security : DTLS for WIFI +2) Tizen 2.3 + Connectivity : WIFI, EDR, BLE(1:1). +3) Arduino Mega + Connectivity : WIFI, ETH,BLE +4) Android 5.0s + Connectivity : WIFI, BLE + +Preconditions: +1)gcc 4.6.3 and above. +2)glib library (sudo apt-get install libglib2.0-dev) for linux, tizen and android devices +3)libcoap.a library ( do make @lib/libcoap-4.1.1) +4)tinyDTLS library for DTLS enabled applications( enable DTLS = 1 in makefile @connectivity\build/linux) +5)Ethernet, BLE, TimedActions, Timer libraries for arduino support. +6)scons for scons script compilation. + +Scope of Release: +1. Supported APIs ( please check below APIs) +2. Samples to test for Supported APIs. +3. OIC Coding guidelines followed based on the current CSDK source. +4. Multi-Threaded, Single threaded Connectivity abstraction. +5. Executed Open Source Verification and Prevent analysis. +Type of Release: Source +The following Connectivity Abstraction API features are supported in this release: + +Supported APIs +CAInitialize() +CATerminate() +CAStartListeningServer() +CAStartDiscoveryServer() +CARegisterHandler() +CAhandleRequestResponse() +FindResource() +SendRequest() +SendResponse() +SelectNetwork() +UnselectNetwork() +SendNotification() +AdvertizeResource() +CAGenerateToken() +CADestryToken() +CAGetNetworkInfo() + + +Known and Open Issues: +1) OIC Log, OIC Malloc will be removed once name changes applied to OIC Bases code. +2) Tizen platform BLE stack is not stable. So we may see random crashes. + +How to Build for Linux: +Follow below steps to execute CA Client / server in different systems +Step 1: Build Libcoap library +Make File Location @connectivity\lib\libcoap-4.1.1 +Step 2: Build CA library +Make File Location @connectivity\build\linux +Step 3: Samples +Make File Location @connectivity\samples\linux + +Execution: +linux$ export LD_LIBRARY_PATH=../../build/out/ +linux$ ./out/sample_main + + +Follow below sequence to test + +Client Option: c +Server Option: s + +Client Option: f (provide a/light) +Server Option: h (will pick from queue and send response) +Client Option: h (to pick server response) + +Client Option: r (provide “ServerIP:5383/a/request”) +Server Option: h (will pick from queue and send response) +Client Option: h (to pick server response) + +Server Option: a +Client Option: h (to pick server response) + +Server Option: b (provide ServerIP:5383/a/notify) +Client Option: h (to pick server response) + +Client: Server side: n for network selection (WIFI enabled by default) + + +How to Build for Linux/DTLS: +./sample.sh WITH_DTLS @@connectivity\samples\linux + diff --git a/resource/csdk/connectivity/SConscript b/resource/csdk/connectivity/SConscript new file mode 100644 index 0000000..acfbac7 --- /dev/null +++ b/resource/csdk/connectivity/SConscript @@ -0,0 +1,65 @@ +## +# CA build script +## + +Import('env') + +target_os = env.get('TARGET_OS') +transport = env.get('TARGET_TRANSPORT') +build_sample = env.get('BUILD_SAMPLE') + +print "Given Transport is %s" % transport +print "Given OS is %s" % target_os +print "BUILD_SAMPLE is %s" % build_sample + +targets_disallow_multitransport = ['arduino'] + +if target_os in targets_disallow_multitransport: + if ('ALL' in transport) or (len(transport) != 1): + print "*** Error invalid option values: TARGET_TRANSPORT" + print "%s disallowed until testing can validate use of multiple transports on %s %d" % (transport, target_os, len(transport)) + Exit(1) + +if 'ALL' in transport: + if target_os == 'linux': + env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER']) + elif target_os == 'tizen': + env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER']) + elif target_os == 'darwin': + env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','NO_EDR_ADAPTER','NO_LE_ADAPTER']) + else: + env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER']) + print "CA Transport is ALL" +else: + if 'BT' in transport: + if target_os == 'linux': + print "CA Transport BT is not supported in Linux" + Exit(1) + else: + env.AppendUnique(CPPDEFINES = ['EDR_ADAPTER']) + print "CA Transport is BT" + else: + env.AppendUnique(CPPDEFINES = ['NO_EDR_ADAPTER']) + + if 'BLE' in transport: + if target_os == 'linux': + print "CA Transport BLE is not supported in Linux" + Exit(1) + else: + env.AppendUnique(CPPDEFINES = ['LE_ADAPTER']) + print "CA Transport is BLE" + else: + env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER']) + + if 'IP' in transport: + env.AppendUnique(CPPDEFINES = ['IP_ADAPTER']) + print "CA Transport is IP" + else: + env.AppendUnique(CPPDEFINES = ['NO_IP_ADAPTER']) + +env.SConscript('./src/SConscript') + +if build_sample == 'ON': + if target_os in ['linux', 'arduino', 'android']: + env.SConscript('./samples/' + target_os + '/SConscript') + diff --git a/resource/csdk/connectivity/SConstruct b/resource/csdk/connectivity/SConstruct new file mode 100644 index 0000000..58d0fd9 --- /dev/null +++ b/resource/csdk/connectivity/SConstruct @@ -0,0 +1,62 @@ +## +# The main build script +# +## + +# Load common build config +# Load common build config +SConscript('./build/SConscript') + +Import('env') + +sample_env = env.Clone() + +target_os = env.get('TARGET_OS') +transport = env.get('TARGET_TRANSPORT') +secured = env.get('SECURED') +release_mode = env.get('RELEASE') +buildsample = env.get('BUILD_SAMPLE') + +print "Given Transport is %s" % transport +print "Given OS is %s" % target_os +print "Secured %s" % env.get('SECURED') +print "Build sample is set to %s" % buildsample + +build_dir = env.get('BUILD_DIR') + +if target_os == 'tizen': + command = "sh build/tizen/gbsbuild.sh %s %s %s" % (transport, buildsample, release_mode) + print "Created Command is %s" % command + gbs_script = env.Command('gbs_build', None, command) + AlwaysBuild ('gbs_script') +elif target_os == 'arduino': + SConscript('build/arduino/arduino.scons') + + # Build 'libcoap' library + SConscript(build_dir + 'lib/libcoap-4.1.1/SConscript') + + # Build 'src' sub-project + SConscript(build_dir + 'SConscript') + + # Build 'samples' sub-project + SConscript(build_dir + 'samples/arduino/SConscript') +elif target_os == 'linux': + + # Build 'libcoap' library + SConscript(build_dir + 'lib/libcoap-4.1.1/SConscript') + + # Build 'src' sub-project + SConscript(build_dir + 'SConscript') + + # Build 'samples' sub-project + env.SConscript(build_dir + 'samples/linux/SConscript') +elif target_os == 'android': + + # Build 'libcoap' library + SConscript(build_dir + 'lib/libcoap-4.1.1/SConscript') + + # Build 'src' sub-project + SConscript(build_dir + 'SConscript') + + # Build 'samples' sub-project + env.SConscript(build_dir + 'samples/android/SConscript') diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index 7e4cda1..1060410 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -22,11 +22,14 @@ * @file cacommon.h * @brief This file contains the common data structures between Resource , CA and adapters */ -#ifndef __CA_COMMON_H_ -#define __CA_COMMON_H_ + +#ifndef CA_COMMON_H_ +#define CA_COMMON_H_ #include #include +#include + #ifdef __cplusplus extern "C" @@ -34,232 +37,305 @@ extern "C" #endif /** - @brief IP Address Length + * @brief IP address Length */ #define CA_IPADDR_SIZE 16 /** - @brief Mac Address Length for BT + * @brief Mac address length for BT port */ #define CA_MACADDR_SIZE 18 /** - @brief Max Header Options data length + * @brief Max header options data length */ #define CA_MAX_HEADER_OPTION_DATA_LENGTH 16 /** - @brief CAPayload_t +* @brief Max token length +*/ +#define CA_MAX_TOKEN_LEN (8) + +/** + * @brief Max URI length + */ +#ifdef ARDUINO +#define CA_MAX_URI_LENGTH 128 /* maximum size of URI for embedded platforms*/ +#else +#define CA_MAX_URI_LENGTH 512 /* maximum size of URI for other platforms*/ +#endif + +/** + * @brief Max PDU length supported */ -typedef char* CAPayload_t; +#ifdef ARDUINO +#define COAP_MAX_PDU_SIZE 320 /* maximum size of a CoAP PDU for embedded platforms*/ +#else +#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU for big platforms*/ +#endif /** - @brief CAURI_t + * @brief option types - the highest option number 63 */ -typedef char* CAURI_t; +#define CA_OPTION_IF_MATCH 1 +#define CA_OPTION_ETAG 4 +#define CA_OPTION_IF_NONE_MATCH 5 +#define CA_OPTION_OBSERVE 6 +#define CA_OPTION_LOCATION_PATH 8 +#define CA_OPTION_URI_PATH 11 +#define CA_OPTION_CONTENT_FORMAT 12 +#define CA_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define CA_OPTION_MAXAGE 14 +#define CA_OPTION_URI_QUERY 15 +#define CA_OPTION_ACCEPT 17 +#define CA_OPTION_LOCATION_QUERY 20 /** - @brief CAToken_t + * @brief Payload information from resource model */ -typedef char* CAToken_t; +typedef char *CAPayload_t; /** - @brief CABool_t + * @brief URI for the OIC base.CA considers relative URI as the URI. */ -typedef enum -{ - CA_FALSE = 0, CA_TRUE -} CABool_t; +typedef char *CAURI_t; /** - @brief CAConnectivityType_t + * @brief Token information for mapping the request and responses by resource model + */ +typedef char *CAToken_t; + +/** + * @enum CATransportType_t + * @brief Different connectivities that are handled in Connectivity Abstraction */ typedef enum { - CA_ETHERNET = (1 << 0), CA_WIFI = (1 << 1), CA_EDR = (1 << 2), CA_LE = (1 << 3) -} CAConnectivityType_t; + CA_IPV4 = (1 << 0), /**< IPV4 Transport Type */ + CA_IPV6 = (1 << 1), /**< IPV6 Transport Type */ + CA_EDR = (1 << 2), /**< EDR Transport Type */ + CA_LE = (1 << 3) /**< LE Transport Type */ +} CATransportType_t; /** - @brief CANetworkStatus_t + * @enum CANetworkStatus_t + * @brief Information about the network status. */ typedef enum { - CA_INTERFACE_UP, CA_INTERFACE_DOWN + CA_INTERFACE_DOWN, /**< Connection is not available */ + CA_INTERFACE_UP /**< Connection is Available */ } CANetworkStatus_t; /** - @brief Address of the local or remote endpoint + * @brief Address of the local or remote endpoint */ typedef union { /** - @brief BT Information + * @brief BT Mac Information */ struct { - /** @brief Bluettoth Mac Address **/ - char btMacAddress[CA_MACADDR_SIZE]; + char btMacAddress[CA_MACADDR_SIZE]; /**< BT mac address **/ } BT; + /** - @brief IP Information + * @brief LE MAC Information */ struct { - /** Ip address of the interface**/ - char ipAddress[CA_IPADDR_SIZE]; - /** port information**/ - uint32_t port; + char leMacAddress[CA_MACADDR_SIZE]; /**< BLE mac address **/ + } LE; + + /** + * @brief IP Information + */ + struct + { + char ipAddress[CA_IPADDR_SIZE]; /**< Ip address of the interface**/ + uint16_t port; /**< port information**/ } IP; } CAAddress_t; /** - @brief CAQualityOfService + * @enum CAMessageType_t + * @brief Message Type for Base source code */ typedef enum { - CA_LOW_QOS = 0, CA_MEDIUM_QOS, CA_HIGH_QOS, CA_NA_QOS // No Quality is defined, let the stack decide -} CAQualityOfService_t; + CA_MSG_CONFIRM = 0, /**< confirmable message (requires ACK/RST) */ + CA_MSG_NONCONFIRM, /**< non-confirmable message (one-shot message) */ + CA_MSG_ACKNOWLEDGE, /**< used to acknowledge confirmable messages */ + CA_MSG_RESET /**< used to indicates not-interested or error (lack of context)in + received messages */ +} CAMessageType_t; /** - @brief CAMethod_t + * @enum CAMethod_t + * @brief Allowed method to be used by resource model */ typedef enum { - CA_GET = 1, CA_POST, CA_PUT, CA_DELETE + CA_GET = 1, /**< GET Method */ + CA_POST, /**< POST Method */ + CA_PUT, /**< PUT Method */ + CA_DELETE /**< DELETE Method */ } CAMethod_t; /** - @brief RemoteEndpoint information for connectivities + * @brief Remote endpoint information for connectivities */ typedef struct { - /** Resource URI information **/ - CAURI_t resourceUri; - /** Remote Endpoint address **/ - CAAddress_t addressInfo; - /** Connectivity of the endpoint**/ - CAConnectivityType_t connectivityType; + + CAURI_t resourceUri; /**< Resource URI information **/ + CAAddress_t addressInfo; /**< Remote Endpoint address **/ + CATransportType_t transportType; /**< Transport Type of the endpoint**/ + bool isSecured; /**< Secure connection**/ } CARemoteEndpoint_t; + +/** + * @brief Group endpoint information for connectivities + */ +typedef struct +{ + CAURI_t resourceUri; /**< Resource URI information **/ + CATransportType_t transportType; /**< Transport type of the endpoint**/ +} CAGroupEndpoint_t; + /** @brief Local Connectivity information */ typedef struct { - /** address of the interface **/ - CAAddress_t addressInfo; - /** Connectivity type that localconnectivity avaialble **/ - CAConnectivityType_t type; -} CALocalConnectivityt_t; + CAAddress_t addressInfo; /**< Address of the interface **/ + CATransportType_t type; /**< Transport type of local device **/ + bool isSecured; /**< Secure connection**/ +} CALocalConnectivity_t; /** - @brief Enums for CA return values + * @enum CAResult_t + * @brief Enums for CA return values */ typedef enum { - /* Success status code - START HERE */ - CA_STATUS_OK = 0, - CA_STATUS_INVALID_PARAM, - CA_DESTINATION_NOT_REACHABLE, - CA_SEND_FAILED, - CA_RECEVIE_FAILED, - CA_MEMORY_ALLOC_FAILED, - CA_REQUEST_TIMEOUT, - CA_DESTINATION_DISCONNECTED, - CA_STATUS_FAILED, - CA_NOT_SUPPORTED -/* Error status code - END HERE */ + // Result code - START HERE + CA_STATUS_OK = 0, /**< Success */ + CA_STATUS_INVALID_PARAM, /**< Invalid Parameter */ + CA_ADAPTER_NOT_ENABLED, /**< Adapter is not enabled */ + CA_SERVER_STARTED_ALREADY, /**< Server is started already */ + CA_SERVER_NOT_STARTED, /**< Server is not started*/ + CA_DESTINATION_NOT_REACHABLE, /**< Destination is not reachable */ + CA_SOCKET_OPERATION_FAILED, /**< Socket operation failed */ + CA_SEND_FAILED, /**< Send request failed */ + CA_RECEIVE_FAILED, /**< Receive failed */ + CA_MEMORY_ALLOC_FAILED, /**< Memory allocation failed */ + CA_REQUEST_TIMEOUT, /**< Request is Timeout */ + CA_DESTINATION_DISCONNECTED, /**< Destination is disconnected */ + CA_NOT_SUPPORTED, /**< Not supported */ + CA_STATUS_FAILED =255 /**< Failure */ + /* Result code - END HERE */ } CAResult_t; /** - @brief Enums for CA Response values + * @enum CAResponseResult_t + * @brief Enums for CA Response values */ typedef enum { - /* Success status code - START HERE */ - CA_CREATED = 201, - CA_DELETED = 202, - CA_VALID = 203, - CA_CONTENT = 205, - CA_BAD_REQ = 400, - CA_BAD_OPT = 402, - CA_NOT_FOUND = 404 -/* Error status code - END HERE */ + /* Response status code - START HERE */ + CA_EMPTY = 0, /**< Empty */ + CA_SUCCESS = 200, /**< Success */ + CA_CREATED = 201, /**< Created */ + CA_DELETED = 202, /**< Deleted */ + CA_BAD_REQ = 400, /**< Bad Request */ + CA_BAD_OPT = 402, /**< Bad Option */ + CA_NOT_FOUND = 404, /**< Not found */ + CA_INTERNAL_SERVER_ERROR = 500, /**< Internal Server Error */ + CA_RETRANSMIT_TIMEOUT = 504 /**< Retransmit timeout */ + /* Response status code - END HERE */ } CAResponseResult_t; /** - @brief Transport Protocol IDs + * @enum CATransportProtocolID_t + * @brief Transport Protocol IDs for additional options */ typedef enum { - CA_INVALID_ID = (1 << 0), CA_COAP_ID = (1 << 1) + CA_INVALID_ID = (1 << 0), /**< Invalid ID */ + CA_COAP_ID = (1 << 1) /**< COAP ID */ } CATransportProtocolID_t; /** + * @enum CAAdapterState_t + * @brief Adapter State to indicate the network changed notifications. + */ +typedef enum +{ + CA_ADAPTER_DISABLED, /**< Adapter is Disabled */ + CA_ADAPTER_ENABLED /**< Adapter is Enabled */ +} CAAdapterState_t; + +/** * @brief Header options structure to be filled * * This structure is used to hold header information. */ typedef struct { - /** The protocol ID this option applies to**/ - CATransportProtocolID_t protocolID; - /** The header option ID which will be added to communication packets**/ - uint16_t optionID; - /** its length 191**/ - uint16_t optionLength; - /** optional data values**/ - uint8_t optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH]; + CATransportProtocolID_t protocolID; /**< Protocol ID of the Option */ + uint16_t optionID; /**< The header option ID which will be + added to communication packets */ + uint16_t optionLength; /**< Option Length **/ + uint8_t optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH]; /**< Optional data values**/ } CAHeaderOption_t; /** - * @brief Request Information to be sent - * - * This structure is used to hold request information - */ - -/** * @brief Base Information received * * This structure is used to hold request & response base information */ typedef struct { - /**Qos for the request **/ - CAQualityOfService_t qos; - /** Token for CA**/ - CAToken_t token; - /** Header Options for the request **/ - CAHeaderOption_t * options; - /** Number of Header options**/ - uint8_t numOptions; - /** payload of the request **/ - CAPayload_t payload; + + CAMessageType_t type; /**< Qos for the request */ + uint16_t messageId; /**< Message id. + * if message id is zero, it will generated by CA inside. + * otherwise, you can use it */ + CAToken_t token; /**< Token for CA */ + uint8_t tokenLength; /**< token length*/ + CAHeaderOption_t *options; /** Header Options for the request */ + uint8_t numOptions; /**< Number of Header options */ + CAPayload_t payload; /**< payload of the request */ } CAInfo_t; +/** + * @brief Request Information to be sent + * + * This structure is used to hold request information + */ typedef struct { - /** Name of the Method Allowed **/ - CAMethod_t method; - /** Base Information **/ - CAInfo_t info; + CAMethod_t method; /**< Name of the Method Allowed */ + CAInfo_t info; /**< Information of the request. */ } CARequestInfo_t; /** - * @brief Response Information received + * @brief Response information received * * This structure is used to hold response information */ typedef struct { - /**Response Result by Resource Model**/ - CAResponseResult_t result; - /**Base Information **/ - CAInfo_t info; + CAResponseResult_t result; /**< Result for response by resource model */ + CAInfo_t info; /**< Information of the response */ } CAResponseInfo_t; #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef __CA_COMMON_H_ +#endif /* CA_COMMON_H_ */ + diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index 8619f92..7607bfc 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,18 +19,23 @@ ******************************************************************/ /** - * @file cainterface.h - * @brief This file contains the APIs for Resource Model to use + * @file + * + * This file contains the APIs for Resource Model to use. */ -#ifndef __CA_INTERFACE_H_ -#define __CA_INTERFACE_H_ +#ifndef CA_INTERFACE_H_ +#define CA_INTERFACE_H_ /** - * Connectivity Abstraction Interface Description APIs. + * Connectivity Abstraction Interface APIs. */ #include "cacommon.h" +#ifdef __WITH_DTLS__ +#include "ocsecurityconfig.h" +#endif + #ifdef __cplusplus extern "C" { @@ -38,165 +43,234 @@ extern "C" /** * @brief Callback function type for request delivery. - * requestInfo contains different parameters for resource model to understand about the request. - * @param object [OUT] Endpoint object from which the request is received. It contains endpoint - * address based on the connectivity type. - * @param requestInfo [OUT] Identifier which needs to be sent with request. + * @param object [OUT] Endpoint object from which the request is received. It contains + * endpoint address based on the connectivity type. + * @param requestInfo [OUT] Info for resource model to understand about the request. + * @return NONE */ -typedef void (*CARequestCallback)(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo); +typedef void (*CARequestCallback)(const CARemoteEndpoint_t *object, + const CARequestInfo_t *requestInfo); /** * @brief Callback function type for response delivery. - * responseInfor contains different parameters for resource model to understand about the request. - * @param object [OUT] Endpoint object from which the response is received. - * @param responseInfo [OUT] Identifier which needs to be mapped with response. + * @param object [OUT] Endpoint object from which the response is received. + * @param responseInfo [OUT] Identifier which needs to be mapped with response. + * @return NONE + */ +typedef void (*CAResponseCallback)(const CARemoteEndpoint_t *object, + const CAResponseInfo_t *responseInfo); + +#ifdef __WITH_DTLS__ + +/** + * Binary blob containing device identity and the credentials for all devices + * trusted by this device. */ -typedef void (*CAResponseCallback)(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); +typedef struct +{ + unsigned char identity[DTLS_PSK_ID_LEN]; /** identity of self */ + uint32_t num; /** number of credentials in this blob */ + OCDtlsPskCreds *creds; /** list of credentials. Size of this + array is determined by 'num' variable. */ +} CADtlsPskCredsBlob_t; + +/** + * @brief Callback function type for getting DTLS credentials. + * @param credInfo [OUT] DTLS credentials info. Handler has to allocate new memory for + * both credInfo and credInfo->creds which is then freed by CA + * @return NONE + */ +typedef void (*CAGetDTLSCredentialsHandler)(CADtlsPskCredsBlob_t **credInfo); +#endif //__WITH_DTLS__ /** * @brief Initialize the connectivity abstraction module. - * It will initialize adapters, thread pool and other modules based on the platform compilation options. + * It will initialize adapters, thread pool and other modules based on the platform + * compilation options. * - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED */ CAResult_t CAInitialize(); /** * @brief Terminate the connectivity abstraction module. * All threads, data structures are destroyed for next initializations. + * @return NONE */ void CATerminate(); /** * @brief Starts listening servers. * This API is used by resource hosting server for listening multicast requests. - * based on the adapters configurations , different kinds of servers are started. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * Based on the adapters configurations, different kinds of servers are started. + * @return #CA_STATUS_OK or #CA_STATUS_FAILED */ CAResult_t CAStartListeningServer(); /** * @brief Starts discovery servers. * This API is used by resource required clients for listening multicast requests. - * based on the adapters configurations , different kinds of servers are started. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * Based on the adapters configurations, different kinds of servers are started. + * @return #CA_STATUS_OK or #CA_STATUS_FAILED */ CAResult_t CAStartDiscoveryServer(); /** * @brief Register request callbacks and response callbacks. - * requests and responses are delivered these callbacks . - * @see CARequestCallback CAResponseCallback - * @param ReqHandler [IN] Request callback ( for GET,PUT ..etc) - * @param RespHandler [IN] Response Handler Callback - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * Requests and responses are delivered these callbacks . + * @param ReqHandler [IN] Request callback ( for GET,PUT ..etc) + * @param RespHandler [IN] Response Handler Callback + * @see CARequestCallback + * @see CAResponseCallback + * @return NONE */ -CAResult_t CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler); +void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHandler); + +#ifdef __WITH_DTLS__ +/** + * @brief Register callback to get DTLS PSK credentials. + * @param GetDTLSCredentials [IN] GetDTLS Credetials callback + * @return #CA_STATUS_OK + */ +CAResult_t CARegisterDTLSCredentialsHandler( + CAGetDTLSCredentialsHandler GetDTLSCredentials); +#endif //__WITH_DTLS__ /** * @brief Create a Remote endpoint if the URI is available already. - * for FindResource-> unicast requests , this API is used. - * FindResource(URI)-> CACreateRemoteEndpoint , CASendRequest(GET) - * @param uri [IN] Absolute URI of the resource to be used to generate the Remote endpoint - * for ex : coap://10.11.12.13:4545/resource_uri ( for IP) - * coap://10:11:12:13:45:45/resource_uri ( for BT) - * @param object [OUT ] Endpoint object which contains the above parsed data - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * This is a Helper function which can be used before calling + * CASendRequest / CASendNotification. + * @param uri [IN] Absolute URI of the resource to be used to generate the + * Remote endpoint + * \n For ex : coap://10.11.12.13:4545/resource_uri ( for IP) + * \n coap://10:11:12:13:45:45/resource_uri ( for BT) + * @param transportType [IN] Transport type of the endpoint + * @param object [OUT] Endpoint object which contains the above parsed data + * @return #CA_STATUS_OK or #CA_STATUS_FAILED + * @remark The created Remote endpoint can be freed using CADestroyRemoteEndpoint() API. + * @see CADestroyRemoteEndpoint */ -CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, CARemoteEndpoint_t** object); +CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, + const CATransportType_t transportType, + CARemoteEndpoint_t **object); /** - * @brief API Destroy the remote endpoint created - * @param object [IN] endpoint object created with CACreateRemoteEndpoint + * @brief Destroy the remote endpoint created + * @param object [IN] Remote Endpoint object created with CACreateRemoteEndpoint + * @return NONE */ -void CADestroyRemoteEndpoint(CARemoteEndpoint_t* object); +void CADestroyRemoteEndpoint(CARemoteEndpoint_t *object); /** - * @brief Generating the token for the requests/response. - * Token memory is created and destroyed by the calle. - * @param token [OUT] token for the request - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Generating the token for matching the request and response. + * @param token [OUT] Token for the request + * @param tokenLength [IN] length of the token + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED + * or #CA_STATUS_NOT_INITIALIZED + * @remark Token memory is destroyed by the caller using CADestroyToken(). + * @see CADestroyToken */ -CAResult_t CAGenerateToken(CAToken_t* token); +CAResult_t CAGenerateToken(CAToken_t *token, uint8_t tokenLength); /** * @brief Destroy the token generated by CAGenerateToken - * @param token [IN] token for the request + * @param token [IN] token to be freed + * @return NONE */ void CADestroyToken(CAToken_t token); /** - * @brief Find the resource in the network. This API internally sends multicast messages on the - * all connectivity adapters. Responses are delivered via response callbacks. + * @brief Find the resource in the network. This API internally sends multicast messages on all + * selected connectivity adapters. Responses are delivered via response callbacks. * - * @param resourceUri [IN] Uri to send multicast search request - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param resourceUri [IN] Uri to send multicast search request. Must contain only relative + * path of Uri to be search. + * @param token [IN] Token for the request + * @param tokenLength [IN] length of the token + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_STATUS_NOT_INITIALIZED */ -CAResult_t CAFindResource(const CAURI_t resourceUri); +CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token, uint8_t tokenLength); /** * @brief Send control Request on a resource - * @param object [IN] Remote Endpoint where the payload need to be sent. - * This Remote endpoint is delivered with Request or response callback. - * @param requestInfo [IN ] information for the request. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param object [IN] Remote Endpoint where the payload need to be sent. + * This Remote endpoint is delivered with Request or response callback. + * @param requestInfo [IN] Information for the request. + * @return #CA_STATUS_OK #CA_STATUS_FAILED #CA_MEMORY_ALLOC_FAILED */ -CAResult_t CASendRequest(const CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo); +CAResult_t CASendRequest(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo); /** - * @brief Sendi the response - * @param object [IN] Remote Endpoint where the payload need to be sent. - * This Remote endpoint is delivered with Request or response callback - * @param responseInfo [IN ] information for the response - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Send control Request on a resource to multicast group + * @param object [IN] Group Endpoint where the payload need to be sent. + * This Remote endpoint is delivered with Request or response callback. + * @param requestInfo [IN] Information for the request. + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED */ -CAResult_t CASendResponse(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); +CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object, + const CARequestInfo_t *requestInfo); + +/** + * @brief Send the response + * @param object [IN] Remote Endpoint where the payload need to be sent. + * This Remote endpoint is delivered with Request or response callback + * @param responseInfo [IN] Information for the response + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED + */ +CAResult_t CASendResponse(const CARemoteEndpoint_t *object, + const CAResponseInfo_t *responseInfo); /** * @brief Send notification to the remote object - * @param object [IN] Remote Endpoint where the payload need to be sent. - * This Remote endpoint is delivered with Request or response callback. - * @param responseInfo [IN ] information for the response. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param object [IN] Remote Endpoint where the payload need to be sent. + * This Remote endpoint is delivered with Request or response callback. + * @param responseInfo [IN] Information for the response. + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_MEMORY_ALLOC_FAILED */ -CAResult_t CASendNotification(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); +CAResult_t CASendNotification(const CARemoteEndpoint_t *object, + const CAResponseInfo_t *responseInfo); /** - * @brief for advertise the resource - * @param resourceUri [IN] URI to be advertised - * @param options [IN] header options information - * @param numOptions [IN] number of options - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief To advertise the resource + * @param resourceUri [IN] URI to be advertised + * @param token [IN] Token for the request + * @param tokenLength [IN] length of the token + * @param options [IN] Header options information + * @param numOptions [IN] Number of options + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or + * #CA_MEMORY_ALLOC_FAILED or #CA_STATUS_NOT_INITIALIZED */ -CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAHeaderOption_t* options, - uint8_t numOptions); +CAResult_t CAAdvertiseResource(const CAURI_t resourceUri,const CAToken_t token, + uint8_t tokenLength, const CAHeaderOption_t *options, + const uint8_t numOptions); /** * @brief Select network to use - * @param interestedNetwork [IN] Connectivity Type enum - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param interestedNetwork [IN] Connectivity Type enum + * @return #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED or #CA_NOT_SUPPORTED */ CAResult_t CASelectNetwork(const uint32_t interestedNetwork); /** * @brief Select network to unuse - * @param nonInterestedNetwork [IN] Connectivity Type enum - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @param nonInterestedNetwork [IN] Connectivity Type enum + * @return #CA_STATUS_OK or #CA_NOT_SUPPORTED or #CA_STATUS_FAILED */ CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork); /** * @brief Get network information - * It should be destroyed by the caller as its Get Information. - * @param info [OUT] LocalConnectivity objects - * @param size [OUT] No Of Array objects - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * It should be destroyed by the caller as it Get Information. + * @param info [OUT] LocalConnectivity objects + * @param size [OUT] No Of Array objects + * @return #CA_STATUS_OK or #CA_STATUS_FAILED or #CA_STATUS_INVALID_PARAM or +* #CA_MEMORY_ALLOC_FAILED */ -CAResult_t CAGetNetworkInformation(CALocalConnectivityt_t **info, uint32_t* size); +CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size); /** - * @brief for usage of singled threaded application. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief To Handle the Request or Response + * @return #CA_STATUS_OK */ CAResult_t CAHandleRequestResponse(); @@ -204,4 +278,5 @@ CAResult_t CAHandleRequestResponse(); } /* extern "C" */ #endif -#endif +#endif /* CA_INTERFACE_H_ */ + diff --git a/resource/csdk/connectivity/build/How_To_Build.txt b/resource/csdk/connectivity/build/How_To_Build.txt new file mode 100644 index 0000000..2725deb --- /dev/null +++ b/resource/csdk/connectivity/build/How_To_Build.txt @@ -0,0 +1,125 @@ +=== Prerequisites === + +* 1. Scons + +Please refer to the following page to install scons: + http://www.scons.org/doc/production/HTML/scons-user.html#chap-build-install +(Note: on Windows, install Python 2.x before installing scons) + +* 2. IDE/SDK Pre-requites +To build for some OS (Android / Arduino / IOS ...), an IDE/SDK may be required, +please go to the relative page to download and install the required IDE/SDK. + +Note: Connectivity module building has been changed. We have to build connectivity + from the iotivity root folder. + +Linux Build: + +1) Go to "iotivity/" folder. + +2) Execute following command(s) to start build based on transport selection required : + + -> Building for all transports : + $ scons resource/csdk/connectivity/samples/linux/ TARGET_OS=linux TARGET_TRANSPORT=ALL + + -> Building for a specific transport : + $ scons resource/csdk/connectivity/samples/linux/ TARGET_OS=linux TARGET_TRANSPORT=IP + + -> Building for multiple transports : + $ scons resource/csdk/connectivity/samples/linux/ TARGET_OS=linux TARGET_TRANSPORT=IP,BT + + -> Clean Build (all transports) : + scons resource/csdk/connectivity/samples/linux/ TARGET_OS=linux TARGET_TRANSPORT=ALL -c (for clean) + + +3) The above command will build sample also. + + For Enabling Secured server, + * Note: tinydtls library has to copied to "connectivity/lib/tinydtls" for secured build. + + Secured Server will be only used for IP transports. + + Give command "scons resource/csdk/connectivity/samples/linux/ TARGET_OS=linux TARGET_TRANSPORT=IP SECURED=1 + +Android Build: + +1) Go to "iotivity/" folder. + +2) Execute following command(s) to start build based on transport selection required : + + -> Building for all transports : + $ scons resource/csdk/connectivity/samples/android/ TARGET_OS=android TARGET_TRANSPORT=ALL TARGET_ARCH=x86 ANDROID_NDK=your_ndk_path + + -> Building for a specific transport : + $ scons resource/csdk/connectivity/samples/android/ TARGET_OS=android TARGET_TRANSPORT=IP TARGET_ARCH=x86 ANDROID_NDK=your_ndk_path + + -> Building for multiple transports : + $ scons resource/csdk/connectivity/samples/android/ TARGET_OS=android TARGET_TRANSPORT=IP,BT TARGET_ARCH=x86 ANDROID_NDK=your_ndk_path + +Note :- Upon successful execution of above command(s) CA library will be generated at path + "iotivity/out/android/TARGET_ARCH/release or debug". + +Tizen Build: + +1) If you are building first time, then delete GBS-ROOT folder from home directory. + +2) Go to "iotivity/" folder. + +3) Execute following command(s) to start build based on transport selection required : + + -> Building for all transports : + $ scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=ALL + + -> Building for a specific transport : + $ scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP + + -> Building for multiple transports : + $ scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=IP,BT,BLE + +4) By default, above command will build sample also. + To disable building sample, add BUILD_SAMPLE=OFF to the build command. + Ex: scons -f resource/csdk/connectivity/build/tizen/SConscript TARGET_OS=tizen TARGET_TRANSPORT=ALL BUILD_SAMPLE=OFF + Making this flag ON builds the sample. + +Note :- Upon successful execution of above command(s) CA library and sample applications will be + generated at path "~/GBS-ROOT/local/repos/redwood/armv7l/RPMS". + +Arduino Build: + +Note :- Currently Mega & Due build is supported. + +1) Set up Arduino first before building. Refer to "connectivity\build\arduino\Arduino_Setup_README.txt" file for help. + +2) Go to "iotivity/" folder. + +3) Execute following command to start build : + +For Arduino Mega + $ scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT= TARGET_ARCH=avr BOARD=mega ARDUINO_HOME= +For Arduino Due + $ scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT= TARGET_ARCH=arm BOARD=arduino_due_x_dbg ARDUINO_HOME= + NOTE: BOARD=arduino_due_x_dbg|arduino_due_x. Default is arduino_due_x_dbg. + + Possible values for are: + -> IP : + $ scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT=IP TARGET_ARCH=avr BOARD=mega ARDUINO_HOME= + -> BLE : + $ scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT=BLE TARGET_ARCH=avr BOARD=mega ARDUINO_HOME= + + Note :- Only single transport can be built at a time for Arduino. + +4) The above command will build sample also. The "CASample.hex" can be found at "/samples/arduino/" + +5) After building sample, script will try to install on "/dev/ttyACM0" port in 'sudo' mode. + To skip installation, set command line argument 'UPLOAD=false'. + "scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=mega ARDUINO_HOME= UPLOAD=false" + +6) To set BLE Shield Name, include the option DEVICE_NAME during scons build. + + -> $ scons resource/csdk/connectivity/samples/arduino/ TARGET_OS=arduino TARGET_TRANSPORT=ETHERNET TARGET_ARCH=avr BOARD=mega ARDUINO_HOME= DEVICE_NAME=OIC + + Specified Device name length MUST be less than 10 characters. RBL Library has this limitation. + By Default DEVICE_NAME=OIC-DEVICE, if device name option is not specified + + To change the port number, please modify "port" variable in __upload() function in: "/build/arduino/SConscript". + diff --git a/resource/csdk/connectivity/build/SConscript b/resource/csdk/connectivity/build/SConscript new file mode 100644 index 0000000..b901f1a --- /dev/null +++ b/resource/csdk/connectivity/build/SConscript @@ -0,0 +1,269 @@ +## +# This script includes generic build options: +# release/debug, target os, target arch, cross toolchain, build environment etc +## +import os +import platform + +# Map of host os and allowed target os (host: allowed target os) +host_target_map = { + 'linux': ['linux', 'android', 'arduino', 'yocto', 'tizen'], + 'windows': ['windows', 'winrt', 'android', 'arduino'], + 'darwin': ['darwin', 'ios', 'android', 'arduino'], + } + +# Map of os and allowed archs (os: allowed archs) +os_arch_map = { + 'linux': ['x86', 'x86_64', 'arm', 'arm64'], + 'tizen': ['x86', 'x86_64', 'arm', 'arm64'], + 'android': ['x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'armeabi-v7a-hard', 'arm64-v8a'], + 'windows': ['x86', 'amd64', 'arm'], + 'winrt': ['arm'], + 'darwin': ['i386', 'x86_64'], + 'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'], + 'arduino': ['avr', 'arm'], + 'yocto': ['i586', 'x86_64', 'arm', 'powerpc', 'powerpc64', 'mips', 'mipsel'], + } + +host = platform.system().lower() + +if not host_target_map.has_key(host): + print "\nError: Current system (%s) isn't supported\n" % host + Exit(1) + +###################################################################### +# Get build options (the optins from command line) +###################################################################### +target_os = ARGUMENTS.get('TARGET_OS', host).lower() # target os + +if target_os not in host_target_map[host]: + print "\nError: Unknown target os: %s (Allow values: %s)\n" % (target_os, host_target_map[host]) + Exit(1) + +default_arch = platform.machine() +if default_arch not in os_arch_map[target_os]: + default_arch = os_arch_map[target_os][0].lower() + +target_arch = ARGUMENTS.get('TARGET_ARCH', default_arch) # target arch + +# True if binary needs to be installed on board. (Might need root permissions) +# set to 'no', 'false' or 0 for only compilation +require_upload = ARGUMENTS.get('UPLOAD', True) + +# Get the device name +device_name = ARGUMENTS.get('DEVICE_NAME', "OIC-DEVICE") + +###################################################################### +# Common build options (release, target os, target arch) +###################################################################### +help_vars = Variables() +help_vars.Add(BoolVariable('RELEASE', 'Build for release?', True)) # set to 'no', 'false' or 0 for debug +help_vars.Add(BoolVariable('LOGGING', 'Enable stack logging', False)) +help_vars.Add(EnumVariable('TARGET_OS', 'Target platform', host, host_target_map[host])) +help_vars.Add(ListVariable('TARGET_TRANSPORT', 'Target transport', 'ALL', ['ALL', 'BT', 'BLE', 'IP'])) +help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, os_arch_map[target_os])) +help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1'))) +help_vars.Add(BoolVariable('UPLOAD', 'Upload binary ? (For Arduino)', require_upload)) +help_vars.Add(EnumVariable('BUILD_SAMPLE', 'Build with sample', 'ON', allowed_values=('ON', 'OFF'))) + +help_vars.AddVariables(('DEVICE_NAME', 'Network display name for device', 'OIC-DEVICE', None, None),) + +###################################################################### +# Platform(build target) specific options: SDK/NDK & toolchain +###################################################################### +targets_support_cc = ['linux', 'arduino', 'tizen'] + +if target_os in targets_support_cc: + # Set cross compile toolchain + help_vars.Add('TC_PREFIX', "Toolchain prefix (Generally only be required for cross-compiling)", os.environ.get('TC_PREFIX')) + help_vars.Add(PathVariable('TC_PATH', + 'Toolchain path (Generally only be required for cross-compiling)', + os.environ.get('TC_PATH'))) + +if target_os in ['android', 'arduino']: # Android/Arduino always uses GNU compiler regardless of the host + env = Environment(variables = help_vars, + tools = ['gnulink', 'gcc', 'g++', 'ar', 'as'] + ) +else: + env = Environment(variables = help_vars, TARGET_ARCH = target_arch, TARGET_OS = target_os) + +Help(help_vars.GenerateHelpText(env)) + +# Set device name to __OIC_DEVICE_NAME__ +env.AppendUnique(CPPDEFINES = ['-D__OIC_DEVICE_NAME__=' + "\'\"" + device_name + "\"\'"]) + +tc_set_msg = ''' +************************************ Warning ********************************** +* Enviornment variable TC_PREFIX/TC_PATH is set. It will change the default * +* toolchain, if it isn't what you expect you should unset it, otherwise it may* +* cause inexplicable errors. * +******************************************************************************* +''' + +if target_os in targets_support_cc: + prefix = env.get('TC_PREFIX') + tc_path = env.get('TC_PATH') + if prefix: + env.Replace(CC = prefix + 'gcc') + env.Replace(CXX = prefix + 'g++') + env.Replace(AR = prefix + 'ar') + env.Replace(AS = prefix + 'as') + env.Replace(LINK = prefix + 'ld') + env.Replace(RANLIB = prefix + 'ranlib') + + if tc_path: + env.PrependENVPath('PATH', tc_path) + sys_root = os.path.abspath(tc_path + '/../') + env.AppendUnique(CCFLAGS = ['--sysroot=' + sys_root]) + env.AppendUnique(LINKFLAGS = ['--sysroot=' + sys_root]) + + if prefix or tc_path: + print tc_set_msg + +# Ensure scons be able to change its working directory +env.SConscriptChdir(1) + +# Set the source directory and build directory +# Source directory: 'dir' +# Build directory: 'dir'/out//// +# +# You can get the directory as following: +# env.get('SRC_DIR') +# env.get('BUILD_DIR') + +def __set_dir(env, dir): + if not os.path.exists(dir + '/SConstruct'): + print ''' +*************************************** Error ********************************* +* The directory(%s) seems isn't a source code directory, no SConstruct file is +* found. * +******************************************************************************* +''' % dir + Exit(1) + + if env.get('RELEASE'): + build_dir = dir + '/out/' + target_os + '/' + target_arch + '/release/' + else: + build_dir = dir + '/out/' + target_os + '/' + target_arch + '/debug/' + env.VariantDir(build_dir, dir, duplicate=0) + + env.Replace(BUILD_DIR = build_dir) + env.Replace(SRC_DIR = dir) + +def __src_to_obj(env, src, home = ''): + obj = env.get('BUILD_DIR') + src.replace(home, '') + if env.get('OBJSUFFIX'): + obj += env.get('OBJSUFFIX') + return env.Object(obj, src) + +def __install(ienv, targets, name): + i_n = ienv.Install(env.get('BUILD_DIR'), targets) + Alias(name, i_n) + env.AppendUnique(TS = [name]) + +def __append_target(ienv, target): + env.AppendUnique(TS = [target]) + +def __print_targets(env): + Help(''' +=============================================================================== +Targets:\n ''') + for t in env.get('TS'): + Help(t + ' ') + Help(''' +\nDefault all targets will be built. You can specify the target to build: + + $ scons [options] [target] +=============================================================================== +''') + +env.AddMethod(__set_dir, 'SetDir') +env.AddMethod(__print_targets, 'PrintTargets') +env.AddMethod(__src_to_obj, 'SrcToObj') +env.AddMethod(__append_target, 'AppendTarget') +env.AddMethod(__install, 'InstallTarget') +env.SetDir(env.GetLaunchDir()) +env['ROOT_DIR']=env.GetLaunchDir()+'/..' + +Export('env') + +###################################################################### +# Link scons to Yocto cross-toolchain ONLY when target_os is yocto +###################################################################### +if target_os == "yocto": + ''' + This code injects Yocto cross-compilation tools+flags into scons' + build environment in order to invoke the relevant tools while + performing a build. + ''' + import os.path + try: + CC = os.environ['CC'] + target_prefix = CC.split()[0] + target_prefix = target_prefix[:len(target_prefix)-3] + tools = {"CC" : target_prefix+"gcc", + "CXX" : target_prefix+"g++", + "AS" : target_prefix+"as", + "LD" : target_prefix+"ld", + "GDB" : target_prefix+"gdb", + "STRIP" : target_prefix+"strip", + "RANLIB" : target_prefix+"ranlib", + "OBJCOPY" : target_prefix+"objcopy", + "OBJDUMP" : target_prefix+"objdump", + "AR" : target_prefix+"ar", + "NM" : target_prefix+"nm", + "M4" : "m4", + "STRINGS": target_prefix+"strings"} + PATH = os.environ['PATH'].split(os.pathsep) + for tool in tools: + if tool in os.environ: + for path in PATH: + if os.path.isfile(os.path.join(path, tools[tool])): + env[tool] = os.path.join(path, os.environ[tool]) + break + env['CROSS_COMPILE'] = target_prefix[:len(target_prefix) - 1] + except: + print "ERROR in Yocto cross-toolchain environment" + Exit(1) + ''' + Now reset TARGET_OS to linux so that all linux specific build configurations + hereupon apply for the entirety of the build process. + ''' + env['TARGET_OS'] = 'linux' + ''' + We want to preserve debug symbols to allow BitBake to generate both DEBUG and + RELEASE packages for OIC. + ''' + env.AppendUnique(CCFLAGS = ['-g']) + ''' + Additional flags to pass to the Yocto toolchain. + ''' + if env.get('RELEASE'): + env.AppendUnique(CPPDEFINES = ['NDEBUG']) + if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['TB_LOG']) + env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__', '_GNU_SOURCE']) + env.AppendUnique(CFLAGS = ['-std=gnu99']) + env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) + env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + Export('env') +else: + ''' + If target_os is not Yocto, continue with the regular build process + ''' + # Load config of target os + if target_os in ['linux', 'tizen']: + env.SConscript('linux/SConscript') + else: + env.SConscript(target_os + '/SConscript') + +# Delete the temp files of configuration +if env.GetOption('clean'): + dir = env.get('SRC_DIR') + + if os.path.exists(dir + '/config.log'): + Execute(Delete(dir + '/config.log')) + Execute(Delete(dir + '/.sconsign.dblite')) + Execute(Delete(dir + '/.sconf_temp')) + +Return('env') diff --git a/resource/csdk/connectivity/build/android/Makefile b/resource/csdk/connectivity/build/android/Makefile new file mode 100644 index 0000000..038e36b --- /dev/null +++ b/resource/csdk/connectivity/build/android/Makefile @@ -0,0 +1,19 @@ +#Assumes ndk directory is at ~/ +#set ndk directory PATH in .bashrc and use the ndk-build directly +#change NDK_PATH to ${your_ndk_path} +NDK_PATH = ~/ndk +NDK_BUILD = $(NDK_PATH)/ndk-build + +BUILD_DIR = $(CURDIR) +APPLICATION_BUILD = $(BUILD_DIR) +ROOT_DIR = $(BUILD_DIR) + +#Clean files +LIBS_DIR = $(ROOT_DIR)/libs +OBJ_DIR = $(ROOT_DIR)/obj + +all: + $(NDK_BUILD) NDK_PROJECT_PATH=$(APPLICATION_BUILD) + +clean : + @$(RM) -rf $(LIBS_DIR) $(OBJ_DIR) diff --git a/resource/csdk/connectivity/build/android/README.txt b/resource/csdk/connectivity/build/android/README.txt new file mode 100644 index 0000000..10fb9a3 --- /dev/null +++ b/resource/csdk/connectivity/build/android/README.txt @@ -0,0 +1,17 @@ +Compiling Interface APIs FOR Android: +=================================== +•Preconditons : + Please download the following + 1) tinydlts library and keep at $(CA_HOME)/lib/tinydtls +•Supported version : 5.0 ( Lollipop ) +•Required NDK version : android-ndk-r10d ( https://developer.android.com/tools/sdk/ndk/index.html ) +• Modify Makefile ( connectivity/build/android/Makefile ) + $ cd ${CA_HOME}/connectivity/build/android + $ vi Makefile + # Change the NDK_PATH + NDK_PATH = ${your_ndk_path} + Build : $(CA_HOME)/build/android/Makefile + $ cd ${CA_HOME}/connectivity/build/android + $ ndk-build clean; ndk-build + + diff --git a/resource/csdk/connectivity/build/android/SConscript b/resource/csdk/connectivity/build/android/SConscript new file mode 100644 index 0000000..32880e7 --- /dev/null +++ b/resource/csdk/connectivity/build/android/SConscript @@ -0,0 +1,184 @@ +## +# This script includes android specific config (GNU GCC) +## +import os +import platform +import subprocess + +Import('env') + +help_vars = Variables() +help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK root directory', os.environ.get('ANDROID_NDK'))) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) + +android_ndk = env.get('ANDROID_NDK') +if not android_ndk: + print ''' +*************************************** Error ********************************* +* Android NDK path isn't set, you can set enviornment variable ANDROID_NDK * +* or add it in command line as: * +* # scons ANDROID_NDK= ... * +******************************************************************************* +''' + Exit(1) + +# Overwrite suffixes and prefixes +if env['HOST_OS'] == 'win32': + env['OBJSUFFIX'] = '.o' + env['SHOBJSUFFIX'] = '.os' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + env['SHLIBPREFIX'] = 'lib' + env['SHLIBSUFFIX'] = '.so' + env['LIBPREFIXES'] = ['lib'] + env['LIBSUFFIXES'] = ['.a', '.so'] + env['PROGSUFFIX'] = '' +elif platform.system().lower() == 'darwin': + env['SHLIBSUFFIX'] = '.so' + env['LIBSUFFIXES'] = ['.a', '.so'] + env['PROGSUFFIX'] = '' + +###################################################################### +# Set common flags +###################################################################### + +# Android build system default cofig +env.AppendUnique(CPPDEFINES = ['ANDROID']) +env.AppendUnique(CFLAGS = ['-std=c99']) +env.AppendUnique(SHCFLAGS = ['-Wa,--noexecstack']) +env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections', '-Wl,-z,nocopyreloc']) + +###################################################################### +# Probe Android NDK default flags +###################################################################### +ndk_build_cmd = android_ndk + '/ndk-build' +if env['HOST_OS'] == 'win32': + if os.path.isfile(ndk_build_cmd + '.cmd'): + ndk_build_cmd += '.cmd' + +if not os.path.isfile(ndk_build_cmd): + print ''' +*************************************** Error ********************************* +* It seems android ndk path is not set properly, please check if "%s" +* is the root directory of android ndk. * +******************************************************************************* +''' % android_ndk + Exit(1) + +ANDROID_HOME = os.environ.get('ANDROID_HOME') +if ANDROID_HOME is not None: + ANDROID_HOME = os.path.abspath(ANDROID_HOME) + +if ANDROID_HOME is None or not os.path.exists(ANDROID_HOME): + print ''' +*************************************** Warning ******************************* +* Enviornment variable ANDROID_HOME is not set properly. It should be the * +* root directory of android sdk. If you'd like build Java code, it's required.* +******************************************************************************* +''' + +target_arch = env.get('TARGET_ARCH') + +# Android ndk early version doesn't support C++11. Detect the toolchain version +# to make sure proper toolchain is used +for tc_ver in ['4.7', '4.8', '4.9', '']: + if os.path.exists(android_ndk + '/toolchains/x86-' + tc_ver): + break + +cmd = [ndk_build_cmd] +cmd.append('APP_ABI=' + target_arch) +cmd.append('APP_STL=gnustl_shared') +if env.get('RELEASE'): + cmd.append('APP_OPTIM=release') +else: + cmd.append('APP_OPTIM=debug') +if tc_ver != '': + cmd.append('NDK_TOOLCHAIN_VERSION=' + tc_ver) +else: + print ''' +*************************************** Warning ******************************* +* To support C++11, the toolchain should be >= 4.7, please make sure your * +* android NDK is at least r8e! * +******************************************************************************* +''' + +cmd.append('-n') + +p = subprocess.Popen(cmd, stdout = subprocess.PIPE) + +for flags in p.stdout.readlines(): + if cmp(flags[0:10], 'TC_PREFIX=') == 0: # toolchain prefix (include path) + prefix = flags[10:].strip() + env.Replace(CC = prefix + 'gcc') + env.Replace(CXX = prefix + 'g++') + env.Replace(AR = prefix + 'ar') + env.Replace(RANLIB = prefix + 'ranlib') + + elif cmp(flags[0:7], 'CFLAGS=') == 0: + env.AppendUnique(CFLAGS = Split(flags[7:])) + + elif cmp(flags[0:9], 'CXXFLAGS=') == 0: + env.AppendUnique(CXXFLAGS = Split(flags[9:])) + + elif cmp(flags[0:8], 'CPPPATH=') == 0: + env.AppendUnique(CPPPATH = Split(flags[8:])) + + elif cmp(flags[0:8], 'SYSROOT=') == 0: + sysroot = flags[8:].strip() + env.AppendUnique(LINKFLAGS = ['--sysroot=' + sysroot]) + env.AppendUnique(LIBPATH = [sysroot + '/usr/lib']) + + elif cmp(flags[0:8], 'LDFLAGS=') == 0: + env.AppendUnique(LINKFLAGS = Split(flags[8:])) + + elif cmp(flags[0:7], 'TC_VER=') == 0: # set gnustl library path + ver = flags[7:].strip() + env.AppendUnique(LIBPATH = [android_ndk + '/sources/cxx-stl/gnu-libstdc++/' + + ver + '/libs/' + target_arch]) + + elif cmp(flags[0:9], 'PLATFORM=') == 0: # get target platform: android-x + platform_ver = flags[9+8:].strip() + if not platform_ver.isdigit(): + platform_ver = '' + +# Determine dependency faux SYS_ROOT +dep_sys_root = os.path.join(env.get('SRC_DIR'), 'dep', 'android', target_arch, 'usr') +dep_src_dir = os.path.join(dep_sys_root, 'include') +dep_lib_dir = os.path.join(dep_sys_root, 'lib') + +env['DEP_SYS_ROOT'] = dep_sys_root + +# Add external libraries including boost +env.AppendUnique(CPPPATH = [ dep_src_dir ]) +env.AppendUnique(LIBPATH = [ dep_lib_dir ]) + +###################################################################### +# Set release/debug flags +###################################################################### +if env.get('RELEASE'): + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) + env.AppendUnique(LINKFLAGS = ['-s']) +else: + env.AppendUnique(CCFLAGS = ['-g']) + +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + +env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__ANDROID__']) +env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) +#env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + +env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')]) +src_dir = env.get('SRC_DIR') +env.AppendUnique(LIBPATH = [src_dir + '/lib/android']) +env.AppendUnique(LIBS = ['log', 'coap']) +if env.get('SECURED') == '1': + env.AppendUnique(LIBS = ['tinydtls']) + +# From android-5 (API > 20), all application must be built with flags '-fPIE' '-pie'. +# Due to the limitation of Scons, it's required to added it into the command line +# directly (otherwise, it will also be added when build share library) +env.Replace(CCCOM = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES') +env.Replace(CXXCOM = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM -fPIE $SOURCES') diff --git a/resource/csdk/connectivity/build/android/jni/Android.mk b/resource/csdk/connectivity/build/android/jni/Android.mk new file mode 100644 index 0000000..54233f6 --- /dev/null +++ b/resource/csdk/connectivity/build/android/jni/Android.mk @@ -0,0 +1,162 @@ +$(info TC_PREFIX=$(TOOLCHAIN_PREFIX)) +$(info CFLAGS=$(TARGET_CFLAGS)) +$(info CXXFLAGS=$(TARGET_CXXFLAGS) $(TARGET_NO_EXECUTE_CFLAGS)) +$(info CPPPATH=$(TARGET_C_INCLUDES) $(__ndk_modules.$(APP_STL).EXPORT_C_INCLUDES)) +$(info SYSROOT=$(SYSROOT_LINK)) +$(info LDFLAGS=$(TARGET_LDFLAGS) $(TARGET_NO_EXECUTE_LDFLAGS) $(TARGET_NO_UNDEFINED_LDFLAGS) $(TARGET_RELRO_LDFLAGS)) +$(info TC_VER=$(TOOLCHAIN_VERSION)) +$(info PLATFORM=$(APP_PLATFORM)) + + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#define build type +BUILD = debug + +PROJECT_ROOT_PATH ?= ../.. +EXT_LIB_PATH = ../../../../../../extlibs +PROJECT_API_PATH = $(PROJECT_ROOT_PATH)/api +PROJECT_INC_PATH = $(PROJECT_ROOT_PATH)/inc +PROJECT_SRC_PATH = $(PROJECT_ROOT_PATH)/src +PROJECT_COMMON_PATH = $(PROJECT_ROOT_PATH)/common +PROJECT_COMMON_INC_PATH = $(PROJECT_COMMON_PATH)/inc +PROJECT_COMMON_SRC_PATH = $(PROJECT_COMMON_PATH)/src +PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/lib +PROJECT_EXTERNAL_PATH = $(PROJECT_ROOT_PATH)/external/inc +DTLS_LIB = $(EXT_LIB_PATH)/tinydtls +#GLIB_PATH = ../../../../../../extlibs/glib/glib-2.40.2 + +#Modify below values to enable/disable the Adapter +#Suffix "NO_" to disable given adapter +EDR = EDR_ADAPTER +IP = IP_ADAPTER +LE = LE_ADAPTER + +#Add Pre processor definitions +DEFINE_FLAG = -DWITH_POSIX -D__ANDROID__ +DEFINE_FLAG = -D__WITH_DTLS__ +DEFINE_FLAG += -D$(EDR) -D$(LE) -D$(IP) + +#Add Debug flags here +DEBUG_FLAG = -DTB_LOG + +BUILD_FLAG.debug = $(DEFINE_FLAG) $(DEBUG_FLAG) +BUILD_FLAG.release = $(DEFINE_FLAG) +BUILD_FLAG = $(BUILD_FLAG.$(BUILD)) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#include glib + +#include $(CLEAR_VARS) +#LOCAL_PATH = $(PROJECT_LIB_PATH)/android +#LOCAL_MODULE = Glib +#LOCAL_SRC_FILES := libglib-2.40.2.so +#LOCAL_EXPORT_C_INCLUDES = $(GLIB_PATH) \ +# $(GLIB_PATH)/glib +# +#include $(PREBUILT_SHARED_LIBRARY) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#include glibthread + +#include $(CLEAR_VARS) +#LOCAL_PATH = $(PROJECT_LIB_PATH)/android +#LOCAL_MODULE = GLibThread +#LOCAL_SRC_FILES := libgthread-2.40.2.so +#LOCAL_EXPORT_C_INCLUDES = $(GLIB_PATH) \ +# $(GLIB_PATH)/glib +# +#include $(PREBUILT_SHARED_LIBRARY) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#Build TinyDtls + +include $(CLEAR_VARS) +include $(DTLS_LIB)/Android.mk + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#Build CACommon + +include $(CLEAR_VARS) + +#Build Common Libraries +LOCAL_PATH = $(PROJECT_COMMON_SRC_PATH) +LOCAL_MODULE = CACommon +LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog +#LOCAL_SHARED_LIBRARIES = Glib GLibThread +LOCAL_STATIC_LIBRARIES = rt pthread + +LOCAL_CFLAGS = -D__ANDROID__ $(DEBUG_FLAG) +LOCAL_CFLAGS += -std=c99 + +LOCAL_C_INCLUDES = $(PROJECT_COMMON_INC_PATH) +LOCAL_C_INCLUDES += $(PROJECT_API_PATH) + +LOCAL_SRC_FILES = oic_logger.c \ + oic_console_logger.c logger.c oic_malloc.c \ + uarraylist.c uqueue.c oic_string.c \ + cathreadpool_pthreads.c camutex_pthreads.c + +include $(BUILD_STATIC_LIBRARY) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#Build CACoap + +include $(CLEAR_VARS) + +LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog +LOCAL_PATH = $(PROJECT_LIB_PATH)/libcoap-4.1.1 +LOCAL_MODULE = CACoap +LOCAL_EXPORT_C_INCLUDES = $(PROJECT_LIB_PATH)/libcoap-4.1.1 +LOCAL_CFLAGS = -DWITH_POSIX +LOCAL_SRC_FILES = pdu.c net.c debug.c encode.c uri.c coap_list.c resource.c hashkey.c \ + str.c option.c async.c subscribe.c block.c + +include $(BUILD_STATIC_LIBRARY) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#Build CA + +#Relative path to LOCAL_PATH (PROJECT_SRC_PATH) +LOCAL_PLATFORM = android + +ENET_ADAPTER_PATH = ethernet_adapter/$(LOCAL_PLATFORM) +EDR_ADAPTER_PATH = bt_edr_adapter/$(LOCAL_PLATFORM) +LE_ADAPTER_PATH = bt_le_adapter/$(LOCAL_PLATFORM) +IP_ADAPTER_PATH = ip_adapter +ADAPTER_UTILS = adapter_util + +include $(CLEAR_VARS) + +LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog +LOCAL_PATH = $(PROJECT_SRC_PATH) +LOCAL_MODULE = CA + +LOCAL_STATIC_LIBRARIES = CACommon CACoap TinyDtls + +LOCAL_C_INCLUDES = $(PROJECT_API_PATH) +LOCAL_C_INCLUDES += $(PROJECT_COMMON_INC_PATH) +LOCAL_C_INCLUDES += $(PROJECT_INC_PATH) +LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/libcoap-4.1.1 +LOCAL_C_INCLUDES += $(PROJECT_EXTERNAL_PATH) +LOCAL_C_INCLUDES += $(DTLS_LIB) + +LOCAL_CFLAGS += $(BUILD_FLAG) +LOCAL_CFLAGS += -std=c99 -DWITH_POSIX + +LOCAL_SRC_FILES = \ + caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c \ + camessagehandler.c canetworkconfigurator.c caprotocolmessage.c \ + caretransmission.c caqueueingthread.c \ + $(ADAPTER_UTILS)/caadapternetdtls.c $(ADAPTER_UTILS)/caadapterutils.c \ + $(ADAPTER_UTILS)/camsgparser.c \ + bt_le_adapter/caleadapter.c $(LE_ADAPTER_PATH)/caleclient.c \ + $(LE_ADAPTER_PATH)/caleserver.c $(LE_ADAPTER_PATH)/caleutils.c \ + $(LE_ADAPTER_PATH)/calenwmonitor.c \ + bt_edr_adapter/caedradapter.c $(EDR_ADAPTER_PATH)/caedrutils.c \ + $(EDR_ADAPTER_PATH)/caedrclient.c $(EDR_ADAPTER_PATH)/caedrserver.c \ + $(EDR_ADAPTER_PATH)/caedrnwmonitor.c \ + $(IP_ADAPTER_PATH)/caipadapter.c $(IP_ADAPTER_PATH)/caipserver.c \ + $(IP_ADAPTER_PATH)/caipclient.c $(IP_ADAPTER_PATH)/android/caipnwmonitor.c \ + +include $(BUILD_STATIC_LIBRARY) + diff --git a/resource/csdk/connectivity/build/android/jni/Application.mk b/resource/csdk/connectivity/build/android/jni/Application.mk new file mode 100644 index 0000000..1de4715 --- /dev/null +++ b/resource/csdk/connectivity/build/android/jni/Application.mk @@ -0,0 +1,9 @@ +#Specify Android.mk path w.r.t APPLICATION_BUILD in the Makefile +APP_PROJECT_PATH = ./ + +APP_STL = gnustl_shared +APP_MODULES := CA +APP_PLATFORM = android-21 +APP_CPPFLAGS += -fexceptions +APP_CPPFLAGS += -frtti += -Wno-error=format-security +APP_CFLAGS = -Wno-error=format-security diff --git a/resource/csdk/connectivity/build/arduino/Arduino_Setup_README.txt b/resource/csdk/connectivity/build/arduino/Arduino_Setup_README.txt new file mode 100644 index 0000000..359ded0 --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/Arduino_Setup_README.txt @@ -0,0 +1,54 @@ +STEPS to setup Arduino on linux machine for building CA code: + +1) Download the Arduino package as per your system specification from the given link : + http://arduino.cc/en/main/software + +2) Unzip the downloaded package to some location say ARDUINO_DIR(This is the arduino installation directory). + ARDUINO_DIR = /arduino-1.5.x + +3) Change permissions for executable in your "ARDUINO_DIR" + chmod -R +x + +4.1) ONE TIME ONLY - ADDITIONAL LIBRARIES (Time) + Arduino builds are dependent on latest Time library. Download it from here: + I. http://playground.arduino.cc/uploads/Code/Time.zip + Place this library in the "ARDUINO_DIR/libraries/Time" folder where other libraries are present. + [P.S - The Time library files path should be as follows "ARDUINO_DIR/libraries/Time/Time/{***files***}"] + Some files in this library has windows style line endings, for patch to run properly, please execute following command: + cd + find ./libraries/Time/ -type f -exec dos2unix {} \; + +4.2) ONE TIME ONLY - ADDITIONAL LIBRARIES (BLE) + Note: Prior to building for BLE Transport, following additional steps are required: + (1) Download RedBearLab Arduino RBL_nRF8001 Library from link(https://github.com/RedBearLab/nRF8001/archive/25643e7b1b7da3740406325a471e3faa4b948747.zip) + (2) Extract zip file and apply RBL patch(connectivity/lib/arduino/RBL_nRF8001.patch) to "RBL_nRF8001" folder by following below steps, + i) Go to downloaded RBL_Library Folder ("nRF8001-master/Arduino/libraries/RBL_nRF8001") + ii) Apply dos2unix for RBL_Library Folder and RBL Patch File (RBL_nRF8001.patch), if we have downloaded Library in Non UNIX Platform. + iii) Apply RBL Patch[connectivity\lib\arduino\RBL_nRF8001.patch] by using the below command + patch -p1 < RBL_Patch_File_Location(RBL_nRF8001.patch) + (3) Copy the patched RBL_nRF8001 Library and place it in "arduino-/libraries" folder + (4) Download Nordic Arduino BLE library [Tag: "0.9.5.Beta" Version] from the link (https://github.com/NordicSemiconductor/ble-sdk-arduino/archive/0.9.5.beta.zip). + Extract the zip file and copy the "BLE" folder available under "libraries" folder and place it in "arduino-/libraries" folder + i) Apply dos2unix for the "BLE" folder. + ii) Go to the BLE folder and apply the patch[connectivity\lib\arduino\arduino_due_ble.patch] using the below command. + patch -p1 < path/to/arduino_due_ble.patch + +5) ONE TIME ONLY - PATCH + Complete patch has been provided at : "connectivity\lib\arduino\arduino_libraries.patch" + Copy this patch file to "ARDUINO_DIR/" + +6) To apply patch give the command : + patch -p1 < arduino_libraries.patch + To undo the patch give the command : + patch -R -p1 < arduino_libraries.patch + +7) ONE TIME ONLY - FIRMWARE UPGRADE (FOR WIFI SHIELD) + To support UDP over WiFi, WiFi shield needs to run latest firmware. Please refer: + (http://arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading) + for instructions on how to upgrade your firmware. + +8) Launch Arduino IDE (required for logs and port and board selection.) + Goto to "ARDUINO_DIR" directory. + Launch command := sudo ./arduino + +9) Select your board and port under the tools option in Arduino IDE. diff --git a/resource/csdk/connectivity/build/arduino/Makefile b/resource/csdk/connectivity/build/arduino/Makefile new file mode 100644 index 0000000..7524a33 --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/Makefile @@ -0,0 +1,75 @@ +# +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# TRANSPORT can be ETHERNET, WIFI, BT, BLE. Include Corresponding Transport during compilation. For Eg: `make PLATFORM=arduinomega TRANSPORT=BLE +# default to release build +# default to build for arduinomega +# default to build for BLE Transport +BUILD := release +PLATFORM := arduinomega +TRANSPORT := BLE +OBJ_DIR := ./bin +APP_NAME := casample +ARDUINO_PORT := ttyACM0 + +include ./local.properties +include ./$(PLATFORM).properties + +VPATH := $(SDIR_ARD_PLATFORM) + +#Include __ARDUINO_BLE__ flag for BLE Transport. Currently, BLE Sample APP is segregated with this MACRO +ifeq ($(TRANSPORT),BLE) +CFLAGS := -Os -Wall -c -DTB_LOG -DOIC_ARDUINODUE -DINTERFACESAMPLE_ARDUINO -DARDUINO -DOIC_ARDUINODUE -D__ARDUINO__ -DWITH_ARDUINO -D__ARDUINO_BLE__ -DLE_ADAPTER +else ifeq ($(TRANSPORT),WIFI) +CFLAGS := -Os -Wall -c -DTB_LOG -DOIC_ARDUINODUE -DINTERFACESAMPLE_ARDUINO -DARDUINO -DOIC_ARDUINODUE -D__ARDUINO__ -DWITH_ARDUINO -DWIFI_ADAPTER +else +CFLAGS := -Os -Wall -c -DTB_LOG -DOIC_ARDUINODUE -DINTERFACESAMPLE_ARDUINO -DARDUINO -DOIC_ARDUINODUE -D__ARDUINO__ -DWITH_ARDUINO -DETHERNET_ADAPTER +endif + +all: prep_dirs core.a $(APP_NAME).o $(APP_NAME).elf $(APP_NAME).hex + +$(info *********PLATFORM_OBJS!!**********) +core.a: $(PLATFORM_OBJS) + @cd $(OBJ_DIR) && $(AR) -x ../../../lib/libcoap-4.1.1/$(BUILD)/libcoap.a + $(AR) rcs $@ $(CORE_COBJ) $(CORE_CPPOBJ) $(PLATFORM_OBJS) $(OBJ_DIR)/*.o + $(RANLIB) $@ + +prep_dirs: + -mkdir $(OBJ_DIR) + +logger.c.o: logger.c + $(CCPLUS) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $@ + +%.c.o: %.c + $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $@ + +%.o: %.c + $(CC) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $@ + +%.o: %.cpp + $(CCPLUS) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $@ + +%.cpp.o: %.cpp + $(CCPLUS) $(CFLAGS) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $@ + +# core.a and $(APP_NAME).cpp.o are combined to generate $(APP_NAME).elf. +# For Integration with Top Layer, we can link top layer with core.a +$(APP_NAME).elf: $(APP_NAME).cpp.o core.a + $(CC) -w -Os -Wl,--gc-sections,--relax -mmcu=atmega2560 -o $@ $^ -L$(ARDUINO_DIR)/libraries -lm + +$(APP_NAME).hex: $(APP_NAME).elf + $(AVR_OBJCOPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $< $(APP_NAME).eep + $(AVR_OBJCOPY) -O ihex -R .eeprom $< $@ + +install: all + $(AVR_PROGRAMMER) -C$(ARDUINO_DIR)/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P/dev/$(ARDUINO_PORT) -b115200 -D -Uflash:w:$(APP_NAME).hex:i + + +.PHONY: clean +clean: + @rm -f *.o *.d *.elf *.eep core.a *.hex *.bin *.map *- + @rm -rf $(OBJ_DIR) + + + + diff --git a/resource/csdk/connectivity/build/arduino/README.txt b/resource/csdk/connectivity/build/arduino/README.txt new file mode 100644 index 0000000..17bff7d --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/README.txt @@ -0,0 +1,20 @@ +BUILDING for ARDUINOMEGA: +======================================== +PREREQ: Arduino MUST be installed in the machine where we compile. Refer to Arduino_Setup_README file for help. + +1) Go to "connectivity\build\arduino" directory, Open Makefile and change ARDUINO_PORT according to the PORT selected in ARDUINO IDE. +2) BUILD : Go to "connectivity\build" directory. To build for a specific TRANSPORT [ETHERNET,BLE,WIFI], use the following command : + sudo make PLATFORM=arduinomega TRANSPORT= ARDUINO_DIR = /arduino-1.5.x + P.S : For PATH_TO_ARDUINO_INSTALL_DIR value refer Arduino_Setup_README.txt file. + +Flashing Interface APIs for ARDUINOMEGA: +======================================== +Precondition: Connect Arduino Mega Board to Linux PC. Open Arduino IDE and select corresponding connected PORT +1) To Install, connect the ArduinoMega Board with corresponding Shields to Linux PC. +2) Perform sudo make install PLATFORM=arduinomega TRANSPORT=BLE + It will flash BLE Transport Adaptor in Arduino Board. Similarly, TRANSPORT can be changed to ETHERNET, BLE, WIFI etc.. + +To Run Adapter code in ARDUINOMEGA Board: +======================================== +PreCondition: Flash the executable in ARDUINO MEGA BOARD. Follow above Step(Flashing Interface APIs for ARDUINOMEGA) +1) Open Serial Monitor in Arduino IDE. It will execute the flashed binary and logs will be available in serial Monitor under BaudRate(115200) diff --git a/resource/csdk/connectivity/build/arduino/SConscript b/resource/csdk/connectivity/build/arduino/SConscript new file mode 100644 index 0000000..d97d596 --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/SConscript @@ -0,0 +1,438 @@ +## +# This script includes arduino specific config +## +import os +import platform + +Import('env') + +def __parse_config(f): + dict = {} + + if not os.path.isfile(f): + return dict + + file = open(f, 'r') + strs = file.readlines() + for str in strs: + str = str.strip() + if len(str) > 0 and str[0] == '#': + continue + + idx = str.find('=') + if idx > 0: + dict.setdefault(str[0:idx], str[idx + 1:]) + + return dict + +def __get_boards(dict): + boards = [] + keys = dict.keys() + for key in keys: + idx = key.find('.name') + if idx > 0: + if key.endswith('.name'): + boards.append(key[0:idx]) + return boards + +def __get_cpu(dict, board): + cpus = [] + keys = dict.keys() + for key in keys: + idx = key.find(board + '.menu.cpu.') + start = len(board + '.menu.cpu.') + if idx >= 0: + end = key.find('.', start) + if end > 0: + cpu = key[start:end] + exist = False + for c in cpus: + if c == cpu: + exist = True + break + + if not exist: + cpus.append(cpu) + return cpus + +def __get_board_info(board, key): + if cpu: + v = boards_info.get(board + '.menu.cpu.' + cpu + key) + if not v: + v = boards_info.get(board + key) + else: + v = boards_info.get(board + key) + return v + +def __search_files(path, pattern, ondisk=True, source=True, strings=False, recursive=True): + if not recursive: + return Glob(pattern, ondisk, source, strings) + + matches = [] + for root, dirnames, filenames in os.walk(path): + #BLE library examples throw lot of errors. We dont need examples. + if 'examples' not in root: + matches.extend(Glob(root + '/' + pattern, ondisk, source, strings)) + return matches + +# To make sure the src is built in 'BUILD_DIR' (by default it will be built at +# the same directory as the .c .cpp .S) +def __src_to_obj(env, srcs): + objs = [] + prefix = env.get('BOARD') + '_' + if env.get('CPU'): + prefix += env.get('CPU') + '_' + + build_dir = env.get('BUILD_DIR') + '/arduino/' + for src in srcs: + obj = src.path.replace(arduino_home, build_dir) + i = obj.rfind('.') + obj = obj[0:i] + if env.get('OBJSUFFIX'): + obj += env.get('OBJSUFFIX') + objs.extend(env.Object(obj, src, OBJPREFIX=prefix)) + return objs + +def __import_lib(env, lib): + lib_path = arduino_home + '/libraries/' + lib + if not os.path.exists(lib_path): + if target_arch == 'avr': + lib_path = arduino_home + '/hardware/arduino/avr/libraries/' + lib + else: + lib_path = arduino_home + '/hardware/arduino/sam/libraries/' + lib + + if os.path.exists(lib_path + '/src'): + lib_path = lib_path + '/src' + + env.AppendUnique(CPPPATH = [lib_path]) + + if os.path.exists(lib_path + '/utility'): + env.AppendUnique(CPPPATH = [lib_path + '/utility']) + + lib_src = [] + lib_src.extend(__search_files(lib_path, '*.S')) + lib_src.extend(__search_files(lib_path, '*.c')) + lib_src.extend(__search_files(lib_path, '*.cpp')) + + lib_obj = __src_to_obj(env, lib_src) + build_dir = env.get('BUILD_DIR') + if build_dir: + lib_a = env.StaticLibrary(build_dir + lib, lib_obj) + else: + lib_a = env.StaticLibrary(lib, lib_obj) + + # If we link libSPI.a, the final binary is not getting launched + # on the board. Which is not the case if we directly use SPI.o. + + if env.get('TARGET_ARCH') == 'arm': + if lib == 'SPI': + for obj in lib_obj: + if obj.name.endswith('SPI.o'): + env.PrependUnique(LIBS = [File(obj)]) + else: + env.AppendUnique(LIBS = [File(lib_a[0])]) + else: + env.PrependUnique(LIBS = [File(lib_a[0])]) + +def __build_core(env): + core_src = __search_files(core_folder, '*.S') + core_src.extend(__search_files(core_folder, '*.c')) + core_src.extend(__search_files(core_folder, '*.cpp')) + + core_src.extend(__search_files(variant_folder, '*.S')) + core_src.extend(__search_files(variant_folder, '*.c')) + core_src.extend(__search_files(variant_folder, '*.cpp')) + + core_obj = __src_to_obj(env, core_src) + build_dir = env.get('BUILD_DIR') + if build_dir: + s_core = env.StaticLibrary(build_dir + 'core', core_obj) + else: + s_core = env.StaticLibrary('core', core_obj) + env.AppendUnique(LIBS = [File(s_core[0])]) + + # To avoid compiler issue. Otherewise there may be warnings: + # undefined reference to '_exit' '_close', '_getpid' ... + # Above functions are used in libc.a and implemented in syscalls_sam3.c + if env.get('TARGET_ARCH') == 'arm': + for obj in core_obj: + if obj.name.endswith('syscalls_sam3.o'): + env.AppendUnique(LIBS = [File(obj)]) + +def __create_bin(env, source): + name = source + if target_arch == 'avr': + eep = env.Command(name + '.eep', source, 'avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $SOURCE $TARGET') + hex = env.Command(name + '.hex', source, 'avr-objcopy -O ihex -R .eeprom $SOURCE $TARGET') + else: + hex = env.Command(name + '.hex', source, 'arm-none-eabi-objcopy -O binary $SOURCE $TARGET') + +#Currently Mega and Due build is supported. +def __upload(env, binary): + if target_arch == 'avr': + protocol = __get_board_info(board, '.upload.protocol') + speed = __get_board_info(board, '.upload.speed') + port = '/dev/ttyACM0' + upload_cmd = arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -p' \ + + mcu + ' -c' + protocol + ' -P' + port + ' -b' + speed + ' -D -Uflash:w:' + binary + ':i' + + print "Upload command: %s" %upload_cmd + install_cmd = env.Command('install_cmd', None, upload_cmd) + env.Default('install_cmd') + else: + uu = __get_board_info(board, '.upload.native_usb') + port = 'ttyACM0' + upload_cmd = 'stty -F /dev/' + port + ' speed 1200 cs8 -cstopb -parenb \n' + arduino_home + '/hardware/tools/bossac -i -d --port=' + port + ' -U ' + uu + ' -e -w -v -b ' + binary + ' -R' + print "Upload command: %s" %upload_cmd + install_cmd = env.Command('install_cmd', None, upload_cmd) + env.Default('install_cmd') + +# Print the command line that to upload binary to the board +def __upload_help(env): + if target_arch == 'avr': + protocol = __get_board_info(board, '.upload.protocol') + speed = __get_board_info(board, '.upload.speed') + + upload_cmd = arduino_home + '/hardware/tools/avr/bin/avrdude -C' + arduino_home +'/hardware/tools/avr/etc/avrdude.conf -v -v -v -v -p' \ + + mcu + ' -c' + protocol + ' -P' + ' -b' + speed + ' -D -Uflash:w::i' + else: + uu = __get_board_info(board, '.upload.native_usb') + upload_cmd = arduino_home + '/hardware/tools/bossac -i -d --port= -U ' + uu + ' -e -w -v -b -R' + + Help(''' +=============================================================================== +You can upload the bin file with following command line: +''') + Help('\n $ ' + upload_cmd) + Help(''' +\nPlease replace according to the actual situation. +=============================================================================== +''') + +# ARDUINO_HOME build option +help_vars = Variables() +help_vars.Add(PathVariable('ARDUINO_HOME', 'ARDUINO root directory', os.environ.get('ARDUINO_HOME'))) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) + +target_arch = env.get('TARGET_ARCH') +arduino_home = env.get('ARDUINO_HOME') +if not arduino_home: + print ''' +************************************* Error *********************************** +* Arduino root directory isn't set, you can set enviornment variable * +* ARDUINO_HOME or add it in command line as: * +* # scons ARDUINO_HOME= ... * +******************************************************************************* +''' + Exit(1) + +# Overwrite suffixes and prefixes +if env['HOST_OS'] == 'win32': + env['OBJSUFFIX'] = '.o' + env['SHOBJSUFFIX'] = '.os' + env['LIBPREFIX'] = 'lib' + env['LIBSUFFIX'] = '.a' + env['SHLIBPREFIX'] = 'lib' + env['SHLIBSUFFIX'] = '.so' + env['LIBPREFIXES'] = ['lib'] + env['LIBSUFFIXES'] = ['.a', '.so'] + env['PROGSUFFIX'] = '' +elif platform.system().lower() == 'darwin': + env['SHLIBSUFFIX'] = '.so' + env['LIBSUFFIXES'] = ['.a', '.so'] + env['PROGSUFFIX'] = '' + +# Debug/release relative flags +if env.get('RELEASE'): + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) +else: + env.AppendUnique(CCFLAGS = ['-g']) + +# BOARD / CPU option + +# Get IDE version +if os.path.exists(arduino_home + '/lib/version.txt'): + vf = open(arduino_home + '/lib/version.txt', 'r') + version = vf.readline().replace('.', '') +else: + print ''' +************************************* Error *********************************** +* Can't find version file (lib/version.txt), please check if (%s) +* is arduino root directory. * +******************************************************************************* +''' % arduino_home + Exit(1) + +if version[0:2] == '10': + is_1_0_x = True + boards_info = __parse_config(arduino_home + '/hardware/arduino/boards.txt') + env.PrependENVPath('PATH', arduino_home + '/hardware/tools/avr/bin/') + env.Replace(CC = 'avr-gcc') + env.Replace(CXX = 'avr-gcc') + env.Replace(AR = 'avr-ar') + env.Replace(AS = 'avr-as') + env.Replace(LINK = 'avr-gcc') + env.Replace(RANLIB = 'avr-ranlib') + if target_arch != 'avr': + print ''' +************************************* Error *********************************** +* Arduino 1.0.x IDE only support 'avr', to support other arch at least 1.5.x * +* is required. +******************************************************************************* +''' + Exit(1) +else: + is_1_0_x = False + if target_arch == 'avr': + boards_info = __parse_config(arduino_home + '/hardware/arduino/avr/boards.txt') + platform_info = __parse_config(arduino_home + '/hardware/arduino/avr/platform.txt') + elif target_arch == 'arm': + boards_info = __parse_config(arduino_home + '/hardware/arduino/sam/boards.txt') + platform_info = __parse_config(arduino_home + '/hardware/arduino/sam/platform.txt') + else: + print ''' +************************************* Error *********************************** +* CPU arch %s isn't supported currently. +******************************************************************************* +''' % target_arch + +#Board option, let user to select the board +boards = __get_boards(boards_info) +help_vars = Variables() +help_vars.Add(EnumVariable('BOARD', 'arduino board', boards[0], boards)) +help_vars.Update(env) +Help(help_vars.GenerateHelpText(env)) + +#CPU option +board = env.get('BOARD') +cpus = __get_cpu(boards_info, board) +if len(cpus) > 0: + help_vars = Variables() + help_vars.Add(EnumVariable('CPU', 'arduino board cpu', cpus[0], cpus)) + help_vars.Update(env) + Help(help_vars.GenerateHelpText(env)) + +# Arduino commom flags +cpu = env.get('CPU') +board = env.get('BOARD') +mcu = __get_board_info(board, '.build.mcu') +f_cpu = __get_board_info(board, '.build.f_cpu') +usb_vid = __get_board_info(board, '.build.vid') +usb_pid = __get_board_info(board, '.build.pid') +variant = __get_board_info(board, '.build.variant') + +if not usb_vid: + usb_vid = __get_board_info(board, '.vid.0') +if not usb_pid: + usb_pid = __get_board_info(board, '.pid.0') + +if is_1_0_x: + core_base = arduino_home + '/hardware/arduino/' +else: + if target_arch == 'avr': + core_base = arduino_home + '/hardware/arduino/avr/' + else: + core_base = arduino_home + '/hardware/arduino/sam/' + +variant_folder = core_base + 'variants/' + variant +env.AppendUnique(CPPPATH = [variant_folder]) + +core = __get_board_info(board, '.build.core') +core_folder = core_base + 'cores/' + core + '/' +env.AppendUnique(CPPPATH = [core_folder]) + +if is_1_0_x: + comm_flags = ['-std=c99'] + if mcu: + comm_flags.extend(['-mmcu=' + mcu]) + if f_cpu: + comm_flags.extend(['-DF_CPU=' + f_cpu]) + comm_flags.extend(['-DARDUINO=' + version]) + if usb_vid: + comm_flags.extend(['-DUSB_VID=' + usb_vid]) + if usb_pid: + comm_flags.extend(['-DUSB_PID=' + usb_pid]) + + env.AppendUnique(ASFLAGS = ['-x', 'assembler-with-cpp']) + env.AppendUnique(ASFLAGS = comm_flags) + + env.AppendUnique(CFLAGS = ['-Os', '-ffunction-sections', '-fdata-sections', '-MMD']) + env.AppendUnique(CFLAGS = comm_flags) + + env.AppendUnique(CXXFLAGS = ['-Os', '-fno-exceptions', '-ffunction-sections', '-fdata-sections','-MMD']) + env.AppendUnique(CXXFLAGS = comm_flags) + + env.AppendUnique(LINKFLAGS = ['-Os']) + if mcu == 'atmega2560': + env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections,--relax']) + else: + env.AppendUnique(LINKFLAGS = ['-Wl,--gc-sections']) + env.AppendUnique(LINKFLAGS = ['-mmcu=' + mcu]) +else: + if target_arch == 'avr': + cpu_flag = '-mmcu=' + mcu + else: + cpu_flag = '-mcpu=' + mcu + + comm_flag = [cpu_flag, '-DF_CPU=' + f_cpu, '-DARDUINO=' + version, '-DARDUINO_' + __get_board_info(board, '.build.board')] + if target_arch == 'arm': + # As of 1.5.8 the arduino headers had asm bugs with ARM and + # require gnu99 to be used. + comm_flag.extend(['-std=gnu99', '-DARDUINO_ARCH_SAM']) + else: + comm_flag.extend(['-std=c99', '-DARDUINO_ARCH_AVR']) + + compiler_path = platform_info.get('compiler.path') + compiler_path = compiler_path.replace('{runtime.ide.path}', arduino_home) + env.PrependENVPath('PATH', compiler_path) + env.Replace(CC = platform_info.get('compiler.c.cmd')) + env.Replace(CXX = platform_info.get('compiler.cpp.cmd')) + env.Replace(AR = platform_info.get('compiler.ar.cmd')) + if target_arch == 'arm': + env.AppendUnique(CPPPATH = [arduino_home + '/hardware/arduino/sam/system/libsam', + arduino_home + '/hardware/arduino/sam/system/CMSIS/CMSIS/Include/', + arduino_home + '/hardware/arduino/sam/system//CMSIS/Device/ATMEL']) + env.AppendUnique(ASFLAGS = ['-x', 'assembler-with-cpp']) + env.AppendUnique(ASFLAGS = comm_flag) + env.AppendUnique(CFLAGS = Split(platform_info.get('compiler.c.flags'))) + env.AppendUnique(CXXFLAGS = Split(platform_info.get('compiler.cpp.flags'))) + env.AppendUnique(ARFLAGS = Split(platform_info.get('compiler.ar.flags'))) + env.AppendUnique(CCFLAGS = comm_flag) + + extra_flags = __get_board_info(board, '.build.extra_flags') + if extra_flags: + extra_flags = extra_flags.replace('{build.usb_flags}', '') + env.AppendUnique(CCFLAGS = Split(extra_flags)) + usb_flags = ['-DUSB_VID=' + usb_vid, '-DUSB_PID=' + usb_pid, '-DUSBCON', '-DUSB_MANUFACTURER="Unknown"'] + env.AppendUnique(CCFLAGS = usb_flags) + + if target_arch == 'arm': + env.AppendUnique(LINKFLAGS = ['-Os', '-Wl,--gc-sections', cpu_flag, + '-T' + variant_folder + '/' + __get_board_info(board, '.build.ldscript'), + '-Wl,-Map,' + env.get('BUILD_DIR') + 'arduino_prj.map']) + env.AppendUnique(LINKFLAGS = Split('-lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group')) + + variant_system_lib = __get_board_info(board, '.build.variant_system_lib') + if variant_system_lib: + if variant_folder.find(' ') >= 0: + variant_folder = '"' + variant_folder + '"' + env.Replace(LINKCOM = '$LINK -o $TARGET $_LIBDIRFLAGS $LINKFLAGS $SOURCES $_LIBFLAGS ' + + variant_folder + '/' + variant_system_lib + ' -Wl,--end-group') + else: + env.Replace(LINKCOM = '$LINK -o $TARGET $_LIBDIRFLAGS $LINKFLAGS $SOURCES $_LIBFLAGS -Wl,--end-group') + else: + env.AppendUnique(LINKFLAGS = Split(platform_info.get('compiler.c.elf.flags'))) + env.AppendUnique(LINKFLAGS = [cpu_flag]) + env.AppendUnique(LIBS = 'm') + env.Replace(ARCOM = '$AR ' + platform_info.get('compiler.ar.flags') + ' $TARGET $SOURCES') + +__build_core(env) + +env.AddMethod(__import_lib, "ImportLib") #import arduino library +#env.AddMethod(__build_core, "BuildCore") #build arduino core +env.AddMethod(__create_bin, "CreateBin") #create binary files(.eep and .hex) +env.AddMethod(__upload, "Upload") #Upload binary to board +env.AddMethod(__upload_help, "UploadHelp") #print the command line that to upload binary to the boardf + diff --git a/resource/csdk/connectivity/build/arduino/arduino.scons b/resource/csdk/connectivity/build/arduino/arduino.scons new file mode 100644 index 0000000..4c13ebd --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/arduino.scons @@ -0,0 +1,29 @@ +## +# This script includes arduino specific config for oic-resource +## +Import('env') + +# Add 'SHIELD' build option, let user select board network connection type +vars = Variables() +if 'IP' in env.get('TARGET_TRANSPORT'): + vars.Add(EnumVariable('SHIELD', 'Network connection type', 'WIFI', ['ETH', 'WIFI'])) +elif 'BLE' in env.get('TARGET_TRANSPORT'): + vars.Add(EnumVariable('SHIELD', 'Network connection type', 'RBL_NRF8001', ['RBL_NRF8001'])) +vars.Update(env) +Help(vars.GenerateHelpText(env)) + +env.ImportLib('SPI') +if 'ETH' in env.get('SHIELD'): + env.ImportLib('Ethernet') +if 'WIFI' in env.get('SHIELD'): + env.ImportLib('WiFi') +if 'RBL_NRF8001' in env.get('SHIELD'): + env.ImportLib('BLE') + env.ImportLib('RBL_nRF8001') + +env.ImportLib('Time/Time') +# we have variety of macros for arduino!! +env.AppendUnique(CPPDEFINES = ['WITH_ARDUINO', '__ARDUINO__']) +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['TB_LOG']) + diff --git a/resource/csdk/connectivity/build/arduino/arduinomega.properties b/resource/csdk/connectivity/build/arduino/arduinomega.properties new file mode 100755 index 0000000..9d55105 --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/arduinomega.properties @@ -0,0 +1,121 @@ +#Source directories +BASE_DIR = ../.. +SDIR_ARD_CORE1 = $(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time/Time +SDIR_ARD_BASE1 = $(BASE_DIR)/common/src/ +SDIR_ARD_BASE2 = $(BASE_DIR)/samples/arduino/ +SDIR_ARD_SPI = $(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI +SDIR_ARD_CALOGIC = $(BASE_DIR)/src/ +SDIR_ARD_UTIL = $(BASE_DIR)/src/adapter_util/ + +ifeq ($(TRANSPORT),ETHERNET) + SDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet/src + SDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/src/utility + SDIR_ARD_ETH1 = $(BASE_DIR)/src/ethernet_adapter/arduino/:$(BASE_DIR)/src/ethernet_adapter/ + SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_BASE1):$(SDIR_ARD_BASE2):$(SDIR_ARD_SPI) \ + $(SDIR_ARD_CALOGIC):$(SDIR_ARD_UTIL):$(SDIR_ARD_ETH):$(SDIR_ARD_ETH_UTIL):$(SDIR_ARD_ETH1) +else ifeq ($(TRANSPORT),WIFI) + SDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi/src + SDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/src/utility + SDIR_ARD_WIFI1 = $(BASE_DIR)/src/wifi_adapter/arduino/:$(BASE_DIR)/src/wifi_adapter/ + SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_BASE1):$(SDIR_ARD_BASE2):$(SDIR_ARD_SPI) \ + $(SDIR_ARD_CALOGIC):$(SDIR_ARD_UTIL):$(SDIR_ARD_WIFI):$(SDIR_ARD_WIFI_UTIL):$(SDIR_ARD_WIFI1) +else ifeq ($(TRANSPORT),BLE) + SDIR_ARD_BLE = $(ARDUINO_DIR)/libraries/BLE + SDIR_ARD_RBL = $(ARDUINO_DIR)/libraries/RBL_nRF8001 + SDIR_ARD_BLE1 = $(BASE_DIR)/src/bt_le_adapter/arduino/ + SDIR_ARD_BLE2 = $(BASE_DIR)/src/bt_le_adapter/ + SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_BASE1):$(SDIR_ARD_BASE2):$(SDIR_ARD_SPI) \ + $(SDIR_ARD_CALOGIC):$(SDIR_ARD_UTIL):$(SDIR_ARD_BLE):$(SDIR_ARD_RBL):$(SDIR_ARD_BLE1):$(SDIR_ARD_BLE2) +else + $(info *********error**********) + $(error Wrong value for TRANSPORT !!) +endif + +#include directories +IDIR_ARD_CORE1 = $(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +IDIR_ARD_CORE2 = $(ARDUINO_DIR)/hardware/tools/avr/avr/include/ +IDIR_ARD_CORE3 = $(ARDUINO_DIR)/hardware/arduino/avr/variants/mega +INCD_ARD_TIME = $(ARDUINO_DIR)/libraries/Time/Time +IDIR_ARD_SPI = $(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI +INCD_ARD_BASE1 = $(BASE_DIR)/inc/ +INCD_ARD_BASE2 = $(BASE_DIR)/common/inc/ +INCD_ARD_BASE3 = $(BASE_DIR)/api/ +INCD_ARD_BASE4 = $(BASE_DIR)/lib/libcoap-4.1.1/ +#ntohs and htons are defined in util.h in the below path +IDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/src/utility + +ifeq ($(TRANSPORT),ETHERNET) + IDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet/src + IDIR_ARD_ETH1 = $(BASE_DIR)/src/ethernet_adapter/arduino/ + INC_DIR_PLATFORM = -I$(IDIR_ARD_CORE1) -I$(IDIR_ARD_CORE2) -I$(IDIR_ARD_CORE3) \ + -I$(INCD_ARD_TIME) -I$(IDIR_ARD_SPI) \ + -I$(INCD_ARD_BASE1) -I$(INCD_ARD_BASE2) -I$(INCD_ARD_BASE3) \ + -I$(INCD_ARD_BASE4) -I$(IDIR_ARD_ETH) -I$(IDIR_ARD_ETH_UTIL) \ + -I$(IDIR_ARD_ETH1) +else ifeq ($(TRANSPORT),WIFI) + IDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi/src + IDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/src/utility + INC_DIR_PLATFORM = -I$(IDIR_ARD_CORE1) -I$(IDIR_ARD_CORE2) -I$(IDIR_ARD_CORE3) \ + -I$(INCD_ARD_TIME) -I$(IDIR_ARD_SPI) \ + -I$(INCD_ARD_BASE1) -I$(INCD_ARD_BASE2) -I$(INCD_ARD_BASE3) \ + -I$(INCD_ARD_BASE4) -I$(IDIR_ARD_ETH_UTIL) -I$(IDIR_ARD_WIFI) \ + -I$(IDIR_ARD_WIFI_UTIL) +else ifeq ($(TRANSPORT),BLE) + IDIR_ARD_BLE = $(ARDUINO_DIR)/libraries/BLE + IDIR_ARD_RBL = $(ARDUINO_DIR)/libraries/RBL_nRF8001 + INCD_ARD_BLE1 = $(BASE_DIR)/src/bt_le_adapter/arduino/ + INC_DIR_PLATFORM = -I$(IDIR_ARD_CORE1) -I$(IDIR_ARD_CORE2) -I$(IDIR_ARD_CORE3) \ + -I$(INCD_ARD_TIME) -I$(IDIR_ARD_SPI) \ + -I$(INCD_ARD_BASE1) -I$(INCD_ARD_BASE2) -I$(INCD_ARD_BASE3) \ + -I$(INCD_ARD_BASE4) -I$(IDIR_ARD_ETH_UTIL) -I$(IDIR_ARD_BLE) \ + -I$(IDIR_ARD_RBL) -I$(INCD_ARD_BLE1) +else + $(info *********error**********) + $(error Wrong value for TRANSPORT !!) +endif + +#Compiler/Linker flags +CFLAGS_PLATFORM = -mmcu=atmega2560 -DF_CPU=16000000L -fno-exceptions -ffunction-sections -fdata-sections -MMD -DARDUINO=157 -DARDUINO_ARCH_AVR \ + -DARDUINO_AVR_ADK + +#Compilers +$(info ************ arduinoMEGA file*****************) + +CCPLUS=$(ARDUINO_TOOLS_DIR)/avr-g++ +CC=$(ARDUINO_TOOLS_DIR)/avr-gcc +AR=$(ARDUINO_TOOLS_DIR)/avr-ar +RANLIB=$(ARDUINO_TOOLS_DIR)/avr-ranlib +AVR_OBJCOPY=$(ARDUINO_TOOLS_DIR)/avr-objcopy +AVR_PROGRAMMER=$(ARDUINO_TOOLS_DIR)/avrdude + +#Objects +CORE_COBJ = hooks.c.o WInterrupts.c.o wiring.c.o wiring_digital.c.o wiring_analog.c.o wiring_shift.c.o wiring_pulse.c.o +CORE_CPPOBJ = CDC.cpp.o HardwareSerial.cpp.o HardwareSerial0.cpp.o HardwareSerial1.cpp.o HardwareSerial2.cpp.o HardwareSerial3.cpp.o IPAddress.cpp.o HID.cpp.o \ + main.cpp.o new.cpp.o Print.cpp.o Stream.cpp.o Tone.cpp.o USBCore.cpp.o WMath.cpp.o WString.cpp.o +SPI_OBJ = SPI.cpp.o +LOGGER_OBJ = logger.c.o oic_logger.c.o oic_console_logger.c.o oic_malloc.c.o oic_string.c.o uarraylist.c.o +UTIL_OBJ = caadapterutils.c.o camsgparser.c.o +CACOMMON_OBJ = caconnectivitymanager_singlethread.c.o cainterfacecontroller_singlethread.c.o camessagehandler_singlethread.c.o canetworkconfigurator_singlethread.c.o caprotocolmessage_singlethread.c.o \ + caremotehandler.c.o caretransmission_singlethread.c.o + +ifeq ($(TRANSPORT),ETHERNET) + ETH_CPPOBJ = Dhcp.o Dns.o Ethernet.o EthernetUdp.o EthernetClient.o + ETH_UTIL_CPPOBJ = socket.o w5100.o + INTERFACE_OBJ = caethernetadapterutils.cpp.o caethernetclient.cpp.o caethernetserver.cpp.o caethernetnwmonitor.cpp.o caethernetadapter_singlethread.c.o + PLATFORM_OBJS = $(CORE_COBJ) $(CORE_CPPOBJ) $(SPI_OBJ) $(LOGGER_OBJ) $(INTERFACE_OBJ) $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ) $(UTIL_OBJ) $(CACOMMON_OBJ) +else ifeq ($(TRANSPORT),WIFI) + WIFI_CPPOBJ = WiFi.cpp.o WiFiClient.cpp.o WiFiServer.cpp.o WiFiUdp.cpp.o + WIFI_UTIL_CPPOBJ = server_drv.cpp.o spi_drv.cpp.o wifi_drv.cpp.o + INTERFACE_OBJ = cawificlient.cpp.o cawifiserver.cpp.o cawifinwmonitor.cpp.o cawifiadapter_singlethread.c.o + PLATFORM_OBJS = $(CORE_COBJ) $(CORE_CPPOBJ) $(SPI_OBJ) $(LOGGER_OBJ) $(INTERFACE_OBJ) $(WIFI_CPPOBJ) $(WIFI_UTIL_CPPOBJ) $(UTIL_OBJ) $(CACOMMON_OBJ) +else ifeq ($(TRANSPORT),BLE) + BLE_OBJ = aci_queue.cpp.o aci_setup.cpp.o acilib.cpp.o hal_aci_tl.cpp.o lib_aci.cpp.o + RBL_OBJ = RBL_nRF8001.cpp.o + INTERFACE_OBJ = caleadapter_singlethread.c.o cableserver.cpp.o cablenwmonitor.cpp.o + PLATFORM_OBJS = $(CORE_COBJ) $(CORE_CPPOBJ) $(SPI_OBJ) $(LOGGER_OBJ) $(INTERFACE_OBJ) $(BLE_OBJ) $(RBL_OBJ) $(UTIL_OBJ) $(CACOMMON_OBJ) +else + $(info *********error**********) + $(error Wrong value for TRANSPORT !!) +endif + diff --git a/resource/csdk/connectivity/build/arduino/build.sh b/resource/csdk/connectivity/build/arduino/build.sh new file mode 100755 index 0000000..ccedb4c --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/build.sh @@ -0,0 +1,21 @@ +#!/bin/sh +if echo $1 | grep -q -i "clean" +then +cd ../lib/libcoap-4.1.1/ +make -f makefile_arduino.mak clean +cd ../../build/arduino +make clean +else +if echo $1 | grep -q -i "make" +then +cd ../lib/libcoap-4.1.1/ +make -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4 +cd ../../build/arduino +make PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5 +else +cd ../lib/libcoap-4.1.1/ +make $1 -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4 +cd ../../build/arduino/ +make $1 PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5 +fi +fi \ No newline at end of file diff --git a/resource/csdk/connectivity/build/arduino/local.properties b/resource/csdk/connectivity/build/arduino/local.properties new file mode 100755 index 0000000..633e822 --- /dev/null +++ b/resource/csdk/connectivity/build/arduino/local.properties @@ -0,0 +1,3 @@ +ARDUINO_DIR = /usr/share/arduino +ARDUINO_TOOLS_DIR = $(ARDUINO_DIR)/hardware/tools/avr/bin + diff --git a/resource/csdk/connectivity/build/common.mk b/resource/csdk/connectivity/build/common.mk new file mode 100644 index 0000000..858dda1 --- /dev/null +++ b/resource/csdk/connectivity/build/common.mk @@ -0,0 +1,60 @@ +#/****************************************************************** +# * +# * Copyright 2014 Samsung Electronics All Rights Reserved. +# * +# * +# * +# * 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. +# * +#******************************************************************/ + +## +## Definitions +## +SHELL = /bin/bash +PROJECT_NAME = connectivity_abstraction +PROJECT_ROOT_PATH = .. +PROJECT_API_PATH = $(PROJECT_ROOT_PATH)/api +PROJECT_INC_PATH = $(PROJECT_ROOT_PATH)/inc +PROJECT_SRC_PATH = $(PROJECT_ROOT_PATH)/src +PROJECT_COMMON_INC_PATH = $(PROJECT_ROOT_PATH)/common/inc +PROJECT_COMMON_SRC_PATH = $(PROJECT_ROOT_PATH)/common/src +PROJECT_COMMON_PATH = $(PROJECT_ROOT_PATH)/common +PROJECT_OUT_PATH = $(PROJECT_ROOT_PATH)/build/out +PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/lib + +## +## macro +## +define MAKE_PROJECT_OUT_PATH + @if [ ! -d $(PROJECT_OUT_PATH) ]; then \ + mkdir $(PROJECT_OUT_PATH); \ + fi +endef + + +## +## Commands +## +CC = gcc +CXX = g++ +RM = rm -rf +CP = cp +MV = mv +AR = ar +LD = ld +LN = ln +CD = cd +RANLIB = ranlib + + diff --git a/resource/csdk/connectivity/build/linux/Makefile b/resource/csdk/connectivity/build/linux/Makefile deleted file mode 100644 index 7fb550a..0000000 --- a/resource/csdk/connectivity/build/linux/Makefile +++ /dev/null @@ -1,161 +0,0 @@ -#/****************************************************************** -# * -# * Copyright 2014 Samsung Electronics All Rights Reserved. -# * -# * -# * -# * 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. -# * -#******************************************************************/ - -# override with `make BUILD=debug` -# default to release build -# default to build for linux -BUILD = release -PLATFORM = linux -TRANSPORT = ALL -OBJ_DIR = ./$(BUILD) -VERSION_MAJOR = 0 -VERSION_MINOR = 1 -VERSION_PATCH = 0 - -COMMON_MAKE = common.mk - -include $(COMMON_MAKE) - -#Modify below values to enable/disable the Adapter -#Suffix "NO_" to disable given adapter -EDR = NO_EDR_ADAPTER -WIFI = WIFI_ADAPTER -LE = NO_LE_ADAPTER -ETHERNET = NO_ETHERNET_ADAPTER - -#Add Pre processor definitions -DEFINE_FLAG = -D$(EDR) -D$(LE) -D$(WIFI) -D$(ETHERNET) - -#Add Debug flags here -DEBUG_FLAG = -DTB_LOG - -## -## definitions -## -LIB_PREFIX = CA -ETHERNET_ADAPTER = ethernet_adapter -WIFI_ADAPTER = wifi_adapter -BT_ADAPTER = bt_edr_adapter -BLE_ADAPTER = bt_le_adapter -ETHERNET_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(ETHERNET_ADAPTER)/$(PLATFORM) -WIFI_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(WIFI_ADAPTER)/$(PLATFORM) -BT_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(BT_ADAPTER)/$(PLATFORM) -BLE_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(BLE_ADAPTER)/$(PLATFORM) -TARGET = lib$(PROJECT_NAME).so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) -TARGET_ALIAS = lib$(PROJECT_NAME).so - -## -## libcoap -## -libcoap_build_dir = $(PROJECT_LIB_PATH)/libcoap-4.1.1 - -LDFLAGS:=-L$(libcoap_build_dir) -LDLIBS:=-lcoap - -BUILD_FLAG.debug = $(DEFINE_FLAG) $(DEBUG_FLAG) -BUILD_FLAG.release = $(DEFINE_FLAG) -BUILD_FLAG = $(BUILD_FLAG.$(BUILD)) - -DEBUG_DIR = ./debug -RELEASE_DIR = ./release - -## -## file declaration -## -COMPONENT_SRCS = \ -logger.c oic_malloc.c oic_logger.c oic_console_logger.c \ -caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c \ -canetworkconfigurator.c caedradapter.c caleadapter.c \ -caethernetadapter.c cawifiadapter.c \ -caprotocolmessage.c cawificore.c \ -uqueue.c uarraylist.c umutex.c uthreadpool.c \ - -COMPONENT_OBJS = $(COMPONENT_SRCS:%.c=$(OBJ_DIR)/%.o) - -## -## compiler flags -## -CFLAGS = -g -c -Wall -fPIC `pkg-config --cflags glib-2.0` - -LFLAGS = -ldl -lpthread `pkg-config --libs glib-2.0` - -IFLAGS = -I$(PROJECT_COMMON_INC_PATH) \ - -I$(PROJECT_API_PATH) \ - -I$(PROJECT_INC_PATH) \ - -I$(ETHERNET_ADAPTER_PATH) \ - -I$(WIFI_ADAPTER_PATH) \ - -I$(BT_ADAPTER_PATH) \ - -I$(BLE_ADAPTER_PATH) \ - -I$(libcoap_build_dir) - -DFLAGS = -DLINUX \ - -DWITH_POSIX \ - $(BUILD_FLAG)\ -## -## compile and link rules -## -vpath %.c $(PROJECT_COMMON_SRC_PATH) -vpath %.c $(ETHERNET_ADAPTER_PATH) -vpath %.c $(WIFI_ADAPTER_PATH) -vpath %.c $(BT_ADAPTER_PATH) -vpath %.c $(BLE_ADAPTER_PATH) -vpath %.c $(PROJECT_SRC_PATH) - -$(OBJ_DIR)/%.o: %.c - @$(MAKE_OBJ_PATH) - @$(CC) -o $@ $(CFLAGS) $(DFLAGS) $(IFLAGS) $< - -all : $(TARGET) - @echo " " - @echo "======================" - @echo " Success!!" - @echo "======================" - -$(TARGET) : $(COMPONENT_OBJS) - @$(MAKE_PROJECT_OUT_PATH) - @$(CC) -shared -Wl,-soname,$(TARGET) -o $@ $(COMPONENT_OBJS) $(LFLAGS) $(LDFLAGS) $(LDLIBS) - @$(MV) $(TARGET) $(PROJECT_OUT_PATH)/. - @$(CD) $(PROJECT_OUT_PATH); $(MAKE_TARGET_ALIAS) - -clean : - @$(RM) $(DEBUG_DIR) $(RELEASE_DIR)\ - $(PROJECT_OUT_PATH) - -install : - @$(MAKE_PROJECT_OUT_PATH) - -## -## macros -## -define MAKE_OBJ_PATH - @if [ ! -d $(OBJ_DIR) ]; then \ - mkdir $(OBJ_DIR); \ - fi -endef - -define MAKE_TARGET_ALIAS - if [ ! -f $(TARGET_ALIAS) ]; then \ - $(LN) -s $(TARGET) $(TARGET_ALIAS); \ - fi -endef - -.PHONY: all clean install - - diff --git a/resource/csdk/connectivity/build/linux/SConscript b/resource/csdk/connectivity/build/linux/SConscript new file mode 100644 index 0000000..bc0176d --- /dev/null +++ b/resource/csdk/connectivity/build/linux/SConscript @@ -0,0 +1,41 @@ +## +# This script set linux specific flags (GNU GCC) +# +## +Import('env') + +print "Reading linux configuration script" + +# Set release/debug flags +if env.get('RELEASE'): + env.AppendUnique(CCFLAGS = ['-Os']) + env.AppendUnique(CPPDEFINES = ['NDEBUG']) +else: + env.AppendUnique(CCFLAGS = ['-g']) + +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + +env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__linux__']) +env.AppendUnique(CCFLAGS = ['-Wall', '-fPIC']) +env.AppendUnique(LINKFLAGS = ['-ldl', '-lpthread']) + +# Set arch flags +target_arch = env.get('TARGET_ARCH') +if target_arch in ['x86']: + env.AppendUnique(CCFLAGS = ['-m32']) + env.AppendUnique(LINKFLAGS = ['-m32']) +elif target_arch in ['x86_64']: + env.AppendUnique(CCFLAGS = ['-m64']) + env.AppendUnique(LINKFLAGS = ['-m64']) +elif target_arch.find('v7a-hard') > 0: + env.AppendUnique(CPPFLAGS = ['-march=armv7-a']) + env.AppendUnique(CPPFLAGS = ['-mfloat-abi=hard']) + env.AppendUnique(CCFLAGS = ['-mfloat-abi=hard']) + env.AppendUnique(LINKFLAGS = ['-mfloat-abi=hard']) +elif target_arch.find('v7a') > 0: + env.AppendUnique(CPPFLAGS = ['-march=armv7-a']) +elif target_arch.find('arm64') > 0: + env.AppendUnique(CPPFLAGS = ['-march=armv8-a']) +else: + env.AppendUnique(CPPFLAGS = ['-march=armv5te']) diff --git a/resource/csdk/connectivity/build/linux/common.mk b/resource/csdk/connectivity/build/linux/common.mk deleted file mode 100644 index fe66585..0000000 --- a/resource/csdk/connectivity/build/linux/common.mk +++ /dev/null @@ -1,59 +0,0 @@ -#/****************************************************************** -# * -# * Copyright 2014 Samsung Electronics All Rights Reserved. -# * -# * -# * -# * 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. -# * -#******************************************************************/ - -## -## Definitions -## -SHELL = /bin/bash -PROJECT_NAME = connectivity_abstraction -PROJECT_ROOT_PATH = ../.. -PROJECT_API_PATH = $(PROJECT_ROOT_PATH)/api -PROJECT_INC_PATH = $(PROJECT_ROOT_PATH)/inc -PROJECT_SRC_PATH = $(PROJECT_ROOT_PATH)/src -PROJECT_COMMON_INC_PATH = $(PROJECT_ROOT_PATH)/common/inc -PROJECT_COMMON_SRC_PATH = $(PROJECT_ROOT_PATH)/common/src -PROJECT_COMMON_PATH = $(PROJECT_ROOT_PATH)/common -PROJECT_OUT_PATH = $(PROJECT_ROOT_PATH)/build/out -PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/lib - -## -## macro -## -define MAKE_PROJECT_OUT_PATH - @if [ ! -d $(PROJECT_OUT_PATH) ]; then \ - mkdir $(PROJECT_OUT_PATH); \ - fi -endef - - -## -## Commands -## -CC = gcc -CXX = g++ -RM = rm -rf -CP = cp -MV = mv -AR = ar -LD = ld -LN = ln -CD = cd -RANLIB = ranlib - diff --git a/resource/csdk/connectivity/build/tizen/Makefile b/resource/csdk/connectivity/build/tizen/Makefile new file mode 100644 index 0000000..8e56590 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/Makefile @@ -0,0 +1,65 @@ +## +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# default to release build +# default to build for linux +BUILD := debug +PLATFORM := tizen +OBJ_DIR := ./bin +ROOT_DIR := . +VERSION_MAJOR := 0 +VERSION_MINOR := 1 +VERSION_PATCH := 0 +ADAPTER_MACRO := -DWIFI_ADAPTER + +$(info *******************tizen Build !!******************) + +CC=gcc +LIBCOAP=./lib/libcoap-4.1.1/ +LIBCOAP_OBJ_DIR=./lib/libcoap-4.1.1/obj + +TINYDTLS=./lib/extlibs/tinydtls +TINYDTLS_OBJ_DIR=./lib/extlibs/tinydtls/obj + +# TODO : Currently Hardcoded WIFI_ADAPTER. Change it to generic +CFLAGS.debug = -DWITH_POSIX -D__TIZEN__ -Wall -std=c99 -DSLP_SDK_LOG -g -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO) +CFLAGS.release = -DWITH_POSIX -D__TIZEN__ -Wall -std=c99 -DSLP_SDK_LOG -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO) +COMPILEFLAG = `pkg-config --cflags --libs capi-network-wifi dlog capi-network-bluetooth glib-2.0` + +# Include files will be copied into a single folder on gbsbuild. +# NO NEED to mention the path explicitly. + +CA_INC = $(ROOT_DIR)/ +DTLS_INC = $(ROOT_DIR)/dtls/ + +INC_DIRS := -I$(CA_INC) +INC_DIRS += -I$(DTLS_INC) + +SRC = $(wildcard *.c) +OBJECTS = $(patsubst %.c, %.o, $(SRC)) + +#Currently compiling libcoap objects. If it's provided by external party. +#Then don't compile, Instead directly extract objects and create liboicinterface.a +all: $(OBJECTS) + $(MAKE) -C $(LIBCOAP) clean + $(MAKE) -C $(LIBCOAP) + -mkdir $(LIBCOAP_OBJ_DIR) + @cd $(LIBCOAP_OBJ_DIR) && $(AR) -x ../libcoap.a + ar rcs liboicinterface.a $(OBJECTS) $(LIBCOAP_OBJ_DIR)/*.o + +%.o : %.c + $(CC) -c $(CFLAGS.$(BUILD)) $(COMPILEFLAG) $(INC_DIRS) $< -o $@ + + +pack: +#$(CC) $(CFLAGS) $(COMPILEFLAG) WiFiInterface.c bt_interface.c tc_interface.c sample_main.c -o sample /usr/lib/liboctbstack.a -lm -pthread + $(info **************************************TEST***************************) +install: +#cp -rf sample ./usr/apps/com.samsung.oicca/bin/sample + +clean: + rm -rf *.o sample + rm -f *.o *.d *.elf *.eep core.a *.hex *.bin *.map *- + rm -rf $(OBJ_DIR) + rm -rf $(LIBCOAP_OBJ_DIR) + diff --git a/resource/csdk/connectivity/build/tizen/SConscript b/resource/csdk/connectivity/build/tizen/SConscript new file mode 100644 index 0000000..c8c105c --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/SConscript @@ -0,0 +1,23 @@ +## +# CA build script +## + +SConscript('./resource/csdk/connectivity/build/SConscript') + +Import('env') + +target_os = env.get('TARGET_OS') +transport = env.get('TARGET_TRANSPORT') +buildsample = env.get('BUILD_SAMPLE') +release_mode = env.get('RELEASE') +secured = env.get('SECURED') +logging = env.get('LOGGING') + +print "Given Transport is %s" % transport +print "Given OS is %s" % target_os + +if target_os == 'tizen': + command = "sh resource/csdk/connectivity/build/tizen/gbsbuild.sh %s %s %s %s %s" % (transport, secured, buildsample, release_mode, logging) + print "Created Command is %s" % command + gbs_script = env.Command('gbs_build', None, command) + AlwaysBuild ('gbs_script') \ No newline at end of file diff --git a/resource/csdk/connectivity/build/tizen/SConstruct b/resource/csdk/connectivity/build/tizen/SConstruct new file mode 100644 index 0000000..eb0f0d2 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/SConstruct @@ -0,0 +1,19 @@ +## +# The main build script +# +## + +# Load common build config + +# Load common build config +env = SConscript('SConscript') + +target_os = env.get('TARGET_OS') +transport = env.get('TARGET_TRANSPORT') +release_mode = env.get('RELEASE') + +print "Given Transport is %s" % transport +print "Given OS is %s" % target_os +print "Given release mode is %s" % release_mode + +env.SConscript('scons/SConscript') diff --git a/resource/csdk/connectivity/build/tizen/com.oic.ca.manifest b/resource/csdk/connectivity/build/tizen/com.oic.ca.manifest new file mode 100644 index 0000000..c26f59d --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/com.oic.ca.manifest @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resource/csdk/connectivity/build/tizen/com.oic.ca.pc b/resource/csdk/connectivity/build/tizen/com.oic.ca.pc new file mode 100644 index 0000000..fbfa187 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/com.oic.ca.pc @@ -0,0 +1,10 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include/OICHeaders + +Name: com-oic-ca +Description: Oic core library +Version: 1.0 +Cflags: -I${includedir} + diff --git a/resource/csdk/connectivity/build/tizen/gbsbuild.sh b/resource/csdk/connectivity/build/tizen/gbsbuild.sh new file mode 100755 index 0000000..528b060 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/gbsbuild.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +cur_dir="./resource/csdk/connectivity/" + +spec=`ls ./resource/csdk/connectivity/build/tizen/packaging/*.spec` +version=`rpm --query --queryformat '%{version}\n' --specfile $spec` + +name=`echo $name|cut -d" " -f 1` +version=`echo $version|cut -d" " -f 1` + +name=oicca + +echo $1 +export TARGET_TRANSPORT=$1 + +echo $2 +export SECURED=$2 + +echo $3 +export BUILD_SAMPLE=$3 + +echo $4 +export RELEASE=$4 + +echo $5 +export LOGGING=$5 + + +echo $TARGET_TRANSPORT +echo $BUILD_SAMPLE + +rm -rf $name-$version + +builddir=`pwd` +sourcedir=`pwd` + +echo `pwd` + +mkdir ./tmp +mkdir ./tmp/con/ +cp -R $cur_dir/* $sourcedir/tmp/con +cp -R $cur_dir/SConscript $sourcedir/tmp/con +cp -R $cur_dir/src/ip_adapter/SConscript $sourcedir/tmp/con/src/ip_adapter/ +cp -R $cur_dir/src/bt_le_adapter/SConscript $sourcedir/tmp/con/src/bt_le_adapter/ +cp -R $cur_dir/src/bt_edr_adapter/SConscript $sourcedir/tmp/con/src/bt_edr_adapter/ +cp -R $cur_dir/common/SConscript $sourcedir/tmp/con/common/ +cp -R $cur_dir/lib/libcoap-4.1.1/SConscript $sourcedir/tmp/con/lib/libcoap-4.1.1/ +cp -R $cur_dir/samples/tizen/ $sourcedir/tmp/con/sample/ +mkdir -p $sourcedir/tmp/con/sample/lib/tizen/ble/libs +cp -R $cur_dir/lib/tizen/ble/libs/* $sourcedir/tmp/con/sample/lib/tizen/ble/libs/ + +cd $sourcedir +cd $cur_dir/build/tizen + +cp -R ./* $sourcedir/tmp/ +rm -f $sourcedir/tmp/SConscript +cp SConstruct $sourcedir/tmp/ +cp scons/SConscript $sourcedir/tmp/scons/ + +mkdir -p $sourcedir/tmp/iotivityconfig +cd $sourcedir/build_common/ +cp -R ./iotivityconfig/* $sourcedir/tmp/iotivityconfig/ +cp -R ./SConscript $sourcedir/tmp/ + +cd $sourcedir/tmp + +echo `pwd` + +whoami +# Initialize Git repository +if [ ! -d .git ]; then + git init ./ + git config user.email "you@example.com" + git config user.name "Your Name" + git add ./ + git commit -m "Initial commit" +fi + +echo "Calling core gbs build command" +gbscommand="gbs build -A armv7l --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'RELEASE $4' --define 'LOGGING $5' --repository ./" +echo $gbscommand +if eval $gbscommand; then + echo "Core build is successful" +else + echo "Core build failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder" + cd $sourcedir + rm -rf $sourcedir/tmp + exit +fi + +if echo $BUILD_SAMPLE|grep -qi '^ON$'; then + cd con/sample + echo `pwd` + # Initialize Git repository + if [ ! -d .git ]; then + git init ./ + git config user.email "you@example.com" + git config user.name "Your Name" + git add ./ + git commit -m "Initial commit" + fi + echo "Calling sample gbs build command" + gbscommand="gbs build -A armv7l --include-all --define 'TARGET_TRANSPORT $1' --define 'SECURED $2' --define 'LOGGING $5' --repository ./" + echo $gbscommand + if eval $gbscommand; then + echo "Sample build is successful" + else + echo "Sample build is failed. Try 'sudo find . -type f -exec dos2unix {} \;' in the 'connectivity/' folder" + fi +else + echo "Sample build is not enabled" +fi + + +cd $sourcedir +rm -rf $sourcedir/tmp + diff --git a/resource/csdk/connectivity/build/tizen/packaging/com.oic.ca.spec b/resource/csdk/connectivity/build/tizen/packaging/com.oic.ca.spec new file mode 100644 index 0000000..aba2653 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/packaging/com.oic.ca.spec @@ -0,0 +1,62 @@ +%define PREFIX /usr/apps/com.oic.ca +%define ROOTDIR %{_builddir}/%{name}-%{version} +%define DEST_INC_DIR %{buildroot}/%{_includedir}/OICHeaders +%define DEST_LIB_DIR %{buildroot}/%{_libdir} + +Name: com-oic-ca +Version: 0.1 +Release: 1 +Summary: Tizen oicca application +URL: http://slp-source.sec.samsung.net +Source: %{name}-%{version}.tar.gz +License: Apache-2.0 +Group: Applications/OIC +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(capi-network-bluetooth) +BuildRequires: boost-devel +BuildRequires: boost-thread +BuildRequires: boost-system +BuildRequires: boost-filesystem +BuildRequires: scons + + +%description +SLP oicca application + +%prep + +%setup -q + +%build + +echo %{ROOTDIR} + +scons TARGET_OS=tizen -c +scons TARGET_OS=tizen TARGET_TRANSPORT=%{TARGET_TRANSPORT} SECURED=%{SECURED} RELEASE=%{RELEASE} LOGGING=%{LOGGING} + +%install +mkdir -p %{DEST_INC_DIR} +mkdir -p %{DEST_LIB_DIR}/pkgconfig + +cp -f %{ROOTDIR}/con/src/libconnectivity_abstraction.so %{buildroot}/%{_libdir} +cp -f %{ROOTDIR}/con/lib/libcoap-4.1.1/libcoap.a %{buildroot}/%{_libdir} +cp -rf %{ROOTDIR}/con/api/cacommon.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/inc/caadapterinterface.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/common/inc/cathreadpool.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/inc/caipadapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/inc/caedradapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/inc/caleadapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/con/api/cainterface.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/com.oic.ca.pc %{DEST_LIB_DIR}/pkgconfig/ + + +%files +%manifest com.oic.ca.manifest +%defattr(-,root,root,-) +%{_libdir}/lib*.so* +%{_libdir}/lib*.a* +%{_includedir}/OICHeaders/* +%{_libdir}/pkgconfig/*.pc + diff --git a/resource/csdk/connectivity/build/tizen/scons/SConscript b/resource/csdk/connectivity/build/tizen/scons/SConscript new file mode 100644 index 0000000..318d954 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/scons/SConscript @@ -0,0 +1,46 @@ +## +# 'resource' sub-project main build script +# +## + +Import('env') + +target_os = env.get('TARGET_OS') +transport = env.get('TARGET_TRANSPORT') + +print "Given Transport is %s" % transport + +if env.get('RELEASE'): + env.AppendUnique(CFLAGS = ['-std=c99', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE']) +else: + env.AppendUnique(CFLAGS = ['-std=c99', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall', '-DSLP_SDK_LOG', '-g','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE']) + +if env.get('LOGGING'): + env.AppendUnique(CPPDEFINES = ['-DTB_LOG']) + +env.ParseConfig("pkg-config --cflags --libs capi-network-wifi dlog glib-2.0") +if 'ALL' in transport: + env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER', 'NO_ETHERNET_ADAPTER','EDR_ADAPTER','LE_ADAPTER']) + print "CA Transport is ALL" +else: + if 'BT' in transport: + env.AppendUnique(CPPDEFINES = ['EDR_ADAPTER']) + print "CA Transport is BT" + else: + env.AppendUnique(CPPDEFINES = ['NO_EDR_ADAPTER']) + + if 'BLE' in transport: + env.AppendUnique(CPPDEFINES = ['LE_ADAPTER']) + print "CA Transport is BLE" + else: + env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER']) + + if 'WIFI' in transport: + env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER']) + print "CA Transport is WIFI" + else: + env.AppendUnique(CPPDEFINES = ['NO_WIFI_ADAPTER']) + + +env.SConscript(['../con/lib/libcoap-4.1.1/SConscript']) +env.SConscript(['../con/SConscript']) diff --git a/resource/csdk/connectivity/common/SConscript b/resource/csdk/connectivity/common/SConscript new file mode 100644 index 0000000..7c6c558 --- /dev/null +++ b/resource/csdk/connectivity/common/SConscript @@ -0,0 +1,60 @@ +## +# CA build script +## + +Import('env') + +print "Reading common folder script" + +ca_os = env.get('TARGET_OS') + +root_dir = './../' + + +ca_common_path = root_dir + 'common/' +ca_common_src_path = ca_common_path + 'src/' + +env.AppendUnique(CPPPATH = [ + 'common/inc/', + ]) + +temp = env['CPPPATH'] +header = ' ' +for item in temp: + header = header + ' -I' + item + +###################################################################### +# Source files and Target(s) +###################################################################### +ca_common_src = [ + ca_common_src_path + 'oic_malloc.c', + ca_common_src_path + 'oic_string.c', + ca_common_src_path + 'uarraylist.c', + ca_common_src_path + 'uqueue.c', + ] + +if ca_os == 'arduino': + env.Command(env.get('BUILD_DIR') + 'logger.c.o', None, '$CXX -o ' + env.get('BUILD_DIR') + 'logger.c.o' + ' $LINKFLAGS $CCFLAGS $CXXFLAGS ' + '-I' + Dir('.').srcnode().path + '/inc' + header + ' ' + Dir('.').srcnode().path + '/src/logger.c') + platform_src = [ + env.get('BUILD_DIR') + 'logger.c.o', + ] +elif env['POSIX_SUPPORTED']: + platform_src = [ + ca_common_src_path + 'logger.c', + ca_common_src_path + 'oic_logger.c', + ca_common_src_path + 'oic_console_logger.c', + ca_common_src_path + 'cathreadpool_pthreads.c', + ca_common_src_path + 'camutex_pthreads.c' + ] +else: + platform_src = [ + ca_common_src_path + 'logger.c', + ca_common_src_path + 'oic_logger.c', + ca_common_src_path + 'oic_console_logger.c' + ] + + + +env.AppendUnique(CA_SRC = ca_common_src) +env.AppendUnique(CA_SRC = platform_src) + diff --git a/resource/csdk/connectivity/common/inc/camutex.h b/resource/csdk/connectivity/common/inc/camutex.h new file mode 100644 index 0000000..be7b085 --- /dev/null +++ b/resource/csdk/connectivity/common/inc/camutex.h @@ -0,0 +1,155 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file provides APIs related to mutex and semaphores. + */ + +#ifndef CA_MUTEX_H_ +#define CA_MUTEX_H_ + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct ca_mutex_internal *ca_mutex; +typedef struct ca_cond_internal *ca_cond; + +/** + * Enums for ca_cond_wait_for return values + */ +typedef enum +{ + CA_WAIT_SUCCESS = 0, /**< Condition Signal */ + CA_WAIT_INVAL = -1, /**< Invalid Condition */ + CA_WAIT_TIMEDOUT = -2 /**< Condition Timed Out */ +} CAWaitResult_t; + +/** + * Creates new mutex. + * + * @return Reference to newly created mutex, otherwise NULL. + * + */ +ca_mutex ca_mutex_new(void); + +/** + * Lock the mutex. + * + * @param mutex The mutex to be locked + * + */ +void ca_mutex_lock(ca_mutex mutex); + +/** + * Checks if the mutex can be locked. + * + * @param mutex The mutex to be locked + * + * @return true if the mutex is not locked currently, otherwise false. + * + */ +bool ca_mutex_trylock(ca_mutex mutex); + +/** + * Unlock the mutex. + * + * @param mutex The mutex to be unlocked + * + */ +void ca_mutex_unlock(ca_mutex mutex); + +/** + * Free the mutex. + * + * @param mutex The mutex to be freed + * + */ +bool ca_mutex_free(ca_mutex mutex); + +/** + * Creates new condition. + * + * @return Reference to newly created @ca_cond, otherwise NULL. + * + */ +ca_cond ca_cond_new(void); + +/** + * One of threads is woken up if multiple threads are waiting for @cond. + * + * @param cond The condtion to be signaled + * + */ +void ca_cond_signal(ca_cond cond); + +/** + * All of threads are woken up if multiple threads are waiting for @cond. + * + * @param cond The condtion to be signaled + * + */ +void ca_cond_broadcast(ca_cond cond); + +/** + * Waits until this thread woken up on @cond. + * + * @param cond The condtion to be wait for to signal + * @param mutex The mutex which is currently locked from calling thread + * + */ +void ca_cond_wait(ca_cond cond, ca_mutex mutex); + +/** + * Waits until this thread woken up on @cond, + * but not longer than the interval specified by microseconds. + * The mutex is unlocked before falling asleep and locked again before resuming. + * If microseconds is 0, ca_cond_wait_for() acts like ca_cond_wait(). + * + * @param cond The condtion to be wait for to signal + * @param mutex The mutex which is currently locked from calling thread + * @param microseconds relative time for waiting, microseconds + * + * @return CA_WAIT_SUCCESS if the condition was signaled. + * CA_WAIT_TIMEDDOUT if wait period exceeded + * CA_WAIT_INVAL for invalid parameters + * + */ +CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds); + +/** + * Free the condition. + * + * @param cond The condition to be freed + * + */ +void ca_cond_free(ca_cond cond); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* CA_MUTEX_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/cathreadpool.h b/resource/csdk/connectivity/common/inc/cathreadpool.h new file mode 100644 index 0000000..9df11e9 --- /dev/null +++ b/resource/csdk/connectivity/common/inc/cathreadpool.h @@ -0,0 +1,90 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file provides APIs related to thread pool. Implementations are provided + * by adding a new .c file for each implementation, and adding them conditionally + * via the SCONS build script. Currently, cathreadpool_pthreads.c is implemented, + * with cathreadpool_winthreads.c being considered. RTOS implementations should use + * a name that best describes the used technology, not the OS. + */ + +#ifndef CA_THREAD_POOL_H_ +#define CA_THREAD_POOL_H_ + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/** + * Callback type can be registered to thread pool. + */ +typedef void (*ca_thread_func)(void *); + +struct ca_thread_pool_details_t; +/** + * Thread pool type. + */ +typedef struct ca_thread_pool +{ + struct ca_thread_pool_details_t* details; +}*ca_thread_pool_t; + +/** + * This function creates a newly allocated thread pool. + * + * @param num_of_threads The number of worker thread used in this pool. + * @param thread_pool_handle Handle to newly create thread pool. + * @return Error code, CA_STATUS_OK if success, else error number. + */ +CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_pool_handle); + +/** + * This function adds a routine to be executed by the thread pool at some future time. + * + * @param thread_pool The thread pool structure. + * @param method The routine to be executed. + * @param data The data to be passed to the routine. + * + * @return CA_STATUS_OK on success. + * @return Error on failure. + */ +CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, + void *data); + +/** + * This function stops all the worker threads (stop & exit). And frees all the allocated memory. + * Function will return only after joining all threads executing the currently scheduled tasks. + * + * @param thread_pool The thread pool structure. + */ +void ca_thread_pool_free(ca_thread_pool_t thread_pool); + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* CA_THREAD_POOL_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/logger.h b/resource/csdk/connectivity/common/inc/logger.h index b19b037..bf6f130 100644 --- a/resource/csdk/connectivity/common/inc/logger.h +++ b/resource/csdk/connectivity/common/inc/logger.h @@ -18,8 +18,8 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifndef _U_LOGGER_H_ -#define _U_LOGGER_H_ +#ifndef U_LOGGER_H_ +#define U_LOGGER_H_ #include #include @@ -29,9 +29,11 @@ #ifdef __ANDROID__ #include +#elif defined(__TIZEN__) +#include #elif defined ARDUINO #include "Arduino.h" -#include +#include "avr/pgmspace.h" #endif #ifdef __cplusplus @@ -42,22 +44,38 @@ extern "C" // Use the PCF macro to wrap strings stored in FLASH on the Arduino // Example: OC_LOG(INFO, TAG, PCF("Entering function")); #ifdef ARDUINO + +#ifdef __cplusplus #define PCF(str) ((PROGMEM const char *)(F(str))) #else +#define PCF(str) ((PROGMEM const char *)(PSTR(str))) +#endif //__cplusplus + +#else #define PCF(str) str -#endif +#endif //ARDUINO // Max buffer size used in variable argument log function #define MAX_LOG_V_BUFFER_SIZE (256) // Log levels +#ifndef __TIZEN__ typedef enum { DEBUG = 0, INFO, WARNING, ERROR, FATAL } LogLevel; +#else +#define DEBUG DLOG_DEBUG +#define INFO DLOG_INFO +#define WARNING DLOG_WARNING +#define ERROR DLOG_ERROR +#define FATAL DLOG_ERROR +#endif -#ifndef ARDUINO - +#ifdef __TIZEN__ +#define OICLog(level,tag,mes) LOG(level,tag,mes) +#define OICLogv(level,tag,fmt,args...) LOG(level,tag,fmt,##args) +#elif defined(ANDROID) || defined(__linux__) || defined(__APPLE__) /** * Configure logger to use a context that defines a custom logger function * @@ -85,7 +103,7 @@ void OICLogShutdown(); * @param tag - Module name * @param logStr - log string */ -void OICLog(LogLevel level, const char * tag, const char * logStr); +void OICLog(LogLevel level, const char *tag, const char *logStr); /** * Output a variable argument list log string with the specified priority level. @@ -95,7 +113,7 @@ void OICLog(LogLevel level, const char * tag, const char * logStr); * @param tag - Module name * @param format - variadic log string */ -void OICLogv(LogLevel level, const char * tag, const char * format, ...); +void OICLogv(LogLevel level, const char *tag, const char *format, ...); /** * Output the contents of the specified buffer (in hex) with the specified priority level. @@ -105,8 +123,8 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...); * @param buffer - pointer to buffer of bytes * @param bufferSize - max number of byte in buffer */ -void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize); -#else +void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16_t bufferSize); +#else // For arduino platforms /** * Initialize the serial logger for Arduino * Only defined for Arduino @@ -121,7 +139,8 @@ void OICLogInit(); * @param tag - Module name * @param logStr - log string */ -void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr); +void OICLog(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, + PROGMEM const char *logStr); /** * Output the contents of the specified buffer (in hex) with the specified priority level. @@ -131,7 +150,7 @@ void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logSt * @param buffer - pointer to buffer of bytes * @param bufferSize - max number of byte in buffer */ -void OICLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buffer, uint16_t bufferSize); +void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16_t bufferSize); /** * Output a variable argument list log string with the specified priority level. @@ -140,28 +159,44 @@ void OICLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buff * @param tag - Module name * @param format - variadic log string */ -void OICLogv(LogLevel level, const char * tag, const char * format, ...); +void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, + PROGMEM const char *format, ...); #endif #ifdef TB_LOG -// These macros are defined for Linux, Android, and Arduino + +#ifdef __TIZEN__ +#define OIC_LOG(level,tag,mes) LOG_(LOG_ID_MAIN, level, tag, mes) +#define OIC_LOG_V(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, level, tag, fmt,##args) +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) +#else // These macros are defined for Linux, Android, and Arduino #define OIC_LOG_INIT() OICLogInit() -#define OIC_LOG(level, tag, logStr) OICLog((level), (tag), (logStr)) -#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) OICLogBuffer((level), (tag), (buffer), (bufferSize)) +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)\ + OICLogBuffer((level), (tag), (buffer), (bufferSize)) #ifdef ARDUINO #define OIC_LOG_CONFIG(ctx) #define OIC_LOG_SHUTDOWN() -// Use full namespace for logInit to avoid function name collision -#define OIC_LOG_INIT() OICLogInit() -// Don't define variable argument log function for Arduino -#define OIC_LOG_V(level, tag, ...) OICLogv((level), (tag), __VA_ARGS__) +#define OIC_LOG(level, tag, logStr) OICLog((level), PCF(tag), __LINE__, PCF(logStr)) +#define OIC_LOG_V(level, tag, ...) +// To enable OIC_LOG_V, uncomment the below +//#define OIC_LOG_V(level, tag, format, ...) OICLogv((level), PCF(tag), __LINE__, PCF(format), __VA_ARGS__) #else #define OIC_LOG_CONFIG(ctx) OICLogConfig((ctx)) #define OIC_LOG_SHUTDOWN() OICLogShutdown() -// Define variable argument log function for Linux and Android -#define OIC_LOG_V(level, tag, ...) OICLogv((level), (tag), __VA_ARGS__) -#endif +#define OIC_LOG(level, tag, logStr) OICLog((level), (tag), (logStr)) +#define OIC_LOG_V(level, tag, ...) OICLogv((level), (tag), __VA_ARGS__) +#endif //ARDUINO +#endif //__TIZEN__ +#else //TB_LOG + +#ifdef __ANDROID__ +#define OIC_LOG_CONFIG(ctx) +#define OIC_LOG_SHUTDOWN() +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) +#define OIC_LOG_INIT() +#define OIC_LOG(level,tag,mes) __android_log_print(ANDROID_LOG_INFO, tag, mes) +#define OIC_LOG_V(level,tag,fmt,args...) __android_log_print(ANDROID_LOG_INFO, tag, fmt,##args) #else #define OIC_LOG_CONFIG(ctx) @@ -170,9 +205,12 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...); #define OIC_LOG_V(level, tag, ...) #define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) #define OIC_LOG_INIT() -#endif +#endif //__ANDROID__ +#endif // TB_LOG + #ifdef __cplusplus } #endif // __cplusplus -#endif /* _U_LOGGER_H_ */ +#endif /* U_LOGGER_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/oic_console_logger.h b/resource/csdk/connectivity/common/inc/oic_console_logger.h index 6ff5894..bb09eb0 100644 --- a/resource/csdk/connectivity/common/inc/oic_console_logger.h +++ b/resource/csdk/connectivity/common/inc/oic_console_logger.h @@ -18,8 +18,8 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifndef __OIC_CONSOLE_LOGGER_ -#define __OIC_CONSOLE_LOGGER_ +#ifndef OIC_CONSOLE_LOGGER_ +#define OIC_CONSOLE_LOGGER_ #include "oic_logger_types.h" @@ -41,4 +41,5 @@ int oic_console_logger_set_module(oic_log_ctx_t *ctx, const char *module_name); } // extern "C" #endif -#endif +#endif /* OIC_CONSOLE_LOGGER_ */ + diff --git a/resource/csdk/connectivity/common/inc/oic_logger.h b/resource/csdk/connectivity/common/inc/oic_logger.h index df738c2..d1a5b8d 100644 --- a/resource/csdk/connectivity/common/inc/oic_logger.h +++ b/resource/csdk/connectivity/common/inc/oic_logger.h @@ -18,8 +18,8 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifndef __OIC_LOGGER_H_ -#define __OIC_LOGGER_H_ +#ifndef OIC_LOGGER_H_ +#define OIC_LOGGER_H_ #include "oic_logger_types.h" @@ -29,9 +29,10 @@ extern "C" #endif /* Basic interface: */ -oic_log_ctx_t *oic_log_make_ctx(void* world, const oic_log_level level, oic_log_init_t init, - oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level, - oic_log_write_level_t write_level, oic_log_set_module_t set_module); +oic_log_ctx_t *oic_log_make_ctx(void *world, const oic_log_level level, oic_log_init_t init, + oic_log_destroy_t destroy, oic_log_flush_t flush, + oic_log_set_level_t set_level,oic_log_write_level_t write_level, + oic_log_set_module_t set_module); void oic_log_destroy(oic_log_ctx_t *ctx); @@ -45,4 +46,5 @@ int oic_log_set_module(oic_log_ctx_t *ctx, const char *module_name); } // extern "C" #endif -#endif +#endif /* OIC_LOGGER_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/oic_logger_types.h b/resource/csdk/connectivity/common/inc/oic_logger_types.h index f372a4c..121270b 100644 --- a/resource/csdk/connectivity/common/inc/oic_logger_types.h +++ b/resource/csdk/connectivity/common/inc/oic_logger_types.h @@ -18,8 +18,8 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifndef __OIC_LOGGER_TYPES_H_ -#define __OIC_LOGGER_TYPES_H_ +#ifndef OIC_LOGGER_TYPES_H_ +#define OIC_LOGGER_TYPES_H_ #include @@ -43,11 +43,11 @@ typedef enum typedef struct _oic_log_ctx { - void* ctx; + void *ctx; oic_log_level log_level; - char* module_name; + char *module_name; /* Required interface: */ int (*init)(struct _oic_log_ctx *, void *); @@ -83,4 +83,5 @@ typedef int (*oic_log_try_lock_t)(oic_log_ctx_t *); } // extern "C" #endif -#endif +#endif /* OIC_LOGGER_TYPES_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/oic_malloc.h b/resource/csdk/connectivity/common/inc/oic_malloc.h index ae06f14..df0b7b2 100644 --- a/resource/csdk/connectivity/common/inc/oic_malloc.h +++ b/resource/csdk/connectivity/common/inc/oic_malloc.h @@ -18,8 +18,8 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -#ifndef _OIC_MALLOC_H_ -#define _OIC_MALLOC_H_ +#ifndef OIC_MALLOC_H_ +#define OIC_MALLOC_H_ // The purpose of this module is to allow custom dynamic memory allocation // code to easily be added to the TB Stack by redefining the OICMalloc and @@ -68,6 +68,19 @@ extern "C" void *OICMalloc(size_t size); /** + * Allocates a block of memory for an array of num elements, each of them + * size bytes long and initializes all its bits to zero. + * + * @param num - The number of elements + * @param size - Size of the element type in bytes, where size > 0 + * + * @return + * on success, a pointer to the allocated memory block + * on failure, a null pointer is returned + */ +void *OICCalloc(size_t num, size_t size); + +/** * Deallocate a block of memory previously allocated by a call to OCMalloc * * NOTE: This function is intended to be used internally by the TB Stack. @@ -81,4 +94,5 @@ void OICFree(void *ptr); #ifdef __cplusplus } #endif // __cplusplus -#endif /* _OIC_MALLOC_H_ */ +#endif /* OIC_MALLOC_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/oic_string.h b/resource/csdk/connectivity/common/inc/oic_string.h new file mode 100644 index 0000000..5c823ba --- /dev/null +++ b/resource/csdk/connectivity/common/inc/oic_string.h @@ -0,0 +1,44 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ +#ifndef OIC_STRING_H_ +#define OIC_STRING_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/** + * Duplicates the source string and returns it. + * + * NOTE: Caller needs to clear this memory by calling OICFree. + * + * @param str - Original valid string which needs to be duplicated + * + * @return + * on success, a pointer to the duplicated string + * on failure, a null pointer is returned + */ +char *OICStrdup(const char *str); + +#ifdef __cplusplus +} +#endif // __cplusplus +#endif /* OIC_STRING_H_ */ diff --git a/resource/csdk/connectivity/common/inc/uarraylist.h b/resource/csdk/connectivity/common/inc/uarraylist.h index b26734e..17edead 100644 --- a/resource/csdk/connectivity/common/inc/uarraylist.h +++ b/resource/csdk/connectivity/common/inc/uarraylist.h @@ -18,8 +18,8 @@ * ******************************************************************/ -#ifndef __U_ARRAYLIST_H_ -#define __U_ARRAYLIST_H_ +#ifndef U_ARRAYLIST_H_ +#define U_ARRAYLIST_H_ #include #include "cacommon.h" @@ -30,11 +30,6 @@ extern "C" #endif /** - * Use this default size when initialized - */ -#define U_ARRAYLIST_DEFAULT_SIZE 1 - -/** * @struct u_arraylist_t * @brief array list structure */ @@ -49,51 +44,52 @@ typedef struct u_arraylist_t * @brief API to creates array list and initializes the elements. * @return u_arraylist_t if Success, NULL otherwise */ -u_arraylist_t* u_arraylist_create(); +u_arraylist_t *u_arraylist_create(); /** * @brief Resets and deletes the array list - * application should free the memory of data in array list - * @param u_arraylist_t- u_arraylist pointer + * Arraylist elements are deleted. Calling function must take care of free + * dynamic memory allocated before freeing the arraylist + * @param list- u_arraylist pointer * @return CAResult_t - * CA_STATUS_OK if Success, CA_STATUS_FAILED otherwise + * CA_STATUS_OK if Success, CA_STATUS_INVALID_PARAM if pointer to list is NULL */ -CAResult_t u_arraylist_free(u_arraylist_t *list); +CAResult_t u_arraylist_free(u_arraylist_t **list); /** * @brief Returns the data of the index from the array list - * @param u_arraylist + * @param list * [IN] pointer of array list * @param index * [IN] index of array list - * @return void pointer of the data + * @return void pointer of data if success or NULL pointer otherwise */ -void* u_arraylist_get(const u_arraylist_t *list, uint32_t index); +void *u_arraylist_get(const u_arraylist_t *list, uint32_t index); /** * @brief Add data in the array list - * @param u_arraylist + * @param list * [IN] pointer of array list * @param data * [IN] pointer of data * @return CAResult_t - * CA_STATUS_OK if Success, CA_STATUS_FAILED otherwise + * CA_STATUS_OK if Success, CA_MEMORY_ALLOC_FAILED if memory allocation fails */ CAResult_t u_arraylist_add(u_arraylist_t *list, void *data); /** * @brief Remove the data of the index from the array list - * @param u_arraylist + * @param list * [IN] pointer of array list * @param index * [IN] index of array list - * @return void pointer of the data + * @return void pointer of the data if success or NULL pointer otherwise */ -void* u_arraylist_remove(u_arraylist_t *list, uint32_t index); +void *u_arraylist_remove(u_arraylist_t *list, uint32_t index); /** * @brief Returns the length of the array list - * @param u_arraylist + * @param list * [IN] pointer of array list * @return length of the array list */ @@ -101,16 +97,16 @@ uint32_t u_arraylist_length(const u_arraylist_t *list); /** * @brief Returns whether the data exists or not - * @param u_arraylist + * @param list * [IN] pointer of array list * @param data * [IN] pointer of data - * @return 1 if exists, 0 otherwise + * @return true if exists, false otherwise */ -uint8_t u_arraylist_contains(const u_arraylist_t *list, void *data); +bool u_arraylist_contains(const u_arraylist_t *list,const void *data); #ifdef __cplusplus } #endif -#endif /* _U_ARRAYLIST_H_ */ +#endif /* U_ARRAYLIST_H_ */ diff --git a/resource/csdk/connectivity/common/inc/umutex.h b/resource/csdk/connectivity/common/inc/umutex.h deleted file mode 100644 index 30f8336..0000000 --- a/resource/csdk/connectivity/common/inc/umutex.h +++ /dev/null @@ -1,143 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * 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. - * - ******************************************************************/ -/** - * @file umutex.h - * @brief This file provides APIs related to mutex and semaphores - */ - -#ifndef __UMUTEX_H_ -#define __UMUTEX_H_ - -#include "cacommon.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -typedef void *u_mutex; -typedef void *u_cond; - -/** - * @fn u_mutex_init - * @brief Initializes the thread system for using other mutex related APIs - * - */ -void u_mutex_init(void); - -/** - * @fn u_mutex_new - * @brief Creates new mutex - * - * @return Reference to newly created mutex, otherwise NULL. - * - * @see u_mutex_Init - */ -u_mutex u_mutex_new(void); - -/** - * @fn u_mutex_lock - * @brief Lock the mutex - * - * @param mutex The mutex to be locked - * - */ -void u_mutex_lock(u_mutex mutex); - -/** - * @fn u_mutex_trylock - * @brief Checks if the mutex can be locked - * - * @param mutex The mutex to be locked - * - * @return CA_TRUE if the mutex is not locked currently, otherwise CA_FALSE. - * - */ -CABool_t u_mutex_trylock(u_mutex mutex); - -/** - * @fn u_mutex_unlock - * @brief Unlock the mutex - * - * @param mutex The mutex to be unlocked - * - */ -void u_mutex_unlock(u_mutex mutex); - -/** - * @fn u_mutex_free - * @brief Free the mutex - * - * @param mutex The mutex to be freed - * - */ -void u_mutex_free(u_mutex mutex); - -/** - * @fn u_cond_new - * @brief Creates new condition - * - * @return Reference to newly created @u_cond, otherwise NULL. - * - * @see u_mutex_Init - */ -u_cond u_cond_new(void); - -/** - * @fn u_cond_signal - * @brief One of threads is woken up if multiple threads are waiting for @cond - * - * @param cond The condtion to be signaled - * - */ -void u_cond_signal(u_cond cond); - -/** - * @fn u_cond_broadcast - * @brief All of threads are woken up if multiple threads are waiting for @cond - * - * @param cond The condtion to be signaled - * - */ -void u_cond_broadcast(u_cond cond); - -/** - * @fn u_cond_wait - * @brief Waits untill this thread woken up on @cond - * - * @param cond The condtion to be wait for to signal - * @param mutex The mutex which is currently locked from calling thread - * - */ -void u_cond_wait(u_cond cond, u_mutex mutex); - -/** - * @fn u_cond_free - * @brief Free the condition - * - * @param mutex The condition to be freed - * - */ -void u_cond_free(u_cond cond); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif //__UMUTEX_H_ diff --git a/resource/csdk/connectivity/common/inc/uqueue.h b/resource/csdk/connectivity/common/inc/uqueue.h index b40be81..cc9a8bb 100644 --- a/resource/csdk/connectivity/common/inc/uqueue.h +++ b/resource/csdk/connectivity/common/inc/uqueue.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,11 +19,13 @@ ******************************************************************/ /** - * @file uqueue.h - * @brief This file contains the APIs for queue to be implemented + * @file + * + * This file contains the APIs for queue to be implemented. */ -#ifndef __U_QUEUE_H_ -#define __U_QUEUE_H_ + +#ifndef U_QUEUE_H_ +#define U_QUEUE_H_ #include "cacommon.h" @@ -53,9 +55,9 @@ typedef struct u_queue_element_t u_queue_element; struct u_queue_element_t { /* pointer to queue message */ - u_queue_message_t* message; + u_queue_message_t *message; /* Pointer to next queue element*/ - u_queue_element* next; + u_queue_element *next; }; /** @@ -65,7 +67,7 @@ struct u_queue_element_t typedef struct u_queue_t { /* Head of the queue */ - u_queue_element* element; + u_queue_element *element; /* Number of messages in Queue*/ uint32_t count; } u_queue_t; @@ -74,7 +76,7 @@ typedef struct u_queue_t * @brief API to creates queue and initializes the elements. * @return u_queue_t pointer if Success, NULL otherwise */ -u_queue_t* u_queue_create(); +u_queue_t *u_queue_create(); /** * @fn u_queue_delete @@ -83,7 +85,7 @@ u_queue_t* u_queue_create(); * @return CAResult_t - CA_STATUS_OK, if Success * @return CA_STATUS_FAILED - otherwise */ -CAResult_t u_queue_delete(u_queue_t* queue); +CAResult_t u_queue_delete(u_queue_t *queue); /** * @fn u_queue_add_element @@ -93,7 +95,7 @@ CAResult_t u_queue_delete(u_queue_t* queue); * @return CAResult_t - CA_STATUS_OK, if Success * @return CA_STATUS_FAILED - otherwise */ -CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message); +CAResult_t u_queue_add_element(u_queue_t *queue, u_queue_message_t *message); /** * @fn u_queue_get_element @@ -103,7 +105,7 @@ CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message); * @return pointer to Message, if Success * @return NULL - otherwise */ -u_queue_message_t* u_queue_get_element(u_queue_t* queue); +u_queue_message_t *u_queue_get_element(u_queue_t *queue); /** * @fn u_queueRemoveElement @@ -112,15 +114,14 @@ u_queue_message_t* u_queue_get_element(u_queue_t* queue); * @return CAResult_t - CA_STATUS_OK, if Success * @return CA_STATUS_FAILED - otherwise */ -CAResult_t u_queue_remove_element(u_queue_t* queue); +CAResult_t u_queue_remove_element(u_queue_t *queue); /** * @fn u_queue_get_size - * Returns number of elements in queue - * Input : queue - pointer to queue - * Return : number of elements in queue + * @param queue - pointer to queue + * @return number of elements in queue */ -uint32_t u_queue_get_size(u_queue_t* queue); +uint32_t u_queue_get_size(u_queue_t *queue); /** * @fn u_queue_reset @@ -129,7 +130,7 @@ uint32_t u_queue_get_size(u_queue_t* queue); * @return CAResult_t - CA_STATUS_OK, if Success * @return CA_STATUS_FAILED - otherwise */ -CAResult_t u_queue_reset(u_queue_t* queue); +CAResult_t u_queue_reset(u_queue_t *queue); /** * @fn u_queue_get_head @@ -138,10 +139,11 @@ CAResult_t u_queue_reset(u_queue_t* queue); * @return pointer to Message, if Success * @return NULL - otherwise */ -u_queue_message_t* u_queue_get_head(u_queue_t* queue); +u_queue_message_t *u_queue_get_head(u_queue_t *queue); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ -#endif /* _U_QUEUE_H_ */ +#endif /* U_QUEUE_H_ */ + diff --git a/resource/csdk/connectivity/common/inc/uthreadpool.h b/resource/csdk/connectivity/common/inc/uthreadpool.h deleted file mode 100644 index fefb852..0000000 --- a/resource/csdk/connectivity/common/inc/uthreadpool.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * 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. - * - ******************************************************************/ -/** - * @file uthreadpool.h - * @brief This file provides APIs related to thread pool - */ - -#ifndef __UTHREAD_POOL_H_ -#define __UTHREAD_POOL_H_ - -#include -#include -#include -#include - -#include "cacommon.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/** - * @var u_thread_func - * @brief Callback type can be registered to thread pool. - */ -typedef void (*u_thread_func)(void *); - -/** - * @struct u_thread_msg_t - * @brief Structure to maintain the data which needs to send to task function. - */ -typedef struct -{ - void *data; - u_thread_func func; -} u_thread_msg_t; - -/** - * @var u_thread_pool_t - * @brief Thread pool type. - */ -typedef void *u_thread_pool_t; - -/** - * This function creates a newly allocated thread pool. - * - * @param num_of_threads The number of worker thread used in this pool. - * @param thread_pool_handle Handle to newly create thread pool. - * @return Error code, CA_STATUS_OK if success, else error number. - */ -CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_pool_handle); - -/** - * This function adds a routine to be executed by the thread pool at some future time. - * - * @param pool The thread pool structure. - * @param routine The routine to be executed. - * @param data The data to be passed to the routine. - * - * @return CA_STATUS_OK on success. - * @return Error on failure. - */ -CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(void *), void *data); - -/** - * This function stops all the worker threads (stop & exit). And frees all the allocated memory. - * Function will return only after joining all threads executing the currently scheduled tasks. - * - * @param pool The thread pool structure. - */ -void u_thread_pool_free(u_thread_pool_t thread_pool); - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* __UTHREAD_POOL_H_ */ diff --git a/resource/csdk/connectivity/common/src/camutex_pthreads.c b/resource/csdk/connectivity/common/src/camutex_pthreads.c new file mode 100644 index 0000000..fea62f2 --- /dev/null +++ b/resource/csdk/connectivity/common/src/camutex_pthreads.c @@ -0,0 +1,378 @@ +//****************************************************************** +// +// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// +//********************************************************************* + +/** + * @file + * This file provides APIs related to mutex and semaphores. + */ + +// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value +// causes header files to expose definitions +// corresponding to the POSIX.1b, Real-time extensions +// (IEEE Std 1003.1b-1993) specification +// +// For this specific file, see use of clock_gettime and PTHREAD_MUTEX_DEFAULT +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "camutex.h" +#include "logger.h" + +/** + * TAG + * Logging tag for module name + */ +#define TAG PCF("UMUTEX") + +static const uint64_t USECS_PER_SEC = 1000000; +static const uint64_t NANOSECS_PER_USECS = 1000; +static const uint64_t NANOSECS_PER_SEC = 1000000000L; + +typedef struct _tagMutexInfo_t +{ + pthread_mutex_t mutex; +} ca_mutex_internal; + +typedef struct _tagEventInfo_t +{ + pthread_cond_t cond; + pthread_condattr_t condattr; +} ca_cond_internal; + +ca_mutex ca_mutex_new(void) +{ + ca_mutex retVal = NULL; + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) OICMalloc(sizeof(ca_mutex_internal)); + if (NULL != mutexInfo) + { + // create the mutex with the attributes set + int ret=pthread_mutex_init(&(mutexInfo->mutex), PTHREAD_MUTEX_DEFAULT); + if (0 == ret) + { + retVal = (ca_mutex) mutexInfo; + } + else + { + OIC_LOG_V(ERROR, TAG, "%s Failed to initialize mutex !", __func__); + OICFree(mutexInfo); + } + } + + return retVal; +} + +bool ca_mutex_free(ca_mutex mutex) +{ + bool bRet=false; + + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; + if (mutexInfo) + { + int ret = pthread_mutex_destroy(&mutexInfo->mutex); + if (0 == ret) + { + OICFree(mutexInfo); + bRet=true; + } + else + { + OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__); + } + } + else + { + OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__); + } + + return bRet; +} + +void ca_mutex_lock(ca_mutex mutex) +{ + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; + if (mutexInfo) + { + int ret = pthread_mutex_lock(&mutexInfo->mutex); + assert(0 == ret); + if(ret != 0) + { + OIC_LOG_V(ERROR, TAG, "Pthread Mutex lock failed: %d", ret); + exit(ret); + } + } + else + { + OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__); + return; + } +} + +bool ca_mutex_trylock(ca_mutex mutex) +{ + if (NULL == mutex) + { + OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__); + return false; + } + + bool bRet = false; + + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; + + int result = pthread_mutex_trylock(&mutexInfo->mutex); + + switch (result) + { + case 0: + // Success + bRet = true; + break; + case EINVAL: + OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__); + break; + case EBUSY: + default: + break; + } + + return bRet; +} + +void ca_mutex_unlock(ca_mutex mutex) +{ + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; + if (mutexInfo) + { + int ret = pthread_mutex_unlock(&mutexInfo->mutex); + + assert ( 0 == ret); + if(ret != 0) + { + OIC_LOG_V(ERROR, TAG, "Pthread Mutex unlock failed: %d", ret); + exit(ret); + } + (void)ret; + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__); + return; + } +} + +ca_cond ca_cond_new(void) +{ + ca_cond retVal = NULL; + ca_cond_internal *eventInfo = (ca_cond_internal*) OICMalloc(sizeof(ca_cond_internal)); + if (NULL != eventInfo) + { + int ret = pthread_condattr_init(&(eventInfo->condattr)); + if(0 != ret) + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to initialize condition variable attribute %d!", + __func__, ret); + OICFree(eventInfo); + return retVal; + } + +#if defined(__ANDROID__) || _POSIX_TIMERS > 0 + ret = pthread_condattr_setclock(&(eventInfo->condattr), CLOCK_MONOTONIC); + + if(0 != ret) + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to set condition variable clock %d!", + __func__, ret); + pthread_condattr_destroy(&(eventInfo->condattr)); + OICFree(eventInfo); + return retVal; + } +#endif + ret = pthread_cond_init(&(eventInfo->cond), &(eventInfo->condattr)); + if (0 == ret) + { + retVal = (ca_cond) eventInfo; + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to initialize condition variable %d!", __func__, ret); + pthread_condattr_destroy(&(eventInfo->condattr)); + OICFree(eventInfo); + } + } + + return retVal; +} + +void ca_cond_free(ca_cond cond) +{ + ca_cond_internal *eventInfo = (ca_cond_internal*) cond; + if (eventInfo != NULL) + { + int ret = pthread_cond_destroy(&(eventInfo->cond)); + int ret2 = pthread_condattr_destroy(&(eventInfo->condattr)); + if (0 == ret && 0 == ret2) + { + OICFree(cond); + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to destroy condition variable %d, %d", + __func__, ret, ret2); + } + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__); + } +} + +void ca_cond_signal(ca_cond cond) +{ + ca_cond_internal *eventInfo = (ca_cond_internal*) cond; + if (eventInfo != NULL) + { + int ret = pthread_cond_signal(&(eventInfo->cond)); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, "%s: Failed to signal condition variable", __func__); + } + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__); + } +} + +void ca_cond_broadcast(ca_cond cond) +{ + ca_cond_internal* eventInfo = (ca_cond_internal*) cond; + if (eventInfo != NULL) + { + int ret = pthread_cond_broadcast(&(eventInfo->cond)); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, "%s: failed to signal condition variable", __func__); + } + } + else + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__); + } +} + +void ca_cond_wait(ca_cond cond, ca_mutex mutex) +{ + ca_cond_wait_for(cond, mutex, 0L); +} + +struct timespec ca_get_current_time() +{ +#if defined(__ANDROID__) || _POSIX_TIMERS > 0 + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + struct timespec ts; + TIMEVAL_TO_TIMESPEC(&tv, &ts); + return ts; +#endif +} + +void ca_add_microseconds_to_timespec(struct timespec* ts, uint64_t microseconds) +{ + time_t secPart = microseconds/USECS_PER_SEC; + uint64_t nsecPart = (microseconds % USECS_PER_SEC) * NANOSECS_PER_USECS; + uint64_t totalNs = ts->tv_nsec + nsecPart; + time_t secOfNs = totalNs/NANOSECS_PER_SEC; + + ts->tv_nsec = (totalNs)% NANOSECS_PER_SEC; + ts->tv_sec += secPart + secOfNs; +} + +CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds) +{ + CAWaitResult_t retVal = CA_WAIT_INVAL; + + ca_cond_internal *eventInfo = (ca_cond_internal*) cond; + ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex; + + if (NULL == mutexInfo) + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex", __func__); + return CA_WAIT_INVAL; + } + + if (NULL == eventInfo) + { + OIC_LOG_V(ERROR, TAG, "%s: Invalid condition", __func__); + return CA_WAIT_INVAL; + } + + if (microseconds > 0) + { + struct timespec abstime = ca_get_current_time(); + ca_add_microseconds_to_timespec(&abstime, microseconds); + + //Wait for the given time + int ret = pthread_cond_timedwait(&(eventInfo->cond), &(mutexInfo->mutex), &abstime); + switch (ret) + { + case 0: + // Success + retVal = CA_WAIT_SUCCESS; + break; + case ETIMEDOUT: + retVal = CA_WAIT_TIMEDOUT; + break; + case EINVAL: + OIC_LOG_V(ERROR, TAG, "%s: condition, mutex, or abstime is Invalid", __func__); + retVal = CA_WAIT_INVAL; + break; + default: + OIC_LOG_V(ERROR, TAG, "%s: pthread_cond_timedwait returned %d", __func__, retVal); + retVal = CA_WAIT_INVAL; + break; + } + } + else + { + // Wait forever + int ret = pthread_cond_wait(&eventInfo->cond, &mutexInfo->mutex); + retVal = ret == 0 ? CA_WAIT_SUCCESS : CA_WAIT_INVAL; + } + + return retVal; +} + diff --git a/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c new file mode 100644 index 0000000..744b1a5 --- /dev/null +++ b/resource/csdk/connectivity/common/src/cathreadpool_pthreads.c @@ -0,0 +1,216 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file provides APIs related to thread pool. + */ + +#define _GNU_SOURCE +#include +#include +#include "cathreadpool.h" +#include "logger.h" +#include "oic_malloc.h" +#include "uarraylist.h" +#include "camutex.h" + +#define TAG PCF("UTHREADPOOL") + +/** + * empty struct to represent the details. This implementation has no data + * that it needs to keep track of, so it only uses NULL for the internal value. + */ +typedef struct ca_thread_pool_details_t +{ + u_arraylist_t* threads_list; + ca_mutex list_lock; +} ca_thread_pool_details_t; + +/** + * struct to wrap the pthreads callback properly. The function pointer for + * pthreads requires a void* return value, however u_thread_func is a void. + */ +typedef struct ca_thread_pool_callback_info_t +{ + ca_thread_func func; + void* data; +} ca_thread_pool_callback_info_t; + +// passthrough function to convert the pthreads call to a u_thread_func call +void* ca_thread_pool_pthreads_delegate(void* data) +{ + ca_thread_pool_callback_info_t* info = (ca_thread_pool_callback_info_t*)data; + info->func(info->data); + OICFree(info); + return NULL; +} + +// this implementation doesn't do a thread pool, so this function is essentially +// a no-op besides creating a valid ca_thread_pool_t object. It was determined after +// reading through the existing implementation that the thread-pooling was unnecessary +// for the posix platforms. Behavior shouldn't be changed since previously num_of_threads +// was greater than the number of requested threads. +CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_pool) +{ + OIC_LOG(DEBUG, TAG, "IN"); + + if(!thread_pool) + { + OIC_LOG(ERROR, TAG, "Parameter thread_pool was null!"); + return CA_STATUS_INVALID_PARAM; + } + + if(num_of_threads <= 0) + { + OIC_LOG(ERROR, TAG, "num_of_threads must be positive and non-zero"); + return CA_STATUS_INVALID_PARAM; + } + + *thread_pool = OICMalloc(sizeof(struct ca_thread_pool)); + + if(!*thread_pool) + { + OIC_LOG(ERROR, TAG, "Failed to allocate for thread-pool"); + return CA_MEMORY_ALLOC_FAILED; + } + + (*thread_pool)->details = OICMalloc(sizeof(struct ca_thread_pool_details_t)); + if(!(*thread_pool)->details) + { + OIC_LOG(ERROR, TAG, "Failed to allocate for thread-pool details"); + OICFree(*thread_pool); + *thread_pool=NULL; + return CA_MEMORY_ALLOC_FAILED; + } + + (*thread_pool)->details->list_lock = ca_mutex_new(); + + if(!(*thread_pool)->details->list_lock) + { + OIC_LOG(ERROR, TAG, "Failed to create thread-pool mutex"); + OICFree((*thread_pool)->details); + OICFree(*thread_pool); + *thread_pool = NULL; + return CA_STATUS_FAILED; + } + + (*thread_pool)->details->threads_list = u_arraylist_create(); + + if(!(*thread_pool)->details->threads_list) + { + OIC_LOG(ERROR, TAG, "Failed to create thread-pool list"); + if(!ca_mutex_free((*thread_pool)->details->list_lock)) + { + OIC_LOG(ERROR, TAG, "Failed to free thread-pool mutex"); + } + + OICFree((*thread_pool)->details); + OICFree(*thread_pool); + *thread_pool = NULL; + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, + void *data) +{ + OIC_LOG(DEBUG, TAG, "IN"); + + if(NULL == thread_pool || NULL == method) + { + OIC_LOG(ERROR, TAG, "thread_pool or method was NULL"); + return CA_STATUS_INVALID_PARAM; + } + + ca_thread_pool_callback_info_t* info = OICMalloc(sizeof(ca_thread_pool_callback_info_t)); + if(!info) + { + OIC_LOG(ERROR, TAG, "Failed to allocate for memory wrapper"); + return CA_MEMORY_ALLOC_FAILED; + } + + info->func = method; + info->data = data; + + pthread_t threadHandle; + + int result = pthread_create(&threadHandle, NULL, ca_thread_pool_pthreads_delegate, info); + + if(result != 0) + { + OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", result); + return CA_STATUS_FAILED; + } + + ca_mutex_lock(thread_pool->details->list_lock); + CAResult_t addResult = u_arraylist_add(thread_pool->details->threads_list, (void*)threadHandle); + ca_mutex_unlock(thread_pool->details->list_lock); + + if(addResult != CA_STATUS_OK) + { + OIC_LOG_V(ERROR, TAG, "Arraylist Add failed, may not be properly joined: %d", addResult); + return addResult; + } + + OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; +} + +void ca_thread_pool_free(ca_thread_pool_t thread_pool) +{ + OIC_LOG(DEBUG, TAG, "IN"); + + if(!thread_pool) + { + OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL"); + return; + } + + ca_mutex_lock(thread_pool->details->list_lock); + + for(uint32_t i = 0; idetails->threads_list); ++i) + { + pthread_t tid = (pthread_t)u_arraylist_get(thread_pool->details->threads_list, i); + int joinres = pthread_join(tid, NULL); + if(0 != joinres) + { + OIC_LOG_V(ERROR, TAG, "Failed to join thread at index %u with error %d", i, joinres); + } + } + + CAResult_t freeres = u_arraylist_free(&(thread_pool->details->threads_list)); + if(CA_STATUS_OK != freeres) + { + OIC_LOG_V(ERROR, TAG, "Failed to free array list, error was: %d", freeres); + } + + ca_mutex_unlock(thread_pool->details->list_lock); + ca_mutex_free(thread_pool->details->list_lock); + + OICFree(thread_pool->details); + OICFree(thread_pool); + + OIC_LOG(DEBUG, TAG, "OUT"); +} diff --git a/resource/csdk/connectivity/common/src/logger.c b/resource/csdk/connectivity/common/src/logger.c index 03b6f85..9772f99 100644 --- a/resource/csdk/connectivity/common/src/logger.c +++ b/resource/csdk/connectivity/common/src/logger.c @@ -18,27 +18,66 @@ // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value +// causes header files to expose definitions +// corresponding to the POSIX.1b, Real-time extensions +// (IEEE Std 1003.1b-1993) specification +// +// For this specific file, see use of clock_gettime, +// Refer to http://pubs.opengroup.org/stage7tc1/functions/clock_gettime.html +// and to http://man7.org/linux/man-pages/man2/clock_gettime.2.html +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200809L +#endif + +// Platform check can be extended to check and/or define more, or could be +// moved into a config.h +#if !defined(__ARDUINO__) && !defined(ARDUINO) +#define HAVE_UNISTD_H 1 +#endif + +// Pull in _POSIX_TIMERS feature test macro to check for +// clock_gettime() support. +#ifdef HAVE_UNISTD_H +#include + +// if we have unistd.h, we're a Unix system +#include +#include +#endif + #include "logger.h" #include "string.h" #include "oic_logger.h" #include "oic_console_logger.h" +#ifndef __TIZEN__ static oic_log_ctx_t *logCtx = 0; static oic_log_level LEVEL_XTABLE[] = { OIC_LOG_DEBUG, OIC_LOG_INFO, OIC_LOG_WARNING, OIC_LOG_ERROR, OIC_LOG_FATAL }; -static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination +#endif + +static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + + 1; // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination // Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino #ifdef __ANDROID__ +#ifdef ADB_SHELL +static const char *LEVEL[] = +{ "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"}; + +#else static android_LogPriority LEVEL[] = { ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL}; +#endif #elif defined __linux__ -static const char * LEVEL[] __attribute__ ((unused)) = +static const char *LEVEL[] __attribute__ ((unused)) = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"}; #elif defined ARDUINO #include +#include "Arduino.h" PROGMEM const char level0[] = "DEBUG"; PROGMEM const char level1[] = "INFO"; @@ -46,10 +85,10 @@ PROGMEM const char level2[] = "WARNING"; PROGMEM const char level3[] = "ERROR"; PROGMEM const char level4[] = "FATAL"; -PROGMEM const char * const LEVEL[] = +PROGMEM const char *const LEVEL[] = { level0, level1, level2, level3, level4}; -static void OICLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr); +static void OICLogString(LogLevel level, PROGMEM const char *tag, PROGMEM const char *logStr); #ifdef ARDUINO_ARCH_AVR //Mega2560 and other 8-bit AVR microcontrollers #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));} @@ -60,8 +99,9 @@ static void OICLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';} #endif #endif // __ANDROID__ -#ifndef ARDUINO +#ifndef ARDUINO +#ifndef __TIZEN__ void OICLogConfig(oic_log_ctx_t *ctx) { logCtx = ctx; @@ -90,7 +130,7 @@ void OICLogShutdown() * @param tag - Module name * @param logStr - log string */ -void OICLog(LogLevel level, const char * tag, const char * logStr) +void OICLog(LogLevel level, const char *tag, const char *logStr) { if (!logStr || !tag) { @@ -98,7 +138,13 @@ void OICLog(LogLevel level, const char * tag, const char * logStr) } #ifdef __ANDROID__ + +#ifdef ADB_SHELL + printf("%s: %s: %s\n", LEVEL[level], tag, logStr); +#else __android_log_write(LEVEL[level], tag, logStr); +#endif + #elif defined __linux__ if (logCtx && logCtx->write_level) { @@ -107,7 +153,31 @@ void OICLog(LogLevel level, const char * tag, const char * logStr) } else { - printf("%s: %s: %s\n", LEVEL[level], tag, logStr); + int min = 0; + int sec = 0; + int ms = 0; +#ifdef _POSIX_TIMERS + struct timespec when = {}; + clockid_t clk = CLOCK_REALTIME; +#ifdef CLOCK_REALTIME_COARSE + clk = CLOCK_REALTIME_COARSE; +#endif + if (!clock_gettime(clk, &when)) + { + min = (when.tv_sec / 60) % 60; + sec = when.tv_sec % 60; + ms = when.tv_nsec / 1000000; + } +#else + struct timeval now; + if (!gettimeofday(&now, NULL)) + { + min = (now.tv_sec / 60) % 60; + sec = now.tv_sec % 60; + ms = now.tv_usec * 1000; + } +#endif + printf("%02d:%02d.%03d %s: %s: %s\n", min, sec, ms, LEVEL[level], tag, logStr); } #endif } @@ -120,7 +190,7 @@ void OICLog(LogLevel level, const char * tag, const char * logStr) * @param tag - Module name * @param format - variadic log string */ -void OICLogv(LogLevel level, const char * tag, const char * format, ...) +void OICLogv(LogLevel level, const char *tag, const char *format, ...) { if (!format || !tag) { @@ -143,7 +213,7 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...) * @param buffer - pointer to buffer of bytes * @param bufferSize - max number of byte in buffer */ -void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize) +void OICLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, uint16_t bufferSize) { if (!buffer || !tag || (bufferSize == 0)) { @@ -173,8 +243,9 @@ void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint OICLog(level, tag, lineBuffer); } } - -#else +#endif //__TIZEN__ +#endif //ARDUINO +#ifdef ARDUINO /** * Initialize the serial logger for Arduino * Only defined for Arduino @@ -193,67 +264,68 @@ void OICLogInit() * @param tag - Module name * @param logStr - log string */ -void OICLogString(LogLevel level, PROGMEM const char * tag, const char * logStr) -{ - if (!logStr || !tag) - { - return; - } - - char buffer[LINE_BUFFER_SIZE]; - - GET_PROGMEM_BUFFER(buffer, &(LEVEL[level])); - Serial.print(buffer); - - char c; - Serial.print(F(": ")); - while ((c = pgm_read_byte(tag))) - { - Serial.write(c); - tag++; - } - Serial.print(F(": ")); - - Serial.println(logStr); -} + void OICLogString(LogLevel level, PROGMEM const char * tag, + const char * logStr) + { + if (!logStr || !tag) + { + return; + } + + char buffer[LINE_BUFFER_SIZE] = {0}; + strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level]))); + Serial.print(buffer); + + char c = NULL; + Serial.print(F(": ")); + while ((c = pgm_read_byte(tag))) + { + Serial.write(c); + tag++; + } + Serial.print(F(": ")); + + Serial.println(logStr); + } /** - * Output the contents of the specified buffer (in hex) with the specified priority level. + * Output the contents of the specified buffer (in hex) with the specified + * priority level. * * @param level - DEBUG, INFO, WARNING, ERROR, FATAL * @param tag - Module name * @param buffer - pointer to buffer of bytes * @param bufferSize - max number of byte in buffer */ -void OICLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buffer, uint16_t bufferSize) -{ - if (!buffer || !tag || (bufferSize == 0)) - { - return; - } - - char lineBuffer[LINE_BUFFER_SIZE] = - { 0}; - uint8_t lineIndex = 0; - for (uint8_t i = 0; i < bufferSize; i++) - { + void OICLogBuffer(LogLevel level, PROGMEM const char * tag, + const uint8_t * buffer, uint16_t bufferSize) + { + if (!buffer || !tag || (bufferSize == 0)) + { + return; + } + + char lineBuffer[LINE_BUFFER_SIZE] = {0}; + uint8_t lineIndex = 0; + for (uint8_t i = 0; i < bufferSize; i++) + { // Format the buffer data into a line snprintf(&lineBuffer[lineIndex*3], sizeof(lineBuffer)-lineIndex*3, "%02X ", buffer[i]); lineIndex++; - // Output 16 values per line - if (((i+1)%16) == 0) - { - OICLogString(level, tag, lineBuffer); - memset(lineBuffer, 0, sizeof lineBuffer); - lineIndex = 0; - } - } - // Output last values in the line, if any - if (bufferSize % 16) - { - OICLogString(level, tag, lineBuffer); - } -} + // Output 16 values per line + if (((i+1)%16) == 0) + { + OICLogString(level, tag, lineBuffer); + memset(lineBuffer, 0, sizeof lineBuffer); + lineIndex = 0; + } + } + // Output last values in the line, if any + if (bufferSize % 16) + { + OICLogString(level, tag, lineBuffer); + } + } /** * Output a log string with the specified priority level. @@ -263,18 +335,16 @@ void OICLogBuffer(LogLevel level, PROGMEM const char * tag, const uint8_t * buff * @param tag - Module name * @param logStr - log string */ -void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr) +void OICLog(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, + PROGMEM const char *logStr) { if (!logStr || !tag) { return; } - - char buffer[LINE_BUFFER_SIZE]; - + char buffer[LINE_BUFFER_SIZE] = {0}; GET_PROGMEM_BUFFER(buffer, &(LEVEL[level])); Serial.print(buffer); - char c; Serial.print(F(": ")); while ((c = pgm_read_byte(tag))) @@ -283,7 +353,8 @@ void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logSt tag++; } Serial.print(F(": ")); - + Serial.print(lineNum); + Serial.print(F(": ")); while ((c = pgm_read_byte(logStr))) { Serial.write(c); @@ -300,29 +371,34 @@ void OICLog(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logSt * @param tag - Module name * @param format - variadic log string */ -void OICLogv(LogLevel level, PROGMEM const char * tag, const char * format, ...) +void OICLogv(LogLevel level, PROGMEM const char *tag, const int16_t lineNum, + PROGMEM const char *format, ...) { char buffer[LINE_BUFFER_SIZE]; va_list ap; va_start(ap, format); - GET_PROGMEM_BUFFER(buffer, &(LEVEL[level])); Serial.print(buffer); char c; Serial.print(F(": ")); - - while ((c = pgm_read_byte(tag))) - { - Serial.write(c); - tag++; - } + while ((c = pgm_read_byte(tag))) { + Serial.write(c); + tag++; + } + Serial.print(F(": ")); + Serial.print(lineNum); Serial.print(F(": ")); +#ifdef __AVR__ + vsnprintf_P(buffer, sizeof(buffer), format, ap); +#else vsnprintf(buffer, sizeof(buffer), format, ap); - for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines +#endif + for (char *p = &buffer[0]; *p; p++) { - if(*p == '\n') + // emulate cooked mode for newlines + if (*p == '\n') { Serial.write('\r'); } @@ -339,23 +415,23 @@ void OICLogv(LogLevel level, PROGMEM const char * tag, const char * format, ...) * @param tag - Module name * @param format - variadic log string */ -void OICLogv(LogLevel level, PROGMEM const char * tag, const __FlashStringHelper *format, ...) +void OICLogv(LogLevel level, const char *tag, const __FlashStringHelper *format, ...) { char buffer[LINE_BUFFER_SIZE]; va_list ap; va_start(ap, format); + // strcpy_P(buffer, (char*)pgm_read_word(&(LEVEL[level]))); + // Serial.print(buffer); - GET_PROGMEM_BUFFER(buffer, &(LEVEL[level])); - Serial.print(buffer); - - char c; + Serial.print(LEVEL[level]); + // char c; Serial.print(F(": ")); - while ((c = pgm_read_byte(tag))) - { - Serial.write(c); - tag++; - } + /*while ((c = pgm_read_byte(tag))) { + Serial.write(c); + tag++; + }*/ + Serial.print(tag); Serial.print(F(": ")); #ifdef __AVR__ @@ -363,17 +439,20 @@ void OICLogv(LogLevel level, PROGMEM const char * tag, const __FlashStringHelper #else vsnprintf(buffer, sizeof(buffer), (const char *)format, ap); // for the rest of the world #endif - for(char *p = &buffer[0]; *p; p++) // emulate cooked mode for newlines + for (char *p = &buffer[0]; *p; p++) { - if(*p == '\n') + // emulate cooked mode for newlines + if (*p == '\n') { - Serial.write('\r'); + // Serial.write('\r'); + Serial.print('\r'); } - Serial.write(*p); + //Serial.write(*p); + Serial.print(p); } Serial.println(); va_end(ap); } -#endif +#endif //ARDUINO diff --git a/resource/csdk/connectivity/common/src/oic_console_logger.c b/resource/csdk/connectivity/common/src/oic_console_logger.c index 500f5a6..bbad2c1 100644 --- a/resource/csdk/connectivity/common/src/oic_console_logger.c +++ b/resource/csdk/connectivity/common/src/oic_console_logger.c @@ -32,8 +32,8 @@ typedef struct oic_log_ctx_t *oic_make_console_logger() { return oic_log_make_ctx(NULL, OIC_LOG_ALL, oic_console_logger_init, oic_console_logger_destroy, - oic_console_logger_flush, oic_console_logger_set_level, oic_console_logger_write, - oic_console_logger_set_module); + oic_console_logger_flush, oic_console_logger_set_level, + oic_console_logger_write,oic_console_logger_set_module); } int oic_console_logger_init(oic_log_ctx_t *ctx, void *world) @@ -91,3 +91,4 @@ int oic_console_logger_set_module(oic_log_ctx_t *ctx, const char *module_name) /* We don't do anything special when the module name changes: */ return 1; } + diff --git a/resource/csdk/connectivity/common/src/oic_logger.c b/resource/csdk/connectivity/common/src/oic_logger.c index 7c1d7e9..46106c6 100644 --- a/resource/csdk/connectivity/common/src/oic_logger.c +++ b/resource/csdk/connectivity/common/src/oic_logger.c @@ -23,14 +23,15 @@ #include #include -oic_log_ctx_t *oic_log_make_ctx(void* world, const oic_log_level level, oic_log_init_t init, - oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level, - oic_log_write_level_t write_level, oic_log_set_module_t set_module) +oic_log_ctx_t *oic_log_make_ctx(void *world, const oic_log_level level, oic_log_init_t init, + oic_log_destroy_t destroy, oic_log_flush_t flush, + oic_log_set_level_t set_level,oic_log_write_level_t write_level, + oic_log_set_module_t set_module) { oic_log_ctx_t *log_ctx; if (0 == init || 0 == destroy || 0 == flush || 0 == set_level || 0 == write_level - || 0 == set_module) + || 0 == set_module) return 0; if (__OIC_LOG_MIN__ > level || __OIC_LOG_MAX__ < level) @@ -133,7 +134,11 @@ int oic_log_set_module(oic_log_ctx_t *ctx, const char *module_name) mn = (char *) malloc(1 + l); if (0 == mn) + { + if (0 != ctx->module_name) + free(ctx->module_name); return 0; + } memcpy(mn, module_name, 1 + l); @@ -146,3 +151,4 @@ int oic_log_set_module(oic_log_ctx_t *ctx, const char *module_name) return ctx->set_module(ctx, ctx->module_name); } + diff --git a/resource/csdk/connectivity/common/src/oic_malloc.c b/resource/csdk/connectivity/common/src/oic_malloc.c index 8136c97..40b7363 100644 --- a/resource/csdk/connectivity/common/src/oic_malloc.c +++ b/resource/csdk/connectivity/common/src/oic_malloc.c @@ -25,11 +25,9 @@ #include "oic_malloc.h" // Enable extra debug logging for malloc. Comment out to disable -//#define ENABLE_MALLOC_DEBUG (1) - #ifdef ENABLE_MALLOC_DEBUG #include "logger.h" -#define TAG PCF("OICMalloc") +#define TAG "OICMalloc" #endif //----------------------------------------------------------------------------- @@ -55,6 +53,9 @@ //----------------------------------------------------------------------------- // Public APIs //----------------------------------------------------------------------------- +#ifdef ENABLE_MALLOC_DEBUG +static uint32_t count; +#endif void *OICMalloc(size_t size) { @@ -67,7 +68,8 @@ void *OICMalloc(size_t size) } ptr = malloc(size); - OIC_LOG_V(INFO, TAG, "malloc: ptr=%p, size=%u", ptr, size); + count++; + OIC_LOG_V(INFO, TAG, "malloc: ptr=%p, size=%u, count=%u", ptr, size, count); return ptr; #else if (0 == size) @@ -78,12 +80,31 @@ void *OICMalloc(size_t size) #endif } +void *OICCalloc(size_t num, size_t size) +{ + if(0 == size || 0 == num) + { + return NULL; + } + +#ifdef ENABLE_MALLOC_DEBUG + void *ptr = 0; + + ptr = calloc(num, size); + OIC_LOG_V(INFO, TAG, "calloc: ptr=%p, num=%u, size=%u", ptr, num, size); + return ptr; +#else + return calloc(num, size); +#endif +} + void OICFree(void *ptr) { #ifdef ENABLE_MALLOC_DEBUG - OIC_LOG_V(INFO, TAG, "free: ptr=%p", ptr); + OIC_LOG_V(INFO, TAG, "free: ptr=%p, count=%u", ptr, --count); #endif free(ptr); } + diff --git a/resource/csdk/connectivity/common/src/oic_string.c b/resource/csdk/connectivity/common/src/oic_string.c new file mode 100644 index 0000000..199b6f6 --- /dev/null +++ b/resource/csdk/connectivity/common/src/oic_string.c @@ -0,0 +1,36 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ +#include "oic_string.h" + +#include +#include "oic_malloc.h" + +char *OICStrdup(const char *str) +{ + // Allocate memory for original string length and 1 extra byte for '\0' + size_t length = strlen(str); + char *dup = (char *)OICMalloc(length + 1); + if (NULL != dup) + { + memcpy(dup, str, length + 1); + } + return dup; +} + diff --git a/resource/csdk/connectivity/common/src/uarraylist.c b/resource/csdk/connectivity/common/src/uarraylist.c index a618e51..7c569d4 100644 --- a/resource/csdk/connectivity/common/src/uarraylist.c +++ b/resource/csdk/connectivity/common/src/uarraylist.c @@ -24,13 +24,19 @@ #include "logger.h" #include "oic_malloc.h" -#define TAG PCF("UARRAYLIST") +#define TAG "UARRAYLIST" + +/** + * Use this default size when initialized + */ +#define U_ARRAYLIST_DEFAULT_SIZE 1 u_arraylist_t *u_arraylist_create() { u_arraylist_t *list = NULL; - if (!(list = (u_arraylist_t*) OICMalloc(sizeof(u_arraylist_t)))) + list = (u_arraylist_t *) OICMalloc(sizeof(u_arraylist_t)); + if (!list) { return NULL; } @@ -38,33 +44,39 @@ u_arraylist_t *u_arraylist_create() list->size = U_ARRAYLIST_DEFAULT_SIZE; list->length = 0; - if (!(list->data = (void*) OICMalloc(list->size * sizeof(void*)))) + list->data = (void *) OICMalloc(list->size * sizeof(void *)); + if (!list->data) { + OIC_LOG(DEBUG, TAG, "Out of memory"); OICFree(list); return NULL; } - return list; } -CAResult_t u_arraylist_free(u_arraylist_t *list) +CAResult_t u_arraylist_free(u_arraylist_t **list) { - OICFree(list->data); - OICFree(list); + if (!list || !(*list)) + { + return CA_STATUS_INVALID_PARAM; + } + + OICFree((*list)->data); + OICFree(*list); - list = NULL; + *list = NULL; return CA_STATUS_OK; } void *u_arraylist_get(const u_arraylist_t *list, uint32_t index) { - if (index >= list->length) + if (!list ) { return NULL; } - if (list->data) + if ((index < list->length) && (list->data)) { return list->data[index]; } @@ -74,31 +86,39 @@ void *u_arraylist_get(const u_arraylist_t *list, uint32_t index) CAResult_t u_arraylist_add(u_arraylist_t *list, void *data) { - uint32_t new_size = 0; + if (!list) + { + return CA_STATUS_INVALID_PARAM; + } if (list->size <= list->length) { - new_size = list->size + 1; + uint32_t new_size = list->size + 1; if (!(list->data = (void **) realloc(list->data, new_size * sizeof(void *)))) { - return -1; + return CA_MEMORY_ALLOC_FAILED; } - (void) memset(list->data + list->size, 0, (new_size - list->size) * sizeof(void *)); + memset(list->data + list->size, 0, (new_size - list->size) * sizeof(void *)); list->size = new_size; } list->data[list->length] = data; list->length++; - return 0; + return CA_STATUS_OK; } void *u_arraylist_remove(u_arraylist_t *list, uint32_t index) { void *removed = NULL; + if (!list) + { + return NULL; + } + if (index >= list->length) { return NULL; @@ -115,6 +135,9 @@ void *u_arraylist_remove(u_arraylist_t *list, uint32_t index) list->size--; list->length--; + // check minimum size. + list->size = (list->size <= U_ARRAYLIST_DEFAULT_SIZE) ? U_ARRAYLIST_DEFAULT_SIZE : list->size; + if (!(list->data = (void **) realloc(list->data, list->size * sizeof(void *)))) { return NULL; @@ -125,25 +148,34 @@ void *u_arraylist_remove(u_arraylist_t *list, uint32_t index) uint32_t u_arraylist_length(const u_arraylist_t *list) { + if (!list) + { + OIC_LOG(DEBUG, TAG, "Invalid Parameter"); + return 0; + } return list->length; } -uint8_t u_arraylist_contains(const u_arraylist_t *list, void *data) +bool u_arraylist_contains(const u_arraylist_t *list,const void *data) { uint32_t i = 0; - for (i = 0; i < u_arraylist_length(list); i++) + if (!list) + { + return false; + } + + uint32_t length = u_arraylist_length(list); + + for (i = 0; i < length; i++) { if (data == u_arraylist_get(list, i)) { - return 1; - } - else - { - continue; + return true; } } - return 0; + return false; } + diff --git a/resource/csdk/connectivity/common/src/umutex.c b/resource/csdk/connectivity/common/src/umutex.c deleted file mode 100644 index 6575453..0000000 --- a/resource/csdk/connectivity/common/src/umutex.c +++ /dev/null @@ -1,169 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * 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. - * - ******************************************************************/ -/** - * @file umutex.c - * @brief This file provides APIs related to mutex and semaphores - */ - -#include "umutex.h" -#include - -#include "logger.h" -#define TAG PCF("UMUTEX") - -void u_mutex_init(void) -{ - /*Initialize the glib thread system if it is not. GMutex works only if the threadsystem is initialized*/ - if (!g_thread_supported()) - { - g_thread_init(NULL); - } -} - -u_mutex u_mutex_new(void) -{ - if (!g_thread_supported()) - { - return NULL; - } - - GMutex *mutexLock = g_mutex_new(); - return (u_mutex) mutexLock; -} - -void u_mutex_lock(u_mutex mutex) -{ - if (NULL == mutex) - { - OIC_LOG_V(ERROR, TAG ,"Invalid mutex !"); - return; - } - - GMutex *mutexLock = (GMutex*) mutex; - g_mutex_lock(mutexLock); -} - -CABool_t u_mutex_trylock(u_mutex mutex) -{ - if (NULL == mutex) - { - OIC_LOG_V(ERROR, TAG,"Invalid mutex !"); - return CA_FALSE; - } - - GMutex *mutexLock = (GMutex*) mutex; - gboolean ret = g_mutex_trylock(mutexLock); - if (TRUE == ret) - { - return CA_TRUE; - } - - return CA_FALSE; -} - -void u_mutex_unlock(u_mutex mutex) -{ - if (NULL == mutex) - { - OIC_LOG_V(ERROR, TAG,"Invalid mutex !"); - return; - } - - GMutex *mutexLock = (GMutex*) mutex; - g_mutex_unlock(mutexLock); -} - -void u_mutex_free(u_mutex mutex) -{ - if (NULL == mutex) - { - OIC_LOG_V(ERROR, TAG,"Invalid mutex !"); - return; - } - - GMutex *mutexLock = (GMutex*) mutex; - g_mutex_free(mutexLock); -} - -u_cond u_cond_new(void) -{ - if (!g_thread_supported()) - { - return NULL; - } - - GCond *condition = g_cond_new(); - return (u_cond) condition; -} - -void u_cond_signal(u_cond cond) -{ - if (NULL == cond) - { - OIC_LOG_V(ERROR, TAG,"Invalid condition !"); - return; - } - - GCond *condition = (GCond*) cond; - g_cond_signal(condition); -} - -void u_cond_broadcast(u_cond cond) -{ - if (NULL == cond) - { - OIC_LOG_V(ERROR, TAG,"Invalid condition !"); - return; - } - - GCond *condition = (GCond*) cond; - g_cond_broadcast(condition); -} - -void u_cond_wait(u_cond cond, u_mutex mutex) -{ - if (NULL == mutex) - { - OIC_LOG_V(ERROR, TAG,"Invalid mutex !"); - return; - } - - if (NULL == cond) - { - OIC_LOG_V(ERROR, TAG,"Invalid condition !"); - return; - } - - GMutex *mutexLock = (GMutex*) mutex; - GCond *condition = (GCond*) cond; - g_cond_wait(condition, mutexLock); -} - -void u_cond_free(u_cond cond) -{ - if (NULL == cond) - { - OIC_LOG_V(ERROR, TAG,"Invalid condition !"); - return; - } - - GCond *condition = (GCond*) cond; - g_cond_free(condition); -} - diff --git a/resource/csdk/connectivity/common/src/uqueue.c b/resource/csdk/connectivity/common/src/uqueue.c index 5b04830..f9e0ada 100644 --- a/resource/csdk/connectivity/common/src/uqueue.c +++ b/resource/csdk/connectivity/common/src/uqueue.c @@ -17,21 +17,29 @@ * limitations under the License. * ******************************************************************/ +#include "uqueue.h" #include #include #include - #include "logger.h" -#include "uqueue.h" #include "oic_malloc.h" +/** + * @def NO_MESSAGES + * @brief Number of messages in the queue + */ #define NO_MESSAGES 0 -#define TAG PCF("UQUEUE") -u_queue_t* u_queue_create() +/** + * @def TAG + * @brief Logging tag for module name + */ +#define TAG "UQUEUE" + +u_queue_t *u_queue_create() { - u_queue_t* queuePtr = (u_queue_t*) OICMalloc(sizeof(u_queue_t)); + u_queue_t *queuePtr = (u_queue_t *) OICMalloc(sizeof(u_queue_t)); if (NULL == queuePtr) { OIC_LOG(DEBUG, TAG, "QueueCreate FAIL"); @@ -44,10 +52,10 @@ u_queue_t* u_queue_create() return queuePtr; } -CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message) +CAResult_t u_queue_add_element(u_queue_t *queue, u_queue_message_t *message) { - u_queue_element* element = NULL; - u_queue_element* ptr = NULL; + u_queue_element *element = NULL; + u_queue_element *ptr = NULL; if (NULL == queue) { @@ -61,7 +69,7 @@ CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message) return CA_STATUS_FAILED; } - element = (u_queue_element*) OICMalloc(sizeof(u_queue_element)); + element = (u_queue_element *) OICMalloc(sizeof(u_queue_element)); if (NULL == element) { OIC_LOG(DEBUG, TAG, "QueueAddElement FAIL, memory allocation failed"); @@ -99,18 +107,15 @@ CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message) queue->element = element; queue->count++; OIC_LOG_V(DEBUG, TAG, "Queue Count : %d", queue->count); - - return CA_STATUS_OK; } return CA_STATUS_OK; } -u_queue_message_t* u_queue_get_element(u_queue_t* queue) +u_queue_message_t *u_queue_get_element(u_queue_t *queue) { - u_queue_element* next = NULL; - u_queue_element* element = NULL; - u_queue_message_t* message = NULL; + u_queue_element *element = NULL; + u_queue_message_t *message = NULL; if (NULL == queue) { @@ -122,12 +127,11 @@ u_queue_message_t* u_queue_get_element(u_queue_t* queue) if (NULL == element) { - OIC_LOG(DEBUG, TAG, "QueueGetElement : FAIL, no messages"); + OIC_LOG(DEBUG, TAG, "QueueGetElement : empty, no messages"); return NULL; } - next = element->next; - queue->element = next; + queue->element = element->next;; queue->count--; message = element->message; @@ -135,10 +139,10 @@ u_queue_message_t* u_queue_get_element(u_queue_t* queue) return message; } -CAResult_t u_queue_remove_element(u_queue_t* queue) +CAResult_t u_queue_remove_element(u_queue_t *queue) { - u_queue_element* next = NULL; - u_queue_element* remove = NULL; + u_queue_element *next = NULL; + u_queue_element *remove = NULL; if (NULL == queue) { @@ -165,7 +169,7 @@ CAResult_t u_queue_remove_element(u_queue_t* queue) return CA_STATUS_OK; } -uint32_t u_queue_get_size(u_queue_t* queue) +uint32_t u_queue_get_size(u_queue_t *queue) { if (NULL == queue) { @@ -176,10 +180,8 @@ uint32_t u_queue_get_size(u_queue_t* queue) return queue->count; } -CAResult_t u_queue_reset(u_queue_t* queue) +CAResult_t u_queue_reset(u_queue_t *queue) { - CAResult_t error = CA_STATUS_FAILED; - if (NULL == queue) { OIC_LOG(DEBUG, TAG, "QueueReset FAIL, Invalid Queue"); @@ -194,9 +196,7 @@ CAResult_t u_queue_reset(u_queue_t* queue) while (NULL != queue->element) { - error = u_queue_remove_element(queue); - if (error == CA_STATUS_FAILED) - break; + u_queue_remove_element(queue); } if (NO_MESSAGES != queue->count) @@ -209,7 +209,7 @@ CAResult_t u_queue_reset(u_queue_t* queue) } -CAResult_t u_queue_delete(u_queue_t* queue) +CAResult_t u_queue_delete(u_queue_t *queue) { CAResult_t error = CA_STATUS_FAILED; @@ -230,7 +230,7 @@ CAResult_t u_queue_delete(u_queue_t* queue) return (CA_STATUS_OK); } -u_queue_message_t* u_queue_get_head(u_queue_t* queue) +u_queue_message_t *u_queue_get_head(u_queue_t *queue) { if (NULL == queue) { @@ -245,3 +245,4 @@ u_queue_message_t* u_queue_get_head(u_queue_t* queue) } return queue->element->message; } + diff --git a/resource/csdk/connectivity/common/src/uthreadpool.c b/resource/csdk/connectivity/common/src/uthreadpool.c deleted file mode 100644 index 477d5fd..0000000 --- a/resource/csdk/connectivity/common/src/uthreadpool.c +++ /dev/null @@ -1,116 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * 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. - * - ******************************************************************/ -/** - * @file uthreadpool.c - * @brief This file provides APIs related to thread pool - */ - -#include "uthreadpool.h" -#include "logger.h" -#include "oic_malloc.h" -#define TAG PCF("UTHREADPOOL") - -/** - * @var gThreadpool - * @brief Glib thread pool. - */ -static GThreadPool *gThreadpool; - -/** - * @fn run - * @brief function which is registed to glib thread pool. - */ -static void run(void *thread_data, void *user_data); - -CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_pool) -{ - OIC_LOG_V(DEBUG, TAG, "IN"); - - GError *error = NULL; - gThreadpool = g_thread_pool_new(run, NULL, num_of_threads, FALSE, &error); - if (NULL == gThreadpool) - { - OIC_LOG_V(ERROR, TAG, "Error: g_thread_pool_new failed!"); - if (NULL != error) - { - OIC_LOG_V(ERROR, TAG, "Error is: %s", error->message); - g_error_free(error); - } - return CA_STATUS_FAILED; - } - *thread_pool = (u_thread_pool_t) gThreadpool; - - OIC_LOG_V(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(void *), void *data) -{ - OIC_LOG_V(DEBUG, TAG, "IN"); - - gboolean result = FALSE; - if (NULL == routine) - { - OIC_LOG_V(ERROR, TAG, "Error: routine is NULL!"); - return CA_STATUS_FAILED; - } - - u_thread_msg_t *message = (u_thread_msg_t *) OICMalloc(sizeof(u_thread_msg_t)); - message->data = data; - message->func = routine; - result = g_thread_pool_push((GThreadPool *) thread_pool, (void *) message, NULL); - if (FALSE == result) - { - OIC_LOG_V(ERROR, TAG, "Error: Failed to push the task to threadpool!"); - return CA_STATUS_FAILED; - } - - OIC_LOG_V(DEBUG, TAG, "OUT"); - return CA_STATUS_OK; -} - -void u_thread_pool_free(u_thread_pool_t thread_pool) -{ - OIC_LOG_V(DEBUG, TAG, "IN"); - - GThreadPool *threadpool = (GThreadPool *) thread_pool; - g_thread_pool_free(threadpool, TRUE, TRUE); - - OIC_LOG_V(DEBUG, TAG, "OUT"); -} - -void run(void *thread_data, void *user_data) -{ - u_thread_msg_t *message = (u_thread_msg_t *) thread_data; - - if (message && message->func) - { - OIC_LOG_V(DEBUG, TAG, "Calling routine with data as parameter"); - message->func(message->data); - } - else - { - OIC_LOG_V(ERROR, TAG, "Error: Invalid task data"); - return; - } - - //Free message - OICFree(message); - message = NULL; -} diff --git a/resource/csdk/connectivity/external/inc/ocsecurityconfig.h b/resource/csdk/connectivity/external/inc/ocsecurityconfig.h new file mode 100644 index 0000000..9ad8af4 --- /dev/null +++ b/resource/csdk/connectivity/external/inc/ocsecurityconfig.h @@ -0,0 +1,56 @@ +//****************************************************************** +// +// Copyright 2014 Intel Corporation All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_SECURITY_CONFIG_H +#define OC_SECURITY_CONFIG_H + +#include + +#define DTLS_PSK_ID_LEN 16 +#define DTLS_PSK_PSK_LEN 16 + +#define DtlsPskCredsBlobVer_1 1 /**< Credentials stored in plaintext */ +#define DtlsPskCredsBlobVer_CurrentVersion DtlsPskCredsBlobVer_1 + +/** + * Credentials for a device. Includes identity and the associated PSK. + */ +typedef struct +{ + unsigned char id[DTLS_PSK_ID_LEN]; + unsigned char psk[DTLS_PSK_PSK_LEN]; +} OCDtlsPskCreds; + +/** + * Binary blob containing device identity and the credentials for all devices + * trusted by this device. + */ +typedef struct +{ + unsigned char identity[DTLS_PSK_ID_LEN]; /** identity of self */ + uint32_t num; /** number of credentials in this blob */ + OCDtlsPskCreds creds[1]; /** list of credentials. Size of this + array is determined by 'num' variable. */ +} OCDtlsPskCredsBlob; + +#endif //OC_SECURITY_CONFIG_H + + + diff --git a/resource/csdk/connectivity/inc/caadapterinterface.h b/resource/csdk/connectivity/inc/caadapterinterface.h index 67a44cb..d0da447 100644 --- a/resource/csdk/connectivity/inc/caadapterinterface.h +++ b/resource/csdk/connectivity/inc/caadapterinterface.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,11 +19,13 @@ ******************************************************************/ /** - * @file caadapterinterface.h - * @brief This file contains the APIs for adapters to be implemented + * @file + * + * This file contains the APIs for adapters to be implemented. */ -#ifndef __CA_ADAPTER_INTERFACE_H_ -#define __CA_ADAPTER_INTERFACE_H_ + +#ifndef CA_ADAPTER_INTERFACE_H_ +#define CA_ADAPTER_INTERFACE_H_ #include "cacommon.h" @@ -34,72 +36,60 @@ extern "C" /** * @brief Starting connectivity adapters and each adapter have transport specific behavior. - * Transport Specific Behavior: - * WIFI/ETH connectivity Starts unicast server on all available IPs and defined port number as per specification. - * EDR will not start any specific servers. - * LE will not start any specific servers. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * Transport Specific Behavior: + * WIFI/ETH connectivity Starts unicast server on all available IPs and defined + * port number as per specification. + * EDR will not start any specific servers. + * LE will not start any specific servers. + * @return CA_STATUS_OK or CA_STATUS_FAILED + * ERROR CODES (CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStart)(); /** * @brief Starting listening server for receiving multicast search requests * Transport Specific Behavior: - * WIFI/ETH Starts multicast server on all available IPs and defined port number and as per specification. - * EDR Starts RFCOMM Server with prefixed UUID as per specification. - * LE Start GATT Server with prefixed UUID and Characteristics as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * WIFI/ETH Starts multicast server on all available IPs and defined + * port number and as per specification. + * EDR Starts RFCOMM Server with prefixed UUID as per specification. + * LE Start GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * @return CA_STATUS_OK or CA_STATUS_FAILED + * ERROR CODES (CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStartListeningServer)(); /** * @brief for starting discovery servers for receiving multicast advertisements * Transport Specific Behavior: - * WIFI/ETH Starts multicast server on all available IPs and defined port number as per OIC Specification. - * EDR Starts RFCOMM Server with prefixed UUID as per OIC Specification. - * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * WIFI/ETH Starts multicast server on all available IPs and defined port + * number as per OIC Specification. + * EDR Starts RFCOMM Server with prefixed UUID as per OIC Specification. + * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * @return CA_STATUS_OK or CA_STATUS_FAILED + * ERROR CODES (CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStartDiscoveryServer)(); /** * @brief Sends data to the endpoint using the adapter connectivity. * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, + * reference uri and connectivity type) to which the unicast data has to be sent. * @param data [IN] Data which required to be sent. * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. */ -typedef uint32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t* endpoint, void* data, - uint32_t dataLen); +typedef int32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t *endpoint, + const void *data, uint32_t dataLen); /** * @brief Sends Multicast data to the endpoint using the adapter connectivity. * Note: length must be > 0. * @param data [IN] Data which required to be sent. * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. */ -typedef uint32_t (*CAAdapterSendMulticastData)(void* data, uint32_t dataLen); - -/** - * @brief Starts notification server on adapters. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -typedef CAResult_t (*CAAdapterStartNotificationRecvServer)(); - -/** - * @brief Send notification information to the given endpoint. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -typedef uint32_t (*CAAdapterSendNotification)(const CARemoteEndpoint_t* endpoint, void* data, - uint32_t dataLen); +typedef int32_t (*CAAdapterSendMulticastData)(const void *data, uint32_t dataLen); /** * @brief Get Network Information @@ -107,7 +97,7 @@ typedef uint32_t (*CAAdapterSendNotification)(const CARemoteEndpoint_t* endpoint * @param size [OUT] Number of local connectivity structures. * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -typedef CAResult_t (*CAAdapterGetNetworkInfo)(CALocalConnectivityt_t** info, uint32_t* size); +typedef CAResult_t (*CAAdapterGetNetworkInfo)(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. @@ -118,15 +108,16 @@ typedef CAResult_t (*CAAdapterReadData)(); /** * @brief Stopping the adapters and close socket connections * Transport Specific Behavior: - * WIFI/ETH Stops all listening servers and close sockets. - * EDR Stops all RFCOMM servers and close sockets. - * LE Stops all GATT servers and close sockets. + * WIFI/ETH Stops all listening servers and close sockets. + * EDR Stops all RFCOMM servers and close sockets. + * LE Stops all GATT servers and close sockets. * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStop)(); /** - * @brief Terminate the connectivity adapter.Configuration information will be deleted from further use + * @brief Terminate the connectivity adapter.Configuration information will be deleted from + * further use. Freeing Memory of threadpool and mutexs and cleanup will be done. */ typedef void (*CAAdapterTerminate)(); @@ -137,24 +128,28 @@ typedef struct { /** Start Transport specific functions*/ CAAdapterStart startAdapter; + /** Listening Server function address*/ CAAdapterStartListeningServer startListenServer; + /** Discovery Server function address **/ - CAAdapterStartDiscoveryServer startDiscoverServer; + CAAdapterStartDiscoveryServer startDiscoveryServer; + /** Unicast data function address**/ CAAdapterSendUnitcastData sendData; + /** Multicast data function address**/ CAAdapterSendMulticastData sendDataToAll; - /** Notify server function address**/ - CAAdapterStartNotificationRecvServer startNotifyServer; - /** Send Notification function address**/ - CAAdapterSendNotification sendNotification; + /** Get Networking information **/ CAAdapterGetNetworkInfo GetnetInfo; + /** Read Data function address**/ CAAdapterReadData readData; + /** Stop Transport specific functions*/ CAAdapterStop stopAdapter; + /** Terminate function address stored in this pointer**/ CAAdapterTerminate terminate; @@ -162,26 +157,27 @@ typedef struct /** * @brief This will be used during the registration of adapters call backs to the common logic - * @see CAConnectivityHandler_t , CAConnectivityType_t + * @see CAConnectivityHandler_t , CATransportType_t */ typedef void (*CARegisterConnectivityCallback)(CAConnectivityHandler_t handler, - CAConnectivityType_t cType); + CATransportType_t cType); /** * @brief This will be used during the recive of network requests and response. * @see SendUnitcastData(), SendMulticastData() */ -typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t* endPoint, void* data, +typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t *endPoint, void *data, uint32_t dataLen); /** - * @brief This will be used to intimate network changes to the connectivity common logic layer + * @brief This will be used to notify network changes to the connectivity common logic layer * @see SendUnitcastData(), SendMulticastData() */ -typedef void (*CANetworkChangeCallback)(CALocalConnectivityt_t* info, CANetworkStatus_t status); +typedef void (*CANetworkChangeCallback)(CALocalConnectivity_t *info, CANetworkStatus_t status); #ifdef __cplusplus } /* extern "C" */ #endif -#endif // __CA_ADAPTER_INTERFACE_H_ +#endif /* CA_ADAPTER_INTERFACE_H_ */ + diff --git a/resource/csdk/connectivity/inc/caadapternetdtls.h b/resource/csdk/connectivity/inc/caadapternetdtls.h new file mode 100644 index 0000000..debf3d3 --- /dev/null +++ b/resource/csdk/connectivity/inc/caadapternetdtls.h @@ -0,0 +1,230 @@ +/****************************************************************** +* +* Copyright 2014 Samsung Electronics All Rights Reserved. +* +* +* +* 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. +* +******************************************************************/ +#ifndef CA_ADAPTER_NET_DTLS_H_ +#define CA_ADAPTER_NET_DTLS_H_ + +#include "dtls.h" +#include "uarraylist.h" +#include "camutex.h" +#include "caadapterutils.h" +#include "ocsecurityconfig.h" +#include "cainterface.h" + +/** + * Currently DTLS supported adapters(2) WIFI and ETHENET for linux platform. + */ +#define MAX_SUPPORTED_ADAPTERS 2 + +/** + * @brief The implementation will be provided by OIC RI layer. + */ +extern void OCGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo); + +typedef void (*CAPacketReceivedCallback)(const char *ipAddress, const uint16_t port, + const void *data, const uint32_t dataLength, const bool isSecured); + +typedef uint32_t (*CAPacketSendCallback)(const char *ipAddress, const uint16_t port, + const void *data, const uint32_t dataLength); + +/** + * @struct stCAAdapterCallbacks_t + * @brief Data structure for holding the send and recv callbacks. + */ +typedef struct CAAdapterCallbacks +{ + CAPacketReceivedCallback recvCallback; /**< Callback used to send data to upper layer. */ + CAPacketSendCallback sendCallback; /**< Callback used to send data to socket layer. */ +} stCAAdapterCallbacks_t; + +/** + * @struct stCADtlsContext_t + * @brief Data structure for holding the tinyDTLS interface + * related info. + */ +typedef struct stCADtlsContext +{ + u_arraylist_t *cacheList; /**< PDU's are cached until DTLS session is formed. */ + struct dtls_context_t *dtlsContext; /**< Pointer to tinyDTLS context. */ + struct stPacketInfo *packetInfo; /**< used by callback during + decryption to hold address/length. */ + dtls_handler_t callbacks; /**< Pointer to callbacks needed by tinyDTLS. */ + stCAAdapterCallbacks_t adapterCallbacks[MAX_SUPPORTED_ADAPTERS]; +} stCADtlsContext_t; + +/** + * @struct stPacketInfo_t + * @brief Data structure for holding the decrypted data address + * and length provided by tinyDTLS callback interface. + */ +typedef struct stPacketInfo +{ + uint8_t *dataAddress; + uint16_t dataLen; +} stPacketInfo_t; + +/** + * @enum eDtlsRet_t + * @brief tinyDTLS library error codes. + * + */ +typedef enum +{ + DTLS_OK = 0, + DTLS_FAIL, + DTLS_SESSION_INITIATED, + DTLS_HS_MSG +} eDtlsRet_t; + + +/** Structure to have address information which will match with DTLS session_t struct.*/ +typedef struct +{ + socklen_t size; /**< Size of address. */ + union + { + struct sockaddr sa; + struct sockaddr_storage st; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; /**< Address information. */ + uint8_t ifIndex; /**< Holds adpater index to get callback info. */ +} stCADtlsAddrInfo_t; + +/** + * @struct stCACacheMessage_t + * @brief structure to holds the information of cachemessage and address info. + * + */ +typedef struct CACacheMessage +{ + void *data; + uint32_t dataLen; + stCADtlsAddrInfo_t *destSession; +} stCACacheMessage_t; + +/** + * @enum eDtlsAdapterType_t + * @brief This enum is used as array index for storing adapter level callbacks. + * So Keeping 0 instead of "1 << 0". It is not going to be used as addition + * and removal of adapter. + * + */ +typedef enum +{ + DTLS_IP = 0, +} eDtlsAdapterType_t; + +/** + * @fn CADTLSSetAdapterCallbacks + * @brief Used set send and recv callbacks for different adapters(WIFI,EtherNet) + * + * @param[in] recvCallback packet received callback + * @param[in] sendCallback packet sent callback + * @param[in] type type of adapter + * + * @retval void + * + */ +void CADTLSSetAdapterCallbacks(CAPacketReceivedCallback recvCallback, + CAPacketSendCallback sendCallback, eDtlsAdapterType_t type); + +/** + * @brief Register callback to get DTLS PSK credentials. + * @param credCallback [IN] callback to get DTLS credentials + * @retval void + */ +void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback); + +/** + * @fn CAAdapterNetDtlsInit + * @brief initialize tinyDTLS library and other necessary intialization. + * + * @return 0 on success otherwise a positive error value. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAAdapterNetDtlsInit(); + +/** + * @fn CAAdapterNetDtlsDeInit + * @brief de-inits tinyDTLS library and free the allocated memory. + * + * @return void + * + */ +void CAAdapterNetDtlsDeInit(); + +/** + * @fn CAAdapterNetDtlsEncrypt + * @brief Performs DTLS encryption of the CoAP PDU. If a + * DTLS session does not exist yet with the @dst, + * a DTLS handshake will be started. In case where + * a new DTLS handshake is started, pdu info is + * cached to be send when session setup is finished. + * + * @param[in] remoteAddress address to which data will be sent. + * @param[in] port port to which data will be sent. + * @param[in] data length of data. + * @param[in] dataLen length of given data + * @param[out] decdata output variable to store the starting address + * of decrypted plaintext. + * @param[out] cacheFlag utput variable to indicate if pdu + * is cached and inform the caller to + * NOT free the memory holding pdu. + * @return 0 on success otherwise a positive error value. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ + +CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, + const uint16_t port, + void *data, + uint32_t dataLen, + uint8_t *cacheFlag, + eDtlsAdapterType_t type); + +/** + * @fn CAAdapterNetDtlsDecrypt + * @brief Performs DTLS decryption of the data received on + * secure port. This method performs in-place decryption + * of the cipher-text buffer. If a DTLS handshake message + * is received or decryption failure happens, this method + * returns -1. If a valid application PDU is decrypted, it + * returns the length of the decrypted pdu. + * + * @return 0 on success otherwise a positive error value. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress, + const uint16_t port, + uint8_t *data, + uint32_t dataLen, + eDtlsAdapterType_t type); + +#endif /* CA_ADAPTER_NET_DTLS_H_ */ + + diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h new file mode 100644 index 0000000..f78cebb --- /dev/null +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -0,0 +1,312 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains common utility function for CA transport adaptors. + */ + +#ifndef CA_ADAPTER_UTILS_H_ +#define CA_ADAPTER_UTILS_H_ + +#include +#ifdef __ANDROID__ +#include +#endif + +#include "cacommon.h" +#include "logger.h" +#include "pdu.h" +#include "uarraylist.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_RET + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL_RET(arg, log_tag, log_message,ret) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return ret; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return; \ + } \ + +/** + * @brief Length of network interface name. + */ +#define CA_INTERFACE_NAME_SIZE 16 + +/** + * @def IPV4_ADDR_ONE_OCTECT_LEN + * @brief Macro to allocate memory for ipv4 address in the form of uint8_t. + */ +#define IPV4_ADDR_ONE_OCTECT_LEN 4 + +/** + * @brief Network Interface Information. + */ +typedef struct +{ + char ipAddress[CA_IPADDR_SIZE]; /**< Address of the interface **/ + char subnetMask[CA_IPADDR_SIZE]; /**< Maintains interface subnetmask **/ + char interfaceName[CA_INTERFACE_NAME_SIZE]; /**< Interface name**/ +} CANetInfo_t; + +/** + * @brief unicast and multicast server information. + */ +typedef struct +{ + int socketFd; /**< Socket decriptor **/ + char ipAddress[CA_IPADDR_SIZE]; /**< Address of the ip **/ + uint16_t port; /**< Server port number **/ + bool isSecured; /**< Indicates secured server **/ + bool isServerStarted; /**< Indicates server started **/ + bool isMulticastServer; /**< Indicates multicast server **/ + char ifAddr[CA_IPADDR_SIZE]; /**< Address of the multicast interface **/ + char interfaceName[CA_INTERFACE_NAME_SIZE]; /**< Interface Name **/ + char subNetMask[CA_IPADDR_SIZE]; /**< Subnet Mask **/ +} CAServerInfo_t; + +/** + * @brief To log the PDU data + */ +void CALogPDUData(coap_pdu_t *pdu); + +/** + * @fn CAAdapterCreateLocalEndpoint + * @brief Create CALocalConnectivity_t instance. + */ +CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CATransportType_t type, const char *address); + +/** + * @fn CAAdapterCopyLocalEndpoint + * @brief Create CALocalConnectivity_t duplicate instance. + */ +CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(const CALocalConnectivity_t *connectivity); + +/** + * @fn CAAdapterFreeLocalEndpoint + * @brief Deallocate CALocalConnectivity_t instance. + */ +void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndPoint); + +/** + * @fn CAAdapterCreateRemoteEndpoint + * @brief Allocate CARemoteEndpoint_t instance. + */ +CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CATransportType_t type, const char *address, + const char *resourceUri); + +/** + * @fn CAAdapterCopyRemoteEndpoint + * @brief Create CARemoteEndpoint_t duplicate instance. + */ +CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint( + const CARemoteEndpoint_t *remoteEndpoint); + +/** + * @fn CAAdapterFreeRemoteEndpoint + * @brief Deallocate CARemoteEndpoint_t instance. + */ +void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndPoint); + +/** + * @fn CAParseIPv4AddressInternal + * @brief To parse the IP address and port from "ipaddress:port" + * @param ipAddrStr [IN] IP address to be parsed + * @param ipAddr [OUT] Parsed IP address + * @param ipAddr [IN] Buffer length for parsed IP address + * @param port [OUT] Parsed Port number + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAParseIPv4AddressInternal(const char *ipAddrStr, uint8_t *ipAddr, + size_t ipAddrLen, uint16_t *port); + +/** + * @fn CAAdapterIsSameSubnet + * @brief Check if two ip address belong to same subnet. + * @param ipAddress1 [IN] IP address to be checked + * @param ipAddress2 [IN] IP address to be checked + * @param netMask [IN] Subnet mask + * @return true if same subnet and false if not same subnet + */ +bool CAAdapterIsSameSubnet(const char *ipAddress1, const char *ipAddress2, + const char *netMask); +/** + * @brief Used to check the multicast server is running or not. + * + * @param serverInfoList [IN] Server information list. + * @param ipAddress [IN] Interface address of the server. + * @param multicastAddress [IN] Multicast address of the server. + * @param port [IN] Port number of the server. + * + * @return true or false. + */ +bool CAIsMulticastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress, + const char *multicastAddress, uint16_t port); + +/** + * @brief Used to check the unicast server is running or not. + * + * @param serverInfoList [IN] Server information list. + * @param ipAddress [IN] Ip address of the server. + * @param port [IN] Port number of the server. + * + * @return true or false. + */ +bool CAIsUnicastServerStarted(const u_arraylist_t *serverInfoList, const char *ipAddress, + uint16_t port); + +/** + * @brief Used to get the port number based on given information. + * + * @param serverInfoList [IN] Server information list. + * @param ipAddress [IN] Ip address of the server. + * @param isSecured [IN] specifies whether to get secured or normal unicast server port. + * + * @return positive value on success and 0 on error. + */ +uint16_t CAGetServerPort(const u_arraylist_t *serverInfoList, const char *ipAddress, + bool isSecured); + +/** + * @brief Used to get the socket fd for given server information. + * + * @param serverInfoList [IN] Server information list. + * @param ipAddress [IN] Ip address of the server. + * @param isSecured [IN] To check whether it is secured server or not. + * @param isMulticast [IN] To check whether it is multicast server or not. + * @param type [IN] CA_IPV4, CA_IPV6 etc. + + * @return positive value on success and -1 on error. + */ +int CAGetSocketFdForUnicastServer(const u_arraylist_t *serverInfoList, const char *ipAddress, + bool isSecured, bool isMulticast, CATransportType_t type); + +/** + * @brief Used to add the server information into serverinfo list + * + * @param serverInfoList [INOUT] server information list. + * @param info [IN] server informations like ip, port. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAAddServerInfo(u_arraylist_t *serverInfoList, CAServerInfo_t *info); + +/** + * @brief Used to remove the server information based on socket fd from server info list. + * + * @param serverInfoList [INOUT] server information list. + * @param sockFd [IN] Socket descriptor. + * + * @return None + */ +void CARemoveServerInfo(u_arraylist_t *serverInfoList, int sockFd); + +/** + * @brief Used to clear the memory of network inteface list + * Memory pointed by infoList will become invalid after this function call. + * + * @param infoList [IN] Network interface list. + * + * @return None + */ +void CAClearNetInterfaceInfoList(u_arraylist_t *infoList); + +/** + * @brief Used to clear the memory of server info list. + * Memory pointed by serverInfoList will become invalid after this function call. + * + * @param infoList [IN] Server information list. + * + * @return None + */ +void CAClearServerInfoList(u_arraylist_t *serverInfoList); + +#ifdef __ANDROID__ +/** + * @fn CANativeJNISetContext + * @brief To set context of JNI Application + * This must be called by the Android API before CA Initialization + * @param env [IN] JNI interface pointer + * @param context [IN] context object + * @return None + */ +void CANativeJNISetContext(JNIEnv *env, jobject context); + +/** + * @fn CANativeJNISetJavaVM + * @brief To set jvm object + * This must be called by the Android API before CA Initialization + * @param jvm [IN] jvm object + * @return None + */ +void CANativeJNISetJavaVM(JavaVM *jvm); + +/** + * @fn CANativeJNISetContext + * @brief To get context + * Called by adapters to get Application context + * @return context object + */ +jobject CANativeJNIGetContext(); + +/** + * @fn CANativeJNIGetJavaVM + * @brief To get JVM object + * Called from adapters to get JavaVM object + * @return JVM object + */ +JavaVM *CANativeJNIGetJavaVM(); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* CA_ADAPTER_UTILS_H_ */ + diff --git a/resource/csdk/connectivity/inc/caedradapter.h b/resource/csdk/connectivity/inc/caedradapter.h index 2b68a07..678f864 100644 --- a/resource/csdk/connectivity/inc/caedradapter.h +++ b/resource/csdk/connectivity/inc/caedradapter.h @@ -17,125 +17,126 @@ * limitations under the License. * ******************************************************************/ + /** - * @file caedradapter.h - * @brief This file contains the APIs for EDR adapters to be implemented + * @file + * + * This file contains the APIs for EDR adapters. */ -#ifndef __CA_EDRADAPTER_H_ -#define __CA_EDRADAPTER_H_ + +#ifndef CA_EDRADAPTER_H_ +#define CA_EDRADAPTER_H_ /** - * BT Interface AP + * EDR Interface AP **/ #include "cacommon.h" #include "caadapterinterface.h" +#include "cathreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" { #endif -#ifndef BLUETOOTH_ADAPTER_TAG -#define BLUETOOTH_ADAPTER_TAG "CA_EDR" -#endif //BLUETOOTH_ADAPTER_TAG /** - * @brief Initialize EDR connectivity interface. - * @param registerCallback [IN] To register EDR interfaces to Connectivity Abstraction Layer - * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers - * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Initialize EDR Interface. + * @param registerCallback [IN] Callback to register EDR interface to Connectivity + * Abstraction Layer + * @param reqRespCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @param handle [IN] Threadpool Handle + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback, ca_thread_pool_t handle); /** - * @brief Starting EDR connectivity adapters .As its peer to peer it doesnot require to start any servers - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Starts EDR connectivity adapters. As its peer to peer it doesnot require to start + * any servers. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAStartEDR(); /** - * @brief Starting listening server for receiving multicast search requests - * Transport Specific Behavior: - * EDR Starts RFCOMM Server with prefixed UUID as per specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Starts listening server for receiving multicast search requests. + * Starts RFCOMM Server with prefixed UUID as per OIC specification. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAStartEDRListeningServer(); /** - * @brief for starting discovery servers for receiving multicast advertisements - * Transport Specific Behavior: - * EDR Starts RFCOMM server with prefixed UUID as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Starting discovery server for receiving multicast advertisements. + * Starts RFCOMM Server with prefixed UUID as per OIC specification. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAStartEDRDiscoveryServer(); /** - * @brief Sends data to the endpoint using the adapter connectivity. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); - -/** - * @brief Sends Multicast data to the endpoint using the EDR connectivity. - * Note: length must be > 0. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendEDRMulticastData(void* data, uint32_t dataLen); - -/** - * @brief Starts notification server on EDR adapters. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Sends data to the peer bluetooth OIC device using the adapter connectivity. + * @param remoteEndpoint [IN] Remote Endpoint information (like ipaddress, port, reference uri and + * connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data to be sent. + * @param dataLength [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns -1 on error. + * */ -CAResult_t CAStartEDRNotifyServer(); +int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data, + uint32_t dataLength); /** - * @brief Send notification information. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @brief Sends multicast data to all discovered bluetooth OIC devices using the adapter + * connectivity. + * @param data [IN] Data which needs to be sent to all discovered bluetooth OIC device. + * @param dataLength [IN] Length of data in bytes. + * @return Number of bytes sent on the network. Returns -1 on error. */ -uint32_t CASendEDRNotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); +int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength); /** - * @brief Get EDR Connectivity network information - * @param info [OUT] Local connectivity information structures - * @param size [OUT] Number of local connectivity structures. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Get EDR Connectivity network information. + * + * @param info [OUT] Array of local connectivity information structures. + * @param size [OUT] Size of the array @info. + * + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ -CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** - * @brief Read Synchronous API callback. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Read Synchronous API callback. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAReadEDRData(); /** - * @brief Stopping the adapters and close socket connections - * EDR Stops all RFCOMM servers and close sockets. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief EDR Stops all RFCOMM servers and close sockets. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) */ CAResult_t CAStopEDR(); /** - * @brief Terminate the EDR connectivity adapter. - * Configuration information will be deleted from further use + * @brief Terminate the EDR connectivity adapter. + * Configuration information will be deleted from further use. + * @return NONE */ void CATerminateEDR(); +/** + * @brief Initializes the adapter queues. + * This will initiates both server and receiver adapter queues. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CAAdapterStartQueue(); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif //__CA_EDRADAPTER_H_ +#endif /* CA_EDRADAPTER_H_ */ + diff --git a/resource/csdk/connectivity/inc/caedradapter_singlethread.h b/resource/csdk/connectivity/inc/caedradapter_singlethread.h new file mode 100644 index 0000000..a5996d0 --- /dev/null +++ b/resource/csdk/connectivity/inc/caedradapter_singlethread.h @@ -0,0 +1,153 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains the APIs for EDR adapters to be implemented. + */ + +#ifndef CA_EDRADAPTER_SINGLETHREAD_H_ +#define CA_EDRADAPTER_SINGLETHREAD_H_ + +/** + * EDR Interface AP + **/ +#include "cacommon.h" +#include "caadapterinterface.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Initialize EDR Interface. + * @param registerCallback [IN] Callback to register EDR interface to Connectivity + * Abstraction Layer + * @param reqRespCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters + * @retval #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is not + * enabled + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback); + +/** + * @brief Starting EDR connectivity adapters. As its peer to peer it doesnot require to start + * any servers. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_ADAPTER_NOT_ENABLED Bluetooth adapter is not enabled + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartEDR(); + +/** + * @brief Starts listening server for receiving multicast search requests. + * Starts RFCOMM Server with prefixed UUID as per OIC specification. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined + * service UUID + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartEDRListeningServer(); + +/** + * @brief Starts discovery server for receiving multicast advertisements. + * Starts RFCOMM Server with prefixed UUID as per OIC specification. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_SERVER_STARTED_ALREADY Server is already started and running for the predefined + * service UUID + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartEDRDiscoveryServer(); + +/** + * @brief Sends data to the peer bluetooth OIC device using the adapter connectivity. + * @param remoteEndpoint [IN] Remote Endpoint information (like ipaddress, port, reference uri and + * connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data to be sent. + * @param dataLength [IN] Size of data to be sent. + * @return Number of bytes sent on the network. Returns -1 on error. + */ +int32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data, + uint32_t dataLength); + +/** + * @brief Sends multicast data to all discovered bluetooth OIC devices using the adapter + * connectivity. + * @param data [IN] Data which needs to be sent to all discovered bluetooth OIC device. + * @param dataLength [IN] Length of data in bytes. + * @return Number of bytes sent on the network. Returns -1 on error. + */ +int32_t CASendEDRMulticastData(const void *data, uint32_t dataLength); + +/** + * @brief Get EDR Connectivity network information. + * + * @param info [OUT] Array of local connectivity information structures. + * @param size [OUT] Size of the array @info. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input parameters + * @retval #CA_MEMORY_ALLOC_FAILED Failed to allocate memory + * @retval #CA_STATUS_FAILED Operation failed + * @remarks info is allocated in this API and should be freed by the caller. + */ +CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Read Synchronous API callback. + * @return #CA_STATUS_OK on success otherwise proper error code. + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAReadEDRData(); + +/** + * @brief EDR Stops all RFCOMM servers and close sockets. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStopEDR(); + +/** + * @brief Terminate the EDR connectivity adapter. + * Configuration information will be deleted from further use. + * @return NONE + */ +void CATerminateEDR(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_EDRADAPTER_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caedrinterface.h b/resource/csdk/connectivity/inc/caedrinterface.h new file mode 100644 index 0000000..57ac40e --- /dev/null +++ b/resource/csdk/connectivity/inc/caedrinterface.h @@ -0,0 +1,288 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file provides APIs for EDR adapter - client, server, network monitor + * modules. + */ + +#ifndef CA_EDR_INTERFACE_H_ +#define CA_EDR_INTERFACE_H_ + +#include "caedradapter.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifndef OIC_EDR_SERVICE_ID +#define OIC_EDR_SERVICE_ID "12341234-1C25-481F-9DFB-59193D238280" +#endif //OIC_EDR_SERVICE_ID + +typedef enum +{ + STATE_DISCONNECTED, /**< State is Disconnected */ + STATE_CONNECTED /**< State is Connected */ +} CAConnectedState_t; + +typedef struct connected_state +{ + uint8_t address[CA_MACADDR_SIZE]; + CAConnectedState_t state; +} state_t; + +/** + * @enum CAAdapterServerType_t + * @brief Enum for defining different server types. + */ +typedef enum +{ + CA_UNICAST_SERVER = 0, /**< Unicast Server */ + CA_MULTICAST_SERVER, /**< Multicast Server */ + CA_SECURED_UNICAST_SERVER /**< Secured Unicast Server */ +} CAAdapterServerType_t; + +/** + * @struct CAEDRData + * @brief Structure to maintain the information of data in message queue. + */ +typedef struct +{ + CARemoteEndpoint_t *remoteEndpoint; /**< Remote Endpoint */ + void *data; /**< Data to be sent */ + uint32_t dataLen; /**< Length of the data to be sent */ +} CAEDRData; + +/** + * @struct CAEDRNetworkEvent + * @brief Structure to maintain the adapter information and its status. + */ +typedef struct +{ + CALocalConnectivity_t *info; /**< Local Connectivity Information */ + CANetworkStatus_t status; /**< Network Status */ +} CAEDRNetworkEvent; + +/** + * @brief This will be used during the recive of network requests and response. + * @param remoteAddress [IN] EDR address of remote OIC device from which data received. + * @param data [IN] Data received + * @param dataLength [IN] Length of the Data received + * @param sentLength [OUT] Length of the sent data + * @return NONE + * @pre Callback must be registered using CAEDRSetPacketReceivedCallback() + */ +typedef void (*CAEDRDataReceivedCallback)(const char *remoteAddress, const void *data, + uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This will be used during change in network status. + * @param status [IN] Network Status of the adapter + * @return NONE + */ +typedef void (*CAEDRNetworkStatusCallback)(CANetworkStatus_t status); + +/** + * @brief Initialize the network monitor module + * @param threadPool [IN] Threadpool Handle + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is + * not enabled. + * @retval #CA_STATUS_FAILED Operation failed + * @see CAEDRTerminateNetworkMonitor() + */ +CAResult_t CAEDRInitializeNetworkMonitor(const ca_thread_pool_t threadPool); + +/** + * @brief Deinitialize with bluetooth adapter. + * @return NONE + * @pre CAEDRInitializeNetworkMonitor() should be invoked before using this API. + * @see CAEDRInitializeNetworkMonitor() + */ +void CAEDRTerminateNetworkMonitor(); + +/** + * @brief Start Network Monitoring Process + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStartNetworkMonitor(); + +/** + * @brief Stop Network Monitoring Process + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRStopNetworkMonitor(); + +/** + * @brief Sets the callback and Starts discovery for nearby OIC bluetooth devices. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRClientSetCallbacks(); + +/** + * @brief Resetting callbacks with bluetooth framework and stop OIC device discovery. + * @return NONE + * @pre CAEDRClientSetCallbacks() should be invoked before using this API. + * @see CAEDRClientSetCallbacks() + */ +void CAEDRClientUnsetCallbacks(); + +/** + * @brief Used to initialize the EDR client module where mutex is initialized + * @return NONE + */ +void CAEDRInitializeClient(ca_thread_pool_t handle); + +/** + * @brief Destroys the Device list and mutex. + * @return NONE + */ +void CAEDRClientTerminate(); + +/** + * @brief Closes all the client connection to peer bluetooth devices. + * @return NONE + */ +void CAEDRClientDisconnectAll(); + +/** + * @brief Register callback to send the received packets from remote bluetooth device to BTAdapter. + * + * @param packetReceivedCallback [IN] Callback function to register for sending network + * packets to EDR Adapter. + * @return NONE + */ +void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback); + +/** + * @brief Register callback for receiving local bluetooth adapter state. + * + * @param networkStateChangeCallback [IN] Callback function to register for receiving local + * bluetooth adapter status. + * @return NONE + */ +void CAEDRSetNetworkChangeCallback(CAEDRNetworkStatusCallback networkStateChangeCallback); + +/** + * @brief Get the local bluetooth adapter information. + * + * @param info [OUT] Local bluetooth adapter information + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + * @see #CALocalConnectivity_t + * + */ +CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info); + +/** + * @brief Start RFCOMM server for given service UUID + * + * @param serviceUUID [IN] The UUID of service with which RFCOMM server needs to be started. + * @param serverFD [IN] The RFCOMM server socket file descriptor. + * @param handle [IN] Threadpool Handle + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAEDRServerStart(const char *serviceUUID, int *serverFD, ca_thread_pool_t handle); + +/** + * @brief Stop RFCOMM server + * + * @param serverFD [IN] The RFCOMM server socket file descriptor which needs to be stopped. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAEDRServerStop(int serverFD); + +/** + * @brief Terminate server for EDR + * @return None + */ +void CAEDRServerTerminate(); + +/** + * @brief All received data will be notified to upper layer. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAEDRManagerReadData(); + +/** + * @brief This function gets bluetooth adapter enable state. + * @param state [OUT] State of the Adapter. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRGetAdapterEnableState(bool *state); + +/** + * @brief This function sends data to specified remote bluetooth device. + * @param remoteAddress [IN] Remote EDR Address + * @param serviceUUID [IN] Service UUID of the device + * @param data [IN] Data to be sent + * @param dataLength [IN] Length of the data to be sent + * @param sentLength [OUT] Length of the actual sent data + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function sends data to all bluetooth devices running OIC service. + * @param serviceUUID [IN] Service UUID of the device + * @param data [IN] Data to be sent + * @param dataLength [IN] Length of the data to be sent + * @param sentLength [OUT] Length of the actual sent data + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data, + uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function gets bonded bluetooth device list + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAEDRGetBondedDeviceList(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_EDR_INTERFACE_H_ */ + diff --git a/resource/csdk/connectivity/inc/caerrorcode.h b/resource/csdk/connectivity/inc/caerrorcode.h deleted file mode 100644 index 80905b4..0000000 --- a/resource/csdk/connectivity/inc/caerrorcode.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -#ifndef __CA_ERROR_CODE_H_ -#define __CA_ERROR_CODE_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * Declares Stack Results & Errors - */ -typedef enum -{ - OC_STACK_OK = 0, - OC_STACK_INVALID_URI, - OC_STACK_INVALID_QUERY, - OC_STACK_INVALID_IP, - OC_STACK_INVALID_PORT, - OC_STACK_INVALID_CALLBACK, - OC_STACK_INVALID_METHOD, - OC_STACK_INVALID_PARAM, - OC_STACK_INVALID_OBSERVE_PARAM, - OC_STACK_NO_MEMORY, - OC_STACK_COMM_ERROR, - OC_STACK_NOTIMPL, - OC_STACK_NO_RESOURCE, /* resource not found*/ - OC_STACK_RESOURCE_ERROR, /*ex: not supported method or interface*/ - OC_STACK_SLOW_RESOURCE, - OC_STACK_NO_OBSERVERS, /* resource has no registered observers */ - OC_STACK_OBSERVER_NOT_FOUND, - OC_STACK_OBSERVER_NOT_ADDED, - OC_STACK_OBSERVER_NOT_REMOVED, -#ifdef WITH_PRESENCE - OC_STACK_PRESENCE_NO_UPDATE, - OC_STACK_PRESENCE_STOPPED, - OC_STACK_PRESENCE_DO_NOT_HANDLE, -#endif - OC_STACK_ERROR -} OCStackResult; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif //#ifndef __CA_ERROR_CODE_H_ diff --git a/resource/csdk/connectivity/inc/caethernetadapter.h b/resource/csdk/connectivity/inc/caethernetadapter.h deleted file mode 100644 index 61e8a4d..0000000 --- a/resource/csdk/connectivity/inc/caethernetadapter.h +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file caethernetadapter.h - * @brief This file contains the APIs for Ethernet Adapter. - */ -#ifndef __CA_ETHERNET_ADAPTER_H__ -#define __CA_ETHERNET_ADAPTER_H__ - -#include "cacommon.h" -#include "caadapterinterface.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @brief Initialize Ethernet connectivity interface. - * @param registerCallback [IN] To register Ethernet interfaces to Connectivity Abstraction Layer - * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers - * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); - -/** - * @brief Start Ethernet Interface adapter. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartEthernet(); - -/** - * @brief Starting listening server for receiving multicast search requests - * Transport Specific Behavior: - * Ethernet Starts Multicast Server on all available IPs and prefixed port number and as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartEthernetListeningServer(); - -/** - * @brief for starting discovery servers for receiving multicast advertisements - * Transport Specific Behavior: - * Ethernet Starts Start multicast server on all available IPs and prefixed port number as per OIC Specification - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartEthernetDiscoveryServer(); - -/** - * @brief Sends data to the endpoint using the adapter connectivity. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t* endpoint, void* data, - uint32_t dataLen); - -/** - * @brief Sends Multicast data to the endpoint using the WIFI connectivity. - * Note: length must be > 0. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendEthernetMulticastData(void* data, uint32_t dataLen); - -/** - * @brief Starts notification server on Ethernet adapters. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartEthernetNotifyServer(); - -/** - * @brief Send notification information. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendEthernetNotification(const CARemoteEndpoint_t* endpoint, void* data, - uint32_t dataLen); -/** - * @brief Get Ethernet Connectivity network information - * @param info [OUT] Local connectivity information structures - * @param size [OUT] Number of local connectivity structures. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); - -/** - * @brief Read Synchronous API callback. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAReadEthernetData(); - -/** - * @brief Stopping the adapters and close socket connections - * Ethernet Stops all multicast and unicast servers and close sockets. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStopEthernet(); - -/** - * @brief Terminate the Ethernet connectivity adapter. - * Configuration information will be deleted from further use - */ -void CATerminateEthernet(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller.h b/resource/csdk/connectivity/inc/cainterfacecontroller.h index d2af4d2..8aa5940 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -17,36 +17,106 @@ * limitations under the License. * ******************************************************************/ -#ifndef __CA_INTERFACE_CONTROLLER_H_ -#define __CA_INTERFACE_CONTROLLER_H_ + +/** + * @file + * + * This file contains common utility function for CA transport adaptors. + */ + +#ifndef CA_INTERFACE_CONTROLLER_H_ +#define CA_INTERFACE_CONTROLLER_H_ #include "caadapterinterface.h" +#include "cathreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" { #endif -void CAInitializeAdapters(); +/** + * @brief Initializes different adapters based on the compilation flags. + * @param handle [IN] thread pool handle created by message handler for different adapters. + * @return none + */ +void CAInitializeAdapters(ca_thread_pool_t handle); +/** + * @brief Set the received packets callback for message handler + * @param callback [IN] message handler callback to receive packets from different adapters. + * @return none + */ void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback); -void CAStartAdapter(CAConnectivityType_t connectivity); +/** + * @brief Set the network status changed callback for message handler + * @param callback [IN] message handler network status callback to receive network changes. + * @return none + */ +void CASetNetworkChangeCallback(CANetworkChangeCallback callback); + +/** + * @brief Starting different connectivity adapters based on the network selection. + * @param transportType [IN] interested network for starting + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAStartAdapter(CATransportType_t transportType); -void CAStopAdapter(CAConnectivityType_t connectivity); +/** + * @brief Stopping different connectivity adapters based on the network un-selection. + * @param transportType [IN] network type that want to stop + * @return none + */ +void CAStopAdapter(CATransportType_t transportType); -CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length); +/** + * @brief Get network information such as ipaddress and mac information + * @param info [OUT] connectivity information such as ipaddress and mac information + * @param size [OUT] number of connectivity information structures + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size); -CAResult_t CASendMulticastData(void* data, uint32_t length); +/** + * @brief Sends unicast data to the remote endpoint + * @param endpoint [IN] endpoint information where the data has to be sent + * @param data [IN] data that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length); +/** + * @brief Sends multicast data to all endpoints in the network. + * @param data [IN] data that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ + +CAResult_t CASendMulticastData(const void *data, uint32_t length); + +/** + * @brief Start listening servers to receive search requests from clients + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ CAResult_t CAStartListeningServerAdapters(); +/** + * @brief Start discovery servers to receive advertisements from server + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ CAResult_t CAStartDiscoveryServerAdapters(); +/** + * @brief Terminates the adapters which are initialized during the initialization + * @return none + */ void CATerminateAdapters(); #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef __CA_INTERFACE_CONTROLLER_H_ +#endif /* CA_INTERFACE_CONTROLLER_H_ */ + diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h b/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h new file mode 100644 index 0000000..70f0759 --- /dev/null +++ b/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h @@ -0,0 +1,131 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains the APIs for the interface controller. + */ + +#ifndef CA_INTERFACE_CONTROLLER_SINGLETHREAD_H_ +#define CA_INTERFACE_CONTROLLER_SINGLETHREAD_H_ + +#include "caadapterinterface.h" + + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Initializes different adapters based on the compilation flags. + * @param handle [IN] thread pool handle created by message handler for different + * adapters. + * @return none + */ +void CAInitializeAdapters(); + +/** + * @brief Set the received packets callback for message handler + * @param callback [IN] message handler callback to receive packets from different + * adapters. + * @return none + */ +void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback); + +/** + * @brief Set the network status changed callback for message handler + * @param callback [IN] message handler network status callback to receive network + * changes. + * @return none + */ +void CASetNetworkChangeCallback(CANetworkChangeCallback callback); + +/** + * @brief Starting different connectivity adapters based on the network selection. + * @param transportType [IN] network type that want to stop + * @return none + */ +CAResult_t CAStartAdapter(CATransportType_t transportType); + +/** + * @brief Stopping different connectivity adapters based on the network un-selection. + * @param transportType [IN] un selected network for stopping the packets transfer + * @return none + */ +void CAStopAdapter(CATransportType_t transportType); + +/** + * @brief Get network information such as ipaddress and mac information. Gets the network + * information of the adapter whichever is enabled. Otherwise info is NULL. + * @param info [OUT] connectivity information such as ipaddress and mac information + * @param size [OUT] number of connectivity information structures + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Sends unicast data to the remote endpoint + * @param endpoint [IN] endpoint information where the data has to be sent + * @param data [IN] data that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, uint32_t length); + +/** + * @brief Sends multicast data to all endpoints in the network. + * @param data [IN] data that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CASendMulticastData(const void *data, uint32_t length); + +/** + * @brief Start listening servers to receive search requests from clients + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAStartListeningServerAdapters(); + +/** + * @brief Start discovery servers to receive advertisements from server + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAStartDiscoveryServerAdapters(); + +/** + * @brief Terminates the adapters which are initialized during the initialization + * @return none + */ +void CATerminateAdapters(); + +/** + * @brief Checks for available data and reads it + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAReadData(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_INTERFACE_CONTROLLER_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caipadapter.h b/resource/csdk/connectivity/inc/caipadapter.h new file mode 100644 index 0000000..fc1e697 --- /dev/null +++ b/resource/csdk/connectivity/inc/caipadapter.h @@ -0,0 +1,131 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file caipadapter.h + * @brief This file contains the APIs for IP Adapter. + */ +#ifndef CA_IP_ADAPTER_H_ +#define CA_IP_ADAPTER_H_ + +#include "cacommon.h" +#include "caadapterinterface.h" +#include "cathreadpool.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief API to initialize IP Interface. + * @param registerCallback [IN] Callback to register IP interfaces to Connectivity + * Abstraction Layer + * @param networkPacketCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @param handle [IN] Threadpool Handle + * @return #CA_STATUS_OK or Appropriate error code + */ + CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback networkPacketCallback, + CANetworkChangeCallback netCallback, ca_thread_pool_t handle); + + +/** + * @brief Start IP Interface adapter. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIP(); + +/** + * @brief Start listening server for receiving multicast search requests + * Transport Specific Behavior: + * IP Starts Multicast Server on a particular interface and prefixed port number and + * as per OIC Specification. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIPListeningServer(); + +/** + * @brief Start discovery servers for receiving multicast advertisements + * Transport Specific Behavior: + * IP Starts Start multicast server on a particular interface and prefixed port + * number as per OIC Specification + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIPDiscoveryServer(); + +/** + * @brief Sends data to the endpoint using the adapter connectivity. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, + * reference uri and transport type) to which the unicast data has to be sent. + * @param data [IN] Data which is required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. + * @remarks dataLen must be > 0. + */ +int32_t CASendIPUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); + +/** + * @brief Sends Multicast data to the endpoint using the IP connectivity. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. + * @remarks dataLen must be > 0. + */ +int32_t CASendIPMulticastData(const void *data, uint32_t dataLen); + +/** + * @brief Get IP Connectivity network information + * @param info [OUT] Local connectivity information structures + * @param size [OUT] Number of local connectivity structures. + * @return #CA_STATUS_OK or Appropriate error code + * @remarks info is allocated in this API and should be freed by the caller. + */ +CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Read Synchronous API callback. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAReadIPData(); + +/** + * @brief Stops Unicast, Multicast servers and close the sockets. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStopIP(); + +/** + * @brief Terminate the IP connectivity adapter. + * Configuration information will be deleted from further use + * @return NONE + */ +void CATerminateIP(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // #ifndef CA_IP_ADAPTER_H_ + diff --git a/resource/csdk/connectivity/inc/caipadapter_singlethread.h b/resource/csdk/connectivity/inc/caipadapter_singlethread.h new file mode 100644 index 0000000..7625a04 --- /dev/null +++ b/resource/csdk/connectivity/inc/caipadapter_singlethread.h @@ -0,0 +1,128 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file caipadapter_singlethread.h + * @brief This file contains the APIs for IP Adapter. + */ +#ifndef CA_IP_ADAPTER_SINGLETHREAD_H_ +#define CA_IP_ADAPTER_SINGLETHREAD_H_ + +#include "cacommon.h" +#include "caadapterinterface.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief API to initialize IP Interface. + * @param registerCallback [IN] Callback to register IP interfaces to Connectivity + * Abstraction Layer + * @param networkPacketCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback networkPacketCallback, + CANetworkChangeCallback netCallback); + +/** + * @brief Start IP Interface adapter. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIP(); + +/** + * @brief Start listening server for receiving multicast search requests + * Transport Specific Behavior: + * IP Starts Multicast Server on all available IPs and prefixed port number and + * as per OIC Specification. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIPListeningServer(); + +/** + * @brief Start discovery servers for receiving multicast advertisements + * Transport Specific Behavior: + * IP Starts multicast server on all available IPs and prefixed port + * number as per OIC Specification + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartIPDiscoveryServer(); + +/** + * @brief Sends data to the endpoint using the adapter connectivity. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, + * reference uri and connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. + * @remark dataLen must be > 0. + */ +int32_t CASendIPUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); + +/** + * @brief Send Multicast data to the endpoint using the IP connectivity. + * @param data [IN] Data which is required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Return value equal to -1 indicates error. + * @remark dataLen must be > 0. + */ +int32_t CASendIPMulticastData(const void *data, uint32_t dataLen); + +/** + * @brief Get IP Connectivity network information + * @param info [OUT] Local connectivity information structures + * @param size [OUT] Number of local connectivity structures. + * @return #CA_STATUS_OK or Appropriate error code + * @remarks info is allocated in this API and should be freed by the caller. + */ +CAResult_t CAGetIPInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Read Synchronous API callback. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAReadIPData(); + +/** + * @brief Stops Unicast, Multicast servers and close the sockets. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStopIP(); + +/** + * @brief Terminate the Ethernet connectivity adapter. + * Configuration information will be deleted from further use + * @return NONE + */ +void CATerminateIP(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_IP_ADAPTER_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caipinterface.h b/resource/csdk/connectivity/inc/caipinterface.h new file mode 100644 index 0000000..092a51e --- /dev/null +++ b/resource/csdk/connectivity/inc/caipinterface.h @@ -0,0 +1,328 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file caipinterface.h + * @brief This file provides APIs IP client/server/network monitor modules + */ + +#ifndef CA_IP_INTERFACE_H_ +#define CA_IP_INTERFACE_H_ + +#include + +#include "cacommon.h" +#include "cathreadpool.h" +#include "uarraylist.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @enum CAAdapterServerType_t + * @brief Enum for defining different server types. + */ +typedef enum +{ + CA_UNICAST_SERVER = 0, /**< Unicast Server */ + CA_MULTICAST_SERVER, /**< Multicast Server */ + CA_SECURED_UNICAST_SERVER /**< Secured Unicast Server */ +} CAAdapterServerType_t; + +/** + * @brief Callback to be notified on reception of any data from remote OIC devices. + * + * @param ipAddress [IN] IP address of remote OIC device. + * @param port [IN] Port number on which data is received. + * @param data [IN] Data received from remote OIC device. + * @param dataLength [IN] Length of data in bytes. + * @param isSecured [IN] Indicates the data is secure or not. + * + * @return NONE + * @pre Callback must be registered using CAIPSetPacketReceiveCallback() + */ +typedef void (*CAIPPacketReceivedCallback)(const char *ipAddress, uint16_t port, + const void *data, uint32_t dataLength, + bool isSecured); + +/** + * @brief Callback to be notified when exception occures on multicast/unicast server. + * @param type [IN] Type of server(#CAAdapterServerType_t) + * @return NONE + * @pre Callback must be registered using CAIPSetExceptionCallback() + */ +typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type); + +/** + * @brief Initialize IP server + * + * @param threadPool [IN] Thread pool for managing Unicast/Multicast server threads. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAIPInitializeServer(const ca_thread_pool_t threadPool); + +/** + * @brief Terminate IP server + * @return NONE + */ +void CAIPTerminateServer(); + +/** + * @brief Start multicast server for specified multicast address and port + * + * @param localAddress [IN] Local adapter address to which server to be binded. + * @param multicastAddress [IN] Multicast group address. + * @param multicastPort [IN,OUT] Port number on which server will be running. If binding + * the port failed, server starts in the next available port. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_SERVER_STARTED_ALREADY Multicast server is already started and running. + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress, + uint16_t multicastPort); + +/** + * @brief Start unicast server for specified local address and port + * + * @param localAddress [IN] Local adapter address to which server to be binded. + * @param port [IN,OUT] Port number on which server will be running. If binding + * the port failed, server starts in the next available port. + * @param forceStart [IN] Indicate whether to start server forcesfully on specified port + * or not. + * @param secured [IN] True if the secure server to be started, otherwise false. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running. + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, bool forceStart, + bool secured); + +/** + * @brief Stop servers that are running in particular interface address. + * + * @param interfaceAddress [IN] interface address in which servers are running. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopServer(const char *interfaceAddress); + +/** + * @brief Used to stop all unicast and multicast servers. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopAllServers(); + +/** + * @brief Used to get the socket fd based on index value of server info list. + * + * @param index [IN] Index where we need socket fd value. + * @param isSecured [IN] For secured unicast server or normal server. + * + * @return positive value on success and -1 on error. + */ +int CAGetSocketFdFromUnicastIPServerbyIndex(int16_t index, bool isSecured); + +/** + * @brief Used to get the number of unicast server currently running. + * + * @param isSecured [IN] To identify whether its secured unicast server or normal server. + * + * @return positive value on success and -1 on error. + */ +int16_t CAGetNumberOfUnicastIPServers(bool isSecured); + +/** + * @brief Used to get the stored socket fd for corresponding ipAddress. + * + * @param ipAddress [IN] IpAddress of server. + * @param isSecured [IN] Used to check the server is secured or not. + * @param isMulticast [IN] To identify whether its for multicast or unicast. + * + * @return socket fd on success and -1 on error. + */ +int CAGetSocketFdFromUnicastIPServer(const char *ipAddress, bool isSecured, bool isMulticast); + +/** + * @brief Used to get the port number to the corresponding ip for giving interface info. + * + * @param ipAddress [IN] IpAddress of server. + * @param isSecured [IN] Used to check the server is secured or not. + * + * @return port number on success and -1 on error. + */ +uint16_t CAGetServerPortNum(const char *ipAddress, bool isSecured); + +/** + * @brief Used to get the port number for corresponding ipAddress. + * + * @param serverInfoList [OUT] ServerInfoList holds unicast and multicast server informations. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAGetIPServerInfoList(u_arraylist_t **serverInfoList); + +/** + * @brief Set this callback for receiving data packets from peer devices. + * + * @param callback [IN] Callback to be notified on reception of unicast/multicast data packets. + * + * @return NONE + */ +void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback); + +/** + * @brief Set this callback for receiving exception notifications. + * + * @param callback [IN] Callback to be notified on occurance of exception on running servers. + * + * @return NONE + */ +void CAIPSetExceptionCallback(CAIPExceptionCallback callback); + +/** + * @brief API to send unicast UDP data + * + * @param remoteAddress [IN] IP address to which data needs to be sent. + * @param port [IN] Port to which data needs to be send. + * @param data [IN] Data to be send. + * @param dataLength [IN] Length of data in bytes + * @param isMulticast [IN] Whether data needs to be sent to multicast ip + * @param isSecured [IN] Whether data to be sent on secured channel. + * + * @return The number of bytes sent on the network. Returns 0 on error. + * @remarks isSecure will be ignored when isMulticast is true. + */ +uint32_t CAIPSendData(const char *remoteAddress, uint16_t port, const void *data, + uint32_t dataLength, bool isMulticast, bool isSecure); + +/** + * @brief Callback to be notified when IP adapter connection state changes. + * + * @param ipAddress [IN] IP address of remote OIC device. + * @param status [IN] Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN. + * @return NONE + * @pre Callback must be registered using CAIPSetConnectionStateChangeCallback() + */ +typedef void (*CAIPConnectionStateChangeCallback)(const char *ipAddress, + CANetworkStatus_t status); + +/** + * @brief Initialize IP network monitor + * + * @param threadPool [IN] Thread pool for managing network monitor thread. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool); + +/** + * @brief Terminate IP network monitor by removing interface list. + * @return NONE + */ +void CAIPTerminateNetworkMonitor(); + +/** + * @brief Start network monitoring process. It will start the monitor thread. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartNetworkMonitor(); + +/** + * @brief Stop network monitoring process. It will stop the monitor thread. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopNetworkMonitor(); + +/** + * @brief Get local adapter network information. + * + * @param netInterfaceList [OUT] network interface information list + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Operation failed + * @remarks interfaceName and ipAddress must be freed using free(). + */ +CAResult_t CAIPGetInterfaceInfo(u_arraylist_t **netInterfaceList); + +/** + * @brief Get local adapter network subnet mask. + * + * @param ipAddress [IN] IpAddress which is used for getting subnet mask. + * @param subnetMask [OUT] Local adapter interface subnet mask + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Operation failed + * @remarks subnetMask must be freed using free(). + */ +CAResult_t CAIPGetInterfaceSubnetMask(const char *ipAddress, char **subnetMask); + +/** + * @brief Get IP adapter connection state. + * + * @return True if IP adapter is connected, otherwise false + */ + bool CAIPIsConnected(); + +/** + * @brief Set callback for receiving local IP adapter connection status. + * + * @param callback [IN] Callback to be notified when IP adapter connection state changes. + * @return NONE + */ +void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback); + +#ifdef __cplusplus +} +#endif + +#endif /* CA_IP_INTERFACE_H_ */ diff --git a/resource/csdk/connectivity/inc/caipinterface_singlethread.h b/resource/csdk/connectivity/inc/caipinterface_singlethread.h new file mode 100644 index 0000000..69133c3 --- /dev/null +++ b/resource/csdk/connectivity/inc/caipinterface_singlethread.h @@ -0,0 +1,307 @@ +/****************************************************************** +* +* Copyright 2014 Samsung Electronics All Rights Reserved. +* +* +* +* 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. +* +******************************************************************/ + +/** + * @file caipinterface_singlethread.h + * @brief This file provides APIs IP client/server/network monitor modules + */ + +#ifndef CA_IP_INTERFACE_SINGLETHREAD_H_ +#define CA_IP_INTERFACE_SINGLETHREAD_H_ + +#include + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @enum CAAdapterServerType_t + * @brief Enum for defining different server types. + */ +typedef enum +{ + CA_UNICAST_SERVER = 0, /**< Unicast Server */ + CA_MULTICAST_SERVER, /**< Multicast Server */ + CA_SECURED_UNICAST_SERVER /**< Secured Unicast Server */ +} CAAdapterServerType_t; + +/** + * @brief Callback to be notified on reception of any data from remote OIC devices. + * @param ipAddress [IN] IP address of remote OIC device. + * @param port [IN] Port number on which data is received. + * @param data [IN] Data received from remote OIC device. + * @param dataLength [IN] Length of data in bytes. + * @return NONE + * @pre Callback must be registered using CAIPSetPacketReceiveCallback() + */ +typedef void (*CAIPPacketReceivedCallback)(const char *ipAddress, uint16_t port, + const void *data, uint32_t dataLength); + +/** + * @brief Callback to be notified when exception occures on multicast/unicast server. + * @param type [IN] Type of server(#CAAdapterServerType_t) + * @return NONE + * @pre Callback must be registered using CAIPSetExceptionCallback() + */ +typedef void (*CAIPExceptionCallback)(CAAdapterServerType_t type); + +/** + * @brief Initialize IP server + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAIPInitializeServer(void); + +/** + * @brief Terminate IP server + * @return NONE + */ +void CAIPTerminateServer(void); + +/** + * @brief Start multicast server for specified multicast address and port + * + * @param localAddress [IN] Local adapter address to which server to be binded. + * @param multicastAddress [IN] Multicast group address. + * @param multicastPort [IN,OUT] Port number on which server will be running. If binding + the port failed, server starts in the next available port. + * @param serverFD [OUT] Multicast server socket FD. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_SERVER_STARTED_ALREADY Multicast server is already started and running. + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartMulticastServer(const char *localAddress, const char *multicastAddress, + uint16_t multicastPort, int *serverFD); + +/** + * @brief Start unicast server for specified local address and port + * + * @param localAddress [IN] Local adapter address to which server to be binded. + * @param port [IN,OUT] Port number on which server will be running. If binding + the port failed, server starts in the next available port. + * @param forceStart [IN] Indicate whether to start server forcesfully on specified port + * or not. + * @param serverFD [OUT] Unicast server socket FD. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running. + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartUnicastServer(const char *localAddress, uint16_t *port, + bool forceStart, int *serverFD); + +/** + * @brief Stop multicast server. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopMulticastServer(void); + +/** + * @brief Stop unicast server. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopUnicastServer(); + +#ifdef __WITH_DTLS__ +/** + * @brief Stop secured unicast server. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopSecureUnicastServer(); +#endif + +/** + * @brief Get the Unicast Server Information if it is started + * @param ipAddress [OUT] IP address on which server is binded and running. + * @param port [OUT]Port number on which server is running + * @param serverFD [OUT]Server socket fd. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Operation failed + * @remarks ipAddress must be freed using free(). + */ +CAResult_t CAIPGetUnicastServerInfo(char **ipAddress, uint16_t *port, int *serverFD); + +/** + * @brief Set this callback for receiving data packets from peer devices. + * @param callback [IN] Callback to be notified on reception of unicast/multicast data packets. + * + * @return NONE + */ +void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback); + +/** + * @brief Pull the Received Data + * @return NONE + */ +void CAIPPullData(); + +/** + * @brief Set this callback for receiving exception notifications. + * + * @param callback [IN] Callback to be notified on occurance of exception on running servers. + * + * @return NONE + */ +void CAIPSetExceptionCallback(CAIPExceptionCallback callback); + +/** + * @brief Set socket description for sending unicast UDP data. Once the Unicast server is started, + * the same socket descriptor is used for sending the Unicast UDP data. + * + * @param socketFD [IN] Socket descriptor used for sending UDP data. + * @return NONE + */ +void CAIPSetUnicastSocket(int socketFD); + +/** + * @brief Set the port number for sending unicast UDP data + * @param port [IN] Port number used for sending UDP data. + * @return NONE + */ +void CAIPSetUnicastPort(uint16_t port); + +#ifdef __WITH_DTLS__ +/** + * @brief Set socket description for sending secured (encrypted) unicast UDP data + * + * @param socketFD [IN] Socket descriptor used for sending secured (encrypted) UDP data. + * @return NONE + */ +void CAIPSetSecureUnicastSocket(int socketFD); +#endif + +/** + * @brief API to send unicast UDP data + * + * @param remoteAddress [IN] IP address to which data needs to be sent. + * @param port [IN] Port to which data needs to be send. + * @param buf [IN] Data to be send. + * @param bufLen [IN] Length of data in bytes + * @param isMulticast [IN] Whether data needs to be sent to multicast ip + * + * @return The number of bytes sent on the network. Returns 0 on error. + */ +uint32_t CAIPSendData(const char *remoteAddress, uint16_t port, + const char *buf, uint32_t bufLen, bool isMulticast); + +/** + * @brief Callback to be notified when IP adapter connection state changes. + * + * @param ipAddress [IN] IP address of remote OIC device. + * @param status [IN] Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN. + * @return NONE + * @pre Callback must be registered using CAIPSetConnectionStateChangeCallback() + */ +typedef void (*CAIPConnectionStateChangeCallback)(const char *ipAddress, + CANetworkStatus_t status); + +/** + * @brief Initialize IP network monitor + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Initialization failed + */ +CAResult_t CAIPInitializeNetworkMonitor(void); + +/** + * @brief Terminate IP network monitor + * @return NONE + */ +void CAIPTerminateNetworkMonitor(void); + +/** + * @brief Start network monitoring process. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStartNetworkMonitor(void); + +/** + * @brief Stop network monitoring process. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAIPStopNetworkMonitor(void); + +/** + * @brief Get local adapter network information. + * + * @param interfaceName [OUT] Local adapter interface name + * @param ipAddress [OUT] IP address + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input data + * @retval #CA_STATUS_FAILED Operation failed + * @remarks interfaceName and ipAddress must be freed using free(). + */ +CAResult_t CAIPGetInterfaceInfo(char **ipAddress, char **interfaceName); + +/** + * @brief Get Ethernet adapter connection state. + * + * @return True if Ethernet adapter is connected, otherwise false + */ +bool CAIPIsConnected(void); + +/** + * @brief Set callback for receiving local ethernet adapter connection status. + * + * @param callback [IN] Callback to be notified when local Ethernet adapter connection state + * changes. + * @return NONE + */ +void CAIPSetConnectionStateChangeCallback + (CAIPConnectionStateChangeCallback callback); + +#ifdef __cplusplus +} +#endif + +#endif /* CA_IP_INTERFACE_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caleadapter.h b/resource/csdk/connectivity/inc/caleadapter.h index a99d161..ad6e4bb 100644 --- a/resource/csdk/connectivity/inc/caleadapter.h +++ b/resource/csdk/connectivity/inc/caleadapter.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -19,14 +19,17 @@ ******************************************************************/ /** - * @file caleadapter.h - * @brief This file contains the APIs for LE adapters to be implemented + * @file + * + * This file contains the APIs for LE adapters to be implemented. */ -#ifndef _CA_LEADAPTER_H_ -#define _CA_LEADAPTER_H_ + +#ifndef CA_LEADAPTER_H_ +#define CA_LEADAPTER_H_ #include "cacommon.h" #include "caadapterinterface.h" +#include "cathreadpool.h" /* for thread pool */ /** * BLE Interface APIs. @@ -37,17 +40,38 @@ extern "C" #endif /** - * @brief Initialize LE connectivity interface. - * @param registerCallback [IN] To register LE interfaces to Connectivity Abstraction Layer - * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers - * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @struct CALEData_t + * @brief Stores the information of the Data to be sent from the queues. + * This structure will be pushed to the sender/receiver queue for processing. + */ +typedef struct +{ + CARemoteEndpoint_t + *remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */ + void *data; /**< Data to be transmitted over LE tranport */ + uint32_t dataLen; /**< Length of the data being transmitted */ +} CALEData_t; + +/** + * @brief Initialize LE connectivity interface. + * @param registerCallback [IN] Callback to register LE interfaces to Connectivity + * Abstraction Layer + * @param reqRespCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @param handle [IN] Threadpool Handle + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback, + ca_thread_pool_t handle); + /** - * @brief Starting LE connectivity adapters .As its peer to peer it doesnot require to start any servers - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Starting LE connectivity adapters. + * As its peer to peer it doesnot require to start any servers + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAStartLE(); @@ -55,7 +79,7 @@ CAResult_t CAStartLE(); * @brief Starting listening server for receiving multicast search requests * Transport Specific Behavior: * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAStartLEListeningServer(); @@ -63,65 +87,67 @@ CAResult_t CAStartLEListeningServer(); * @brief for starting discovery servers for receiving multicast advertisements * Transport Specific Behavior: * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAStartLEDiscoveryServer(); /** * @brief Sends data to the endpoint using the adapter connectivity. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \ + * and connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns -1 on error. + * @remarks dataLen must be > 0. */ -uint32_t CASendLEUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); +int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); /** * @brief Sends Multicast data to the endpoint using the LE connectivity. - * Note: length must be > 0. * @param data [IN] Data which required to be sent. * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @return The number of bytes sent on the network. Returns -1 on error. + * @remarks dataLen must be > 0. */ -uint32_t CASendLEMulticastData(void* data, uint32_t dataLen); +int32_t CASendLEMulticastData(const void *data, uint32_t dataLen); /** * @brief Starts notification server on EDR adapters. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAStartLENotifyServer(); /** - * @brief Send notification information. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. + * @brief Send notification information. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \ + * and connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns 0 on error. + * @remarks dataLen must be > 0. */ -uint32_t CASendLENotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); +uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); /** - * @brief Get LE Connectivity network information - * @param info [OUT] Local connectivity information structures - * @param size [OUT] Number of local connectivity structures. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @brief Get LE Connectivity network information + * @param info [OUT] Local connectivity information structures + * @param size [OUT] Number of local connectivity structures. + * @return #CA_STATUS_OK or Appropriate error code */ -CAResult_t CAGetLEInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAReadLEData(); /** * @brief Stopping the adapters and close socket connections - * LE Stops all GATT servers and close sockets. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + * LE Stops all GATT servers and GATT Clients. + * @return #CA_STATUS_OK or Appropriate error code */ CAResult_t CAStopLE(); @@ -131,8 +157,284 @@ CAResult_t CAStopLE(); */ void CATerminateLE(); +/** + * @brief This function will receive the data from the GattServer and add the data to + * the Server receiver queue. + * @param remoteAddress [IN] Remote address of the device from where data is received. + * @param serviceUUID [IN] Uuid of the OIC service running on the remote device + * @param data [IN] Actual data recevied from the remote device. + * @param dataLength [IN] Length of the data received from the remote device. + * @param sentLength [IN] Length of the data sent from the remote device. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function will receive the data from the GattClient and add the data into the + * Client receiver queue. + * @param remoteAddress [IN] Remote address of the device from where data is received. + * @param serviceUUID [IN] Uuid of the OIC service running on the remote device + * @param data [IN] Actual data recevied from the remote device. + * @param dataLength [IN] Length of the data received from the remote device. + * @param sentLength [IN] Length of the data sent from the remote device. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function is used to set the NetworkPacket received callback to CA layer from + * adapter layer. + * @param callback [IN] callback handle sent from the upper layer. + * @return NONE + */ +void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback); + +/** + * @brief This function will push the data from CA layer to the Sender processor queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLen [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint, + const void *data, uint32_t dataLen); + +/** + * @brief This function will push the data from CA layer to the Sender processor queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLen [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint, + const void *data, uint32_t dataLen); + +/** + * @brief This function will be associated with the sender queue for GattServer.This function will + * fragment the data to the MTU of the transport and send the data in fragments to the + * adapters. The function will be blocked untill all data is sent out from the adapter. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEServerSendDataThread(void *threadData); + +/** + * @brief This function will be associated with the sender queue for GattClient.This function will + * fragment the data to the MTU of the transport and send the data in fragments to the + * adapters. The function will be blocked untill all data is sent out from the adapter. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEClientSendDataThread(void *threadData); + +/** + * @brief This function will be associated with the receiver queue of GattServer. This function + * will defragment the data received and will send the data UP to the CA layer only after + * it collects all the data from the adapter layer. Adapter Header will provide the + * length of the data sent from the server. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEServerDataReceiverHandler(void *threadData); + +/** + * @brief This function will be associated with the receiver queue of GattClient. This function + * will defragment the data received and will send the data UP to the CA layer only after + * it collects all the data from the adapter layer. Adapter Header will provide the length + * of the data sent from the server. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * @return NONE + */ +void CABLEClientDataReceiverHandler(void *threadData); + +/** + * @brief This function is used to Initalize both GattServer and GattClient queues. All four + * queues will be initialized with this function invocations. + * @return NONE + */ +void CAInitBleQueues(); + +/** + * @brief This function will stop all queues created for GattServer and GattClient. All + * four queues will be be stopped with this function invocations. + * @return NONE + */ +void CAStopBleQueues(); + +/** + * @brief This function will terminate all queues created for GattServer and GattClient. All + * four queues will be be terminated with this function invocations. + * @return NONE + */ +void CATerminateBleQueues(); + +/** + * @brief This function will initalize the Receiver and Sender queues for GattServer. This + * function will inturn call the functions CAInitBleServerReceiverQueue() and + * CAInitBleServerSenderQueue() to initialize the queues. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleServerQueues(); + +/** + * @brief This function will initalize the Receiver and Sender queues for GattClient. This + * function will inturn call the functions CAInitBleClientReceiverQueue() and + * CAInitBleClientSenderQueue() to initialize the queues. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAInitBleClientQueues(); + +/** + * @brief This function will initalize the Receiver queue for GattServer. This will initialize + * the queue to process the function CABLEServerSendDataThread() when ever the task is + * added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleServerSenderQueue(); + +/** + * @brief This function will initalize the Receiver queue for GattClient. This will initialize + * the queue to process the function CABLEClientSendDataThread() when ever the task is + * added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleClientSenderQueue(); + +/** + * @brief This function will initalize the Receiver queue for GattServer. This will initialize + * the queue to process the function CABLEServerDataReceiverHandler() when ever the task + * is added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAInitBleServerReceiverQueue(); + +/** + * @brief This function will initalize the Receiver queue for GattClient. This will initialize + * the queue to process the function CABLEClientDataReceiverHandler() when ever the task + * is added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleClientReceiverQueue(); + +/** + * @brief This function will create the Data required to send it in the queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLength [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void *data, + uint32_t dataLength); + +/** + * @brief Used to free the BLE information stored in the sender/receiver queues. + * @param bleData [IN] Structure contains the information of a particular data segment. + * @return NONE + */ +void CAFreeBLEData(CALEData_t *bleData); + +/** + * @brief This will be used to notify device status changes to the LE adapter layer + * @param adapter_state [IN] State of the adapter + * @return NONE + */ +typedef void (*CALEDeviceStateChangedCallback)(CAAdapterState_t adapter_state); + +/** + * @brief This will be used to notify that network packet recieved from GATTClient to adapter layer. + * @param remoteAddress [IN] Remote endpoint Address + * @param serviceUUID [IN] Service UUID + * @param data [IN] Data received + * @param dataLength [IN] Length of the data received + * @param sentLength [IN] Length of the data sent + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +typedef CAResult_t (*CABLEClientDataReceivedCallback)(const char *remoteAddress, + const char *serviceUUID, const void *data, + uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This will be used to notify that network packet recieved from GATTServer to adapter layer. + * @param remoteAddress [IN] Remote endpoint Address + * @param serviceUUID [IN] Service UUID + * @param data [IN] Data received + * @param dataLength [IN] Length of the data received + * @param sentLength [IN] Length of the data sent + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +typedef CAResult_t (*CABLEServerDataReceivedCallback)(const char *remoteAddress, + const char *serviceUUID, const void *data, + uint32_t dataLength, uint32_t *sentLength); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef _CA_LEADAPTER_H_ +#endif /* CA_LEADAPTER_H_ */ + diff --git a/resource/csdk/connectivity/inc/caleadapter_singlethread.h b/resource/csdk/connectivity/inc/caleadapter_singlethread.h new file mode 100644 index 0000000..c790889 --- /dev/null +++ b/resource/csdk/connectivity/inc/caleadapter_singlethread.h @@ -0,0 +1,427 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains the APIs for LE adapters to be implemented. + */ + +#ifndef CA_LEADAPTER_SINGLETHREAD_H_ +#define CA_LEADAPTER_SINGLETHREAD_H_ + +#include "cacommon.h" +#include "caadapterinterface.h" + +/** + * BLE Interface APIs. + */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @struct CALEData_t + * @brief Stores the information of the Data to be sent from the queues. + * This structure will be pushed to the sender/receiver queue for processing. + */ +typedef struct +{ + CARemoteEndpoint_t + *remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */ + void *data; /**< Data to be transmitted over LE tranport */ + uint32_t dataLen; /**< Length of the data being transmitted */ +} CALEData_t; + +/** + * @brief Initialize LE connectivity interface. + * @param registerCallback [IN] Callback to register LE interfaces to Connectivity Abstraction Layer + * @param reqRespCallback [IN] Callback to notify request and response messages from server(s) + * started at Connectivity Abstraction Layer. + * @param netCallback [IN] Callback to notify the network additions to Connectivity + * Abstraction Layer. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback); + +/** + * @brief Starting LE connectivity adapters. + * As its peer to peer it doesnot require to start any servers + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartLE(); + +/** + * @brief Starting listening server for receiving multicast search requests + * Transport Specific Behavior: + * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartLEListeningServer(); + +/** + * @brief for starting discovery servers for receiving multicast advertisements + * Transport Specific Behavior: + * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartLEDiscoveryServer(); + +/** + * @brief Sends data to the endpoint using the adapter connectivity. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri + * and connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns -1 on error. + * @remarks dataLen must be > 0. + */ +int32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); + +/** + * @brief Sends Multicast data to the endpoint using the LE connectivity. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns -1 on error. + * @remarks dataLen must be > 0. + */ +int32_t CASendLEMulticastData(const void *data, uint32_t dataLen); + +/** + * @brief Starts notification server on EDR adapters. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStartLENotifyServer(); + +/** + * @brief Send notification information. + * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri + * and connectivity type) to which the unicast data has to be sent. + * @param data [IN] Data which required to be sent. + * @param dataLen [IN] Size of data to be sent. + * @return The number of bytes sent on the network. Returns 0 on error. + * @remarks dataLen must be > 0. + */ +uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, const void *data, + uint32_t dataLen); + +/** + * @brief Get LE Connectivity network information + * @param info [OUT] Local connectivity information structures + * @param size [OUT] Number of local connectivity structures. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Read Synchronous API callback. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAReadLEData(); + +/** + * @brief Stopping the adapters and close socket connections + * LE Stops all GATT servers and close sockets. + * @return #CA_STATUS_OK or Appropriate error code + */ +CAResult_t CAStopLE(); + +/** + * @brief Terminate the LE connectivity adapter. + * Configuration information will be deleted from further use + */ +void CATerminateLE(); + +/** + * @brief This function will receive the data from the GattServer and add the data to + * the Server receiver queue. + * @param remoteAddress [IN] Remote address of the device from where data is received. + * @param serviceUUID [IN] Uuid of the OIC service running on the remote device + * @param data [IN] Actual data recevied from the remote device. + * @param dataLength [IN] Length of the data received from the remote device. + * @param sentLength [IN] Length of the data sent from the remote device. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function will receive the data from the GattClient and add the data into the + * Client receiver queue. + * @param remoteAddress [IN] Remote address of the device from where data is received. + * @param serviceUUID [IN] Uuid of the OIC service running on the remote device + * @param data [IN] Actual data recevied from the remote device. + * @param dataLength [IN] Length of the data received from the remote device. + * @param sentLength [IN] Length of the data sent from the remote device. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID, + const void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @brief This function is used to set the NetworkPacket received callback to CA layer from + * adapter layer. + * @param callback [IN] callback handle sent from the upper layer. + * @return NONE + */ +void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback); + +/** + * @brief This function will push the data from CA layer to the Sender processor queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLen [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint, + const void *data, uint32_t dataLen); + +/** + * @brief This function will push the data from CA layer to the Sender processor queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLen [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint, + const void *data, uint32_t dataLen); + +/** + * @brief This function will be associated with the sender queue for GattClient.This function will + * fragment the data to the MTU of the transport and send the data in fragments to the + * adapters. The function will be blocked untill all data is sent out from the adapter. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEClientSendDataThread(void *threadData); + +/** + * @brief This function will be associated with the receiver queue of GattClient. This function + * will defragment the data received and will send the data UP to the CA layer only after + * it collects all the data from the adapter layer. Adapter Header will provide the length + * of the data sent from the server. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * @return NONE + */ +void CABLEClientDataReceiverHandler(void *threadData); + +/** + * @brief This function will terminate all queues created for GattServer and GattClient. All + * four queues will be be terminated with this function invocations. + * @return NONE + */ +void CATerminateBleQueues(); + +/** + * @brief This function will initalize the Receiver queue for GattClient. This will initialize + * the queue to process the function CABLEClientDataReceiverHandler() when ever the task + * is added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleClientReceiverQueue(); + +/** + * @brief This function will initalize the Receiver queue for GattServer. This will initialize + * the queue to process the function CABLEServerDataReceiverHandler() when ever the task + * is added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAInitBleServerReceiverQueue(); + +/** + * @brief This function is used to Initalize both GattServer and GattClient queues. All four + * queues will be initialized with this function invocations. + * @return NONE + */ +void CAInitBleQueues(); + +/** + * @brief This function will initalize the Receiver and Sender queues for GattServer. This + * function will inturn call the functions CAInitBleServerReceiverQueue() and + * CAInitBleServerSenderQueue() to initialize the queues. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleServerQueues(); + +/** + * @brief This function will initalize the Receiver and Sender queues for GattClient. This + * function will inturn call the functions CAInitBleClientReceiverQueue() and + * CAInitBleClientSenderQueue() to initialize the queues. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CAInitBleClientQueues(); + +/** + * @brief This function will initalize the Receiver queue for GattServer. This will initialize + * the queue to process the function CABLEServerSendDataThread() when ever the task is + * added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleServerSenderQueue(); + +/** + * @brief This function will initalize the Receiver queue for GattClient. This will initialize + * the queue to process the function CABLEClientSendDataThread() when ever the task is + * added to this queue. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitBleClientSenderQueue(); + +/** + * @brief This function will be associated with the receiver queue of GattServer. This function + * will defragment the data received and will send the data UP to the CA layer only after + * it collects all the data from the adapter layer. Adapter Header will provide the + * length of the data sent from the server. + * + * @param context [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEServerDataReceiverHandler(void *context); + +/** + * @brief This function will be associated with the sender queue for GattServer.This function will + * fragment the data to the MTU of the transport and send the data in fragments to the + * adapters. The function will be blocked untill all data is sent out from the adapter. + * + * @param threadData [IN] Data pushed to the queue which contains the info about RemoteEndpoint + * and Data. + * + * @return NONE + */ +void CABLEServerSendDataThread(void *threadData); + +/** + * @brief This function will create the Data required to send it in the queue. + * + * @param remoteEndpoint [IN] Remote endpoint information of the server. + * @param data [IN] Data to be transmitted from LE. + * @param dataLength [IN] length of the Data being transmitted. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CALEData_t *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, const void *data, + uint32_t dataLength); + +/** + * @brief Used to free the BLE information stored in the sender/receiver queues. + * @param bleData [IN] Structure contains the information of a particular data segment. + * @return NONE + */ +void CAFreeBLEData(CALEData_t *bleData); + +/** + * @brief This will be used to notify the device status changes to the LE adapter layer + * @param adapter_state [IN] State of the adapter + * @return NONE + */ +typedef void (*CALEDeviceStateChangedCallback)(CAAdapterState_t adapter_state); + +/** + * @brief This will be used to notify that network packet recieved from GATTClient to adapter layer. + * @param remoteAddress [IN] Remote endpoint Address + * @param serviceUUID [IN] Service UUID + * @param data [IN] Data received + * @param dataLength [IN] Length of the data received + * @param sentLength [IN] Length of the data sent + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +typedef CAResult_t (*CABLEClientDataReceivedCallback)(const char *remoteAddress, + const char *serviceUUID, const void *data, uint32_t dataLength, + uint32_t *sentLength); + +/** + * @brief This will be used to notify that network packet recieved from GATTServer to adapter layer. + * @param remoteAddress [IN] Remote endpoint Address + * @param serviceUUID [IN] Service UUID + * @param data [IN] Data received + * @param dataLength [IN] Length of the data received + * @param sentLength [IN] Length of the data sent + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +typedef CAResult_t (*CABLEServerDataReceivedCallback)(const char *remoteAddress, + const char *serviceUUID, const void *data, uint32_t dataLength, uint32_t *sentLength); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_LEADAPTER_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caleinterface.h b/resource/csdk/connectivity/inc/caleinterface.h new file mode 100644 index 0000000..ff1ab29 --- /dev/null +++ b/resource/csdk/connectivity/inc/caleinterface.h @@ -0,0 +1,294 @@ +/* **************************************************************** +* +* Copyright 2014 Samsung Electronics All Rights Reserved. +* +* +* +* 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. +* +******************************************************************/ + +/** + * @file + * + * This file provides APIs for BLE modules. + */ + +#ifndef CA_LE_INTERFACE_H_ +#define CA_LE_INTERFACE_H_ + +#include + +#include "cacommon.h" +#include "caleadapter.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @enum CALETransferType_t + * @brief Provide info about different mode of data transfer + * This enum is used to differentiate between unicast and multicast data transfer. + */ +typedef enum +{ + LE_MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */ + LE_UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */ +} CALETransferType_t; + + +/** + * @brief Initialize the LE adapter layer. This will be invoked from the CA layer. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitializeLEAdapter(); + +/** + * @brief Used to get the current state of the LE adapter. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_ADAPTER_NOT_ENABLED adapter not enabled + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAGetLEAdapterState(); + +/** + * @brief Used to initialize the network monitor layer of the LE adapter. Mutex variables required + * to operate in this layer and other paramters can be initialized in this function. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitializeLENetworkMonitor(); + +/** + * @brief Used to terminate the network monitor layer of the LE adapter. The variables intialized + * in CAInitializeLEAdapterController() must be cleared in this function. + * @return NONE + */ +void CATerminateLENetworkMonitor(); + +/** + * @brief This function is used to set the callback for the Device state changes in the adapter. + * + * @param callback [IN] Callback to notify the Device state change to the CA Layer + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback); + +/** + * @brief Used to initilaze all the mutex variables required to operate the LE network monitor + * layer. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAInitLENetworkMonitorMutexVariables(); + +/** + * @brief Used to terminate all the mutex variables required to operate the LE network monitor + * layer. + * @return NONE + */ +void CATerminateLENetworkMonitorMutexVariables(); + +/** + * @brief Provides the BD address of the local adapter. + * @param local_address [OUT] pointer to the location where bd address needs to be stored. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAGetLEAddress(char **local_address); + +/** + * @brief Used to start Gatt Server thread for service creation and advertise ble service. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartBleGattServer(); + +/** + * @brief Used to stop BLE Gatt Service. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStopBleGattServer(); + +/** + * @brief Used to stop Gatt Server thread and remove service registration, stop advertising. + * @return NONE + */ +void CATerminateBleGattServer(); + +/** + * @brief Used to store upper layer callback locally which will be used to send the data to + * application + * @param callback [IN] Callback function to pass the data to CA layer. + * @return NONE + */ +void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback); + +/** + * @brief Used to update characteristics(Read/Write) value that we want to send to particular + * client. + * + * @param address [IN] BD address of Gatt client + * @param charValue [IN] Data that we want to send to client(unicast) + * @param charValueLen [IN] Length of the data. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *charValue, + const uint32_t charValueLen); + +/** + * @brief Used to update characteristics(Read/Write) value that we want to multicast to all clients + * + * @param charValue [IN] Data that we want to send to clients(multicast) + * @param charValueLen [IN] Length of the data. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue, + const uint32_t charValueLen); + +/** + * @brief Used to start CAStartBleGattClientThread for initializing Gatt Client + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartBLEGattClient(); + +/** + * @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient + * function. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +void CAStopBLEGattClient(); + +/** + * @brief Used to unset all the callbacks and stop service discovery + * @return NONE + */ +void CATerminateBLEGattClient(); + +/** + * @brief Sets the value of characteristic and update the value to GATTServer(unicast). + * + * @param remoteAddress [IN] The address of the remote device + * @param data [IN] The value of characteristic (byte array) + * @param dataLen [IN] The length of value + * @param type [IN] Type of the transfer(#CALETransferType_t) + * @param position [IN] The unique index of each ble server. Used for multicast feature. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data, + const uint32_t dataLen, CALETransferType_t type, + const int32_t position); + +/** + * @brief Sets the value of characteristic and update the value to all registered + * GATTServer -> Multicast + * @param data [IN] The value of characteristic (byte array) + * @param dataLen [IN] The length of value + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen); + +/** + * @brief Used to store upper layer callback locally which will be used to send the data to + * application + * @param callback [IN] Callback function to pass the data to CA layer. + * + * @return void + */ +void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback); + +/** + * @brief Used to Set the gThreadPool handle which is required for spawning new thread. + * + * @param handle [IN] Thread pool handle which is given by above layer for using thread + * creation task. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle); + +/** +* @brief Used to Set the gThreadPool handle which is required for spawning new thread. +* @param handle [IN] Thread pool handle which is given by above layer for using thread creation +* task. +* @return NONE +*/ +void CASetBleClientThreadPoolHandle(ca_thread_pool_t handle); + +/** + * @brief Used to unset the callback of adapter connection state change. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUnSetLEAdapterStateChangedCb(); +#ifdef __cplusplus +} +#endif + +#endif /* CA_LE_INTERFACE_H_ */ + diff --git a/resource/csdk/connectivity/inc/caleinterface_singlethread.h b/resource/csdk/connectivity/inc/caleinterface_singlethread.h new file mode 100644 index 0000000..6cc639b --- /dev/null +++ b/resource/csdk/connectivity/inc/caleinterface_singlethread.h @@ -0,0 +1,216 @@ +/* **************************************************************** +* +* Copyright 2014 Samsung Electronics All Rights Reserved. +* +* +* +* 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. +* +******************************************************************/ + +/** + * @file + * + * This file provides APIs for BLE modules. + */ + +#ifndef CA_LE_INTERFACE_SINGLETHREAD_H_ +#define CA_LE_INTERFACE_SINGLETHREAD_H_ + +#include + +#include "cacommon.h" +#include "caleadapter_singlethread.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @enum CALETransferType_t + * @brief Provide information about different mode of data transfer + * This enum is used to differentiate between unicast and multicast data transfer. + */ +typedef enum +{ + LE_MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */ + LE_UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */ +} CALETransferType_t; + + +/** + * @brief Used to get the current state of the LE adapter. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_ADAPTER_NOT_ENABLED adapter not enabled + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAGetLEAdapterState(); + +/** + * @brief Used to initialize the network monitor layer of the LE adapter. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CALEInitializeNetworkMonitor(); + +/** + * @brief Used to terminate the network monitor layer of the LE adapter. + * @return NONE + */ +void CALETerminateNetworkMonitor(); + +/** + * @brief This function is used to set the callback for the Device state changes in the adapter. + * + * @param callback [IN] Callback to notify the Device state change to the CA Layer + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback); + +/** + * @brief Provides the BD address of the local adapter. + * @param local_address [OUT] pointer to the location where bd address needs to be stored. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAGetLEAddress(char **local_address); + +/** + * @brief Used to start Gatt Server thread for service creation and advertise ble service. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartBleGattServer(); + +/** + * @brief Used to stop BLE Gatt Service. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStopBleGattServer(); + +/** + * @brief Used to store upper layer callback locally which will be used to send the data to + * application + * @param callback [IN] Callback function to pass the data to CA layer. + * @return NONE + */ +void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback); + +/** + * @brief Used to update characteristics(Read/Write) value that we want to send to particular + * client. Both unicast and multicast will use the same api. In mulicast, we will be + * sending in loop to all clients. + * + * @param charValue [IN] Data that we want to send to client(unicast)/clients(multicast) + * @param charValueLen [IN] Length of the data. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue, + uint8_t charValueLen); + +/** + * @brief Used to start CAStartBleGattClientThread for initializing Gatt Client + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAStartBLEGattClient(); + +/** + * @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient + * function. + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +void CAStopBLEGattClient(); + +/** + * @brief Used to unset all the callbacks and stop service discovery + * @return NONE + */ +void CATerminateBLEGattClient(); + +/** + * @brief Sets the value of characteristic and update the value to GATTServer(unicast). + * + * @param remoteAddress [IN] The address of the remote device + * @param data [IN] The value of characteristic (byte array) + * @param dataLen [IN] The length of value + * @param type [IN] Type of the transfer(#CALETransferType_t) + * @param position [IN] The unique index of each ble server. Used for multicast feature. + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data, + const uint32_t dataLen, CALETransferType_t type, + const int32_t position); + +/** + * @brief Sets the value of characteristic and update the value to all registered + * GATTServer -> Multicast + * @param data [IN] The value of characteristic (byte array) + * @param dataLen [IN] The length of value + * + * @return #CA_STATUS_OK or Appropriate error code + * @retval #CA_STATUS_OK Successful + * @retval #CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval #CA_STATUS_FAILED Operation failed + */ +CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen); + +/** + * @brief Used to store upper layer callback locally which will be used to send the data to + * application + * @param callback [IN] Callback function to pass the data to CA layer. + * + * @return void + */ +void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback); + +#ifdef __cplusplus +} +#endif + +#endif /* CA_LE_INTERFACE_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/camessagehandler.h b/resource/csdk/connectivity/inc/camessagehandler.h index 597da7b..e5ee5cb 100644 --- a/resource/csdk/connectivity/inc/camessagehandler.h +++ b/resource/csdk/connectivity/inc/camessagehandler.h @@ -17,42 +17,121 @@ * limitations under the License. * ******************************************************************/ -#ifndef __CA_MESSAGE_HANDLER_H_ -#define __CA_MESSAGE_HANDLER_H_ -#include +/** + * @file camessagehandler.h + * @brief This file contains message functionality. + */ + +#ifndef CA_MESSAGE_HANDLER_H_ +#define CA_MESSAGE_HANDLER_H_ + #include "cacommon.h" +#include "coap.h" + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return; \ + } \ + +#define CA_MEMORY_ALLOC_CHECK(arg) { if (NULL == arg) {OIC_LOG(ERROR, TAG, "Out of memory"); \ +goto memory_error_exit;} } #ifdef __cplusplus extern "C" { #endif -typedef enum -{ - SUCCESS = 0, NETWORK_ERROR, FAIL -} CADetachErrorCode; - -typedef void (*CAMessageHandlerCallback)(int32_t id, CADetachErrorCode code); - -int32_t CADetachRequestMessage(const CARemoteEndpoint_t* object, const CARequestInfo_t* request); +/** + * @brief Detaches control from the caller for sending unicast request + * @param endpoint [IN] endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint, + const CARequestInfo_t *request); -int32_t CADetachResponseMessage(const CARemoteEndpoint_t* object, const CAResponseInfo_t* response); +/** + * @brief Detaches control from the caller for sending multicast request + * @param object [IN] Group endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, + const CARequestInfo_t *request); -int32_t CADetachMessageResourceUri(const CAURI_t resourceUri); +/** + * @brief Detaches control from the caller for sending response + * @param endpoint [IN] endpoint information where the data has to be sent + * @param response [IN] response that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint, + const CAResponseInfo_t *response); -void CASetMessageHandlerCallback(CAMessageHandlerCallback callback); +/** + * @brief Detaches control from the caller for sending request + * @param resourceUri [IN] resource uri that needs to be sent in the request + * @param token [IN] token information of the request + * @param tokenLength [IN] length of the token + * @param options [IN] header options that need to be append in the request + * @param numOptions [IN] number of options be appended + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, + uint8_t tokenLength, const CAHeaderOption_t *options, + uint8_t numOptions); +/** + * @brief Setting the request and response callbacks for network packets + * @param ReqHandler [IN] callback for receiving the requests + * @param RespHandler [IN] callback for receiving the response + * @return NONE + */ void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler); +/** + * @brief Initialize the message handler by starting thread pool and initializing the + * send and receive queue + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ CAResult_t CAInitializeMessageHandler(); +/** + * @brief Terminate the message handler by stopping the thread pool and destroying the queues + * @return NONE + */ void CATerminateMessageHandler(); +/** + * @brief Handler for receiving request and response callback in single thread model + */ void CAHandleRequestResponseCallbacks(); +/** + * @brief To log the PDU data + * @param pdu [IN] pdu data + */ +void CALogPDUInfo(coap_pdu_t *pdu); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef __CA_MESSAGE_HANDLER_H_ +#endif /* CA_MESSAGE_HANDLER_H_ */ + diff --git a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h new file mode 100644 index 0000000..469c6ea --- /dev/null +++ b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h @@ -0,0 +1,137 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file camessagehandler_singlethread.h + * @brief This file contains message functionality. + */ + +#ifndef CA_MESSAGE_HANDLER_SINGLETHREAD_H_ +#define CA_MESSAGE_HANDLER_SINGLETHREAD_H_ + +#include "cacommon.h" +#include "coap.h" + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument. + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input:%s", log_message); \ + return; \ + } \ + +#define CA_MEMORY_ALLOC_CHECK(arg) { if (NULL == arg) {OIC_LOG(ERROR, TAG, "Out of memory"); \ +goto memory_error_exit;} } + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Detaches control from the caller for sending unicast request + * @param endpoint [IN] endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint, + const CARequestInfo_t *request); + +/** + * @brief Detaches control from the caller for sending multicast request + * @param object [IN] Group endpoint information where the data has to be sent + * @param request [IN] request that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object, + const CARequestInfo_t *request); + +/** + * @brief Detaches control from the caller for sending response + * @param endpoint [IN] endpoint information where the data has to be sent + * @param response [IN] response that needs to be sent + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint, + const CAResponseInfo_t *response); + +/** + * @brief Detaches control from the caller for sending request + * @param resourceUri [IN] resource uri that needs to be sent in the request + * @param token [IN] token information of the request + * @param tokenLength [IN] length of the token + * @param options [IN] header options that need to be append in the request + * @param numOptions [IN] number of options be appended + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, + uint8_t tokenLength, const CAHeaderOption_t *options, + uint8_t numOptions); + +/** + * @brief Setting the request and response callbacks for network packets + * @param ReqHandler [IN] callback for receiving the requests + * @param RespHandler [IN] callback for receiving the response + * @return NONE + */ +void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler); + +/** + * @brief Initialize the message handler by starting thread pool and initializing the + * send and receive queue + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CAInitializeMessageHandler(); + +/** + * @brief Terminate the message handler by stopping the thread pool and destroying the queues + * @return NONE + */ +void CATerminateMessageHandler(); + +/** + * @brief Handler for receiving request and response callback in single thread model + */ +void CAHandleRequestResponseCallbacks(); + +/** + * @brief To log the PDU data + * @param pdu [IN] pdu data + */ +void CALogPDUInfo(coap_pdu_t *pdu); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_MESSAGE_HANDLER_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/camsgparser.h b/resource/csdk/connectivity/inc/camsgparser.h new file mode 100644 index 0000000..6780860 --- /dev/null +++ b/resource/csdk/connectivity/inc/camsgparser.h @@ -0,0 +1,171 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains common utility functions to manage the CA msg + * fragmentation and reassemebly. + */ + +#ifndef CA_MSG_PARSER_H_ +#define CA_MSG_PARSER_H_ + +#include "cacommon.h" +#include "logger.h" + +/** + * @var MAX_DATA_LENGTH_SUPPORTED + * @brief From the adapter level, this is the maximum data length is supported + * for the data transmission. + */ +#define MAX_DATA_LENGTH_SUPPORTED 4095 + +/** + * @var NUMBER_OF_BITS_TO_IDENTIFY_DATA + * @brief The number of bits allocated to represent data length in header. + */ +#define NUMBER_OF_BITS_TO_IDENTIFY_DATA 12 + +/** + * @var NUMBER_OF_BITS_IN_CA_HEADER + * @brief The length of the header in bits. + */ +#define NUMBER_OF_BITS_IN_CA_HEADER 15 + +/** + * @var CA_HEADER_LENGTH + * @brief The length of the header in bytes. + */ +#define CA_HEADER_LENGTH 2 + +/** + * @var CA_SUPPORTED_BLE_MTU_SIZE + * @brief The MTU supported for BLE adapter + */ +#define CA_SUPPORTED_BLE_MTU_SIZE 20 + +#ifdef __TIZEN__ +/** + * @var PLATFORM_IDENTIFIER_BIT + * @brief Reserved bit to differentiating the platform. Currently not in use. + */ +#define PLATFORM_IDENTIFIER_BIT 1 + +/** + * @var CA_SUPPORTED_EDR_MTU_SIZE + * @brief The MTU supported from Tizen platform for EDR adapter. + */ +#define CA_SUPPORTED_EDR_MTU_SIZE 512 + +#elif __ANDROID__ +/** + * @var PLATFORM_IDENTIFIER_BIT + * @brief Reserved bit to differentiating the platform. Currently not in use. + */ +#define PLATFORM_IDENTIFIER_BIT 0 + +/** + * @var CA_SUPPORTED_EDR_MTU_SIZE + * @brief The MTU supported from Android platform for EDR adapter. + */ +#define CA_SUPPORTED_EDR_MTU_SIZE 200 + +#elif __ARDUINO__ +/** + * @var PLATFORM_IDENTIFIER_BIT + * @brief Reserved bit to differentiating the platform. Currently not in use. + */ +#define PLATFORM_IDENTIFIER_BIT 0 + +/** + * @var CA_SUPPORTED_EDR_MTU_SIZE + * @brief The MTU supported from Arduino platform for EDR adapter. + */ +#define CA_SUPPORTED_EDR_MTU_SIZE 200 + +#else //Other Platforms +/** + * @var PLATFORM_IDENTIFIER_BIT + * @brief Reserved bit to differentiating the platform. Currently not in use. + */ +#define PLATFORM_IDENTIFIER_BIT 0 + +/** + * @var CA_SUPPORTED_EDR_MTU_SIZE + * @brief The MTU supported for EDR adapter + */ +#define CA_SUPPORTED_EDR_MTU_SIZE 200 + +#endif + +/** + * @var HEADER_VERSION + * @brief Current Header version. + */ +#define HEADER_VERSION 1 + +#ifdef __cplusplus +extern "C" +{ +#endif + +/***************************************************************** + * @file The CA Header format + * @brief CA Header will be difined by 2 bytes of Header. + * First two bits : Header version(Currently Its not being used) + * Third bit and fourth bit: Reserved bits for future use. + * 5th to 16th bit : 12 bits to provide the length of the data. + *****************************************************************/ + +/** +* @fn CAGenerateHeader +* @brief This function is used to generate the CA specific header to maintain the fragmentation +* logic. The header sturcture explained above will be formed and returned to the caller. +* +* @param[in] data Pointer to the charcter data which needs to be printed. +* @param[in] length The total legth of the data which will be represented from 5th -16th bits +* in the header. +* +* @return CA_STATUS_OK on success. One of theCA_STATUS_FAILED or other error values on error. +* @retval CA_STATUS_OK Successful +* @retval CA_STATUS_INVALID_PARAM Invalid input argumets +* @retval CA_STATUS_FAILED Operation failed +*/ +CAResult_t CAGenerateHeader(char *header, uint32_t length); + +/** +* @fn CAParseHeader +* @brief This function is used to parse the header in the receiver end. This function will +* provide the information of the total length of the data which has been fragmented. +* +* @param[in] header Pointer to the charcter data which contains the header information. +* Note that pointer should point to two bytes of data header +* which needs to be parsed. +* +*/ +uint32_t CAParseHeader(const char *header); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_MSG_PARSER_H_ */ + diff --git a/resource/csdk/connectivity/inc/canetworkconfigurator.h b/resource/csdk/connectivity/inc/canetworkconfigurator.h index 4117bf7..2031ab6 100644 --- a/resource/csdk/connectivity/inc/canetworkconfigurator.h +++ b/resource/csdk/connectivity/inc/canetworkconfigurator.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -17,9 +17,17 @@ * limitations under the License. * ******************************************************************/ -#ifndef _NETWORK_CONFIGURATOR_H_ -#define _NETWORK_CONFIGURATOR_H_ +/** + * @file + * + * This file contains utility function for network configurations. + */ + +#ifndef NETWORK_CONFIGURATOR_H_ +#define NETWORK_CONFIGURATOR_H_ + +#include "cacommon.h" #include "uarraylist.h" #ifdef __cplusplus @@ -27,19 +35,44 @@ extern "C" { #endif -static uint32_t NETWORK_ETHERNET = CA_ETHERNET; -static uint32_t NETWORK_WIFI = CA_WIFI; -static uint32_t NETWORK_EDR = CA_EDR; -static uint32_t NETWORK_LE = CA_LE; +/** + * @brief Add network type to the selected networks for network packets reception + * @param transportType [IN] Transport type that needs to be added + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAAddNetworkType(CATransportType_t transportType); -CAResult_t CAAddNetworkType(uint32_t CAConnectivityType); +/** + * @brief Remove network type from the selected configuration + * @param transportType [IN] Transport type that needs to be removed + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CARemoveNetworkType(CATransportType_t transportType); -CAResult_t CARemoveNetworkType(uint32_t CAConnectivityType); +/** + * @brief Get selected network information + * @return array list having the connectivity types + */ +u_arraylist_t *CAGetSelectedNetworkList(); + +/** + * @brief Getnetwork informations of the selected networks + * @param info [OUT] LocalConnectivity objects + * @param size [OUT] No Of Array objects + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t *size); + +/** + * @brief Terminate network type from selected configuration + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CATerminateNetworkType(); -u_arraylist_t* CAGetSelectedNetworkList(); #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef _NETWORK_CONFIGURATOR_H_ +#endif /* NETWORK_CONFIGURATOR_H_ */ + diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index baeb261..d96c7a3 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -17,64 +17,218 @@ * limitations under the License. * ******************************************************************/ -#ifndef __CA_PROTOCOL_MESSAGE_H_ -#define __CA_PROTOCOL_MESSAGE_H_ +/** + * @file caprotocolmessage.h + * @brief This file contains common function for handling protocol messages. + */ + +#ifndef CA_PROTOCOL_MESSAGE_H_ +#define CA_PROTOCOL_MESSAGE_H_ #include "cacommon.h" #include "config.h" #include "coap.h" +#include "debug.h" #ifdef __cplusplus extern "C" { #endif -uint32_t flags = 0; +typedef uint32_t code_t; -uint8_t msgtype = COAP_MESSAGE_CON; /* usually, requests are sent confirmable */ +#define CA_RESPONSE_CLASS(C) (((C) >> 5)*100) +#define CA_RESPONSE_CODE(C) (CA_RESPONSE_CLASS(C) + (C - COAP_RESPONSE_CODE(CA_RESPONSE_CLASS(C)))) -coap_block_t block = -{ .num = 0, .m = 0, .szx = 6}; +/** + * @brief generates pdu structure from the given information. + * @param uri [IN] uri information of the pdu + * @param code [IN] code of the pdu packet + * @param info [IN] pdu information + * @return generated pdu + */ +coap_pdu_t *CAGeneratePDU(const char *uri, uint32_t code, const CAInfo_t info); -typedef uint32_t code_t; +/** + * function for generating + */ /** - * function for generate + * @brief extracts request information from received pdu. + * @param pdu [IN] received pdu + * @param outReqInfo [OUT] request info structure made from received pdu + * @param outUri [OUT] uri received in the received pdu + * @param buflen [IN] Buffer Length for outUri parameter + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -coap_pdu_t* CAGeneratePdu(const char* uri, const uint32_t code, const CAInfo_t info); +CAResult_t CAGetRequestInfoFromPDU(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri, + uint32_t buflen); + /** - * function for parsing + * @brief extracts response information from received pdu. + * @param pdu [IN] received pdu + * @param outResInfo [OUT] response info structure made from received pdu + * @param outUri [OUT] uri received in the received pdu + * @param buflen [IN] Buffer Length for outUri parameter + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo); +CAResult_t CAGetResponseInfoFromPDU(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + char *outUri, uint32_t buflen); -uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo); +/** + * @brief creates pdu from the request information + * @param code [IN] request or response code + * @param options [OUT] options for the request and response + * @param info [IN] information to create pdu + * @param payload [IN] payload for the request or response consumed + * @return generated pdu + */ +coap_pdu_t *CAGeneratePDUImpl(code_t code, coap_list_t *options, const CAInfo_t info, + const char *payload, size_t payloadSize); -coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options); +/** + * @brief parse the URI and creates the options + * @param uriInfo [IN] uri information + * @param options [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAParseURI(const char *uriInfo, coap_list_t **options); -coap_pdu_t* CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *optlist, - const char* payload); +/** + * @brief Helper that uses libcoap to parse either the path or the parameters of a URI + * and populate the supplied options list. + * + * @param str [IN] the input partial URI string (either path or query) + * @param length [IN] the length of the supplied partial URI + * @param target [IN] the part of the URI to parse (either COAP_OPTION_URI_PATH + * or COAP_OPTION_URI_QUERY) + * @param optlist [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target, + coap_list_t **optlist); -void CAParseURI(const char* uriInfo, coap_list_t **options); +/** + * @brief create option list from header information in the info + * @param code [IN] uri information + * @param info [IN] information of the request/response + * @param optlist [OUT] options information + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t info, coap_list_t **optlist); -void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist); +/** + * @brief creates option node from key length and data + * @param key [IN] key for the that needs to be sent + * @param length [IN] length of the data that needs to be sent + * @param data [IN] data that needs to be sent + * @return created list + */ +coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const uint8_t *data); -coap_list_t* CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data); +/** + * @brief order the inserted options + * need to replace queue head if new node has to be added before the existing queue head + * @param a [IN] option 1 for insertion + * @param b [IN] option 2 for insertion + * @return 0 or 1 + */ +int CAOrderOpts(void *a, void *b); -int32_t CAOrderOpts(void *a, void *b); +/** + * @brief number of options count + * @param opt_iter [IN] option iteration for count + * @return number of options + */ +uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter); -void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo); +/** + * @brief gets option data + * @param data [IN] data that is received + * @param length [IN] length of the data + * @param option [OUT] result of the operation + * @param buflen [IN] buffer length of the result + * @return option count + */ +uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *option, uint32_t buflen); + +/** + * @brief extracts request information from received pdu. + * @param pdu [IN] received pdu + * @param outCode [OUT] code of the received pdu + * @param outInfo [OUT] request info structure made from received pdu + * @param outUri [OUT] uri received in the received pdu + * @param buflen [IN] Buffer Length for outUri parameter + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetInfoFromPDU(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, + char *outUri, uint32_t buflen); + +/** + * @brief create pdu from received data + * @param data [IN] received data + * @param length [IN] length of the data received + * @param outCode [OUT] code received + * @return coap_pdu_t value + */ +coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode); -coap_pdu_t* CAParsePDU(const char* data, uint32_t* outCode); +/** + * @brief get Token fromn received data(pdu) + * @param pdu_hdr [IN] header of received pdu + * @param outInfo [OUT] information with token received + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAGetTokenFromPDU(const coap_hdr_t *pdu_hdr, CAInfo_t *outInfo); /** - * function for token + * @brief generates the token + * @param token [OUT] generated token + * @param tokenLength [IN] length of the token + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -CAResult_t CAGenerateTokenInternal(CAToken_t* token); +CAResult_t CAGenerateTokenInternal(CAToken_t *token, uint8_t tokenLength); +/** + * @brief destroys the token + * @param token [IN] generated token + * @return None + */ void CADestroyTokenInternal(CAToken_t token); +/** + * @brief destroy the ca info structure + * @param info [IN] info structure created from received packet + * @return None + */ +void CADestroyInfo(CAInfo_t *info); + +/** + * @brief gets message type from PDU binary data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data + * @return message type + */ +CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void *pdu, uint32_t size); + +/** + * @brief gets message ID PDU binary data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data + * @return message ID + */ +uint16_t CAGetMessageIdFromPduBinaryData(const void *pdu, uint32_t size); + +/** + * @brief gets code PDU binary data + * @param pdu [IN] pdu data + * @param size [IN] size of pdu data + * @return code + */ +CAResponseResult_t CAGetCodeFromPduBinaryData(const void *pdu, uint32_t size); + #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef __CA_PROTOCOL_MESSAGE_H_ +#endif /* CA_PROTOCOL_MESSAGE_H_ */ diff --git a/resource/csdk/connectivity/inc/caqueueingthread.h b/resource/csdk/connectivity/inc/caqueueingthread.h new file mode 100644 index 0000000..b3d282d --- /dev/null +++ b/resource/csdk/connectivity/inc/caqueueingthread.h @@ -0,0 +1,113 @@ +/* **************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file + * + * This file contains common utility function for handling message ques. + */ + +#ifndef CA_QUEUEING_THREAD_H_ +#define CA_QUEUEING_THREAD_H_ + +#include + +#include "cathreadpool.h" +#include "camutex.h" +#include "uqueue.h" +#include "cacommon.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +/**Thread function to be invoked**/ +typedef void (*CAThreadTask)(void *threadData); + +/**Data destroy function**/ +typedef void (*CADataDestroyFunction)(void *data, uint32_t size); + +typedef struct +{ + /** Thread pool of the thread started **/ + ca_thread_pool_t threadPool; + /** mutex for synchrnoization **/ + ca_mutex threadMutex; + /** conditional mutex for synchrnoization **/ + ca_cond threadCond; + /**Thread function to be invoked**/ + CAThreadTask threadTask; + /**Data destroy function**/ + CADataDestroyFunction destroy; + /** Variable to inform the thread to stop **/ + bool isStop; + /** Que on which the thread is operating. **/ + u_queue_t *dataQueue; +} CAQueueingThread_t; + +/** + * @brief Initializes the queing thread + * @param thread [IN] thread data for each thread + * @param handle [IN] thread pool handle created + * @param task [IN] function to be called for each data + * @param destroy [IN] function to data destroy + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, ca_thread_pool_t handle, + CAThreadTask task, CADataDestroyFunction destroy); + +/** + * @brief Starting the queueing thread + * @param thread [IN] thread data that needs to be started + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread); + +/** + * @brief Add queueing thread data for new thread + * @param thread [IN] thread data for new thread control + * @param data [IN] data that needs to be given for each thread + * @param size [IN] length of the data + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ +CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint32_t size); + +/** + * @brief Stopping the queueing thread + * @param thread [IN] thread data that needs to be started + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ + +CAResult_t CAQueueingThreadStop(CAQueueingThread_t *thread); + +/** + * @brief Terminating the queing thread + * @param thread [IN] thread data for each thread + * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) + */ + +CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t *thread); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_QUEUEING_THREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/caremotehandler.h b/resource/csdk/connectivity/inc/caremotehandler.h index 4c3a984..002a6c5 100644 --- a/resource/csdk/connectivity/inc/caremotehandler.h +++ b/resource/csdk/connectivity/inc/caremotehandler.h @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -17,12 +17,15 @@ * limitations under the License. * ******************************************************************/ -#ifndef __CA_REMOTE_HANDLER_H_ -#define __CA_REMOTE_HANDLER_H_ -#include -#include -#include +/** + * @file + * + * This file contains common utility function for remote endpoints. + */ + +#ifndef CA_REMOTE_HANDLER_H_ +#define CA_REMOTE_HANDLER_H_ #include "cacommon.h" @@ -31,25 +34,71 @@ extern "C" { #endif -CARemoteEndpoint_t* CACloneRemoteEndpoint(const CARemoteEndpoint_t* rep); +/** + * @brief Creates a new remote endpoint from the input endpoint + * @param endpoint [IN] endpoint information where the data has to be sent + * @return remote endpoint created + */ +CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *endpoint); -CARemoteEndpoint_t* CACreateRemoteEndpointUriInternal(const CAURI_t uri); +/** + * @brief Creates a new remote endpoint from the input uri + * @param uri [IN] absolute uri information to create remote endpoint + * @param transportType [IN] transport type of the endpoint + * @return remote endpoint created + */ +CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri, + const CATransportType_t transportType); -CARemoteEndpoint_t* CACreateRemoteEndpointInternal(const CAURI_t resourceUri, - const CAAddress_t addr, const CAConnectivityType_t type); +/** + * @brief Creates a new remote endpoint from the input and other information + * @param resourceUri [IN] absolute uri information to create remote endpoint + * @param addr [IN] address of the endpoint + * @param type [IN] transport type of the endpoint + * @return remote endpoint created + */ +CARemoteEndpoint_t *CACreateRemoteEndpointInternal(const CAURI_t resourceUri, + const CAAddress_t addr, + const CATransportType_t type); -void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t* rep); +/** + * @brief Destroy remote endpoint + * @param endpoint [IN] endpoint information where the data has to be sent + * @return none + */ +void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t *rep); -CARequestInfo_t* CACloneRequestInfo(const CARequestInfo_t* rep); +/** + * @brief Creates a new request information + * @param request [IN] request information that needs to be duplicated + * @return remote endpoint created + */ +CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *request); -void CADestroyRequestInfoInternal(CARequestInfo_t* rep); +/** + * @brief Destroy the request information + * @param request [IN] request information that needs to be destroyed + * @return none + */ +void CADestroyRequestInfoInternal(CARequestInfo_t *request); -CAResponseInfo_t* CACloneResponseInfo(const CAResponseInfo_t* rep); +/** + * @brief Creates a new response information + * @param response [IN] response information that needs to be duplicated + * @return remote endpoint created + */ +CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *response); -void CADestroyResponseInfoInternal(CAResponseInfo_t* rep); +/** + * @brief Destroy the response information + * @param response [IN] response information that needs to be destroyed + * @return + */ +void CADestroyResponseInfoInternal(CAResponseInfo_t *response); #ifdef __cplusplus } /* extern "C" */ #endif -#endif //#ifndef __CA_REMOTE_HANDLER_H_ +#endif /* CA_REMOTE_HANDLER_H_ */ + diff --git a/resource/csdk/connectivity/inc/caretransmission.h b/resource/csdk/connectivity/inc/caretransmission.h new file mode 100644 index 0000000..052fa41 --- /dev/null +++ b/resource/csdk/connectivity/inc/caretransmission.h @@ -0,0 +1,166 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file caretransmission.h + * @brief This file contains common function for retransmission messages. + */ + +#ifndef CA_RETRANSMISSION_H_ +#define CA_RETRANSMISSION_H_ + +#include + +#include "cathreadpool.h" +#include "camutex.h" +#include "uarraylist.h" +#include "cacommon.h" + +/** CA_IPV4, CA_EDR, CA_LE **/ +#define DEFAULT_RETRANSMISSION_TYPE (CA_IPV4 | CA_EDR | CA_LE) + +/** default ACK time is 2 sec.(CoAP) **/ +#define DEFAULT_ACK_TIMEOUT_SEC 2 + +/** default max retransmission trying count is 4.(CoAP) **/ +#define DEFAULT_MAX_RETRANSMIT 4 + +/** check period is 1 sec. **/ +#define RETRANSMISSION_CHECK_PERIOD_SEC 1 + +/** retransmission data send method type**/ +typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size); + +/** retransmission timeout callback type**/ +typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size); + +typedef struct +{ + /** retransmission support transport type **/ + CATransportType_t supportType; + + /** retransmission trying count **/ + uint8_t tryingCount; + +} CARetransmissionConfig_t; + +typedef struct +{ + /** Thread pool of the thread started **/ + ca_thread_pool_t threadPool; + + /** mutex for synchronization **/ + ca_mutex threadMutex; + + /** conditional mutex for synchronization **/ + ca_cond threadCond; + + /** send method for retransmission data **/ + CADataSendMethod_t dataSendMethod; + + /** callback function for retransmit timeout **/ + CATimeoutCallback_t timeoutCallback; + + /** retransmission configure data **/ + CARetransmissionConfig_t config; + + /** Variable to inform the thread to stop **/ + bool isStop; + + /** array list on which the thread is operating. **/ + u_arraylist_t *dataList; + +} CARetransmission_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Initializes the retransmission context + * @param context [IN] context for retransmission + * @param handle [IN] thread pool handle + * @param retransmissionSendMethod [IN] function to be called for retransmission + * @param timeoutCallback [IN] callback for retransmit timeout + * @param config [IN] configuration for retransmission. + * if NULL is coming, it will set default values. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionInitialize(CARetransmission_t *context, ca_thread_pool_t handle, + CADataSendMethod_t retransmissionSendMethod, + CATimeoutCallback_t timeoutCallback, + CARetransmissionConfig_t* config); + +/** + * @brief Starting the retransmission context + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionStart(CARetransmission_t *context); + +/** + * @brief Pass the sent pdu data. if retransmission process need, internal thread will wake up and + * process the retransmission data + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] sent pdu binary data + * @param size [IN] sent pdu binary data size + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionSentData(CARetransmission_t* context, + const CARemoteEndpoint_t* endpoint, const void* pdu, + uint32_t size); + +/** + * @brief Pass the received pdu data. if received pdu is ACK data for the retransmission CON data, + * the specified CON data will remove on retransmission list. + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] received pdu binary data + * @param size [IN] received pdu binary data size + * @param retransmissionPdu [OUT] pdu data of the request for reset and ack + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, + const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size, void **retransmissionPdu); + +/** + * @brief Stopping the retransmission context + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionStop(CARetransmission_t *context); + +/** + * @brief Terminating the retransmission context + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionDestroy(CARetransmission_t *context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_RETRANSMISSION_H_ */ diff --git a/resource/csdk/connectivity/inc/caretransmission_singlethread.h b/resource/csdk/connectivity/inc/caretransmission_singlethread.h new file mode 100644 index 0000000..5e581be --- /dev/null +++ b/resource/csdk/connectivity/inc/caretransmission_singlethread.h @@ -0,0 +1,155 @@ +/****************************************************************** + * + * Copyright 2014 Samsung Electronics All Rights Reserved. + * + * + * + * 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. + * + ******************************************************************/ + +/** + * @file caretransmission_singlethread.h + * @brief This file contains common function for retransmission messages. + */ + +#ifndef CA_RETRANSMISSION_SINGLETHREAD_H_ +#define CA_RETRANSMISSION_SINGLETHREAD_H_ + +#include + +#include "uarraylist.h" +#include "cacommon.h" + +/** CA_IPV4, CA_LE **/ +#define DEFAULT_RETRANSMISSION_TYPE (CA_IPV4 | CA_LE) + +/** default retransmission trying count is 4. **/ +#define DEFAULT_RETRANSMISSION_COUNT 4 + +/** check period is 1 sec. **/ +#define RETRANSMISSION_CHECK_PERIOD_SEC 1 + +/** retransmission data send method type**/ +typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size); + +/** retransmission timeout callback type**/ +typedef void (*CATimeoutCallback_t)(const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size); + +typedef struct +{ + /** retransmission support transport type **/ + CATransportType_t supportType; + + /** retransmission trying count **/ + uint8_t tryingCount; + +} CARetransmissionConfig_t; + +typedef struct +{ + /** send method for retransmission data **/ + CADataSendMethod_t dataSendMethod; + + /** callback function for retransmit timeout **/ + CATimeoutCallback_t timeoutCallback; + + /** retransmission configure data **/ + CARetransmissionConfig_t config; + + /** Variable to inform the thread to stop **/ + bool isStop; + + /** array list on which the thread is operating. **/ + u_arraylist_t *dataList; + +} CARetransmission_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Initializes the retransmission context + * @param context [IN] context for retransmission + * @param retransmissionSendMethod [IN] function to be called for retransmission + * @param timeoutCallback [IN] callback for retransmit timeout + * @param config [IN] configuration for retransmission. + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionInitialize(CARetransmission_t *context, + CADataSendMethod_t retransmissionSendMethod, + CATimeoutCallback_t timeoutCallback, + CARetransmissionConfig_t *config); + +/** + * @brief Pass the sent pdu data. if retransmission process need, internal thread will wake up + * and process the retransmission data. + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] sent pdu binary data + * @param size [IN] sent pdu binary data size + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionSentData(CARetransmission_t *context, + const CARemoteEndpoint_t *endpoint, + const void *pdu, uint32_t size); + +/** + * @brief Paas the received pdu data. if received pdu is ACK data for the retransmission CON data, + * the specified CON data will remove on retransmission list. + * @param context [IN] context for retransmission + * @param endpoint [IN] endpoint information + * @param pdu [IN] received pdu binary data + * @param size [IN] received pdu binary data size + * @param retransmissionPdu [OUT] pdu data of the request for reset and ack + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionReceivedData(CARetransmission_t *context, + const CARemoteEndpoint_t *endpoint, const void *pdu, + uint32_t size, void **retransmissionPdu); + +/** + * @brief Stopping the retransmission context + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionStop(CARetransmission_t *context); + +/** + * @brief Terminating the retransmission context + * @param context [IN] context for retransmission + * @return CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h) + */ +CAResult_t CARetransmissionDestroy(CARetransmission_t *context); + +/** + * @brief Retransmitting the request/response for CONFIRMABLE type + */ +void CACheckRetransmissionList(); + +/** + * @brief Invoke Retransmission according to TimedAction Response + * @param threadValue [IN] context for retransmission + */ +void CARetransmissionBaseRoutine(void *threadValue); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* CA_RETRANSMISSION_SINGLETHREAD_H_ */ + diff --git a/resource/csdk/connectivity/inc/cawifiadapter.h b/resource/csdk/connectivity/inc/cawifiadapter.h deleted file mode 100644 index 07ad36a..0000000 --- a/resource/csdk/connectivity/inc/cawifiadapter.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file cawifiadapter.h - * @brief This file contains the APIs for WiFi Adapter. - */ -#ifndef __CA_WIFI_ADAPTER_H__ -#define __CA_WIFI_ADAPTER_H__ - -#include "cacommon.h" -#include "caadapterinterface.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @brief API to initialize WiFi Interface. - * @param registerCallback [IN] To register WIFI interfaces to Connectivity Abstraction Layer - * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers - * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); - -/** - * @brief Start WiFi Interface adapter. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFI(); - -/** - * @brief Starting listening server for receiving multicast search requests - * Transport Specific Behavior: - * WIFI Starts Multicast Server on all available IPs and prefixed port number and as per OIC Specification. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFIListeningServer(); - -/** - * @brief for starting discovery servers for receiving multicast advertisements - * Transport Specific Behavior: - * WIFI Starts Start multicast server on all available IPs and prefixed port number as per OIC Specification - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFIDiscoveryServer(); - -/** - * @brief Sends data to the endpoint using the adapter connectivity. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); - -/** - * @brief Sends Multicast data to the endpoint using the WIFI connectivity. - * Note: length must be > 0. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendWIFIMulticastData(void* data, uint32_t dataLen); - -/** - * @brief Starts notification server on WIFI adapters. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFINotifyRecvServers(); - -/** - * @brief Send notification information. - * Note: length must be > 0. - * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to - * which the unicast data has to be sent. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. - * @return - The number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendWIFINotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); -/** - * @brief Get WIFI Connectivity network information - * @param info [OUT] Local connectivity information structures - * @param size [OUT] Number of local connectivity structures. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); - -/** - * @brief Read Synchronous API callback. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAReadWIFIData(); - -/** - * @brief Stopping the adapters and close socket connections - * WIFI Stops all multicast and unicast servers and close sockets. - * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStopWIFI(); - -/** - * @brief Terminate the WIFI connectivity adapter. - * Configuration information will be deleted from further use - */ -void CATerminateWIfI(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif//#ifndef __CA_WIFI_ADAPTER_H__ diff --git a/resource/csdk/connectivity/inc/cawificore.h b/resource/csdk/connectivity/inc/cawificore.h deleted file mode 100644 index 64e7a20..0000000 --- a/resource/csdk/connectivity/inc/cawificore.h +++ /dev/null @@ -1,83 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file cawificore.h - * @brief This file contains the APIs for Wi-Fi communications. - */ -#ifndef __CA_WIFICORE_H_ -#define __CA_WIFICORE_H_ - -#include "cacommon.h" -#include "config.h" -#include "coap.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef void (*CAPacketReceiveCallback)(const char* address, const char* data); - -void CAWiFiInitialize(); - -void CAWiFiTerminate(); - -int32_t CAWiFiSendUnicastMessage(const char* address, const char* data, int32_t length); - -int32_t CAWiFiSendMulticastMessage(const char* m_address, const char* data); - -int32_t CAWiFiStartUnicastServer(const char* address, int32_t port); - -int32_t CAWiFiStartMulticastServer(const char* m_address, int32_t port); - -int32_t CAWiFiStopUnicastServer(int32_t server_id); - -int32_t CAWiFiStopMulticastServer(int32_t server_id); - -void CAWiFiSetCallback(CAPacketReceiveCallback callback); - -void* CAUnicastReceiveThread(void* data); - -void* CAUnicastSendThread(void* data); - -void CASendUnicastMessage(char* address, void* data); - -int32_t CASendUnicastMessageImpl(const char* address, const char* data, int32_t lengh); - -void CAStopUnicastSendThread(); - -void* CAMulticastReceiveThread(void* data); - -void* CAMulticastSendThread(void* data); - -void CASendMulticastMessage(void* data); - -int32_t CASendMulticastMessageImpl(const char* msg); - -void CAStopMulticastSendThread(); - -void CAGetLocalAddress(char* addressBuffer); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/resource/csdk/connectivity/inc/cawifiethernetadapter.h b/resource/csdk/connectivity/inc/cawifiethernetadapter.h deleted file mode 100644 index 45dcab8..0000000 --- a/resource/csdk/connectivity/inc/cawifiethernetadapter.h +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************** - * - * Copyright 2014 Samsung Electronics All Rights Reserved. - * - * - * - * 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. - * - ******************************************************************/ - -/** - * @file cawifiethernetadapter.h - * @brief This file contains the APIs for WiFi/Ethernet Adapter. - */ -#ifndef __CA_WIFI_ETHERNET_ADAPTER_H__ -#define __CA_WIFI_ETHERNET_ADAPTER_H__ - -#include "cacommon.h" -#include "caadapterinterface.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @brief API to initialize WiFi Interface. - * @param registerCallback to register WIFI interfaces to things communication - * @param reqRespCallback for sending responses and discovery messages from unicast , multicast servers - * @param netCallback to intimate the network additions to things communication - * @return Error Code - */ -CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); - -/** - * @brief API to Start WiFi Interface. - * @return Error Code - */ -CAResult_t CAStartWIFI(); - -/** - * @brief starting listening server - * Transport Specific Behaviour - * IP :- Start Multicast Server on all available IPs and prefixed port number and as per OIC Specification. - * @return Error Code CAResult_t. - */ -CAResult_t CAStartWIFIListeningServer(); - -/** - * @brief for starting discovery servers. - * Transport Specific Behaviour - * IP :- Start Multicast Server on all available IPs and prefixed port number as per OIC Specification. - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFIDiscoveryServer(); - -/** - * @brief Send Multicast Data interface API callback. - * Note: length must be > 0 - * @param endpoint - Endpoint information (like ipaddress , port, reference uri and connectivity type) to which the multicast data has to be sent. - * @param data - void pointer data which will be sent via client - * @param dataLen - size of data to be sent - * @return - Will return the number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); - -/** - * @brief API to send data to a group of remote addresses. - * @param endpoint - Endpoint information (like ipaddress , port, reference uri and connectivity type) to which the multicast data has to be sent. - * @param data - void pointer data which will be sent via client - * @param dataLen - size of data to be sent - * @return - size of data sent or -1 on error - */ -uint32_t CASendWIFIMulticastData(void* data, uint32_t dataLen); - -/** - * @brief Start Notification Server interface API callback. - * - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFINotifyRecvServers(); - -/** - * @brief Send Notification Data interface API callback. - * Note: length must be > 0 - * @param endpoint - remote endpoint having endpoint details - * @param data - data to be sent - * @param dataLen - length of data to be sent - * @return Will return the number of bytes sent on the network. Return value equal to zero indicates error. - */ -uint32_t CASendWIFINotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen); -/** - * @brief Get Network Information - * - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); - -/** - * @brief Read Synchronous API callback. - * @return Error Code CAResult_t. - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAReadWIFIData(); - -/** - * @brief API to Stop WiFi Interface. - * @return CAResult_t - */ -CAResult_t CAStopWIFI(); - -/** - * @brief API to terminate WiFi Interface. - * @return none. - */ -void CATerminateWifi(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/resource/csdk/connectivity/lib/android/jni/Android.mk b/resource/csdk/connectivity/lib/android/jni/Android.mk new file mode 100644 index 0000000..ee3d6a1 --- /dev/null +++ b/resource/csdk/connectivity/lib/android/jni/Android.mk @@ -0,0 +1,31 @@ +#/****************************************************************** +#* +#* Copyright 2015 Samsung Electronics All Rights Reserved. +#* +#* +#* +#* 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. +#* +#******************************************************************/ +#define build type +BUILD = debug + +DEFINE_FLAG = -D__ANDROID__ + + +BUILD_FLAG.debug = $(DEFINE_FLAG) +BUILD_FLAG = $(BUILD_FLAG.$(BUILD)) + +LOCAL_PATH = ../ + +include $(CLEAR_VARS) diff --git a/resource/csdk/connectivity/lib/android/jni/Application.mk b/resource/csdk/connectivity/lib/android/jni/Application.mk new file mode 100644 index 0000000..46e2863 --- /dev/null +++ b/resource/csdk/connectivity/lib/android/jni/Application.mk @@ -0,0 +1,28 @@ +#/****************************************************************** +#* +#* Copyright 2015 Samsung Electronics All Rights Reserved. +#* +#* +#* +#* 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. +#* +#******************************************************************/ + +#Specify Android.mk path w.r.t APPLICATION_BUILD in the Makefile +APP_PROJECT_PATH = ./ + +APP_STL = gnustl_shared +APP_PLATFORM = android-21 +APP_CPPFLAGS += -fexceptions +APP_CPPFLAGS += -frtti += -Wno-error=format-security +APP_CFLAGS = -Wno-error=format-security diff --git a/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch b/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch new file mode 100644 index 0000000..ab0e231 --- /dev/null +++ b/resource/csdk/connectivity/lib/arduino/RBL_nRF8001.patch @@ -0,0 +1,137 @@ +diff -rupN RBL_nRF8001_old/RBL_nRF8001.cpp RBL_nRF8001/RBL_nRF8001.cpp +--- RBL_nRF8001_old/RBL_nRF8001.cpp 2015-01-13 12:25:32.000000000 +0530 ++++ RBL_nRF8001/RBL_nRF8001.cpp 2015-01-13 12:40:41.740244741 +0530 +@@ -22,7 +22,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOU + #endif + + /* Store the setup for the nRF8001 in the flash of the AVR to save on RAM */ +-static hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] PROGMEM = SETUP_MESSAGES_CONTENT; ++static const hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] PROGMEM = SETUP_MESSAGES_CONTENT; + + #if defined(BLEND_MICRO) + static char device_name[11] = "BlendMicro"; +@@ -31,7 +31,10 @@ static char device_name[11] = "Blend + #else + static char device_name[11] = "BLE Shield"; + #endif +- ++ ++#define BLE_ADDRESS_SIZE 18 ++static unsigned char *gLeAddress = NULL; ++ + static uint16_t Adv_Timeout = 0; // Advertising all the time + static uint16_t Adv_Interval = 0x0050; /* advertising interval 50ms + +@@ -117,7 +120,7 @@ void ble_begin() + aci_state.aci_setup_info.services_pipe_type_mapping = NULL; + } + aci_state.aci_setup_info.number_of_pipes = NUMBER_OF_PIPES; +- aci_state.aci_setup_info.setup_msgs = setup_msgs; ++ aci_state.aci_setup_info.setup_msgs = (hal_aci_data_t*)setup_msgs; + aci_state.aci_setup_info.num_setup_msgs = NB_SETUP_MESSAGES; + + /* +@@ -159,7 +162,7 @@ void ble_begin() + static volatile byte ack = 0; + + void ble_write(unsigned char data) +-{ ++{ + if(tx_buffer_len == MAX_TX_BUFF) + { + return; +@@ -199,13 +202,13 @@ unsigned char ble_connected() + } + + void ble_set_name(char *name) +-{ ++{ + unsigned char len=0; +- ++ + len = strlen(name); + if(len > 10) + { +- Serial.print("the new name is too long"); ++ Serial.print("the new name is too long"); + } + else + { +@@ -236,6 +239,10 @@ void ble_reset(uint8_t reset_pin) + void ble_disconnect(void) + { + lib_aci_disconnect(&aci_state, ACI_REASON_TERMINATE); ++ if (NULL != gLeAddress) ++ { ++ free(gLeAddress); ++ } + } + + static void process_events() +@@ -271,6 +278,7 @@ static void process_events() + lib_aci_set_local_data(&aci_state, PIPE_GAP_DEVICE_NAME_SET , (uint8_t *)&device_name , strlen(device_name)); + lib_aci_connect(Adv_Timeout/* in seconds */, Adv_Interval /* advertising interval 50ms*/); + Serial.println(F("Advertising started")); ++ lib_aci_get_address(); + } + break; + } +@@ -294,6 +302,32 @@ static void process_events() + lib_aci_set_local_data(&aci_state, PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET, + (uint8_t *)&(aci_evt->params.cmd_rsp.params.get_device_version), sizeof(aci_evt_cmd_rsp_params_get_device_version_t)); + } ++ ++ if (ACI_CMD_GET_DEVICE_ADDRESS == aci_evt->params.cmd_rsp.cmd_opcode) ++ { ++ if (NULL != gLeAddress) ++ { ++ free(gLeAddress); ++ } ++ gLeAddress = (unsigned char *) malloc (BLE_ADDRESS_SIZE); ++ if (NULL == gLeAddress) ++ { ++ Serial.println("error"); ++ break; ++ } ++ char *tempAddr = (char *) gLeAddress; ++ int8_t iter = 0; ++ for (iter = BTLE_DEVICE_ADDRESS_SIZE - 1; iter >= 0; iter--) ++ { ++ sprintf(tempAddr, "%02x%c", ++ (uint8_t)aci_evt->params.cmd_rsp.params.get_device_address.bd_addr_own[iter], 58); ++ tempAddr += 3; ++ } ++ gLeAddress[BLE_ADDRESS_SIZE - 1] = '\0'; ++ Serial.println("LEAddress :"); ++ Serial.println((char *)gLeAddress); ++ return; ++ } + break; + + case ACI_EVT_CONNECTED: +@@ -471,3 +505,12 @@ void ble_do_events() + #endif + } + ++unsigned char* ble_getAddress() ++{ ++ return gLeAddress; ++} ++ ++void ble_radio_reset() ++{ ++ lib_aci_radio_reset(); ++} +diff -rupN RBL_nRF8001_old/RBL_nRF8001.h RBL_nRF8001/RBL_nRF8001.h +--- RBL_nRF8001_old/RBL_nRF8001.h 2015-01-13 12:25:32.000000000 +0530 ++++ RBL_nRF8001/RBL_nRF8001.h 2015-01-13 12:40:41.740244741 +0530 +@@ -48,6 +48,8 @@ void ble_set_pins(uint8_t reqn, uint8_t + unsigned char ble_busy(); + void ble_reset(uint8_t reset_pin); + void ble_disconnect(void); ++unsigned char* ble_getAddress(); ++void ble_radio_reset(); + + #endif + + diff --git a/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch b/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch new file mode 100644 index 0000000..2e0b165 --- /dev/null +++ b/resource/csdk/connectivity/lib/arduino/arduino_due_ble.patch @@ -0,0 +1,69 @@ +diff -rupN BLE_Old/aci_setup.cpp BLE_New/aci_setup.cpp +--- BLE_Old/aci_setup.cpp 2015-02-26 08:59:03.289267311 +0530 ++++ BLE_New/aci_setup.cpp 2015-02-26 08:59:02.985267313 +0530 +@@ -63,6 +63,9 @@ static bool aci_setup_fill(aci_state_t * + //Add 2 bytes to the length byte for status byte, length for the total number of bytes + memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]), + (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2)); ++ #elif defined(__SAM3X8E__) ++ memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]), ++ (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2)); + #endif + + //Put the Setup ACI message in the command queue +diff -rupN BLE_Old/hal_aci_tl.cpp BLE_New/hal_aci_tl.cpp +--- BLE_Old/hal_aci_tl.cpp 2015-02-26 08:59:03.521267309 +0530 ++++ BLE_New/hal_aci_tl.cpp 2015-02-26 08:59:03.285267311 +0530 +@@ -346,6 +346,12 @@ void hal_aci_tl_init(aci_pins_t *a_pins, + + The SPI library assumes that the hardware pins are used + */ ++#if defined(__SAM3X8E__) ++ SPI.begin (DUE_SPI_CSN); ++ SPI.setBitOrder (DUE_SPI_CSN, LSBFIRST); ++ SPI.setClockDivider(DUE_SPI_CSN, a_pins->spi_clock_divider); /* This will run the SPI at 3MHz assuming a 84MHz clock to the mcu*/ ++ SPI.setDataMode (DUE_SPI_CSN, SPI_MODE0); ++#else + SPI.begin(); + //Board dependent defines + #if defined (__AVR__) +@@ -357,6 +363,7 @@ void hal_aci_tl_init(aci_pins_t *a_pins, + #endif + SPI.setClockDivider(a_pins->spi_clock_divider); + SPI.setDataMode(SPI_MODE0); ++#endif + + /* Initialize the ACI Command queue. This must be called after the delay above. */ + aci_queue_init(&aci_tx_q); +@@ -429,6 +436,8 @@ static uint8_t spi_readwrite(const uint8 + uint8_t tmp_bits; + tmp_bits = SPI.transfer(REVERSE_BITS(aci_byte)); + return REVERSE_BITS(tmp_bits); ++#elif defined(__SAM3X8E__) ++ return SPI.transfer(DUE_SPI_CSN, aci_byte, SPI_CONTINUE); + #endif + } + +diff -rupN BLE_Old/hal_platform.h BLE_New/hal_platform.h +--- BLE_Old/hal_platform.h 2015-02-26 08:59:03.293267311 +0530 ++++ BLE_New/hal_platform.h 2015-02-26 08:59:02.989267313 +0530 +@@ -71,6 +71,19 @@ + + //Redefine the function for reading from flash in ChipKit + #define memcpy_P memcpy ++#elif defined(__SAM3X8E__) ++ /* definition for DUE */ ++ #include "Arduino.h" ++ ++ #define F(X) (X) ++ #undef PSTR ++ #define PSTR(x) (x) ++ #define PROGMEM ++ ++ #define pgm_read_byte_near(x) (x) ++ #define memcpy_P memcpy ++ ++ #define DUE_SPI_CSN 52 + #endif + + #endif /* PLATFORM_H__ */ diff --git a/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch b/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch new file mode 100644 index 0000000..507aa99 --- /dev/null +++ b/resource/csdk/connectivity/lib/arduino/arduino_libraries.patch @@ -0,0 +1,340 @@ +diff -rupN ./libraries/Ethernet/src/Ethernet.cpp ./arduino-1.5.8/libraries/Ethernet/src/Ethernet.cpp +--- ./libraries/Ethernet/src/Ethernet.cpp 2014-10-01 20:45:35.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Ethernet/src/Ethernet.cpp 2015-02-05 15:51:09.000000000 +0530 +@@ -7,10 +7,10 @@ uint8_t EthernetClass::_state[MAX_SOCK_N + 0, 0, 0, 0 }; + uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { + 0, 0, 0, 0 }; ++static DhcpClass s_dhcp; + + int EthernetClass::begin(uint8_t *mac_address) + { +- static DhcpClass s_dhcp; + _dhcp = &s_dhcp; + + +diff -rupN ./libraries/Ethernet/src/utility/socket.cpp ./arduino-1.5.8/libraries/Ethernet/src/utility/socket.cpp +--- ./libraries/Ethernet/src/utility/socket.cpp 2014-10-01 20:45:35.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Ethernet/src/utility/socket.cpp 2015-02-05 15:55:18.000000000 +0530 +@@ -295,6 +295,7 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf + { + uint8_t head[8]; + uint16_t data_len=0; ++ uint16_t data_copied=0; + uint16_t ptr=0; + + if ( len > 0 ) +@@ -316,10 +317,6 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf + data_len = head[6]; + data_len = (data_len << 8) + head[7]; + +- W5100.read_data(s, ptr, buf, data_len); // data copy. +- ptr += data_len; +- +- W5100.writeSnRX_RD(s, ptr); + break; + + case SnMR::IPRAW : +@@ -332,11 +329,6 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf + addr[3] = head[3]; + data_len = head[4]; + data_len = (data_len << 8) + head[5]; +- +- W5100.read_data(s, ptr, buf, data_len); // data copy. +- ptr += data_len; +- +- W5100.writeSnRX_RD(s, ptr); + break; + + case SnMR::MACRAW: +@@ -344,19 +336,22 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf + ptr+=2; + data_len = head[0]; + data_len = (data_len<<8) + head[1] - 2; +- +- W5100.read_data(s, ptr, buf, data_len); +- ptr += data_len; +- W5100.writeSnRX_RD(s, ptr); + break; + + default : + break; + } ++ ++ if (data_len > 0) ++ { ++ data_copied = (data_len <= len) ? data_len : len;// only copy the len bytes, rest of is discarded. ++ W5100.read_data(s, ptr, buf, data_copied); // data copy. ++ ptr += data_len; ++ W5100.writeSnRX_RD(s, ptr); ++ } + W5100.execCmdSn(s, Sock_RECV); +- SPI.endTransaction(); + } +- return data_len; ++ return data_copied; + } + + /** +diff -rupN ./libraries/Time/Time/DateStrings.cpp ./arduino-1.5.8/libraries/Time/Time/DateStrings.cpp +--- ./libraries/Time/Time/DateStrings.cpp 2010-03-06 11:09:22.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Time/Time/DateStrings.cpp 2015-02-05 16:35:01.000000000 +0530 +@@ -6,8 +6,18 @@ + * the long strings can be any length up to the constant dt_MAX_STRING_LEN defined in Time.h + * + */ +- +-#include ++ ++#if defined(__AVR__) ++#include ++#else ++// for compatiblity with Arduino Due and Teensy 3.0 and maybe others? ++#define PROGMEM ++#define PGM_P const char * ++#define pgm_read_byte(addr) (*(const unsigned char *)(addr)) ++#define pgm_read_word(addr) (*(const unsigned char **)(addr)) ++#define strcpy_P(dest, src) strcpy((dest), (src)) ++#endif ++#include // for strcpy_P or strcpy + #include "Time.h" + + // the short strings for each day or month must be exactly dt_SHORT_STR_LEN +@@ -15,38 +25,38 @@ + + static char buffer[dt_MAX_STRING_LEN+1]; // must be big enough for longest string and the terminating null + +-char monthStr1[] PROGMEM = "January"; +-char monthStr2[] PROGMEM = "February"; +-char monthStr3[] PROGMEM = "March"; +-char monthStr4[] PROGMEM = "April"; +-char monthStr5[] PROGMEM = "May"; +-char monthStr6[] PROGMEM = "June"; +-char monthStr7[] PROGMEM = "July"; +-char monthStr8[] PROGMEM = "August"; +-char monthStr9[] PROGMEM = "September"; +-char monthStr10[] PROGMEM = "October"; +-char monthStr11[] PROGMEM = "November"; +-char monthStr12[] PROGMEM = "December"; ++const char monthStr1[] PROGMEM = "January"; ++const char monthStr2[] PROGMEM = "February"; ++const char monthStr3[] PROGMEM = "March"; ++const char monthStr4[] PROGMEM = "April"; ++const char monthStr5[] PROGMEM = "May"; ++const char monthStr6[] PROGMEM = "June"; ++const char monthStr7[] PROGMEM = "July"; ++const char monthStr8[] PROGMEM = "August"; ++const char monthStr9[] PROGMEM = "September"; ++const char monthStr10[] PROGMEM = "October"; ++const char monthStr11[] PROGMEM = "November"; ++const char monthStr12[] PROGMEM = "December"; + +-PGM_P monthNames_P[] PROGMEM = ++PGM_P const monthNames_P[] PROGMEM = + { + "",monthStr1,monthStr2,monthStr3,monthStr4,monthStr5,monthStr6, + monthStr7,monthStr8,monthStr9,monthStr10,monthStr11,monthStr12 + }; + +-char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec"; ++const char monthShortNames_P[] PROGMEM = "ErrJanFebMarAprMayJunJulAugSepOctNovDec"; + +-char dayStr0[] PROGMEM = "Err"; +-char dayStr1[] PROGMEM = "Sunday"; +-char dayStr2[] PROGMEM = "Monday"; +-char dayStr3[] PROGMEM = "Tuesday"; +-char dayStr4[] PROGMEM = "Wednesday"; +-char dayStr5[] PROGMEM = "Thursday"; +-char dayStr6[] PROGMEM = "Friday"; +-char dayStr7[] PROGMEM = "Saturday"; ++const char dayStr0[] PROGMEM = "Err"; ++const char dayStr1[] PROGMEM = "Sunday"; ++const char dayStr2[] PROGMEM = "Monday"; ++const char dayStr3[] PROGMEM = "Tuesday"; ++const char dayStr4[] PROGMEM = "Wednesday"; ++const char dayStr5[] PROGMEM = "Thursday"; ++const char dayStr6[] PROGMEM = "Friday"; ++const char dayStr7[] PROGMEM = "Saturday"; + +-PGM_P dayNames_P[] PROGMEM = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7}; +-char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat"; ++PGM_P const dayNames_P[] PROGMEM = { dayStr0,dayStr1,dayStr2,dayStr3,dayStr4,dayStr5,dayStr6,dayStr7}; ++const char dayShortNames_P[] PROGMEM = "ErrSunMonTueWedThrFriSat"; + + /* functions to return date strings */ + +diff -rupN ./libraries/Time/Time/keywords.txt ./arduino-1.5.8/libraries/Time/Time/keywords.txt +--- ./libraries/Time/Time/keywords.txt 2010-01-05 12:02:50.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Time/Time/keywords.txt 2015-02-05 16:35:47.000000000 +0530 +@@ -22,7 +22,7 @@ weekday KEYWORD2 + setTime KEYWORD2 + adjustTime KEYWORD2 + setSyncProvider KEYWORD2 +-setSyncInteval KEYWORD2 ++setSyncInterval KEYWORD2 + timeStatus KEYWORD2 + ####################################### + # Instances (KEYWORD2) +diff -rupN ./libraries/Time/Time/Time.cpp ./arduino-1.5.8/libraries/Time/Time/Time.cpp +--- ./libraries/Time/Time/Time.cpp 2010-11-01 18:02:50.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Time/Time/Time.cpp 2015-02-05 16:32:08.000000000 +0530 +@@ -31,7 +31,7 @@ + + static tmElements_t tm; // a cache of time elements + static time_t cacheTime; // the time the cache was updated +-static time_t syncInterval = 300; // time sync will be attempted after this many seconds ++static uint32_t syncInterval = 300; // time sync will be attempted after this many seconds + + void refreshCache( time_t t){ + if( t != cacheTime) +@@ -143,15 +143,17 @@ int year(time_t t) { // the year for the + + static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; // API starts months from 1, this array starts from 0 + +-void breakTime(time_t time, tmElements_t &tm){ ++void breakTime(time_t timeInput, tmElements_t &tm){ + // break the given time_t into time components + // this is a more compact version of the C library localtime function + // note that year is offset from 1970 !!! + + uint8_t year; + uint8_t month, monthLength; ++ uint32_t time; + unsigned long days; +- ++ ++ time = (uint32_t)timeInput; + tm.Second = time % 60; + time /= 60; // now it is minutes + tm.Minute = time % 60; +@@ -200,7 +202,7 @@ time_t makeTime(tmElements_t &tm){ + // previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 + + int i; +- time_t seconds; ++ uint32_t seconds; + + // seconds from 1970 till 1 jan 00:00:00 of the given year + seconds= tm.Year*(SECS_PER_DAY * 365); +@@ -222,14 +224,14 @@ time_t makeTime(tmElements_t &tm){ + seconds+= tm.Hour * SECS_PER_HOUR; + seconds+= tm.Minute * SECS_PER_MIN; + seconds+= tm.Second; +- return seconds; ++ return (time_t)seconds; + } + /*=====================================================*/ + /* Low level system time functions */ + +-static time_t sysTime = 0; +-static time_t prevMillis = 0; +-static time_t nextSyncTime = 0; ++static uint32_t sysTime = 0; ++static uint32_t prevMillis = 0; ++static uint32_t nextSyncTime = 0; + static timeStatus_t Status = timeNotSet; + + getExternalTime getTimePtr; // pointer to external sync function +@@ -251,13 +253,15 @@ time_t now(){ + if(nextSyncTime <= sysTime){ + if(getTimePtr != 0){ + time_t t = getTimePtr(); +- if( t != 0) ++ if( t != 0) { + setTime(t); +- else ++ } else { ++ nextSyncTime = sysTime + syncInterval; + Status = (Status == timeNotSet) ? timeNotSet : timeNeedsSync; ++ } + } + } +- return sysTime; ++ return (time_t)sysTime; + } + + void setTime(time_t t){ +@@ -266,9 +270,9 @@ void setTime(time_t t){ + sysUnsyncedTime = t; // store the time of the first call to set a valid Time + #endif + +- sysTime = t; +- nextSyncTime = t + syncInterval; +- Status = timeSet; ++ sysTime = (uint32_t)t; ++ nextSyncTime = (uint32_t)t + syncInterval; ++ Status = timeSet; + prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) + } + +@@ -293,6 +297,7 @@ void adjustTime(long adjustment){ + } + + timeStatus_t timeStatus(){ // indicates if time has been set and recently synchronized ++ now(); // required to actually update the status + return Status; + } + +@@ -303,5 +308,6 @@ void setSyncProvider( getExternalTime ge + } + + void setSyncInterval(time_t interval){ // set the number of seconds between re-sync +- syncInterval = interval; ++ syncInterval = (uint32_t)interval; ++ nextSyncTime = sysTime + syncInterval; + } +\ No newline at end of file +diff -rupN ./libraries/Time/Time/Time.h ./arduino-1.5.8/libraries/Time/Time/Time.h +--- ./libraries/Time/Time/Time.h 2011-07-22 17:30:06.000000000 +0530 ++++ ./arduino-1.5.8/libraries/Time/Time/Time.h 2015-02-05 16:22:27.000000000 +0530 +@@ -8,12 +8,29 @@ + */ + + #ifndef _Time_h ++#ifdef __cplusplus + #define _Time_h + + #include ++#ifndef __AVR__ ++#include // for __time_t_defined, but avr libc lacks sys/types.h ++#endif + ++ ++#if !defined(__time_t_defined) // avoid conflict with newlib or other posix libc + typedef unsigned long time_t; ++#endif ++ + ++// This ugly hack allows us to define C++ overloaded functions, when included ++// from within an extern "C", as newlib's sys/stat.h does. Actually it is ++// intended to include "time.h" from the C library (on ARM, but AVR does not ++// have that file at all). On Mac and Windows, the compiler will find this ++// "Time.h" instead of the C library "time.h", so we may cause other weird ++// and unpredictable effects by conflicting with the C library header "time.h", ++// but at least this hack lets us define C++ functions as intended. Hopefully ++// nothing too terrible will result from overriding the C library header?! ++extern "C++" { + typedef enum {timeNotSet, timeNeedsSync, timeSet + } timeStatus_t ; + +@@ -100,7 +117,11 @@ int month(time_t t); // the month + int year(); // the full four digit year: (2009, 2010 etc) + int year(time_t t); // the year for the given time + ++extern "C" ++{ + time_t now(); // return the current time as seconds since Jan 1 1970 ++} ++ + void setTime(time_t t); + void setTime(int hr,int min,int sec,int day, int month, int yr); + void adjustTime(long adjustment); +@@ -121,6 +142,7 @@ void setSyncInterval(time_t interval) + void breakTime(time_t time, tmElements_t &tm); // break time_t into elements + time_t makeTime(tmElements_t &tm); // convert time elements into time_t + +- ++} // extern "C++" ++#endif // __cplusplus + #endif /* _Time_h */ + diff --git a/resource/csdk/connectivity/lib/arduino/arduinomega.properties b/resource/csdk/connectivity/lib/arduino/arduinomega.properties new file mode 100644 index 0000000..3da589e --- /dev/null +++ b/resource/csdk/connectivity/lib/arduino/arduinomega.properties @@ -0,0 +1,33 @@ +#Source directories +SDIR_ARD_CORE1 = $(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +#SDIR_ARD_CORE2 = $(ARDUINO_DIR)/hardware/arduino/sam/cores/arduino/avr +SDIR_ARD_TIME = $(ARDUINO_DIR)/libraries/Time/Time +SDIR_ARD_TIMED_ACTION = $(ARDUINO_DIR)/libraries/TimedAction +SDIR_ARD_SPI = $(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI + +SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_TIMED_ACTION):$(SDIR_ARD_SPI) + +#include directories +IDIR_ARD_CORE1 = $(ARDUINO_DIR)/hardware/arduino/avr/cores/arduino +IDIR_ARD_CORE2 = $(ARDUINO_DIR)/hardware/tools/avr/avr/include/ +IDIR_ARD_CORE3 = $(ARDUINO_DIR)/hardware/arduino/avr/variants/mega +INCD_ARD_TIME = $(ARDUINO_DIR)/libraries/Time/Time +INCD_ARD_TIMED_ACTION = $(ARDUINO_DIR)/libraries/TimedAction +IDIR_ARD_SPI = $(ARDUINO_DIR)/hardware/arduino/avr/libraries/SPI +IDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/src/utility + + +INC_DIR_PLATFORM = -I$(IDIR_ARD_CORE1) -I$(IDIR_ARD_CORE2) -I$(IDIR_ARD_CORE3) -I$(INCD_ARD_TIME) -I$(INCD_ARD_TIMED_ACTION) \ + -I$(IDIR_ARD_SPI) -I$(IDIR_ARD_ETH_UTIL) + +#Compiler/Linker flags +CFLAGS_PLATFORM = -mmcu=atmega2560 -DF_CPU=16000000L -fno-exceptions -ffunction-sections -fdata-sections -MMD \ + -DARDUINO=157 -DARDUINO_ARCH_AVR -DARDUINO_AVR_ADK -DWITH_ARDUINO -D__AVR__ + +#Compilers +$(info ************ arduinodue file*****************) +CCPLUS=$(ARDUINO_TOOLS_DIR)/avr-g++ +CC=$(ARDUINO_TOOLS_DIR)/avr-gcc +AR=$(ARDUINO_TOOLS_DIR)/avr-ar +RANLIB=$(ARDUINO_TOOLS_DIR)/avr-ranlib + diff --git a/resource/csdk/connectivity/lib/arduino/local.properties b/resource/csdk/connectivity/lib/arduino/local.properties new file mode 100644 index 0000000..e318153 --- /dev/null +++ b/resource/csdk/connectivity/lib/arduino/local.properties @@ -0,0 +1,2 @@ +ARDUINO_DIR = /usr/share/arduino +ARDUINO_TOOLS_DIR = $(ARDUINO_DIR)/hardware/tools/avr/bin diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/Makefile b/resource/csdk/connectivity/lib/libcoap-4.1.1/Makefile deleted file mode 100644 index 23475f8..0000000 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/Makefile +++ /dev/null @@ -1,113 +0,0 @@ -# Makefile for libcoap -# -# Copyright (C) 2010--2013 Olaf Bergmann -# -# This file is part of the CoAP library libcoap. Please see -# README for terms of use. - -# the library's version -VERSION:=4.1.1 - -# tools - -RANLIB=ranlib -SHELL = /bin/sh -MKDIR = mkdir -ETAGS = /bin/false - -abs_builddir = /connectivity/connectivity/src/bt_edr_adapter/libcoap-4.1.1 -top_builddir = . -package = libcoap-4.1.1 - -# files and flags -SOURCES:= pdu.c net.c debug.c encode.c uri.c coap_list.c resource.c hashkey.c \ - str.c option.c async.c subscribe.c block.c -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -HEADERS:=coap.h config.h debug.h pdu.h net.h encode.h uri.h coap_list.h mem.h \ - str.h option.h bits.h uthash.h utlist.h resource.h hashkey.h async.h \ - subscribe.h block.h address.h prng.h coap_time.h t_list.h -CFLAGS:=-Wall -Wextra -std=c99 -pedantic -g -O2 -CPPFLAGS:= -DWITH_POSIX -DISTDIR=$(top_builddir)/$(package) -SUBDIRS:=#examples #doc tests -FILES:=ChangeLog README LICENSE.BSD LICENSE.GPL Makefile.in configure configure.in config.h.in $(SOURCES) $(HEADERS) -LIB:=libcoap.a -LDSOFLAGS=-shared -LDFLAGS:= -ARFLAGS:=cru -examples:=examples -doc:=doc - - -ifdef BUILD_SO - MACHINE?=$(shell $(CC) -dumpmachine) - ifeq ($(findstring Darwin, $(MACHINE)), Darwin) - LDSOFLAGS=-dynamiclib - LIBSO=libcoap.dylib - endif - ifeq ($(findstring Windows, $(MACHINE)), Windows) - LIBSO=libcoap.dll - endif - # more platforms go here - ifndef LIBSO - LIBSO=libcoap.so - endif - ifndef PICFLAG - CFLAGS+=-fPIC - else - CFLAGS+=$(PICFLAG) - endif -endif - -.PHONY: all dirs clean distclean .gitignore doc TAGS - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(LIB) $(LIBSO) dirs - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - $(MAKE) -C examples check - -dirs: $(SUBDIRS) - for dir in $^; do \ - $(MAKE) -C $$dir ; \ - done - -$(LIB): $(OBJECTS) - $(AR) $(ARFLAGS) $@ $^ - $(RANLIB) $@ - -$(LIBSO): $(OBJECTS) - $(LD) $(LDSOFLAGS) $(LDFLAGS) -o $@ $^ - -clean: - @rm -f $(PROGRAM) main.o $(LIB) $(LIBSO) $(OBJECTS) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir clean ; \ - done - -doc: - $(MAKE) -C doc - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ $(DISTDIR).tar.gz - -dist: $(FILES) $(SUBDIRS) - test -d $(DISTDIR) || mkdir $(DISTDIR) - cp $(FILES) $(DISTDIR) - for dir in $(SUBDIRS); do \ - $(MAKE) -C $$dir dist; \ - done - tar czf $(package).tar.gz $(DISTDIR) - -TAGS: - $(ETAGS) -o $@.new $(SOURCES) - $(ETAGS) -a -o $@.new $(HEADERS) - mv $@.new $@ - -.gitignore: - echo "core\n*~\n*.[oa]\n*.gz\n*.cap\n$(PROGRAM)\n$(DISTDIR)\n.gitignore" >$@ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/SConscript b/resource/csdk/connectivity/lib/libcoap-4.1.1/SConscript new file mode 100644 index 0000000..167613c --- /dev/null +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/SConscript @@ -0,0 +1,71 @@ +## +# libcoap (share library) build script +## + +Import('env') + +libcoap_env = env.Clone() + +target_os = env.get('TARGET_OS') +# As in the source code(C) includes arduino Time library head file(C++) +# It requires compile the .c with g++ +if target_os == 'arduino': + libcoap_env.Replace(CFLAGS = env.get('CXXFLAGS')) + +###################################################################### +# Build flags +###################################################################### + libcoap_env.PrependUnique(CPPPATH = [ + './', + env.get('ARDUINO_HOME')+'/', + env.get('ARDUINO_HOME')+'/hardware/arduino/avr/cores/arduino', + env.get('ARDUINO_HOME')+'/hardware/tools/avr/avr/include/', + env.get('ARDUINO_HOME')+'/hardware/arduino/avr/variants/mega', + env.get('ARDUINO_HOME')+'/libraries/Time/Time', + env.get('ARDUINO_HOME')+'/libraries/TimedAction', + env.get('ARDUINO_HOME')+'/hardware/arduino/avr/libraries/SPI', + env.get('ARDUINO_HOME')+'/libraries/Ethernet/src/utility', + ]) + +if target_os not in ['arduino', 'windows', 'winrt']: + libcoap_env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '_BSD_SOURCE']) + libcoap_env.AppendUnique(CFLAGS = ['-std=gnu99','-fPIC']) + +if target_os not in ['windows', 'winrt']: + libcoap_env.AppendUnique(CFLAGS = ['-Wall', '-ffunction-sections', + '-fdata-sections', '-fno-exceptions']) + +if target_os == 'android': + libcoap_env.AppendUnique(LIBS = ['log']) + +if target_os == 'arduino': + libcoap_env.AppendUnique(CPPDEFINES = ['NDEBUG', 'WITH_ARDUINO']) + +if target_os in ['darwin', 'ios']: + libcoap_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE']) + +if env.get('LOGGING'): + libcoap_env.AppendUnique(CPPDEFINES = ['TB_LOG']) + +###################################################################### +# Source files and Target(s) +###################################################################### +libcoap_src = [ + 'pdu.c', + 'net.c', + 'debug.c', + 'encode.c', + 'uri.c', + 'coap_list.c', + 'resource.c', + 'hashkey.c', + 'str.c', + 'option.c', + 'async.c', + 'subscribe.c', + 'block.c' + ] + +libcoap = libcoap_env.StaticLibrary('libcoap', libcoap_src, OBJPREFIX='libcoap_') + +libcoap_env.InstallTarget([libcoap], 'libcoap') diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h index 24ebce7..bb44a99 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file address.h * @brief representation of network addresses */ @@ -36,6 +36,10 @@ #include #endif +#ifdef WITH_ARDUINO +#define DEV_ADDR_SIZE_MAX (16) +#endif + #ifdef WITH_LWIP #include @@ -117,29 +121,65 @@ _coap_is_mcast_impl(const coap_address_t *a) { if (!a) { - printf("[COAP] address - coap_address_t is false\n"); return 0; } switch (a->addr.sa.sa_family) { case AF_INET: - printf("[COAP] address - local address : %s\n", a->addr.sin.sin_addr.s_addr); return IN_MULTICAST(a->addr.sin.sin_addr.s_addr); case AF_INET6: return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr); default: /* fall through and signal error */ - printf("[COAP] address - sa_family is default value\n"); ; } return 0; } #endif /* WITH_POSIX */ -/** +#ifdef WITH_ARDUINO +typedef struct coap_address_t +{ + uint32_t size; /**< length of the address stored in addr field. */ + uint8_t addr[DEV_ADDR_SIZE_MAX]; /**< device address. */ +} coap_address_t; + +static inline int +_coap_address_equals_impl(const coap_address_t *a, + const coap_address_t *b) +{ + uint32_t i; + + if ((a == NULL) || (b == NULL)) + return 0; + + if (a->size != b->size) + return 0; + + for (i = 0; i < a->size; i++) + { + if (a->addr[i] != b->addr[i]) + return 0; + } + return 1; +} + +static inline int +_coap_is_mcast_impl(const coap_address_t *a) +{ + if (!a) + return 0; + + /* TODO */ + return 0; +} + +#endif /* WITH_ARDUINO */ + +/** * Resets the given coap_address_t object @p addr to its default * values. In particular, the member size must be initialized to the * available size for storing addresses. - * + * * @param addr The coap_address_t object to initialize. */ static inline void coap_address_init(coap_address_t *addr) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h index 9f6c7b0..879cb38 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file async.h * @brief state management for asynchronous messages */ @@ -32,7 +32,7 @@ typedef struct coap_async_state_t { unsigned char flags; /**< holds the flags to control behaviour */ - /** + /** * Holds the internal time when the object was registered with a * resource. This field will be updated whenever * coap_register_async() is called for a specific resource. @@ -63,7 +63,7 @@ typedef struct coap_async_state_t /** release application data on destruction */ #define COAP_ASYNC_RELEASE_DATA 0x08 -/** +/** * Allocates a new coap_async_state_t object and fills its fields * according to the given @p request. The @p flags are used to control * generation of empty ACK responses to stop retransmissions and to @@ -72,7 +72,7 @@ typedef struct coap_async_state_t * coap_async_t object or @c NULL on error. Note that this function will * return @c NULL in case that an object with the same identifier is * already registered. - * + * * @param context The context to use. * @param peer The remote peer that is to be asynchronously notified. * @param request The request that is handled asynchronously. @@ -80,7 +80,7 @@ typedef struct coap_async_state_t * @param data Opaque application data to register. Note that the * storage occupied by @p data is released on destruction * only if flag COAP_ASYNC_RELEASE_DATA is set. - * + * * @return A pointer to the registered coap_async_state_t object or * @c NULL in case of an error. */ @@ -88,52 +88,52 @@ coap_async_state_t * coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request, unsigned char flags, void *data); -/** +/** * Removes the state object identified by @p id from @p context. The * removed object is returned in @p s, if found. Otherwise, @p s is * undefined. This function returns @c 1 if the object was removed, @c * 0 otherwise. Note that the storage allocated for the stored object * is not released by this functions. You will have to call * coap_free_async() to do so. - * + * * @param context The context where the async object is registered. * @param id The identifier of the asynchronous transaction. - * @param s Will be set to the object identified by @p id + * @param s Will be set to the object identified by @p id * after removal. - * + * * @return @c 1 if object was removed and @p s updated, or @c 0 if no * object was found with the given id. @p s is valid only if the * return value is @c 1. */ int coap_remove_async(coap_context_t *context, coap_tid_t id, coap_async_state_t **s); -/** +/** * Releases the memory that was allocated by coap_async_state_init() * for the object @p s. The registered application data will be * released automatically if COAP_ASYNC_RELEASE_DATA is set. - * + * * @param s The object to delete. */ void coap_free_async(coap_async_state_t *state); -/** +/** * Retrieves the object identified by @p id from the list of asynchronous * transactions that are registered with @p context. This function returns * a pointer to that object or @c NULL if not found. - * - * @param context The context where the asynchronous objects are + * + * @param context The context where the asynchronous objects are * registered with. * @param id The id of the object to retrieve. - * + * * @return A pointer to the object identified by @p id or @c NULL if * not found. */ coap_async_state_t *coap_find_async(coap_context_t *context, coap_tid_t id); -/** +/** * Updates the time stamp of @p s. - * + * * @param s The state object to update. */ static inline void coap_touch_async(coap_async_state_t *s) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h index 487af39..20281a0 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h @@ -4,7 +4,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** @@ -15,18 +15,20 @@ #ifndef _BITS_H_ #define _BITS_H_ +#ifdef HAVE_SYS_TYPES_H #include +#endif #include -/** +/** * Sets the bit @p bit in bit-vector @p vec. This function returns @c * 1 if bit was set or @c -1 on error (i.e. when the given bit does * not fit in the vector). - * + * * @param vec The bit-vector to change. * @param size The size of @p vec in bytes. * @param bit The bit to set in @p vec. - * + * * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. */ inline static int bits_setb(uint8_t *vec, size_t size, uint8_t bit) @@ -38,15 +40,15 @@ inline static int bits_setb(uint8_t *vec, size_t size, uint8_t bit) return 1; } -/** +/** * Clears the bit @p bit from bit-vector @p vec. This function returns * @c 1 if bit was cleared or @c -1 on error (i.e. when the given bit * does not fit in the vector). - * + * * @param vec The bit-vector to change. * @param size The size of @p vec in bytes. * @param bit The bit to clear from @p vec. - * + * * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. */ inline static int bits_clrb(uint8_t *vec, size_t size, uint8_t bit) @@ -58,14 +60,14 @@ inline static int bits_clrb(uint8_t *vec, size_t size, uint8_t bit) return 1; } -/** +/** * Gets the status of bit @p bit from bit-vector @p vec. This function returns * @c 1 if the bit is set, @c 0 otherwise (even in case of an error).. - * + * * @param vec The bit-vector to read from.. * @param size The size of @p vec in bytes. * @param bit The bit to get from @p vec. - * + * * @return @c 1 if the bit is set, @c 0 otherwise. */ inline static int bits_getb(const uint8_t *vec, size_t size, uint8_t bit) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c index 3ad47e3..c0373f7 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -12,6 +12,11 @@ # include #endif +#ifdef WITH_ARDUINO +/* On Arduino the abort function, needed for assert, is defined in std lib */ +#include +#endif + #include "debug.h" #include "block.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h index 6451383..2d5ef07 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012,2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_BLOCK_H_ @@ -32,17 +32,21 @@ #endif /** - * Structure of Block options. + * Structure of Block options. */ typedef struct { - unsigned int num :20; /**< block number */ - unsigned int m :1; /**< 1 if more blocks follow, 0 otherwise */ - unsigned int szx :3; /**< block size */ +#ifdef WITH_ARDUINO + unsigned long int num : 20; +#else + unsigned int num : 20; +#endif + unsigned int m : 1; /**< 1 if more blocks follow, 0 otherwise */ + unsigned int szx : 3; /**< block size */ } coap_block_t; /** - * Returns the value of the least significant byte of a Block option @p opt. + * Returns the value of the least significant byte of a Block option @p opt. * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST * returns @c NULL. */ @@ -88,7 +92,7 @@ static inline void coap_opt_block_set_m(coap_opt_t *block_opt, int m) * value @c 1. Otherwise, @c 0 is returned. * * @param pdu The pdu to search for option @p type. - * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or * COAP_OPTION_BLOCK2) * @param block The block structure to initilize. * @return @c 1 on success, @c 0 otherwise. @@ -102,9 +106,9 @@ int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); * space is required. The actual length of the resource is specified * in @p data_length. * - * This function may change *block to reflect the values written to + * This function may change *block to reflect the values written to * @p pdu. As the function takes into consideration the remaining space - * @p pdu, no more options should be added after coap_write_block_opt() + * @p pdu, no more options should be added after coap_write_block_opt() * has returned. * * @param block The block structure to use. On return, this object @@ -120,7 +124,7 @@ int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); int coap_write_block_opt(coap_block_t *block, unsigned short type, coap_pdu_t *pdu, size_t data_length); -/** +/** * Adds the @p block_num block of size 1 << (@p block_szx + 4) from * source @p data to @p pdu. * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h index d4bf9c5..0d7623b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h @@ -34,3 +34,4 @@ extern "C" #endif #endif /* _COAP_H_ */ + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c index ba31c54..73f1595 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -75,7 +75,7 @@ void coap_delete_list(coap_list_t *queue) coap_list_t * coap_new_listnode(void *data, void (*delete_func)(void *)) { - coap_list_t *node = coap_malloc( sizeof(coap_list_t) ); + coap_list_t *node = (coap_list_t *) coap_malloc( sizeof(coap_list_t) ); if (!node) { #ifndef NDEBUG diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h index 0c1334b..22d8fba 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_LIST_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h index 041d9a8..76dcd9d 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h @@ -3,10 +3,10 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file coap_time.h * @brief Clock Handling */ @@ -106,20 +106,52 @@ extern "C" extern time_t clock_offset; #endif /* WITH_POSIX */ +#ifdef WITH_ARDUINO +#include "Time.h" +#ifdef ARDUINO_ARCH_SAM +#include // time_t is defined in sys/types.h for ARM compiler +#else +typedef unsigned long time_t; //AVR compiler doesnt define time_t +#endif +typedef time_t coap_tick_t; + +/** + * This data type is used to represent the difference between two + * clock_tick_t values. This data type must have the same size in + * memory as coap_tick_t to allow wrapping. + */ +typedef int coap_tick_diff_t; + +/* TODO: Ticks per second value for Arduino needs verification from + * documentation */ +#define COAP_TICKS_PER_SECOND 1000 + +extern time_t clock_offset; + +#endif /* WITH_ARDUINO */ + #ifndef coap_clock_init static inline void coap_clock_init_impl(void) { #ifdef HAVE_TIME_H clock_offset = time(NULL); #else -# ifdef __GNUC__ - /* Issue a warning when using gcc. Other prepropressors do - * not seem to have a similar feature. */ -# warning "cannot initialize clock" -# endif - clock_offset = 0; +# ifdef WITH_ARDUINO +#ifdef __AVR__ + clock_offset = 1; //now(); +#else + clock_offset = now(); #endif - } +# else +# ifdef __GNUC__ + /* Issue a warning when using gcc. Other prepropressors do + * not seem to have a similar feature. */ +# warning "cannot initialize clock" +# endif + clock_offset = 0; +# endif /* WITH_ARDUINO */ +#endif /* HAVE_TIME */ +} #define coap_clock_init coap_clock_init_impl #endif /* coap_clock_init */ @@ -132,9 +164,19 @@ extern "C" *t = (tv.tv_sec - clock_offset) * COAP_TICKS_PER_SECOND + (tv.tv_usec * COAP_TICKS_PER_SECOND / 1000000); #else -#error "clock not implemented" +# ifdef WITH_ARDUINO + coap_tick_t tv; +#ifdef __AVR__ + tv = 1; //now(); +#else + tv = now(); #endif - } + *t = (tv - clock_offset) * COAP_TICKS_PER_SECOND; +# else +# error "clock not implemented" +# endif /* WITH_ARDUINO */ +#endif /* HAVE_SYS_TIME_H */ +} #define coap_ticks coap_ticks_impl #endif /* coap_ticks */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/config.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/config.h index 654c4ea..6d2beb6 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/config.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/config.h @@ -5,7 +5,9 @@ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_ARPA_INET_H 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 @@ -36,7 +38,9 @@ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_NETINET_IN_H 1 +#endif /* Define to 1 if you have the `select' function. */ #define HAVE_SELECT 1 @@ -66,28 +70,42 @@ #define HAVE_STRRCHR 1 /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_SYSLOG_H 1 +#endif /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_SYS_SOCKET_H 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_SYS_TIME_H 1 +#endif /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_SYS_TYPES_H 1 +#endif /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_SYS_UNISTD_H 1 +#endif /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_TIME_H 1 +#endif /* Define to 1 if you have the header file. */ +#ifndef WITH_ARDUINO #define HAVE_UNISTD_H 1 +#endif /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/config.status b/resource/csdk/connectivity/lib/libcoap-4.1.1/config.status deleted file mode 100644 index 4984732..0000000 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/config.status +++ /dev/null @@ -1,1020 +0,0 @@ -#! /bin/bash -# Generated by configure. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=${CONFIG_SHELL-/bin/bash} -export SHELL -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by libcoap $as_me 4.1.1, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -# Files that config.status was made for. -config_files=" Makefile doc/Makefile doc/Doxyfile examples/Makefile tests/Makefile" -config_headers=" config.h" - -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to the package provider." - -ac_cs_config="" -ac_cs_version="\ -libcoap config.status 4.1.1 -configured by ./configure, generated by GNU Autoconf 2.69, - with options \"$ac_cs_config\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='/connectivity/connectivity/src/bt_edr_adapter/libcoap-4.1.1' -srcdir='.' -test -n "$AWK" || AWK=awk -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -if $ac_cs_recheck; then - set X /bin/bash './configure' $ac_configure_extra_args --no-create --no-recursion - shift - $as_echo "running CONFIG_SHELL=/bin/bash $*" >&6 - CONFIG_SHELL='/bin/bash' - export CONFIG_SHELL - exec "$@" -fi - -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; - "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && -S["LTLIBOBJS"]="" -S["BUILD_SO"]="" -S["TESTS"]="" -S["LIBOBJS"]="" -S["EGREP"]="/bin/grep -E" -S["GREP"]="/bin/grep" -S["CPP"]="gcc -E" -S["ETAGS"]="/bin/false" -S["DOXYGEN"]=":" -S["RANLIB"]="ranlib" -S["OBJEXT"]="o" -S["EXEEXT"]="" -S["ac_ct_CC"]="gcc" -S["CPPFLAGS"]=" -DWITH_POSIX" -S["LDFLAGS"]="" -S["CFLAGS"]="-g -O2" -S["CC"]="gcc" -S["SET_MAKE"]="" -S["target_alias"]="" -S["host_alias"]="" -S["build_alias"]="" -S["LIBS"]="" -S["ECHO_T"]="" -S["ECHO_N"]="-n" -S["ECHO_C"]="" -S["DEFS"]="-DHAVE_CONFIG_H" -S["mandir"]="${datarootdir}/man" -S["localedir"]="${datarootdir}/locale" -S["libdir"]="${exec_prefix}/lib" -S["psdir"]="${docdir}" -S["pdfdir"]="${docdir}" -S["dvidir"]="${docdir}" -S["htmldir"]="${docdir}" -S["infodir"]="${datarootdir}/info" -S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}" -S["oldincludedir"]="/usr/include" -S["includedir"]="${prefix}/include" -S["localstatedir"]="${prefix}/var" -S["sharedstatedir"]="${prefix}/com" -S["sysconfdir"]="${prefix}/etc" -S["datadir"]="${datarootdir}" -S["datarootdir"]="${prefix}/share" -S["libexecdir"]="${exec_prefix}/libexec" -S["sbindir"]="${exec_prefix}/sbin" -S["bindir"]="${exec_prefix}/bin" -S["program_transform_name"]="s,x,x," -S["prefix"]="/usr/local" -S["exec_prefix"]="${prefix}" -S["PACKAGE_URL"]="" -S["PACKAGE_BUGREPORT"]="" -S["PACKAGE_STRING"]="libcoap 4.1.1" -S["PACKAGE_VERSION"]="4.1.1" -S["PACKAGE_TARNAME"]="libcoap" -S["PACKAGE_NAME"]="libcoap" -S["PATH_SEPARATOR"]=":" -S["SHELL"]="/bin/bash" -_ACAWK -cat >>"$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -D["PACKAGE_NAME"]=" \"libcoap\"" -D["PACKAGE_TARNAME"]=" \"libcoap\"" -D["PACKAGE_VERSION"]=" \"4.1.1\"" -D["PACKAGE_STRING"]=" \"libcoap 4.1.1\"" -D["PACKAGE_BUGREPORT"]=" \"\"" -D["PACKAGE_URL"]=" \"\"" -D["STDC_HEADERS"]=" 1" -D["HAVE_SYS_TYPES_H"]=" 1" -D["HAVE_SYS_STAT_H"]=" 1" -D["HAVE_STDLIB_H"]=" 1" -D["HAVE_STRING_H"]=" 1" -D["HAVE_MEMORY_H"]=" 1" -D["HAVE_STRINGS_H"]=" 1" -D["HAVE_INTTYPES_H"]=" 1" -D["HAVE_STDINT_H"]=" 1" -D["HAVE_UNISTD_H"]=" 1" -D["HAVE_ASSERT_H"]=" 1" -D["HAVE_ARPA_INET_H"]=" 1" -D["HAVE_LIMITS_H"]=" 1" -D["HAVE_NETDB_H"]=" 1" -D["HAVE_NETINET_IN_H"]=" 1" -D["HAVE_STDLIB_H"]=" 1" -D["HAVE_STRING_H"]=" 1" -D["HAVE_STRINGS_H"]=" 1" -D["HAVE_SYS_SOCKET_H"]=" 1" -D["HAVE_SYS_TIME_H"]=" 1" -D["HAVE_TIME_H"]=" 1" -D["HAVE_UNISTD_H"]=" 1" -D["HAVE_SYS_UNISTD_H"]=" 1" -D["HAVE_SYSLOG_H"]=" 1" -D["HAVE_STDLIB_H"]=" 1" -D["HAVE_MALLOC"]=" 1" -D["HAVE_MEMSET"]=" 1" -D["HAVE_SELECT"]=" 1" -D["HAVE_SOCKET"]=" 1" -D["HAVE_STRCASECMP"]=" 1" -D["HAVE_STRRCHR"]=" 1" -D["HAVE_GETADDRINFO"]=" 1" -D["HAVE_STRNLEN"]=" 1" - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { - line = $ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} - ac_datarootdir_hack=' - s&@datadir@&${datarootdir}&g - s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g - s&@infodir@&${datarootdir}/info&g - s&@localedir@&${datarootdir}/locale&g - s&@mandir@&${datarootdir}/man&g - s&\${datarootdir}&${prefix}/share&g' ;; -esac -ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -} - -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - - - esac - -done # for ac_tag - - -as_fn_exit 0 diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure deleted file mode 100644 index b6f5dad..0000000 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure +++ /dev/null @@ -1,5411 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libcoap 4.1.1. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='libcoap' -PACKAGE_TARNAME='libcoap' -PACKAGE_VERSION='4.1.1' -PACKAGE_STRING='libcoap 4.1.1' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -ac_unique_file="coap.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='LTLIBOBJS -BUILD_SO -TESTS -LIBOBJS -EGREP -GREP -CPP -ETAGS -DOXYGEN -RANLIB -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -SET_MAKE -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -with_contiki -with_debug -with_async -with_block -with_observe -with_query_filter -with_tests -with_shared -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures libcoap 4.1.1 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/libcoap] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of libcoap 4.1.1:";; - esac - cat <<\_ACEOF - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-contiki build libcoap for the Contiki OS - --without-debug disable all debug output and assertions - --without-async disable handling of asynchronous transactions and - observe - --without-block disable block transfer - --without-observe disable resource observation - --without-query-filter disable support for filters on /.well-known/core - --with-tests enable unit tests (requires cunit) - --with-shared build shared library - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -libcoap configure 4.1.1 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by libcoap $as_me 4.1.1, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -# First check for Contiki build to quit configure before any other test - -# Check whether --with-contiki was given. -if test "${with_contiki+set}" = set; then : - withval=$with_contiki; cp -p Makefile.contiki Makefile - cp -p config.h.contiki config.h - { $as_echo "$as_me:${as_lineno-$LINENO}: Contiki build prepared" >&5 -$as_echo "$as_me: Contiki build prepared" >&6;} - exit 0 -fi - - -# Checks for programs. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -# Extract the first word of "doxygen", so it can be a program name with args. -set dummy doxygen; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DOXYGEN+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $DOXYGEN in - [\\/]* | ?:[\\/]*) - ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_DOXYGEN" && ac_cv_path_DOXYGEN=":" - ;; -esac -fi -DOXYGEN=$ac_cv_path_DOXYGEN -if test -n "$DOXYGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 -$as_echo "$DOXYGEN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -# Extract the first word of "etags", so it can be a program name with args. -set dummy etags; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ETAGS+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ETAGS in - [\\/]* | ?:[\\/]*) - ac_cv_path_ETAGS="$ETAGS" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ETAGS="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_ETAGS" && ac_cv_path_ETAGS="/bin/false" - ;; -esac -fi -ETAGS=$ac_cv_path_ETAGS -if test -n "$ETAGS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ETAGS" >&5 -$as_echo "$ETAGS" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - - -# Checks for libraries. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for coap_new_pdu in -lcoap" >&5 -$as_echo_n "checking for coap_new_pdu in -lcoap... " >&6; } -if ${ac_cv_lib_coap_coap_new_pdu+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcoap $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char coap_new_pdu (); -int -main () -{ -return coap_new_pdu (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_coap_coap_new_pdu=yes -else - ac_cv_lib_coap_coap_new_pdu=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_coap_coap_new_pdu" >&5 -$as_echo "$ac_cv_lib_coap_coap_new_pdu" >&6; } -if test "x$ac_cv_lib_coap_coap_new_pdu" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBCOAP 1 -_ACEOF - - LIBS="-lcoap $LIBS" - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 -$as_echo_n "checking for library containing gethostbyname... " >&6; } -if ${ac_cv_search_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -for ac_lib in '' nsl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_gethostbyname=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_gethostbyname+:} false; then : - break -fi -done -if ${ac_cv_search_gethostbyname+:} false; then : - -else - ac_cv_search_gethostbyname=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 -$as_echo "$ac_cv_search_gethostbyname" >&6; } -ac_res=$ac_cv_search_gethostbyname -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 -$as_echo_n "checking for library containing socket... " >&6; } -if ${ac_cv_search_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char socket (); -int -main () -{ -return socket (); - ; - return 0; -} -_ACEOF -for ac_lib in '' socket; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_socket=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_socket+:} false; then : - break -fi -done -if ${ac_cv_search_socket+:} false; then : - -else - ac_cv_search_socket=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 -$as_echo "$ac_cv_search_socket" >&6; } -ac_res=$ac_cv_search_socket -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -# configuration options that may change compile flags - -# Check whether --with-debug was given. -if test "${with_debug+set}" = set; then : - withval=$with_debug; CPPFLAGS="${CPPFLAGS} -DNDEBUG" -fi - - - -# Check whether --with-async was given. -if test "${with_async+set}" = set; then : - withval=$with_async; CPPFLAGS="${CPPFLAGS} -DWITHOUT_ASYNC" -fi - - - -# Check whether --with-block was given. -if test "${with_block+set}" = set; then : - withval=$with_block; CPPFLAGS="${CPPFLAGS} -DWITHOUT_BLOCK" -fi - - - -# Check whether --with-observe was given. -if test "${with_observe+set}" = set; then : - withval=$with_observe; CPPFLAGS="${CPPFLAGS} -DWITHOUT_OBSERVE" -fi - - - -# Check whether --with-query-filter was given. -if test "${with_query_filter+set}" = set; then : - withval=$with_query_filter; CPPFLAGS="${CPPFLAGS} -DWITHOUT_QUERY_FILTER" -fi - - - -# Check whether --with-tests was given. -if test "${with_tests+set}" = set; then : - withval=$with_tests; TESTS="tests" -fi - - - -# Check whether --with-shared was given. -if test "${with_shared+set}" = set; then : - withval=$with_shared; BUILD_SO="BUILD_SO=1" -fi - - -# disambiguate between autoconf generated setups and contiki / lwip setups -# which use explicit config.h.* files -CPPFLAGS="${CPPFLAGS} -DWITH_POSIX" - -# Checks for header files. -for ac_header in assert.h arpa/inet.h limits.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/socket.h sys/time.h time.h unistd.h sys/unistd.h syslog.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -# Checks for typedefs, structures, and compiler characteristics. -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" -if test "x$ac_cv_type_ssize_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define ssize_t int -_ACEOF - -fi - - -# Checks for library functions. -for ac_header in stdlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 -$as_echo_n "checking for GNU libc compatible malloc... " >&6; } -if ${ac_cv_func_malloc_0_nonnull+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_malloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *malloc (); -#endif - -int -main () -{ -return ! malloc (0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_malloc_0_nonnull=yes -else - ac_cv_func_malloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } -if test $ac_cv_func_malloc_0_nonnull = yes; then : - -$as_echo "#define HAVE_MALLOC 1" >>confdefs.h - -else - $as_echo "#define HAVE_MALLOC 0" >>confdefs.h - - case " $LIBOBJS " in - *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" - ;; -esac - - -$as_echo "#define malloc rpl_malloc" >>confdefs.h - -fi - - -for ac_func in memset select socket strcasecmp strrchr getaddrinfo strnlen -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - - - - -ac_config_headers="$ac_config_headers config.h" - - -ac_config_files="$ac_config_files Makefile doc/Makefile doc/Doxyfile examples/Makefile tests/Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by libcoap $as_me 4.1.1, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -libcoap config.status 4.1.1 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "doc/Doxyfile") CONFIG_FILES="$CONFIG_FILES doc/Doxyfile" ;; - "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; - "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - - - esac - -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in index 77f6c8f..86881ab 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in @@ -96,3 +96,4 @@ AC_CONFIG_FILES([Makefile examples/Makefile tests/Makefile]) AC_OUTPUT + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c index eedf247..df9ae7b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -81,12 +81,12 @@ print_timestamp(char *s, size_t len, coap_tick_t t) #ifndef NDEBUG #ifndef HAVE_STRNLEN -/** - * A length-safe strlen() fake. - * +/** + * A length-safe strlen() fake. + * * @param s The string to count characters != 0. * @param maxlen The maximum length of @p s. - * + * * @return The length of @p s. */ static inline size_t @@ -148,7 +148,11 @@ size_t coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, si { #ifdef HAVE_ARPA_INET_H const void *addrptr = NULL; +#if defined(__ANDROID__) + __uint16_t port; +#else in_port_t port; +#endif unsigned char *p = buf; switch (addr->addr.sa.sa_family) @@ -341,6 +345,14 @@ coap_show_pdu(const coap_pdu_t *pdu) #endif /* NDEBUG */ +#ifdef WITH_ARDUINO +void coap_log_impl(coap_log_t level, const char *format, ...) +{ + //TODO: Implement logging functionalities for Arduino +} +#endif + +#ifndef WITH_ARDUINO #ifndef WITH_CONTIKI void coap_log_impl(coap_log_t level, const char *format, ...) { @@ -389,3 +401,4 @@ coap_log_impl(coap_log_t level, const char *format, ...) va_end(ap); } #endif /* WITH_CONTIKI */ +#endif diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h index 708ffc2..4c55054 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_DEBUG_H_ @@ -36,7 +36,7 @@ coap_log_t coap_get_log_level(); /** Sets the log level to the specified value. */ void coap_set_log_level(coap_log_t level); -/** +/** * Writes the given text to @c COAP_ERR_FD (for @p level <= @c * LOG_CRIT) or @c COAP_DEBUG_FD (for @p level >= @c LOG_WARNING). The * text is output only when @p level is below or equal to the log @@ -59,6 +59,8 @@ void coap_log_impl(coap_log_t level, const char *format, ...); void coap_show_pdu(const coap_pdu_t *); struct coap_address_t; +unsigned int print_readable(const unsigned char *data, unsigned int len, unsigned char *result, + unsigned int buflen, int encode_always); size_t coap_print_addr(const struct coap_address_t *, unsigned char *, size_t); #else diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c index 9e70ea8..86a5b89 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef NDEBUG diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h index e58cad6..b9b304e 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_ENCODE_H_ @@ -12,8 +12,10 @@ #if (BSD >= 199103) || defined(WITH_CONTIKI) # include #else +#ifndef WITH_ARDUINO # include #endif +#endif #define Nn 8 /* duplicate definition of N if built on sky motes */ #define E 4 diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile deleted file mode 100644 index 9f93ca3..0000000 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# Makefile for libcoap -# -# Copyright (C) 2010,2011 Olaf Bergmann -# -# This file is part of the CoAP library libcoap. Please see -# README for terms of use. - -# the library's version -VERSION:=4.1.1 - -# tools - -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = /connectivity/connectivity/src/bt_edr_adapter/libcoap-4.1.1/examples -top_builddir = .. -top_srcdir = .. -# files and flags -PROGRAMS:=coap-server coap-client rd etsi_iot_01 #tiny -SOURCES:= tiny.c client.c server.c rd.c etsi_iot_01.c -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -#CFLAGS:=-g -Wall -ansi -pedantic -I.. -CFLAGS:=-g -Wall -g -O2 -CPPFLAGS:=-I$(top_srcdir) -DWITH_POSIX -DISTDIR?=$(top_builddir)/libcoap-4.1.1 -FILES:=Makefile.in $(SOURCES) -LDFLAGS:=-L$(top_builddir) -LDLIBS:=-lcoap -libcoap =$(top_builddir)/libcoap.a - -.PHONY: clean distclean - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(PROGRAMS) - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -tiny: tiny.o $(libcoap) - $(CC) -o $@ $< $(LDFLAGS) - -coap-client: client.o $(libcoap) - $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS) - -coap-server: server.o $(libcoap) - $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS) - -clean: - @rm -f $(PROGRAMS) $(OBJECTS) - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ - -dist: $(FILES) - test -d $(DISTDIR)/examples || mkdir $(DISTDIR)/examples - cp $(FILES) $(DISTDIR)/examples diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in index 80445ad..a2dfb14 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in @@ -59,3 +59,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/examples || mkdir $(DISTDIR)/examples cp $(FILES) $(DISTDIR)/examples + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c index 72a0908..89d27ff 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -284,10 +284,10 @@ get_block(coap_pdu_t *pdu, coap_opt_iterator_t *opt_iter) return coap_option_next(opt_iter); } -#define HANDLE_BLOCK1(Pdu) \ - ((method == COAP_REQUEST_PUT || method == COAP_REQUEST_POST) && \ - ((flags & FLAGS_BLOCK) == 0) && \ - ((Pdu)->hdr->code == COAP_RESPONSE_CODE(201) || \ +#define HANDLE_BLOCK1(Pdu) \ + ((method == COAP_REQUEST_PUT || method == COAP_REQUEST_POST) && \ + ((flags & FLAGS_BLOCK) == 0) && \ + ((Pdu)->hdr->code == COAP_RESPONSE_CODE(201) || \ (Pdu)->hdr->code == COAP_RESPONSE_CODE(204))) inline int check_token(coap_pdu_t *received) @@ -761,7 +761,7 @@ int cmdline_blocksize(char *arg) return 1; } -/* Called after processing the options from the commandline to set +/* Called after processing the options from the commandline to set * Block1 or Block2 depending on method. */ void set_blocksize() { diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c index 83f582e..ba68c0e 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c @@ -37,7 +37,7 @@ static int quit = 0; #define COAP_OPT_BLOCK_SZX_MAX 6 /**< allowed maximum for block szx value */ -#define REQUIRE_ETAG 0x01 /* flag for coap_payload_t: require ETag option */ +#define REQUIRE_ETAG 0x01 /* flag for coap_payload_t: require ETag option */ typedef struct { UT_hash_handle hh; @@ -76,7 +76,7 @@ void handle_sigint(int signum) } #define INDEX "libcoap server for ETSI CoAP Plugtest, March 2012, Paris\n" \ - "Copyright (C) 2012 Olaf Bergmann \n\n" + "Copyright (C) 2012 Olaf Bergmann \n\n" coap_payload_t * coap_new_payload(size_t size) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c index 0cc97d2..11e01ca 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c index 0d3e055..09b2fdc 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -54,7 +54,7 @@ void handle_sigint(int signum) } #define INDEX "This is a test server made with libcoap (see http://libcoap.sf.net)\n" \ - "Copyright (C) 2010--2013 Olaf Bergmann \n\n" + "Copyright (C) 2010--2013 Olaf Bergmann \n\n" void hnd_get_index(coap_context_t *ctx, struct coap_resource_t *resource, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c index 9ccee12..7b7d437 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c index a794292..30447e6 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "hashkey.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h index 4732a70..5ed5e03 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file hashkey.h * @brief definition of hash key type and helper functions */ @@ -19,12 +19,12 @@ typedef unsigned char coap_key_t[4]; #ifndef coap_hash -/** +/** * Calculates a fast hash over the given string @p s of length @p len * and stores the result into @p h. Depending on the exact * implementation, this function cannot be used as one-way function to * check message integrity or simlar. - * + * * @param s The string used for hash calculation. * @param len The length of @p s. * @param h The result buffer to store the calculated hash key. @@ -40,18 +40,18 @@ void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); #undef __COAP_DEFAULT_HASH #endif /* coap_hash */ -/** +/** * Calls coap_hash() with given @c str object as parameter. - * + * * @param Str Must contain a pointer to a coap string object. * @param H A coap_key_t object to store the result. - * + * * @hideinitializer */ -#define coap_str_hash(Str,H) { \ - assert(Str); \ - memset((H), 0, sizeof(coap_key_t)); \ - coap_hash((H), (Str)->s, (Str)->length); \ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((H), (Str)->s, (Str)->length); \ } #endif /* _COAP_HASHKEY_H_ */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/makefile_arduino.mak b/resource/csdk/connectivity/lib/libcoap-4.1.1/makefile_arduino.mak new file mode 100644 index 0000000..e12a01e --- /dev/null +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/makefile_arduino.mak @@ -0,0 +1,72 @@ +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# default to release build +# default to build for linux +BUILD := release +#other options are android, arduino +PLATFORM=linux +# override with `make PLATFORM=arduinomega ARDUINOWIFI=1` to enable Arduino WiFi shield +ARDUINOWIFI := 0 + +OUT_DIR := ./$(BUILD) +OBJ_DIR := $(OUT_DIR)/obj + +ROOT_DIR = .. + +# Note for Arduino: The CC flag is set to the C++ compiler since Arduino build +# includes Time.h header file which has C++ style definitions. +ifeq ($(PLATFORM),arduinomega) + include $(ROOT_DIR)/arduino/local.properties + include $(ROOT_DIR)/arduino/$(PLATFORM).properties + CC=$(ARDUINO_TOOLS_DIR)/avr-gcc +else ifeq ($(PLATFORM),arduinodue) + include $(ROOT_DIR)/local.properties + include $(ROOT_DIR)/$(PLATFORM).properties + CC=$(ARDUINO_TOOLS_DIR)/arm-none-eabi-g++ +else + $(error Wrong value for PLATFORM !!) +endif + +CC_FLAGS.debug := -O0 -g3 -Wall -ffunction-sections -fdata-sections -fno-exceptions -pedantic \ +-DTB_LOG +CC_FLAGS.release := -Os -Wall -ffunction-sections -fdata-sections -fno-exceptions + +SOURCES:= pdu.c net.c debug.c encode.c uri.c coap_list.c resource.c hashkey.c \ + str.c option.c async.c subscribe.c block.c +#VPATH := $(OCSOCK_DIR)/src:$(LOGGER_DIR)/src:$(RANDOM_DIR)/src +ifeq (arduino, $(findstring arduino,$(PLATFORM))) + SOURCESCPP:= Time.cpp + OBJECTSCPP:= $(patsubst %.cpp, %.o, $(SOURCESCPP)) + VPATH += $(SDIR_ARD_TIME) +endif + +OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) + +all: prep_dirs libcoap.a + +prep_dirs: + -mkdir $(OUT_DIR) + -mkdir $(OBJ_DIR) + +%.o: %.c + $(CC) -c $(CC_FLAGS.$(BUILD)) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@ + +%.o: %.cpp + $(CCPLUS) -c $(CC_FLAGS.$(BUILD)) $(CFLAGS_PLATFORM) $(INC_DIR_PLATFORM) $< -o $(OBJ_DIR)/$@ + +libcoap.a: $(OBJECTS) $(OBJECTSCPP) + $(AR) rcs $(OUT_DIR)/$@ $(addprefix $(OBJ_DIR)/,$^) + $(RANLIB) $(OUT_DIR)/$@ + +.PHONY: clean + +clean: legacy_clean + -rm -rf release + -rm -rf debug + +#There is no installation in LibCoap. +install: all + +legacy_clean: + rm -f *.o libcoap.a + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h index a84405e..475df6a 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h @@ -4,7 +4,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_MEM_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c index 7138f4a..02bc6ec 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -18,7 +18,9 @@ #elif HAVE_SYS_UNISTD_H #include #endif +#ifdef HAVE_SYS_TYPES_H #include +#endif #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -45,9 +47,9 @@ #include "block.h" #include "net.h" -#if defined(WITH_POSIX) +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) -time_t clock_offset; +time_t clock_offset=0; static inline coap_queue_t * coap_malloc_node() @@ -60,7 +62,7 @@ coap_free_node(coap_queue_t *node) { coap_free(node); } -#endif /* WITH_POSIX */ +#endif /* WITH_POSIX || WITH_ARDUINO */ #ifdef WITH_LWIP #include @@ -135,8 +137,7 @@ static void received_package(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip context->pending_address.addr = addr->addr; /* FIXME: this has to become address-type independent, probably there'll be an lwip function for that */ context->pending_port = port; - char* data; - coap_read(context, data); + coap_read(context); } #endif /* WITH_LWIP */ @@ -296,7 +297,7 @@ coap_pop_next(coap_context_t *context) #ifdef COAP_DEFAULT_WKC_HASHKEY /** Checks if @p Key is equal to the pre-defined hash key for.well-known/core. */ -#define is_wkc(Key) \ +#define is_wkc(Key) \ (memcmp((Key), COAP_DEFAULT_WKC_HASHKEY, sizeof(coap_key_t)) == 0) #else /* Implements a singleton to store a hash key for the .wellknown/core @@ -315,10 +316,12 @@ is_wkc(coap_key_t k) } #endif + +#ifndef WITH_ARDUINO coap_context_t * coap_new_context(const coap_address_t *listen_addr) { -#ifdef WITH_POSIX +#if defined(WITH_POSIX) coap_context_t *c = coap_malloc( sizeof( coap_context_t ) ); int reuse = 1; #endif /* WITH_POSIX */ @@ -380,7 +383,7 @@ coap_new_context(const coap_address_t *listen_addr) coap_register_option(c, COAP_OPTION_BLOCK2); coap_register_option(c, COAP_OPTION_BLOCK1); -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) c->sockfd = socket(listen_addr->addr.sa.sa_family, SOCK_DGRAM, 0); if ( c->sockfd < 0 ) { @@ -413,7 +416,7 @@ coap_new_context(const coap_address_t *listen_addr) coap_free( c ); return NULL; -#endif /* WITH_POSIX */ +#endif /* WITH_POSIX || WITH_ARDUINO */ #ifdef WITH_CONTIKI c->conn = udp_new(NULL, 0, NULL); udp_bind(c->conn, listen_addr->port); @@ -462,7 +465,7 @@ void coap_free_context(coap_context_t *context) coap_retransmittimer_restart(context); #endif -#if defined(WITH_POSIX) || defined(WITH_LWIP) +#if defined(WITH_POSIX) || defined(WITH_LWIP) || defined(WITH_ARDUINO) #ifdef COAP_RESOURCES_NOHASH LL_FOREACH(context->resources, res) { @@ -488,7 +491,7 @@ void coap_free_context(coap_context_t *context) initialized = 0; #endif /* WITH_CONTIKI */ } - +#endif //ifndef WITH_ARDUINO int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_filter_t unknown) { @@ -548,6 +551,11 @@ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap return; } #endif + +#ifdef WITH_ARDUINO + coap_hash((const unsigned char *)peer->addr, peer->size, h); +#endif /* WITH_ARDUINO */ + #if defined(WITH_LWIP) || defined(WITH_CONTIKI) /* FIXME: with lwip, we can do better */ coap_hash((const unsigned char *)&peer->port, sizeof(peer->port), h); @@ -576,16 +584,23 @@ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coa return result; } -#ifdef WITH_POSIX +#if defined(WITH_ARDUINO) +coap_tid_t +coap_send_impl(coap_context_t *context, + const coap_address_t *dst, + coap_pdu_t *pdu) +{ + return 0; +} +#endif + +#if defined(WITH_POSIX) /* releases space allocated by PDU if free_pdu is set */ coap_tid_t coap_send_impl(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu) { - - char* z = inet_ntoa(*(struct in_addr *)&(dst->addr)); - ssize_t bytes_written; coap_tid_t id = COAP_INVALID_TID; @@ -606,7 +621,7 @@ coap_send_impl(coap_context_t *context, return id; } -#endif /* WITH_POSIX */ +#endif /* WITH_POSIX || WITH_ARDUINO */ #ifdef WITH_CONTIKI /* releases space allocated by PDU if free_pdu is set */ coap_tid_t @@ -688,7 +703,9 @@ coap_send_impl(coap_context_t *context, coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu) { +#ifndef WITH_ARDUINO return coap_send_impl(context, dst, pdu); +#endif } coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request, const coap_address_t *dst, @@ -826,7 +843,7 @@ coap_tid_t coap_retransmit(coap_context_t *context, coap_queue_t *node) /* no more retransmissions, remove node from system */ -#ifndef WITH_CONTIKI +#if !defined(WITH_CONTIKI) && !defined(WITH_ARDUINO) debug("** removed transaction %d\n", ntohs(node->id)); #endif @@ -865,9 +882,10 @@ static inline int check_opt_size(coap_opt_t *opt, unsigned char *maxpos) return 0; } -int coap_read(coap_context_t *ctx, char* data) +#ifndef WITH_ARDUINO +int coap_read(coap_context_t *ctx) { -#ifdef WITH_POSIX +#if defined(WITH_POSIX) static char buf[COAP_MAX_PDU_SIZE]; #endif #if defined(WITH_LWIP) || defined(WITH_CONTIKI) @@ -891,10 +909,10 @@ int coap_read(coap_context_t *ctx, char* data) coap_address_init(&src); -#ifdef WITH_POSIX +#if defined(WITH_POSIX) bytes_read = recvfrom(ctx->sockfd, buf, sizeof(buf), 0, &src.addr.sa, &src.size); -#endif /* WITH_POSIX */ +#endif /* WITH_POSIX || WITH_ARDUINO */ #ifdef WITH_CONTIKI if(uip_newdata()) { @@ -991,6 +1009,7 @@ int coap_read(coap_context_t *ctx, char* data) #endif return -1; } +#endif //#ifndef WITH_ARDUINO int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id, coap_queue_t **node) { @@ -1050,7 +1069,7 @@ static inline int token_match(const unsigned char *a, size_t alen, const unsigne void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst, const unsigned char *token, size_t token_length) { - /* cancel all messages in sendqueue that are for dst + /* cancel all messages in sendqueue that are for dst * and use the specified token */ coap_queue_t *p, *q; @@ -1269,7 +1288,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) need_block2 = 1; } - /* Check if there is sufficient space to add Content-Format option + /* Check if there is sufficient space to add Content-Format option * and data. We do this before adding the Content-Format option to * avoid sending error responses with that option but no actual * content. */ @@ -1346,7 +1365,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) return resp; } -#define WANT_WKC(Pdu,Key) \ +#define WANT_WKC(Pdu,Key) \ (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key)) void handle_request(coap_context_t *context, coap_queue_t *node, const char* responseData) @@ -1429,8 +1448,7 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res str token = { node->pdu->hdr->token_length, node->pdu->hdr->token }; - //h(context, resource, &node->remote, - //node->pdu, &token, response); + h(context, resource, &node->remote, node->pdu, &token, response); unsigned char buf[3]; response->hdr->code = COAP_RESPONSE_CODE(205); @@ -1519,7 +1537,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), str token = { 0, NULL }; - /* remove observer for this resource, if any + /* remove observer for this resource, if any * get token from sent and try to find a matching resource. Uh! */ @@ -1547,7 +1565,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), } } #endif /* WITH_CONTIKI */ -#endif /* WITOUT_OBSERVE */ +#endif /* WITOUT_OBSERVE */ } void coap_dispatch(coap_context_t *context, const char* responseData) @@ -1584,7 +1602,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), if (rcvd->pdu->hdr->code == 0) goto cleanup; - /* FIXME: if sent code was >= 64 the message might have been a + /* FIXME: if sent code was >= 64 the message might have been a * notification. Then, we must flag the observer to be alive * by setting obs->fail_cnt = 0. */ if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->code) == 2) @@ -1618,7 +1636,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), if (coap_option_check_critical(context, rcvd->pdu, opt_filter) == 0) { - /* FIXME: send response only if we have received a request. Otherwise, + /* FIXME: send response only if we have received a request. Otherwise, * send RST. */ response = coap_new_error_response(rcvd->pdu, COAP_RESPONSE_CODE(402), opt_filter); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h index 254b2b4..725bbc4 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h @@ -3,12 +3,16 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_NET_H_ #define _COAP_NET_H_ +#ifdef WITH_ARDUINO +#include "Time.h" +#endif /* WITH_ARDUINO */ + #ifdef __cplusplus extern "C" { @@ -104,14 +108,14 @@ extern "C" /** list of asynchronous transactions */ struct coap_async_state_t *async_state; #endif /* WITHOUT_ASYNC */ - /** - * The time stamp in the first element of the sendqeue is relative - * to sendqueue_basetime. */ - coap_tick_t sendqueue_basetime; - coap_queue_t *sendqueue, *recvqueue; -#if WITH_POSIX - int sockfd; /**< send/receive socket */ -#endif /* WITH_POSIX */ + /** + * The time stamp in the first element of the sendqeue is relative + * to sendqueue_basetime. */ + coap_tick_t sendqueue_basetime; + coap_queue_t *sendqueue, *recvqueue; +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) + int sockfd; /**< send/receive socket */ +#endif /* WITH_POSIX || WITH_ARDUINO */ #ifdef WITH_CONTIKI struct uip_udp_conn *conn; /**< uIP connection object */ @@ -146,8 +150,8 @@ extern "C" /** * Registers a new message handler that is called whenever a response - * was received that matches an ongoing transaction. - * + * was received that matches an ongoing transaction. + * * @param context The context to register the handler for. * @param handler The response handler to register. */ @@ -157,10 +161,10 @@ extern "C" context->response_handler = handler; } - /** + /** * Registers the option type @p type with the given context object @p * ctx. - * + * * @param ctx The context to use. * @param type The option type to register. */ @@ -185,20 +189,23 @@ extern "C" /** Creates a new coap_context_t object that will hold the CoAP stack status. */ coap_context_t *coap_new_context(const coap_address_t *listen_addr); - /** - * Returns a new message id and updates @p context->message_id - * accordingly. The message id is returned in network byte order - * to make it easier to read in tracing tools. - * - * @param context the current coap_context_t object - * @return incremented message id in network byte order - */ - static inline unsigned short coap_new_message_id(coap_context_t *context) - { -#ifndef WITH_CONTIKI - return htons(++(context->message_id)); +/** + * Returns a new message id and updates @p context->message_id + * accordingly. The message id is returned in network byte order + * to make it easier to read in tracing tools. + * + * @param context the current coap_context_t object + * @return incremented message id in network byte order + */ +static inline unsigned short coap_new_message_id(coap_context_t *context) +{ + ++(context->message_id); +#if defined(WITH_ARDUINO) + return ((context->message_id << 8) | ((context->message_id >> 8) & (0xFF))); +#elif defined(WITH_CONTIKI) + return uip_htons(context->message_id); #else /* WITH_CONTIKI */ - return uip_htons(++context->message_id); + return htons(context->message_id); #endif } @@ -218,7 +225,7 @@ extern "C" coap_tid_t coap_send_confirmed(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu); - /** + /** * Creates a new ACK PDU with specified error @p code. The options * specified by the filter expression @p opts will be copied from the * original request contained in @p request. Unless @c @@ -227,12 +234,12 @@ extern "C" * 0. This function returns a pointer to the new response message, or * @c NULL on error. The storage allocated for the new message must be * relased with coap_free(). - * + * * @param request Specification of the received (confirmable) request. * @param code The error code to set. * @param opts An option filter that specifies which options to copy * from the original request in @p node. - * + * * @return A pointer to the new message or @c NULL on error. */ coap_pdu_t *coap_new_error_response(coap_pdu_t *request, unsigned char code, @@ -249,27 +256,27 @@ extern "C" */ coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu); - /** + /** * Sends an error response with code @p code for request @p request to * @p dst. @p opts will be passed to coap_new_error_response() to * copy marked options from the request. This function returns the * transaction id if the message was sent, or @c COAP_INVALID_TID * otherwise. - * + * * @param context The context to use. * @param request The original request to respond to. * @param dst The remote peer that sent the request. * @param code The reponse code. - * @param opts A filter that specifies the options to copy from the + * @param opts A filter that specifies the options to copy from the * @p request. - * + * * @return The transaction id if the message was sent, or @c * COAP_INVALID_TID otherwise. */ coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request, const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts); - /** + /** * Helper funktion to create and send a message with @p type (usually * ACK or RST). This function returns @c COAP_INVALID_TID when the * message was not sent, a valid transaction id otherwise. @@ -283,30 +290,30 @@ extern "C" coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *request, unsigned char type); - /** + /** * Sends an ACK message with code @c 0 for the specified @p request to * @p dst. This function returns the corresponding transaction id if * the message was sent or @c COAP_INVALID_TID on error. - * + * * @param context The context to use. * @param dst The destination address. * @param request The request to be acknowledged. - * + * * @return The transaction id if ACK was sent or @c COAP_INVALID_TID * on error. */ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *request); - /** + /** * Sends an RST message with code @c 0 for the specified @p request to * @p dst. This function returns the corresponding transaction id if * the message was sent or @c COAP_INVALID_TID on error. - * + * * @param context The context to use. * @param dst The destination address. * @param request The request to be reset. - * + * * @return The transaction id if RST was sent or @c COAP_INVALID_TID * on error. */ @@ -324,9 +331,9 @@ extern "C" * and a new node with the parsed PDU is added to the receive queue in the specified context * object. */ - int coap_read(coap_context_t *context, char* data); + int coap_read(coap_context_t *context); - /** + /** * Calculates a unique transaction id from given arguments @p peer and * @p pdu. The id is returned in @p id. * @@ -336,33 +343,33 @@ extern "C" */ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap_tid_t *id); - /** + /** * This function removes the element with given @p id from the list * given list. If @p id was found, @p node is updated to point to the - * removed element. Note that the storage allocated by @p node is + * removed element. Note that the storage allocated by @p node is * @b not released. The caller must do this manually using * coap_delete_node(). This function returns @c 1 if the element with * id @p id was found, @c 0 otherwise. For a return value of @c 0, * the contents of @p node is undefined. - * + * * @param queue The queue to search for @p id. * @param id The node id to look for. - * @param node If found, @p node is updated to point to the + * @param node If found, @p node is updated to point to the * removed node. You must release the storage pointed to by * @p node manually. - * + * * @return @c 1 if @p id was found, @c 0 otherwise. */ int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id, coap_queue_t **node); - /** + /** * Removes the transaction identified by @p id from given @p queue. * This is a convenience function for coap_remove_from_queue() with * automatic deletion of the removed node. - * + * * @param queue The queue to search for @p id. * @param id The transaction id. - * + * * @return @c 1 if node was found, removed and destroyed, @c 0 otherwise. */ inline static int coap_remove_transaction(coap_queue_t **queue, coap_tid_t id) @@ -384,13 +391,13 @@ extern "C" coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_tid_t id); /** - * Cancels all outstanding messages for peer @p dst that have the + * Cancels all outstanding messages for peer @p dst that have the * specified token. * * @param context The context in use * @param dst Destination address of the messages to remove. * @param token Message token - * @param token_length Actual length of @p token + * @param token_length Actual length of @p token */ void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst, const unsigned char *token, size_t token_length); @@ -403,11 +410,11 @@ extern "C" /** * Returns the current value of an internal tick counter. The counter - * counts \c COAP_TICKS_PER_SECOND ticks every second. + * counts \c COAP_TICKS_PER_SECOND ticks every second. */ void coap_ticks(coap_tick_t *); - /** + /** * Verifies that @p pdu contains no unknown critical options. Options * must be registered at @p ctx, using the function * coap_register_option(). A basic set of options is registered @@ -415,7 +422,7 @@ extern "C" * @p pdu is ok, @c 0 otherwise. The given filter object @p unknown * will be updated with the unknown options. As only @c COAP_MAX_OPT * options can be signalled this way, remaining options must be - * examined manually. + * examined manually. * * @code coap_opt_filter_t f = COAP_OPT_NONE; @@ -430,13 +437,13 @@ extern "C" } } } - * @endcode + * @endcode * * @param ctx The context where all known options are registered. * @param pdu The PDU to check. * @param unknown The output filter that will be updated to indicate the * unknown critical options found in @p pdu. - * + * * @return @c 1 if everything was ok, @c 0 otherwise. */ int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_filter_t unknown); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c index c8c8496..3255020 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c @@ -4,7 +4,7 @@ * Copyright (C) 2010-2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -42,12 +42,12 @@ size_t coap_opt_parse(const coap_opt_t *opt, size_t length, coap_option_t *resul assert(opt); assert(result); -#define ADVANCE_OPT(o,e,step) if ((e) < step) { \ - debug("cannot advance opt past end\n"); \ - return 0; \ - } else { \ - (e) -= step; \ - (o) = ((unsigned char *)(o)) + step; \ +#define ADVANCE_OPT(o,e,step) if ((e) < step) { \ + debug("cannot advance opt past end\n"); \ + return 0; \ + } else { \ + (e) -= step; \ + (o) = ((unsigned char *)(o)) + step; \ } if (length < 1) @@ -201,7 +201,7 @@ coap_option_next(coap_opt_iterator_t *oi) /* Exit the while loop when: * - no filtering is done at all * - the filter matches for the current option - * - the filter is too small for the current option number + * - the filter is too small for the current option number */ if (!oi->filtered || (b = coap_option_getb(oi->filter, oi->type)) > 0) break; diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h index 78b2a03..13a97f0 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h @@ -4,7 +4,7 @@ * Copyright (C) 2010-2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** @@ -18,7 +18,7 @@ #include "bits.h" #include "pdu.h" -/** +/** * Use byte-oriented access methods here because sliding a complex * struct coap_opt_t over the data buffer may cause bus error on * certain platforms. @@ -39,7 +39,7 @@ typedef struct * function returns the number of bytes that have been parsed, or @c 0 * on error. An error is signaled when illegal delta or length values * are encountered or when option parsing would result in reading past - * the option (i.e. beyond opt + length). + * the option (i.e. beyond opt + length). * * @param opt The beginning of the option to parse. * @param length The maximum length of @p opt. @@ -66,7 +66,7 @@ size_t coap_opt_size(const coap_opt_t *opt); /** * Calculates the beginning of the PDU's option section. - * + * * @param pdu The PDU containing the options. * @return A pointer to the first option if available, or @c NULL otherwise. */ @@ -85,7 +85,7 @@ coap_opt_t *options_start(coap_pdu_t *pdu); * @{ */ -/** +/** * Fixed-size bit-vector we use for option filtering. It is large * enough to hold the highest option number known at build time (20 in * the core spec). @@ -95,9 +95,9 @@ typedef unsigned char coap_opt_filter_t[(COAP_MAX_OPT >> 3) + 1]; /** Pre-defined filter that includes all options. */ #define COAP_OPT_ALL NULL -/** +/** * Clears filter @p f. - * + * * @param f The filter to clear. */ static inline void coap_option_filter_clear(coap_opt_filter_t f) @@ -105,14 +105,14 @@ static inline void coap_option_filter_clear(coap_opt_filter_t f) memset(f, 0, sizeof(coap_opt_filter_t)); } -/** +/** * Sets the corresponding bit for @p type in @p filter. This function * returns @c 1 if bit was set or @c -1 on error (i.e. when the given * type does not fit in the filter). - * + * * @param filter The filter object to change. - * @param type The type for which the bit should be set. - * + * @param type The type for which the bit should be set. + * * @return @c 1 if bit was set, @c -1 otherwise. */ inline static int coap_option_setb(coap_opt_filter_t filter, unsigned short type) @@ -120,14 +120,14 @@ inline static int coap_option_setb(coap_opt_filter_t filter, unsigned short type return bits_setb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Clears the corresponding bit for @p type in @p filter. This function * returns @c 1 if bit was cleared or @c -1 on error (i.e. when the given * type does not fit in the filter). - * + * * @param filter The filter object to change. - * @param type The type for which the bit should be cleared. - * + * @param type The type for which the bit should be cleared. + * * @return @c 1 if bit was set, @c -1 otherwise. */ inline static int coap_option_clrb(coap_opt_filter_t filter, unsigned short type) @@ -135,14 +135,14 @@ inline static int coap_option_clrb(coap_opt_filter_t filter, unsigned short type return bits_clrb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Gets the corresponding bit for @p type in @p filter. This function * returns @c 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. * when the given type does not fit in the filter). - * + * * @param filter The filter object to read bit from.. * @param type The type for which the bit should be read. - * + * * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. */ inline static int coap_option_getb(const coap_opt_filter_t filter, unsigned short type) @@ -150,7 +150,7 @@ inline static int coap_option_getb(const coap_opt_filter_t filter, unsigned shor return bits_getb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Iterator to run through PDU options. This object must be * initialized with coap_option_iterator_init(). Call * coap_option_next() to walk through the list of options until @@ -176,27 +176,27 @@ typedef struct coap_opt_filter_t filter; /**< option filter */ } coap_opt_iterator_t; -/** +/** * Initializes the given option iterator @p oi to point to the * beginning of the @p pdu's option list. This function returns @p oi * on success, @c NULL otherwise (i.e. when no options exist). * Note that a length check on the option list must be performed before * coap_option_iterator_init() is called. - * + * * @param pdu The PDU the options of which should be walked through. * @param oi An iterator object that will be initilized. - * @param filter An optional option type filter. - * With @p type != @c COAP_OPT_ALL, coap_option_next() - * will return only options matching this bitmask. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. * Fence-post options @c 14, @c 28, @c 42, ... are always * skipped. - * + * * @return The iterator object @p oi on success, @c NULL otherwise. */ coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter); -/** +/** * Updates the iterator @p oi to point to the next option. This * function returns a pointer to that option or @c NULL if no more * options exist. The contents of @p oi will be updated. In @@ -205,30 +205,30 @@ coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterato * oi->option points to the beginning of the current option * itself. When advanced past the last option, @c oi->option will be * @c NULL. - * + * * Note that options are skipped whose corresponding bits in the * filter specified with coap_option_iterator_init() are @c 0. Options * with type codes that do not fit in this filter hence will always be * returned. - * + * * @param oi The option iterator to update. - * + * * @return The next option or @c NULL if no more options exist. */ coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); -/** +/** * Retrieves the first option of type @p type from @p pdu. @p oi must * point to a coap_opt_iterator_t object that will be initialized by * this function to filter only options with code @p type. This * function returns the first option with this type, or @c NULL if not * found. - * + * * @param pdu The PDU to parse for options. * @param type The option type code to search for. * @param oi An iterator object to use. - * - * @return A pointer to the first option of type @p type, or @c NULL + * + * @return A pointer to the first option of type @p type, or @c NULL * if not found. */ coap_opt_t *coap_check_option(coap_pdu_t *pdu, unsigned char type, coap_opt_iterator_t *oi); @@ -281,7 +281,7 @@ unsigned short coap_opt_delta(const coap_opt_t *opt); #define COAP_OPT_DELTA(opt) coap_opt_delta(opt) /** @deprecated { Use coap_opt_encode() instead. } */ -#define COAP_OPT_SETDELTA(opt,val) \ +#define COAP_OPT_SETDELTA(opt,val) \ coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0) /** @@ -304,7 +304,7 @@ unsigned short coap_opt_length(const coap_opt_t *opt); /** * Returns a pointer to the value of the given option. @p opt must - * point to an option jump or the beginning of the option. This + * point to an option jump or the beginning of the option. This * function returns @c NULL if @p opt is not a valid option. * * @param opt The option whose value should be returned. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c index b8aaaad..5762007 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -24,6 +24,10 @@ #include "option.h" #include "encode.h" +#ifdef WITH_ARDUINO +#include "util.h" +#endif + #ifdef WITH_CONTIKI #include "memb.h" @@ -93,8 +97,8 @@ coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t return NULL; /* size must be large enough for hdr */ -#ifdef WITH_POSIX - pdu = coap_malloc(sizeof(coap_pdu_t) + size); +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) + pdu = (coap_pdu_t *) coap_malloc(sizeof(coap_pdu_t) + size); #endif #ifdef WITH_CONTIKI pdu = (coap_pdu_t *)memb_alloc(&pdu_storage); @@ -147,12 +151,12 @@ coap_new_pdu() void coap_delete_pdu(coap_pdu_t *pdu) { -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) coap_free( pdu ); #endif #ifdef WITH_LWIP if (pdu != NULL) /* accepting double free as the other implementation accept that too */ - pbuf_free(pdu->pbuf); + pbuf_free(pdu->pbuf); #endif #ifdef WITH_CONTIKI memb_free(&pdu_storage, pdu); @@ -299,7 +303,7 @@ typedef struct char *phrase; } error_desc_t; -/* if you change anything here, make sure, that the longest string does not +/* if you change anything here, make sure, that the longest string does not * exceed COAP_ERROR_PHRASE_LENGTH. */ error_desc_t coap_error[] = { @@ -340,7 +344,7 @@ coap_response_phrase(unsigned char code) #endif /** - * Advances *optp to next option if still in PDU. This function + * Advances *optp to next option if still in PDU. This function * returns the number of bytes opt has been advanced or @c 0 * on error. */ @@ -368,9 +372,6 @@ int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) { coap_opt_t *opt; - char optionResult[256] = - { 0, }; - assert(data); assert(pdu); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h index e01d851..c469b24 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _PDU_H_ @@ -24,7 +24,11 @@ #define COAP_DEFAULT_PORT 5683 /* CoAP default UDP port */ #define COAP_DEFAULT_MAX_AGE 60 /* default maximum object lifetime in seconds */ #ifndef COAP_MAX_PDU_SIZE -#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU */ +#ifdef WITH_ARDUINO +#define COAP_MAX_PDU_SIZE 320 /* maximum size of a CoAP PDU for embedded platforms*/ +#else +#define COAP_MAX_PDU_SIZE 1400 /* maximum size of a CoAP PDU for big platforms*/ +#endif #endif /* COAP_MAX_PDU_SIZE */ #define COAP_DEFAULT_VERSION 1 /* version of CoAP supported */ @@ -95,13 +99,13 @@ #define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) #ifndef SHORT_ERROR_RESPONSE -/** +/** * Returns a human-readable response phrase for the specified CoAP * response @p code. This function returns @c NULL if not found. - * + * * @param code The response code for which the literal phrase should * be retrieved. - * + * * @return A zero-terminated string describing the error, or @c NULL * if not found. */ @@ -178,16 +182,16 @@ typedef struct #endif #define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG)->code == 0) -#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ - && ((MSG)->code < 32)) +#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ + && ((MSG)->code < 32)) #define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG)->code >= 64 && (MSG)->code <= 191) -#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list in a - * CoAP message is limited by 0b11110000 marker */ +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list in a + * CoAP message is limited by 0b11110000 marker */ -#define COAP_OPT_END 0xF0 /* end marker */ +#define COAP_OPT_END 0xF0 /* end marker */ -#define COAP_PAYLOAD_START 0xFF /* payload marker */ +#define COAP_PAYLOAD_START 0xFF /* payload marker */ /** * Structures for more convenient handling of options. (To be used with ordered @@ -216,7 +220,8 @@ typedef struct unsigned char *data; /**< payload */ #ifdef WITH_LWIP - struct pbuf *pbuf; /**< lwIP PBUF. The allocated coap_pdu_t will always reside inside the pbuf's payload, but the pointer has to be kept because no exact offset can be given. This field must not be accessed from outside, because the pbuf's reference count is checked to be 1 when the pbuf is assigned to the pdu, and the pbuf stays exclusive to this pdu. */ + struct pbuf + *pbuf; /**< lwIP PBUF. The allocated coap_pdu_t will always reside inside the pbuf's payload, but the pointer has to be kept because no exact offset can be given. This field must not be accessed from outside, because the pbuf's reference count is checked to be 1 when the pbuf is assigned to the pdu, and the pbuf stays exclusive to this pdu. */ #endif } coap_pdu_t; @@ -245,24 +250,24 @@ typedef struct coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); #endif -/** - * Creates a new CoAP PDU of given @p size (must be large enough to hold the +/** + * Creates a new CoAP PDU of given @p size (must be large enough to hold the * basic CoAP message header (coap_hdr_t). The function returns a pointer to * the node coap_pdu_t object on success, or @c NULL on error. The storage * allocated for the result must be released with coap_delete_pdu(). - * + * * @param type The type of the PDU (one of COAP_MESSAGE_CON, - * COAP_MESSAGE_NON, COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * COAP_MESSAGE_NON, COAP_MESSAGE_ACK, COAP_MESSAGE_RST). * @param code The message code. * @param id The message id to set or COAP_INVALID_TID if unknown. * @param size The number of bytes to allocate for the actual message. - * + * * @return A pointer to the new PDU object or @c NULL on error. */ coap_pdu_t * coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size); -/** +/** * Clears any contents from @p pdu and resets @c version field, @c * length and @c data pointers. @c max_size is set to @p size, any * other field is set to @c 0. Note that @p pdu must be a valid @@ -273,9 +278,9 @@ void coap_pdu_clear(coap_pdu_t *pdu, size_t size); /** * Creates a new CoAP PDU. The object is created on the heap and must be released * using coap_delete_pdu(); - * + * * @deprecated This function allocates the maximum storage for each - * PDU. Use coap_pdu_init() instead. + * PDU. Use coap_pdu_init() instead. */ coap_pdu_t *coap_new_pdu(); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h index ca86e72..25e7720 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file prng.h * @brief Pseudo Random Numbers */ @@ -16,7 +16,7 @@ #include "config.h" -/** +/** * @defgroup prng Pseudo Random Numbers * @{ */ @@ -64,16 +64,16 @@ contiki_prng_impl(unsigned char *buf, size_t len) #endif /* WITH_CONTIKI */ #ifndef prng -/** - * Fills \p Buf with \p Length bytes of random data. - * +/** + * Fills \p Buf with \p Length bytes of random data. + * * @hideinitializer */ #define prng(Buf,Length) coap_prng_impl((Buf), (Length)) #endif #ifndef prng_init -/** +/** * Called to set the PRNG seed. You may want to re-define this to * allow for a better PRNG. * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c index d6ae50f..8c3a3ec 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -27,7 +27,7 @@ #define COAP_FREE_TYPE(Type, Object) memp_free(MEMP_COAP_##Type, Object) #endif -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) #include "utlist.h" #include "mem.h" @@ -74,21 +74,21 @@ coap_free_subscription(coap_subscription_t *subscription) * Adds Char to Buf if Offset is zero. Otherwise, Char is not written * and Offset is decremented. */ -#define PRINT_WITH_OFFSET(Buf,Offset,Char) \ - if ((Offset) == 0) { \ - (*(Buf)++) = (Char); \ - } else { \ - (Offset)--; \ - } \ +#define PRINT_WITH_OFFSET(Buf,Offset,Char) \ + if ((Offset) == 0) { \ + (*(Buf)++) = (Char); \ + } else { \ + (Offset)--; \ + } \ /** * Adds Char to Buf if Offset is zero and Buf is less than Bufend. */ -#define PRINT_COND_WITH_OFFSET(Buf,Bufend,Offset,Char,Result) { \ - if ((Buf) < (Bufend)) { \ - PRINT_WITH_OFFSET(Buf,Offset,Char); \ - } \ - (Result)++; \ +#define PRINT_COND_WITH_OFFSET(Buf,Bufend,Offset,Char,Result) { \ + if ((Buf) < (Bufend)) { \ + PRINT_WITH_OFFSET(Buf,Offset,Char); \ + } \ + (Result)++; \ } /** @@ -96,11 +96,11 @@ coap_free_subscription(coap_subscription_t *subscription) * characters are skipped. Output may be truncated to Bufend - Buf * characters. */ -#define COPY_COND_WITH_OFFSET(Buf,Bufend,Offset,Str,Length,Result) { \ - size_t i; \ - for (i = 0; i < (Length); i++) { \ +#define COPY_COND_WITH_OFFSET(Buf,Bufend,Offset,Str,Length,Result) { \ + size_t i; \ + for (i = 0; i < (Length); i++) { \ PRINT_COND_WITH_OFFSET((Buf), (Bufend), (Offset), (Str)[i], (Result)); \ - } \ + } \ } int match(const str *text, const str *pattern, int match_prefix, int match_substring) @@ -119,7 +119,7 @@ int match(const str *text, const str *pattern, int match_prefix, int match_subst { size_t token_length; unsigned char *token = next_token; - next_token = memchr(token, ' ', remaining_length); + next_token = (unsigned char *) memchr(token, ' ', remaining_length); if (next_token) { @@ -144,22 +144,22 @@ int match(const str *text, const str *pattern, int match_prefix, int match_subst && memcmp(text->s, pattern->s, pattern->length) == 0; } -/** +/** * Prints the names of all known resources to @p buf. This function * sets @p buflen to the number of bytes actually written and returns * @c 1 on succes. On error, the value in @p buflen is undefined and * the return value will be @c 0. - * + * * @param context The context with the resource map. * @param buf The buffer to write the result. * @param buflen Must be initialized to the maximum length of @p buf and will be * set to the length of the well-known response on return. * @param offset The offset in bytes where the output shall start and is * shifted accordingly with the characters that have been - * processed. This parameter is used to support the block - * option. + * processed. This parameter is used to support the block + * option. * @param query_filter A filter query according to Link Format - * + * * @return COAP_PRINT_STATUS_ERROR on error. Otherwise, the lower 28 bits are * set to the number of bytes that have actually been written to * @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been @@ -339,7 +339,7 @@ coap_resource_init(const unsigned char *uri, size_t len, int flags) { coap_resource_t *r; -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) r = (coap_resource_t *)coap_malloc(sizeof(coap_resource_t)); #endif #ifdef WITH_LWIP @@ -381,7 +381,7 @@ coap_add_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen, if (!resource || !name) return NULL; -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) attr = (coap_attr_t *)coap_malloc(sizeof(coap_attr_t)); #endif #ifdef WITH_LWIP @@ -431,7 +431,7 @@ coap_find_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen for (attr = list_head(resource->link_attr); attr; attr = list_item_next(attr)) { -#endif /* WITH_CONTIKI */ +#endif /* WITH_CONTIKI */ if (attr->name.length == nlen && memcmp(attr->name.s, name, nlen) == 0) return attr; } @@ -501,7 +501,7 @@ int coap_delete_resource(coap_context_t *context, coap_key_t key) if (!resource) return 0; -#if defined(WITH_POSIX) || defined(WITH_LWIP) +#if defined(WITH_POSIX) || defined(WITH_LWIP) || defined(WITH_ARDUINO) #ifdef COAP_RESOURCES_NOHASH LL_DELETE(context->resources, resource); #else @@ -512,15 +512,15 @@ int coap_delete_resource(coap_context_t *context, coap_key_t key) LL_FOREACH_SAFE(resource->link_attr, attr, tmp) coap_delete_attr(attr); if (resource->flags & COAP_RESOURCE_FLAGS_RELEASE_URI) - coap_free(resource->uri.s); + coap_free(resource->uri.s); -#ifdef WITH_POSIX +#if defined(WITH_POSIX) || defined(WITH_ARDUINO) coap_free(resource); #endif #ifdef WITH_LWIP memp_free(MEMP_COAP_RESOURCE, resource); #endif -#else /* not (WITH_POSIX || WITH_LWIP) */ +#else /* not (WITH_POSIX || WITH_LWIP || WITH_ARDUINO) */ /* delete registered attributes */ while ((attr = list_pop(resource->link_attr))) memb_free(&attribute_storage, attr); @@ -637,7 +637,8 @@ coap_find_observer(coap_resource_t *resource, const coap_address_t *peer, const assert(resource); assert(peer); - for (s = list_head(resource->subscribers); s; s = list_item_next(s)) + for (s = (coap_subscription_t *) list_head(resource->subscribers); + s; s = (coap_subscription_t *) list_item_next((void *) s)) { if (coap_address_equals(&s->subscriber, peer) && (!token @@ -752,7 +753,8 @@ static void coap_notify_observers(coap_context_t *context, coap_resource_t *r) assert(h); /* we do not allow subscriptions if no * GET handler is defined */ - for (obs = list_head(r->subscribers); obs; obs = list_item_next(obs)) + for (obs = (coap_subscription_t *) list_head(r->subscribers); + obs; obs = (coap_subscription_t *) list_item_next((void *) obs)) { if (r->dirty == 0 && obs->dirty == 0) /* running this resource due to partiallydirty, but this observation's notification was already enqueued */ @@ -866,7 +868,8 @@ static void coap_remove_failed_observers(coap_context_t *context, coap_resource_ { coap_subscription_t *obs; - for (obs = list_head(resource->subscribers); obs; obs = list_item_next(obs)) + for (obs = (coap_subscription_t *) list_head(resource->subscribers); + obs; obs = (coap_subscription_t *) list_item_next((void *) obs)) { if (coap_address_equals(peer, &obs->subscriber) && token->length == obs->token_length && memcmp(token->s, obs->token, token->length) == 0) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h index 5ed3583..ae3d37a 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011,2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file resource.h * @brief generic resource handling */ @@ -65,7 +65,7 @@ typedef struct coap_resource_t unsigned int observable :1; /**< can be observed */ unsigned int cacheable :1; /**< can be cached */ - /** + /** * Used to store handlers for the four coap methods @c GET, @c POST, * @c PUT, and @c DELETE. coap_dispatch() will pass incoming * requests to the handler that corresponds to its request method or @@ -98,15 +98,15 @@ typedef struct coap_resource_t } coap_resource_t; -/** +/** * Creates a new resource object and initializes the link field to the * string of length @p len. This function returns the * new coap_resource_t object. - * + * * @param uri The URI path of the new resource. * @param len The length of @p uri. * @param flags Flags for memory management (in particular release of memory) - * + * * @return A pointer to the new object or @c NULL on error. */ coap_resource_t *coap_resource_init(const unsigned char *uri, size_t len, int flags); @@ -115,29 +115,29 @@ coap_resource_t *coap_resource_init(const unsigned char *uri, size_t len, int fl * Registers the given @p resource for @p context. The resource must * have been created by coap_resource_init(), the storage allocated * for the resource will be released by coap_delete_resource(). - * + * * @param context The context to use. * @param resource The resource to store. */ void coap_add_resource(coap_context_t *context, coap_resource_t *resource); -/** +/** * Deletes a resource identified by @p key. The storage allocated for * that resource is freed. - * + * * @param context The context where the resources are stored. * @param key The unique key for the resource to delete. - * + * * @return @c 1 if the resource was found (and destroyed), @c 0 otherwise. */ int coap_delete_resource(coap_context_t *context, coap_key_t key); -/** +/** * Registers a new attribute with the given @p resource. As the - * attributes str fields will point to @p name and @p val the + * attributes str fields will point to @p name and @p val the * caller must ensure that these pointers are valid during the * attribute's lifetime. - * + * * @param resource The resource to register the attribute with. * @param name The attribute's name. * @param nlen Length of @p name. @@ -162,11 +162,11 @@ coap_attr_t *coap_add_attr(coap_resource_t *resource, const unsigned char *name, */ coap_attr_t *coap_find_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen); -/** +/** * Deletes an attribute - * + * * @param attr Pointer to a previously created attribute - * + * */ void coap_delete_attr(coap_attr_t *attr); @@ -187,22 +187,22 @@ typedef unsigned int coap_print_status_t; #define COAP_PRINT_STATUS_ERROR 0x80000000u #define COAP_PRINT_STATUS_TRUNC 0x40000000u -/** +/** * Writes a description of this resource in link-format to given text * buffer. @p len must be initialized to the maximum length of @p buf * and will be set to the number of characters actually written if * successful. This function returns @c 1 on success or @c 0 on * error. - * + * * @param resource The resource to describe. * @param buf The output buffer to write the description to. - * @param len Must be initialized to the length of @p buf and + * @param len Must be initialized to the length of @p buf and * will be set to the length of the printed link description. * @param offset The offset within the resource description where to * start writing into @p buf. This is useful for dealing * with the Block2 option. @p offset is updated during * output as it is consumed. - * + * * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, * the lower 28 bits will indicate the number of characters that * have actually been output into @p buffer. The flag @@ -212,12 +212,12 @@ typedef unsigned int coap_print_status_t; coap_print_status_t coap_print_link(const coap_resource_t *resource, unsigned char *buf, size_t *len, size_t *offset); -/** +/** * Registers the specified @p handler as message handler for the request type * @p method - * + * * @param resource The resource for which the handler shall be registered. - * @param method The CoAP request method to handle. + * @param method The CoAP request method to handle. * @param handler The handler to register with @p resource. */ static inline void coap_register_handler(coap_resource_t *resource, unsigned char method, @@ -231,28 +231,28 @@ static inline void coap_register_handler(coap_resource_t *resource, unsigned cha resource->handler[method - 1] = handler; } -/** +/** * Returns the resource identified by the unique string @p key. If no * resource was found, this function returns @c NULL. - * + * * @param context The context to look for this resource. * @param key The unique key of the resource. - * + * * @return A pointer to the resource or @c NULL if not found. */ coap_resource_t *coap_get_resource_from_key(coap_context_t *context, coap_key_t key); -/** +/** * Calculates the hash key for the resource requested by the * Uri-Options of @p request. This function calls coap_hash() for * every path segment. - * + * * @param request The requesting pdu. * @param key The resulting hash is stored in @p key */ void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); -/** +/** * @addtogroup observe */ @@ -267,7 +267,7 @@ void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); * @param token The token that identifies this subscription. * @param token_length The actual length of @p token. Must be @c 0 when * @p token is @c NULL. - * @return A pointer to the added/updated subscription information or + * @return A pointer to the added/updated subscription information or * @c NULL on error. */ coap_subscription_t *coap_add_observer(coap_resource_t *resource, const coap_address_t *observer, @@ -290,7 +290,7 @@ coap_subscription_t *coap_find_observer(coap_resource_t *resource, const coap_ad * * @param context The CoAP context to use * @param observer The transport address of the observer - * @param token The corresponding token that has been used for + * @param token The corresponding token that has been used for * the subscription */ void coap_touch_observer(coap_context_t *context, const coap_address_t *observer, const str *token); @@ -307,7 +307,7 @@ void coap_touch_observer(coap_context_t *context, const coap_address_t *observer void coap_delete_observer(coap_resource_t *resource, const coap_address_t *observer, const str *token); -/** +/** * Checks for all known resources, if they are dirty and notifies * subscribed observers. */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c index 8b275e3..950803d 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -16,7 +16,7 @@ str *coap_new_string(size_t size) { - str *s = coap_malloc(sizeof(str) + size + 1); + str *s = (str *) coap_malloc(sizeof(str) + size + 1); if (!s) { #ifndef NDEBUG diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h index 6405298..0a96686 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_STR_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c index 295f5c5..e5c3d24 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h index 7b7dc05..eb76151 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h @@ -4,7 +4,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_SUBSCRIBE_H_ @@ -13,7 +13,7 @@ #include "config.h" #include "address.h" -/** +/** * @defgroup observe Resource observation * @{ */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h index 47653d1..5f25f96 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h @@ -82,13 +82,13 @@ struct list #define LIST_CONCAT(s1, s2) s1##s2 -#define LIST_STRUCT(name) \ - void *LIST_CONCAT(name, _list); \ +#define LIST_STRUCT(name) \ + void *LIST_CONCAT(name, _list); \ list_t name -#define LIST_STRUCT_INIT(struct_ptr, name) { \ - (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ - (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ +#define LIST_STRUCT_INIT(struct_ptr, name) { \ + (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ + (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ } static inline void * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile deleted file mode 100644 index 6397552..0000000 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# Makefile for libcoap -# -# Copyright (C) 2012 Olaf Bergmann -# -# This file is part of the CoAP library libcoap. Please see -# README for terms of use. - -# the library's version -VERSION:=4.1.1 - -# tools - -SHELL = /bin/sh -MKDIR = mkdir - -abs_builddir = /connectivity/connectivity/src/bt_edr_adapter/libcoap-4.1.1/tests -top_builddir = .. -top_srcdir = .. -# files and flags -ifneq (,) - PROGRAMS:=testdriver -endif -SOURCES:= test_uri.c test_options.c test_pdu.c test_error_response.c \ - test_sendqueue.c test_wellknown.c -HEADERS:=$(SOURCES:.c=.h) -OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) -CFLAGS:=-g -Wall -g -O2 -CPPFLAGS:=-I$(top_srcdir) -DWITH_POSIX -DISTDIR?=$(top_builddir)/libcoap-4.1.1 -FILES:=Makefile.in testdriver.c $(HEADERS) $(SOURCES) -LDFLAGS:=-L$(top_builddir) -LDLIBS:=-lcunit -libcoap =$(top_builddir)/libcoap.a - -.PHONY: clean distclean - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(PROGRAMS) - -check: - echo DISTDIR: $(DISTDIR) - echo top_builddir: $(top_builddir) - -testdriver: $(OBJECTS) $(libcoap) - -clean: - @rm -f $(PROGRAMS) $(OBJECTS) - -distclean: clean - @rm -rf $(DISTDIR) - @rm -f *~ - -dist: $(FILES) - test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests - cp $(FILES) $(DISTDIR)/tests diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in index 95da5c0..f065c1e 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in @@ -55,3 +55,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests cp $(FILES) $(DISTDIR)/tests + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c index fad0941..69c62bd 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -310,10 +310,10 @@ CU_pSuite t_init_error_response_tests(void) return NULL; } -#define ERROR_RESPONSE_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ +#define ERROR_RESPONSE_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ fprintf(stderr, "W: cannot add error response generator test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } ERROR_RESPONSE_TEST(suite[0], t_error_response1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h index 2bab63c..5ae3cea 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c index de5b3a6..27c12ad 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -756,10 +756,10 @@ CU_pSuite t_init_option_tests(void) return NULL; } -#define OPTION_TEST(n,s) \ - if (!CU_add_test(suite[0], s, t_parse_option##n)) { \ - fprintf(stderr, "W: cannot add option parser test (%s)\n", \ - CU_get_error_msg()); \ +#define OPTION_TEST(n,s) \ + if (!CU_add_test(suite[0], s, t_parse_option##n)) { \ + fprintf(stderr, "W: cannot add option parser test (%s)\n", \ + CU_get_error_msg()); \ } OPTION_TEST(1, "parse option #1"); @@ -779,10 +779,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[1] = CU_add_suite("option encoder", NULL, NULL))) { -#define OPTION_ENCODER_TEST(n,s) \ - if (!CU_add_test(suite[1], s, t_encode_option##n)) { \ +#define OPTION_ENCODER_TEST(n,s) \ + if (!CU_add_test(suite[1], s, t_encode_option##n)) { \ fprintf(stderr, "W: cannot add option encoder test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ENCODER_TEST(1, "encode option #1"); @@ -802,10 +802,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[2] = CU_add_suite("option accessors", NULL, NULL))) { -#define OPTION_ACCESSOR_TEST(n,s) \ - if (!CU_add_test(suite[2], s, t_access_option##n)) { \ +#define OPTION_ACCESSOR_TEST(n,s) \ + if (!CU_add_test(suite[2], s, t_access_option##n)) { \ fprintf(stderr, "W: cannot add option accessor function test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ACCESSOR_TEST(1, "access option #1"); @@ -825,10 +825,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[3] = CU_add_suite("option iterator", NULL, NULL))) { -#define OPTION_ITERATOR_TEST(n,s) \ - if (!CU_add_test(suite[3], s, t_iterate_option##n)) { \ +#define OPTION_ITERATOR_TEST(n,s) \ + if (!CU_add_test(suite[3], s, t_iterate_option##n)) { \ fprintf(stderr, "W: cannot add option iterator test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ITERATOR_TEST(1, "option iterator #1"); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h index 3ffcefe..8c2be65 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c index 2592a32..8d004d8 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -609,10 +609,10 @@ CU_pSuite t_init_pdu_tests(void) return NULL; } -#define PDU_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add pdu parser test (%s)\n", \ - CU_get_error_msg()); \ +#define PDU_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add pdu parser test (%s)\n", \ + CU_get_error_msg()); \ } PDU_TEST(suite[0], t_parse_pdu1); @@ -633,10 +633,10 @@ CU_pSuite t_init_pdu_tests(void) suite[1] = CU_add_suite("pdu encoder", t_pdu_tests_create, t_pdu_tests_remove); if (suite[1]) { -#define PDU_ENCODER_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add pdu encoder test (%s)\n", \ - CU_get_error_msg()); \ +#define PDU_ENCODER_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add pdu encoder test (%s)\n", \ + CU_get_error_msg()); \ } PDU_ENCODER_TEST(suite[1], t_encode_pdu1); PDU_ENCODER_TEST(suite[1], t_encode_pdu2); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h index 992b377..a052240 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c index 1b6c076..5207039 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -291,7 +291,7 @@ void t_sendqueue10(void) /* This function creates a set of nodes for testing. These nodes * will exist for all tests and are modified by coap_insert_node() - * and + * and */ int t_sendqueue_tests_create(void) { @@ -357,10 +357,10 @@ CU_pSuite t_init_sendqueue_tests(void) return NULL; } -#define SENDQUEUE_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add sendqueue test (%s)\n", \ - CU_get_error_msg()); \ +#define SENDQUEUE_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add sendqueue test (%s)\n", \ + CU_get_error_msg()); \ } SENDQUEUE_TEST(suite, t_sendqueue1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h index 56f3c1e..694072b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c index d5dafc5..04a3d14 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -371,10 +371,10 @@ CU_pSuite t_init_uri_tests(void) return NULL; } -#define URI_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add uri parser test (%s)\n", \ - CU_get_error_msg()); \ +#define URI_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add uri parser test (%s)\n", \ + CU_get_error_msg()); \ } URI_TEST(suite, t_parse_uri1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h index 165fad3..ca96090 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c index 97584d8..843e249 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c @@ -3,7 +3,7 @@ * Copyright (C) 2013--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -296,7 +296,7 @@ int t_wkc_tests_create(void) } } -#endif +#endif return ctx == NULL || pdu == NULL; } @@ -319,10 +319,10 @@ CU_pSuite t_init_wellknown_tests(void) return NULL; } -#define WKC_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \ - CU_get_error_msg()); \ +#define WKC_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \ + CU_get_error_msg()); \ } WKC_TEST(suite, t_wellknown1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h index 47f20b3..8ba1d6d 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c index 1b78686..31ac600 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -22,15 +22,15 @@ #include "option.h" #include "uri.h" -/** +/** * A length-safe version of strchr(). This function returns a pointer * to the first occurrence of @p c in @p s, or @c NULL if not found. - * + * * @param s The string to search for @p c. * @param len The length of @p s. * @param c The character to search. - * - * @return A pointer to the first occurence of @p c, or @c NULL + * + * @return A pointer to the first occurence of @p c, or @c NULL * if not found. */ static inline unsigned char * @@ -125,7 +125,7 @@ int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri) { /* IPv4 address or FQDN */ while (len && *q != ':' && *q != '/' && *q != '?') { - // *q = tolower(*q); + *q = tolower(*q); ++q; --len; @@ -201,23 +201,23 @@ int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri) error: return res; } -/** +/** * Calculates decimal value from hexadecimal ASCII character given in * @p c. The caller must ensure that @p c actually represents a valid - * heaxdecimal character, e.g. with isxdigit(3). + * heaxdecimal character, e.g. with isxdigit(3). * * @hideinitializer */ #define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F)) -/** +/** * Decodes percent-encoded characters while copying the string @p seg * of size @p length to @p buf. The caller of this function must * ensure that the percent-encodings are correct (i.e. the character * '%' is always followed by two hex digits. and that @p buf provides * sufficient space to hold the result. This function is supposed to * be called by make_decoded_option() only. - * + * * @param seg The segment to decode and copy. * @param length Length of @p seg. * @param buf The result buffer. @@ -274,7 +274,7 @@ int check_segment(const unsigned char *s, size_t length) return n; } -/** +/** * Writes a coap option from given string @p s to @p buf. @p s should * point to a (percent-encoded) path or query segment of a coap_uri_t * object. The created option will have type @c 0, and the length @@ -282,12 +282,12 @@ int check_segment(const unsigned char *s, size_t length) * On success, this function returns the option's size, or a value * less than zero on error. This function must be called from * coap_split_path_impl() only. - * + * * @param s The string to decode. * @param length The size of the percent-encoded string @p s. * @param buf The buffer to store the new coap option. * @param buflen The maximum size of @p buf. - * + * * @return The option's size, or @c -1 on error. * * @bug This function does not split segments that are bigger than 270 @@ -336,14 +336,14 @@ int make_decoded_option(const unsigned char *s, size_t length, unsigned char *bu typedef void (*segment_handler_t)(unsigned char *, size_t, void *); -/** +/** * Splits the given string into segments. You should call one of the * macros coap_split_path() or coap_split_query() instead. - * + * * @param parse_iter The iterator used for tokenizing. * @param h A handler that is called with every token. * @param data Opaque data that is passed to @p h when called. - * + * * @return The number of characters that have been parsed from @p s. */ size_t coap_split_path_impl(coap_parse_iterator_t *parse_iter, segment_handler_t h, void *data) @@ -379,7 +379,7 @@ void write_option(unsigned char *s, size_t len, void *data) assert(state); /* skip empty segments and those that consist of only one or two dots */ - if (memcmp(s, "..", min(len,2)) == 0) + if (memcmp(s, "..", min(len, 2)) == 0) return; res = make_decoded_option(s, len, state->buf.s, state->buf.length); @@ -427,7 +427,7 @@ coap_new_uri(const unsigned char *uri, unsigned int length) { unsigned char *result; - result = coap_malloc(length + 1 + sizeof(coap_uri_t)); + result = (unsigned char *) coap_malloc(length + 1 + sizeof(coap_uri_t)); if (!result) return NULL; @@ -451,8 +451,8 @@ coap_clone_uri(const coap_uri_t *uri) if (!uri) return NULL; - result = (coap_uri_t *) coap_malloc( uri->query.length + uri->host.length + - uri->path.length + sizeof(coap_uri_t) + 1); + result = (coap_uri_t *) coap_malloc( + uri->query.length + uri->host.length + uri->path.length + sizeof(coap_uri_t) + 1); if (!result) return NULL; @@ -494,7 +494,7 @@ coap_clone_uri(const coap_uri_t *uri) * segment_handler_t hence we use this wrapper as safe typecast. */ static inline void hash_segment(unsigned char *s, size_t len, void *data) { - coap_hash(s, len, data); + coap_hash(s, len, (unsigned char *) data); } int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h index 20dd28e..820a045 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_URI_H_ @@ -19,7 +19,7 @@ typedef struct { str host; /**< host part of the URI */ unsigned short port; /**< The port in host byte order */ - str path; /**< Beginning of the first path segment. + str path; /**< Beginning of the first path segment. Use coap_split_path() to create Uri-Path options */ str query; /**< The query part if present */ } coap_uri_t; @@ -41,14 +41,14 @@ coap_uri_t *coap_new_uri(const unsigned char *uri, unsigned int length); * be released with coap_free(). */ coap_uri_t *coap_clone_uri(const coap_uri_t *uri); -/** - * Calculates a hash over the given path and stores the result in +/** + * Calculates a hash over the given path and stores the result in * @p key. This function returns @c 0 on error or @c 1 on success. - * + * * @param path The URI path to generate hash for. * @param len The length of @p path. * @param key The output buffer. - * + * * @return @c 1 if @p key was set, @c 0 otherwise. */ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); @@ -61,7 +61,7 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); * @{ */ -/** +/** * Iterator to for tokenizing a URI path or query. This structure must * be initialized with coap_parse_iterator_init(). Call * coap_parse_next() to walk through the tokens. @@ -86,43 +86,43 @@ typedef struct size_t segment_length; /**< length of current segment */ } coap_parse_iterator_t; -/** - * Initializes the given iterator @p pi. - * +/** + * Initializes the given iterator @p pi. + * * @param s The string to tokenize. * @param n The length of @p s. * @param separator The separator character that delimits tokens. * @param delim A set of characters that delimit @s. * @param dlen The length of @p delim. * @param pi The iterator object to initialize. - * + * * @return The initialized iterator object @p pi. */ coap_parse_iterator_t * coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char separator, unsigned char *delim, size_t dlen, coap_parse_iterator_t *pi); -/** +/** * Updates the iterator @p pi to point to the next token. This * function returns a pointer to that token or @c NULL if no more * tokens exist. The contents of @p pi will be updated. In particular, * @c pi->segment_length specifies the length of the current token, @c * pi->pos points to its beginning. - * + * * @param pi The iterator to update. - * + * * @return The next token or @c NULL if no more tokens exist. */ unsigned char *coap_parse_next(coap_parse_iterator_t *pi); -/** +/** * Parses a given string into URI components. The identified syntactic * components are stored in the result parameter @p uri. Optional URI * components that are not specified will be set to { 0, 0 }, except * for the port which is set to @c COAP_DEFAULT_PORT. This function * returns @p 0 if parsing succeeded, a value less than zero * otherwise. - * + * * @param str_var The string to split up. * @param len The actual length of @p str_var * @param uri The coap_uri_t object to store the result. @@ -134,32 +134,32 @@ unsigned char *coap_parse_next(coap_parse_iterator_t *pi); int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri); -/** +/** * Splits the given URI path into segments. Each segment is preceded * by an option pseudo-header with delta-value 0 and the actual length * of the respective segment after percent-decoding. - * - * @param s The path string to split. + * + * @param s The path string to split. * @param length The actual length of @p s. - * @param buf Result buffer for parsed segments. + * @param buf Result buffer for parsed segments. * @param buflen Maximum length of @p buf. Will be set to the actual number * of bytes written into buf on success. - * + * * @return The number of segments created or @c -1 on error. */ int coap_split_path(const unsigned char *s, size_t length, unsigned char *buf, size_t *buflen); -/** +/** * Splits the given URI query into segments. Each segment is preceded * by an option pseudo-header with delta-value 0 and the actual length * of the respective query term. - * - * @param s The query string to split. + * + * @param s The query string to split. * @param length The actual length of @p s. - * @param buf Result buffer for parsed segments. + * @param buf Result buffer for parsed segments. * @param buflen Maximum length of @p buf. Will be set to the actual number * of bytes written into buf on success. - * + * * @return The number of segments created or @c -1 on error. * * @bug This function does not reserve additional space for delta > 12. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h index 21e8141..be8f2bd 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h @@ -22,7 +22,7 @@ */ #ifndef UTHASH_H -#define UTHASH_H +#define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ @@ -48,7 +48,7 @@ do { char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ } while(0) -#else +#else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ @@ -121,9 +121,9 @@ do { HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else -#define HASH_BLOOM_MAKE(tbl) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif @@ -299,10 +299,10 @@ do { } \ } while (0) #else -#define HASH_FSCK(hh,head) +#define HASH_FSCK(hh,head) #endif -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS @@ -312,12 +312,12 @@ do { write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION +#ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN @@ -333,7 +333,7 @@ do { bkt = (hashv) & (num_bkts-1); \ } while (0) -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ @@ -484,14 +484,14 @@ do { /* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * So MurmurHash comes in two versions, the faster unaligned one and the slower - * aligned one. We only use the faster one on CPU's where we know it's safe. + * aligned one. We only use the faster one on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ -#if (defined(__i386__) || defined(__x86_64__)) +#if (defined(__i386__) || defined(__x86_64__)) #define HASH_MUR HASH_MUR_UNALIGNED #else #define HASH_MUR HASH_MUR_ALIGNED @@ -630,7 +630,7 @@ do { #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ @@ -671,36 +671,36 @@ do { } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ - } + } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * + * the hash function as it applies to the key domain). + * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain + * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. - * + * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate + * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write - * + * * ceil(n/b) = (n/b) + ((n%b)?1:0) - * + * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: - * + * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * + * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ @@ -751,7 +751,7 @@ do { } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. +/* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ @@ -833,10 +833,10 @@ do { } \ } while (0) -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ @@ -889,7 +889,7 @@ do { #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) #else #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ @@ -897,7 +897,7 @@ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); #endif /* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) typedef struct UT_hash_bucket @@ -907,7 +907,7 @@ typedef struct UT_hash_bucket /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). + * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. @@ -915,7 +915,7 @@ typedef struct UT_hash_bucket * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. + * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; @@ -942,7 +942,7 @@ typedef struct UT_hash_table * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; - /* ineffective expands occur when a bucket doubling was performed, but + /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h index 4073e04..a1c739c 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h @@ -26,7 +26,7 @@ #define UTLIST_VERSION 1.9.1 -/* +/* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. @@ -36,7 +36,7 @@ * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. - * + * * ----------------.EXAMPLE ------------------------- * struct item { * int id; @@ -83,7 +83,7 @@ #define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } -#else +#else #define _SV(elt,list) #define _NEXT(elt,list) ((elt)->next) #define _NEXTASGN(elt,list,to) ((elt)->next)=(to) @@ -369,14 +369,14 @@ do { LL_FOREACH(head,out) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define LL_SEARCH(head,out,elt,cmp) \ do { \ LL_FOREACH(head,out) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) /****************************************************************************** * doubly linked list macros (non-circular) * @@ -464,7 +464,7 @@ do { } while (0); #define CDL_FOREACH(head,el) \ - for(el=head;el;el=(el->next==head ? 0L : el->next)) + for(el=head;el;el=(el->next==head ? 0L : el->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ @@ -476,14 +476,14 @@ do { CDL_FOREACH(head,out) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define CDL_SEARCH(head,out,elt,cmp) \ do { \ CDL_FOREACH(head,out) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) #endif /* UTLIST_H */ diff --git a/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth.h b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth.h new file mode 100644 index 0000000..a6574c7 --- /dev/null +++ b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth.h @@ -0,0 +1,4474 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + + +#ifndef __TIZEN_NETWORK_BLUETOOTH_H__ +#define __TIZEN_NETWORK_BLUETOOTH_H__ + +#include +#include +#include +#include + +#include "bluetooth_type.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** + * @file bluetooth.h + * @brief API to control the Bluetooth adapter and devices and communications. + * @ingroup CAPI_NETWORK_BLUETOOTH_MODULE + */ + + +/** + * @addtogroup CAPI_NETWORK_BLUETOOTH_MODULE + * @{ + */ + + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_MODULE + * @brief Initializes the Bluetooth API. + * @since_tizen 2.3 + * + * @remarks This function must be called before Bluetooth API starts. \n + * You must free all resources of the Bluetooth service by calling bt_deinitialize() if Bluetooth service is no longer needed. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @see bt_deinitialize() + */ +int bt_initialize(void); + + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_MODULE + * @brief Releases all resources of the Bluetooth API. + * @since_tizen 2.3 + * + * @remarks This function must be called if Bluetooth API is no longer needed. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre Bluetooth API must be initialized with bt_initialize(). + * + * @see bt_initialize() + */ +int bt_deinitialize(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enables the local Bluetooth adapter, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function enables Bluetooth protocol stack and hardware. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_ALREADY_DONE Already enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre Bluetooth service must be initialized with bt_initialize(). + * @pre The state of local Bluetooth must be #BT_ADAPTER_DISABLED + * @post This function invokes bt_adapter_state_changed_cb(). + * + * @see bt_initialize() + * @see bt_adapter_get_state() + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb() + * @see bt_adapter_state_changed_cb() + * + */ +int bt_adapter_enable(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Disables the local Bluetooth adapter, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function disables Bluetooth protocol stack and hardware. + * + * @remarks You should disable Bluetooth adapter, which is helpful for saving power. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED + * @post This function invokes bt_adapter_state_changed_cb(). + * + * @see bt_adapter_get_state() + * @see bt_adapter_state_changed_cb() + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb () + * + */ +int bt_adapter_disable(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Recover the local Bluetooth adapter, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function does recovery logic, disables Bluetooth protocol stack and hardware, then enables after a few seconds. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED + * @post This function invokes bt_adapter_state_changed_cb(). + * + * @see bt_adapter_get_state() + * @see bt_adapter_state_changed_cb() + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb () + * + */ +int bt_adapter_recover(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Reset the local Bluetooth adapter, synchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function resets Bluetooth protocol and values. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_state_changed_cb() will be invoked if The state of local Bluetooth was #BT_ADAPTER_ENABLED. + * + * @see bt_initialize() + * @see bt_adapter_get_state() + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb() + * @see bt_adapter_state_changed_cb() + * + */ +int bt_adapter_reset(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the current state of local Bluetooth adapter. + * @since_tizen 2.3 + * + * @param[out] adapter_state The current adapter state + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + */ +int bt_adapter_get_state(bt_adapter_state_e *adapter_state); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the address of local Bluetooth adapter. + * @since_tizen 2.3 + * + * @remarks The @a local_address must be released with free() by you. + * + * @param[out] local_address The device address of local Bluetooth adapter + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_get_name() + */ +int bt_adapter_get_address(char **local_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the version of local Bluetooth adapter. + * @since_tizen 2.3 + * @remarks The @a local_version must be released with free() by you. + * + * @param[out] local_version The version of local Bluetooth adapter + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_adapter_get_version(char **local_version); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the information regarding local Bluetooth adapter. + * @since_tizen 2.3 + * @remarks The @a all parameters must be released with free() by you. + * + * @param[out] chipset Chipset name of local Bluetooth adapter + * @param[out] firmware Firmware info. of local Bluetooth adapter + * @param[out] stack_version Bluetooth stack version + * @param[out] profiles The profile list of local Bluetooth adapter + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_adapter_get_local_info(char **chipset, char **firmware, char **stack_version, char **profiles); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the name of local Bluetooth adapter. + * @since_tizen 2.3 + * + * @details Use this function to get the friendly name associated with Bluetooth + * device, retrieved by the remote Bluetooth devices. + * + * @remarks The @a local_name must be released with free() by you. + * + * @param[out] local_name The local device name + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_set_name() + */ +int bt_adapter_get_name(char **local_name); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the name of local Bluetooth adapter. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] local_name The name of the Bluetooth device. \n + * The maximum length is 248 characters. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post bt_adapter_name_changed_cb() will be invoked if this function returns #BT_ERROR_NONE. + * + * @see bt_adapter_get_name() + * @see bt_adapter_name_changed_cb() + * @see bt_adapter_set_name_changed_cb() + * @see bt_adapter_unset_name_changed_cb() + */ +int bt_adapter_set_name(const char *local_name); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the visibility mode of local Bluetooth adapter. + * @since_tizen 2.3 + * @param[out] mode The visibility mode of the Bluetooth device + * @param[out] duration The duration until the visibility mode is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE (in seconds). + * @a duration is valid only if @a mode is #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE. This value can be NULL. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_adapter_get_visibility(bt_adapter_visibility_mode_e *mode, int *duration); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the visibility mode. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE will change to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE + * after the given @a duration goes. + * + * @param[in] discoverable_mode The Bluetooth visibility mode to set + * @param[in] duration The duration until the visibility mode is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE (in seconds). + * @a duration is used only for #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE mode. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post bt_adapter_visibility_mode_changed_cb() will be invoked if this function returns #BT_ERROR_NONE. + * + * @see bt_adapter_get_visibility() + * @see bt_adapter_visibility_mode_changed_cb() + * @see bt_adapter_set_visibility_mode_changed_cb() + * @see bt_adapter_unset_visibility_mode_changed_cb() + */ +int bt_adapter_set_visibility(bt_adapter_visibility_mode_e discoverable_mode, int duration); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Starts the device discovery, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @details If a device is discovered, bt_adapter_device_discovery_state_changed_cb() will be invoked + * with #BT_ADAPTER_DEVICE_DISCOVERY_FOUND, and then bt_adapter_device_discovery_state_changed_cb() + * will be called with #BT_ADAPTER_DEVICE_DISCOVERY_FINISHED in case of the completion or cancellation of the discovery. + * + * @remarks To connect to peer Bluetooth device, you need to know its Bluetooth address. \n + * The device discovery can be stopped by bt_adapter_stop_device_discovery(). + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation is now in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post This function invokes bt_adapter_device_discovery_state_changed_cb(). + * + * @see bt_adapter_is_discovering() + * @see bt_adapter_stop_device_discovery() + * @see bt_adapter_device_discovery_state_changed_cb() + * @see bt_adapter_set_device_discovery_state_changed_cb() + * @see bt_adapter_unset_device_discovery_state_changed_cb() + */ +int bt_adapter_start_device_discovery(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Stops the device discovery, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks The device discovery process will take 10 ~ 20 seconds to get all the devices in vicinity. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOT_IN_PROGRESS Operation is not in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The device discovery must be in progress with bt_adapter_start_device_discovery(). + * @post This function invokes bt_adapter_device_discovery_state_changed_cb(). + * + * @see bt_adapter_is_discovering() + * @see bt_adapter_start_device_discovery() + * @see bt_adapter_set_device_discovery_state_changed_cb() + * @see bt_adapter_unset_device_discovery_state_changed_cb() + * @see bt_adapter_device_discovery_state_changed_cb() + */ +int bt_adapter_stop_device_discovery(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Checks for the device discovery is in progress or not. + * @since_tizen 2.3 + * + * @remarks If Bluetooth discovery is in progress, other operations are not allowed and + * you have to either stop the discovery operation, or wait for it to be finished, + * before performing other operations. + + * @param[out] is_discovering The discovering status: (@c true = in progress , @c false = not in progress ) + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_start_device_discovery() + * @see bt_adapter_stop_device_discovery() + */ +int bt_adapter_is_discovering(bool *is_discovering); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Get the service mask from the uuid list. + * @since_tizen 2.3 + * + * @param[in] uuids The UUID list of the device. + * @param[in] no_of_service The number of the UUID list count. + * @param[out] service_mask_list Service mask list converted from the given UUID list. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see bt_service_class_t + */ +int bt_device_get_service_mask_from_uuid_list(char **uuids, + int no_of_service, + bt_service_class_t *service_mask_list); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Retrieves the device information of all bonded devices. + * @since_tizen 2.3 + * + * @param [in] callback The callback function to invoke + * @param [in] user_data The user data passed from the foreach function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post This function invokes bt_adapter_bonded_device_cb(). + * + * @see bt_adapter_bonded_device_cb() + */ +int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the device information of a bonded device. + * @since_tizen 2.3 + * @remarks The @a device_info must be released with bt_adapter_free_device_info() by you . + * + * @param [in] remote_address The address of remote device + * @param [out] device_info The bonded device information + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post This function invokes bt_adapter_bonded_device_cb(). + * + * @see bt_adapter_bonded_device_cb() + */ +int bt_adapter_get_bonded_device_info(const char *remote_address, bt_device_info_s **device_info); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Frees device info. + * @since_tizen 2.3 + * + * @param [in] device_info The bonded device information + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see bt_adapter_get_bonded_device_info() + */ +int bt_adapter_free_device_info(bt_device_info_s *device_info); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Checks whether the UUID of service is used or not + * @since_tizen 2.3 + * @param[in] service_uuid The UUID of service + * @param[out] used Indicates whether the service is used or not + * @return true on success, otherwise false. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + */ +int bt_adapter_is_service_used(const char *service_uuid, bool *used); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked when the Bluetooth adapter state changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_state_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_state_changed_cb() + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb() + */ +int bt_adapter_set_state_changed_cb(bt_adapter_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_state_changed_cb() + */ +int bt_adapter_unset_state_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked when the name of Bluetooth adapter changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_name_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_name_changed_cb() + * @see bt_adapter_unset_name_changed_cb() + */ +int bt_adapter_set_name_changed_cb(bt_adapter_name_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_name_changed_cb() + */ +int bt_adapter_unset_name_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked when the visibility mode changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_visibility_mode_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_visibility_mode_changed_cb() + * @see bt_adapter_unset_visibility_mode_changed_cb() + */ +int bt_adapter_set_visibility_mode_changed_cb(bt_adapter_visibility_mode_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_visibility_mode_changed_cb() + */ +int bt_adapter_unset_visibility_mode_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked every second + * @since_tizen 2.3 + * until the visibility mode is changed from #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE + * to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE. + * @details When you set visibility mode as #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE, + * @a callback will be called every second until visibility mode is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE. + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @post bt_adapter_visibility_duration_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_adapter_visibility_duration_changed_cb() + * @see bt_adapter_unset_visibility_duration_changed_cb() + */ +int bt_adapter_set_visibility_duration_changed_cb(bt_adapter_visibility_duration_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_adapter_set_visibility_duration_changed_cb() + */ +int bt_adapter_unset_visibility_duration_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked when the device discovery state changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_device_discovery_state_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_device_discovery_state_changed_cb() + * @see bt_adapter_set_device_discovery_state_changed_cb() + * @see bt_adapter_unset_device_discovery_state_changed_cb() + */ +int bt_adapter_set_device_discovery_state_changed_cb(bt_adapter_device_discovery_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_device_discovery_state_changed_cb() + */ +int bt_adapter_unset_device_discovery_state_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Get the Hash and Randmoizer value, synchronously. + * @since_tizen 2.3 + * + * @param[out] hash The hash value recieved from the controller + * @param[out] randomizer The hash value recieved from the controller + * @param[out] hash_len The length of the hash value + * @param[out] randomizer_len The length of the randomizer value + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + */ +int bt_adapter_get_local_oob_data(unsigned char **hash, unsigned char **randomizer, + int *hash_len, int *randomizer_len); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the Hash and Randmoizer value, synchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] remote_address Remote device address + * @param[in] hash The hash value recieved from the controller + * @param[in] randomizer The hash value recieved from the controller + * @param[in] hash_len The length of the hash value. Allowed value is 16 + * @param[in] randomizer_len The length of the randomizer value. Allowed value is 16 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + */ +int bt_adapter_set_remote_oob_data(const char *remote_address, + unsigned char *hash, unsigned char *randomizer, + int hash_len, int randomizer_len); +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Deletes the Hash and Randomizer value, synchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] remote_address Remote device address + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + */ +int bt_adapter_remove_remote_oob_data(const char *remote_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked when the connectable state changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_connectable_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_connectable_changed_cb() + * @see bt_adapter_unset_connectable_changed_cb() + */ +int bt_adapter_set_connectable_changed_cb(bt_adapter_connectable_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_connectable_changed_cb() + */ +int bt_adapter_unset_connectable_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Gets the connectable state of local Bluetooth adapter. + * @since_tizen 2.3 + * + * @remarks When connectable state is false, no device can connect to this device and visibility mode cannot be changed. + * + * @param[out] connectable The connectable state of local Bluetooth adapter + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_set_connectable() + */ +int bt_adapter_get_connectable(bool *connectable); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the connectable state of local Bluetooth adapter. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks When connectable state is false, no device can connect to this device and visibility mode cannot be changed. + * + * @param[in] connectable The connectable state to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post bt_adapter_connectable_changed_cb() will be invoked if this function returns #BT_ERROR_NONE. + * + * @see bt_adapter_get_connectable() + * @see bt_adapter_connectable_changed_cb() + * @see bt_adapter_set_connectable_changed_cb() + * @see bt_adapter_unset_connectable_changed_cb() + */ +int bt_adapter_set_connectable(bool connectable); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enables the local Bluetooth le adapter, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function enables Bluetooth protocol stack and hardware. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_ALREADY_DONE Already enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre Bluetooth service must be initialized with bt_initialize(). + * @post This function invokes bt_adapter_le_state_changed_cb(). + * + * @see bt_initialize() + * @see bt_adapter_le_get_state() + * @see bt_adapter_le_set_state_changed_cb() + * @see bt_adapter_le_unset_state_changed_cb() + * @see bt_adapter_le_state_changed_cb() + * + */ +int bt_adapter_le_enable(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Disables the local Bluetooth le adapter, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @details This function disables Bluetooth le protocol stack and hardware. + * + * @remarks + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_LE_ENABLED + * @post This function invokes bt_adapter_le_state_changed_cb(). + * + * @see bt_adapter_le_get_state() + * @see bt_adapter_le_state_changed_cb() + * @see bt_adapter_le_set_state_changed_cb() + * @see bt_adapter_le_unset_state_changed_cb () + * + */ +int bt_adapter_le_disable(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Gets the current state of local Bluetooth adapter. + * @since_tizen 2.3 + * + * @param[out] adapter_le_state The current adapter le state + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + */ +int bt_adapter_le_get_state(bt_adapter_le_state_e *adapter_le_state); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Starts the LE device discovery for a BT_ADAPTER_DEVICE_DISCOVERY_LE type. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @details If a LE device is discovered, bt_adapter_le_device_discovery_state_changed_cb() +* will be invoked with #BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND, and then bt_adapter_le_device_discovery_state_changed_cb() + * will be called with #BT_ADAPTER_LE_DEVICE_DISCOVERY_FINISHED in case of the completion or cancellation of the discovery. + * + * @remarks To connect to peer Bluetooth device, you need to know its Bluetooth address. \n + * The device discovery can be stopped by bt_adapter_le_stop_device_discovery(). + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation is now in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * or must be #BT_ADAPTER_LE_ENABLED. + * @post This function invokes bt_adapter_le_device_discovery_state_changed_cb(). + * + * @see bt_adapter_le_is_discovering() + * @see bt_adapter_le_device_discovery_state_changed_cb() + * @see bt_adapter_le_set_device_discovery_state_changed_cb() + * @see bt_adapter_le_unset_device_discovery_state_changed_cb() + */ +int bt_adapter_le_start_device_discovery(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Stops the LE device discovery, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOT_IN_PROGRESS Operation is not in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The device discovery must be in progress with bt_adapter_le_start_device_discovery(). + * @post This function invokes bt_adapter_le_device_discovery_state_changed_cb(). + * + * @see bt_adapter_le_is_discovering() + * @see bt_adapter_le_start_device_discovery() + * @see bt_adapter_le_set_device_discovery_state_changed_cb() + * @see bt_adapter_le_unset_device_discovery_state_changed_cb() + * @see bt_adapter_le_device_discovery_state_changed_cb() + */ +int bt_adapter_le_stop_device_discovery(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Checks for the LE device discovery is in progress or not. + * @since_tizen 2.3 + * + * @remarks If Bluetooth LE discovery is in progress, other operations are not allowed and + * you have to either stop the LE discovery operation, or wait for it to be finished, + * before performing other operations. + + * @param[out] is_discovering The discovering status: (@c true = in progress , @c false = not in progress ) + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * or must be #BT_ADAPTER_LE_ENABLED. + * + * @see bt_adapter_le_start_device_discovery() + * @see bt_adapter_le_stop_device_discovery() + */ +int bt_adapter_le_is_discovering(bool *is_discovering); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Registers a callback function to be invoked when the LE device discovery state changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_le_device_discovery_state_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_le_device_discovery_state_changed_cb() + * @see bt_adapter_le_unset_device_discovery_state_changed_cb() + */ +int bt_adapter_le_set_device_discovery_state_changed_cb(bt_adapter_le_device_discovery_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_le_set_device_discovery_state_changed_cb() + */ +int bt_adapter_le_unset_device_discovery_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Registers a callback function to be invoked when the Bluetooth adapter le state changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_le_state_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_le_state_changed_cb() + * @see bt_adapter_le_unset_state_changed_cb() + */ +int bt_adapter_le_set_state_changed_cb(bt_adapter_le_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_le_set_state_changed_cb() + */ +int bt_adapter_le_unset_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief add address to whitelist for accepting scanning request. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks If the adress is in the whitelist then other LE devices are able to + * search this device. Before calling this API, make sure that the adapter is + * enabled. There is no callback event for this API. + + * @param[in] address The other device's address + * @param[in] address_type The other device's address type + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Adapter is not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_le_start_advertising() + * @see bt_adapter_le_stop_advertising() + */ +int bt_adapter_le_add_white_list(const char *address, bt_device_address_type_e address_type); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief remove address from the whitelist for not accepting scanning request. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks If the adress is in the whitelist then other LE devices are able to + * search this device. Before calling this API, make sure that the adapter is + * enabled. There is no callback event for this API. + * + * @param[in] address The other device's address + * @param[in] address_type The other device's address type + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Adapter is not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_le_start_advertising() + * @see bt_adapter_le_stop_advertising() + */ +int bt_adapter_le_remove_white_list(const char *address, bt_device_address_type_e address_type); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief clear address from the whitelist for not accepting scanning request. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks If the adress is in the whitelist then other LE devices are able to + * search this device. Before calling this API, make sure that the adapter is + * enabled. There is no callback event for this API. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Adapter is not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_adapter_le_start_advertising() + * @see bt_adapter_le_stop_advertising() + */ +int bt_adapter_le_clear_white_list(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Create advertiser to advertise device's existence or respond to LE scanning reqeust. + * @since_tizen 2.3 + * + * @param[out] advertiser The handle of advertiser + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_destroy_advertiser() + */ +int bt_adapter_le_create_advertiser(bt_advertiser_h *advertiser); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Destroy advertiser. + * @since_tizen 2.3 + * + * @param[out] advertiser The handle of advertiser + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_create_advertiser() + */ +int bt_adapter_le_destroy_advertiser(bt_advertiser_h advertiser); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Set the data to be advertised or responded to scan request from LE scanning device. + * The maximum advertised or responded data size is 31 bytes + * including data type and system wide data. + * @since_tizen 2.3 + * + * @param[in] advertiser The handle of advertiser + * @param[in] pkt_type The packet type + * @param[in] data_type The data type that is included in packet + * @param[in] data The data to be advertised or be responded to scan request from LE scanning device + * @param[in] data_size The size of data to be set. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_QUOTA_EXCEEDED Quota exceeded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_remove_advertising_data() + * @see bt_adapter_le_clear_advertising_data() + */ +int bt_adapter_le_add_advertising_data(bt_advertiser_h advertiser, + bt_adapter_le_packet_type_e pkt_type, bt_adapter_le_packet_data_type_e data_type, + void *data, unsigned int data_size); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Unset the data to be advertised or responded to scan request from LE scanning device. + * @since_tizen 2.3 + * + * @param[in] advertiser The handle of advertiser + * @param[in] pkt_type The packet type + * @param[in] data_type The data type to be removed from selected packet + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_add_advertising_data() + * @see bt_adapter_le_clear_advertising_data() + */ +int bt_adapter_le_remove_advertising_data(bt_advertiser_h advertiser, + bt_adapter_le_packet_type_e pkt_type, bt_adapter_le_packet_data_type_e data_type); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Clear all data to be advertised or responded to scan request from LE scanning device. + * @since_tizen 2.3 + * + * @param[in] advertiser The handle of advertiser + * @param[in] pkt_type The packet type to be cleared + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_adapter_le_add_advertising_data() + * @see bt_adapter_le_remove_advertising_data() + */ +int bt_adapter_le_clear_advertising_data(bt_advertiser_h advertiser, bt_adapter_le_packet_type_e pkt_type); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Start advertising with passed advertiser and advertising parameters. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @details Once Bluetooth advertising is started, nearby Bluetooth LE(Low Energy) supported + * devices can know this device's existence. And one of them can make a connection reqeust, + * if it is allowed. + * + * @param[in] advertiser The handle of advertiser + * @param[in] adv_params The parameters of advertising \n + * If NULL is passed, default values which are defined in driver / controller are used. + * @param[in] cb The callback to report the result of this function + * @param[in] user_data The user data to be passed when callback is called + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation is now in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post This function invokes bt_adapter_le_advertising_state_changed_cb(). + * + * @see bt_adapter_le_stop_advertising() + * @see bt_adapter_le_advertising_state_changed_cb() + */ +int bt_adapter_le_start_advertising(bt_advertiser_h advertiser, bt_adapter_le_advertising_params_s *adv_params, + bt_adapter_le_advertising_state_changed_cb cb, void *user_data); +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Stops the advertising. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] advertiser The handle of advertiser + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOT_IN_PROGRESS Operation is not in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The advertising must be going on with bt_adapter_le_start_advertising(). + * @post This function invokes bt_adapter_le_advertising_state_changed_cb(). + * + * @see bt_adapter_le_start_advertising() + * @see bt_adapter_le_advertising_state_changed_cb() + */ +int bt_adapter_le_stop_advertising(bt_advertiser_h advertiser); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the Privacy feature state of local Bluetooth adapter. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] enable_privacy The privacy feature to set/unset. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The state of local Bluetooth must be #BT_ADAPTER_LE_ENABLED. + * + */ +int bt_adapter_le_enable_privacy(bool enable_privacy); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Creates a bond with a remote Bluetooth device, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks A bond can be destroyed by bt_device_destroy_bond().\n + * The bonding request can be cancelled by bt_device_cancel_bonding(). + * + * @param[in] remote_address The address of the remote Bluetooth device with which the bond should be created + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The remote device must be discoverable with bt_adapter_start_device_discovery(). + * @post This function invokes bt_device_bond_created_cb(). + * + * @see bt_adapter_start_device_discovery() + * @see bt_device_bond_created_cb() + * @see bt_device_cancel_bonding() + * @see bt_device_destroy_bond() + * @see bt_device_set_bond_created_cb() + * @see bt_device_unset_bond_created_cb() + */ +int bt_device_create_bond(const char *remote_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Creates a bond with a remote Bluetooth device, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @remarks A bond can be destroyed by bt_device_destroy_bond().\n + * The bonding request can be cancelled by bt_device_cancel_bonding(). + * + * @param[in] remote_address The address of the remote Bluetooth device with which the bond should be created + * @param[in] conn_type The connection type(LE or BREDR) to create bond with remote device + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The remote device must be discoverable with bt_adapter_start_device_discovery(). + * @post This function invokes bt_device_bond_created_cb(). + * + * @see bt_adapter_start_device_discovery() + * @see bt_device_create_bond() + * @see bt_device_bond_created_cb() + * @see bt_device_cancel_bonding() + * @see bt_device_destroy_bond() + * @see bt_device_set_bond_created_cb() + * @see bt_device_unset_bond_created_cb() + */ +int bt_device_create_bond_by_type(const char *remote_address, + bt_device_connection_link_type_e conn_type); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Cancels the bonding process. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks Use this function when the remote Bluetooth device is not responding to the + * bond request or you wish to cancel the bonding request. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOT_IN_PROGRESS Operation not in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The creating a bond must be in progress by bt_device_create_bond(). + * + * @see bt_device_create_bond() + * @see bt_device_bond_created_cb() + * @see bt_device_set_bond_created_cb() + * @see bt_device_unset_bond_created_cb() + */ +int bt_device_cancel_bonding(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Destroys the bond, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] remote_address The address of the remote Bluetooth device to remove bonding + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The bond with the remote device must be created with bt_device_create_bond(). + * @post This function invokes bt_device_bond_destroyed_cb(). + * + * @see bt_device_create_bond() + * @see bt_device_bond_destroyed_cb() + * @see bt_device_set_bond_destroyed_cb() + * @see bt_device_unset_bond_destroyed_cb() + */ +int bt_device_destroy_bond(const char *remote_address); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Sets an alias for the bonded device. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] remote_address The address of the remote Bluetooth device + * @param[in] alias The alias of the remote Bluetooth device + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The bond with the remote device must be created with bt_device_create_bond(). + * + * @see bt_device_create_bond() + */ +int bt_device_set_alias(const char *remote_address, const char *alias); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Sets the authorization of a bonded device, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks Once a device is authorized, you don't need to receive a confirmation. + * + * @param[in] remote_address The address of the remote Bluetooth device to authorize + * @param[in] authorization_state The Bluetooth authorization state + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The bond with the remote device must be created with bt_device_create_bond(). + * @post bt_device_authorization_changed_cb() will be invoked. + * + * @see bt_device_create_bond() + * @see bt_device_authorization_changed_cb() + * @see bt_device_set_authorization_changed_cb() + * @see bt_device_unset_authorization_changed_cb() + */ +int bt_device_set_authorization(const char *remote_address, bt_device_authorization_e authorization_state); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Starts the search for services supported by the specified device, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks If creating a bond succeeds, which means bt_device_bond_created_cb() is called with result #BT_ERROR_NONE, + * then you don't need to run this function.\n + * The service search takes a couple of seconds to complete normally. \n + * The service search can be canceled by bt_device_cancel_service_search(). + * + * @param[in] remote_address The address of the remote Bluetooth device whose services need to be checked + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_SERVICE_SEARCH_FAILED Service search failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The remote device must be discoverable with bt_adapter_start_device_discovery(). + * @pre The bond with the remote device must be created with bt_device_create_bond(). + * @post This function invokes bt_device_service_searched_cb(). + * + * @see bt_adapter_start_device_discovery() + * @see bt_device_create_bond() + * @see bt_device_bond_created_cb() + * @see bt_device_service_searched_cb() + * @see bt_device_cancel_service_search() + * @see bt_device_set_service_searched_cb() + * @see bt_device_unset_service_searched_cb() + */ +int bt_device_start_service_search(const char *remote_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Cancels service search process. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_NOT_IN_PROGRESS Operation not in progress + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The service search must be in progress by bt_device_start_service_search(). + * + * @see bt_device_start_service_search() + * @see bt_device_service_searched_cb() + * @see bt_device_set_service_searched_cb() + * @see bt_device_unset_service_searched_cb() + */ +int bt_device_cancel_service_search(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Gets the connected profiles. + * @since_tizen 2.3 + * @param[in] remote_address The address of the remote device + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post bt_device_connected_profile() will be invoked. + * @see bt_device_connected_profile() + */ +int bt_device_foreach_connected_profiles(const char *remote_address, bt_device_connected_profile callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Gets the profile connected status. + * @since_tizen 2.3 + * @param[in] remote_address The address of the remote device + * @param[in] bt_profile wish to know bt_profile + * @param[out] connected_status the connected status + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_device_is_profile_connected(const char *remote_address, bt_profile_e bt_profile, + bool *connected_status); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Registers a callback function to be invoked when the bond creates. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_device_bond_created_cb() will be invoked. + * @see bt_initialize() + * @see bt_device_bond_created_cb() + * @see bt_device_unset_bond_created_cb() + */ +int bt_device_set_bond_created_cb(bt_device_bond_created_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_device_set_bond_created_cb() + */ +int bt_device_unset_bond_created_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Registers a callback function to be invoked when the bond destroys. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_device_bond_destroyed_cb() will be invoked. + * @see bt_initialize() + * @see bt_device_bond_destroyed_cb() + * @see bt_device_unset_bond_destroyed_cb() + */ +int bt_device_set_bond_destroyed_cb(bt_device_bond_destroyed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_device_set_bond_destroyed_cb() + */ +int bt_device_unset_bond_destroyed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Registers a callback function to be invoked when the authorization of device changes. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_device_authorization_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_device_authorization_changed_cb() + * @see bt_device_set_authorization_changed_cb() + * @see bt_device_unset_authorization_changed_cb() + */ +int bt_device_set_authorization_changed_cb(bt_device_authorization_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_device_set_authorization_changed_cb() + */ +int bt_device_unset_authorization_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Registers a callback function to be invoked when the process of service search finishes. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_device_service_searched_cb() will be invoked. + * @see bt_initialize() + * @see bt_device_service_searched_cb() + * @see bt_device_unset_service_searched_cb() + */ +int bt_device_set_service_searched_cb(bt_device_service_searched_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_device_set_service_searched_cb() + */ +int bt_device_unset_service_searched_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Registers a callback function to be invoked when the connection state is changed. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_device_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_device_connection_state_changed_cb() + * @see bt_device_unset_connection_state_changed_cb() + */ +int bt_device_set_connection_state_changed_cb(bt_device_connection_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unregisters the callback function to be invoked when the connection state is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_device_set_connection_state_changed_cb() + */ +int bt_device_unset_connection_state_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Registers a rfcomm server socket with a specific UUID. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks A socket can be destroyed by bt_socket_destroy_rfcomm(). + * + * @param[in] service_uuid The UUID of service to provide + * @param[out] socket_fd The file descriptor of socket to listen + * @return 0 on success, otherwise a negative error value. + * + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * + * @see bt_socket_listen_and_accept_rfcomm() + * @see bt_socket_destroy_rfcomm() + */ +int bt_socket_create_rfcomm(const char *service_uuid, int *socket_fd); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Removes the rfcomm server socket which was created using bt_socket_create_rfcomm(). + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks If callback function bt_socket_connection_state_changed_cb() is set and the remote Bluetooth device is connected, + * then bt_socket_connection_state_changed_cb() will be called when this function is finished successfully. + * + * @param[in] socket_fd The file descriptor of socket (which was created using bt_socket_create_rfcomm()) to destroy + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The socket must be created with bt_socket_create_rfcomm(). + * @post If callback function bt_socket_connection_state_changed_cb() is set and the remote Bluetooth device is connected, + * then bt_socket_connection_state_changed_cb() will be called. + * @see bt_socket_create_rfcomm() + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_destroy_rfcomm(int socket_fd); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Starts listening on passed rfcomm socket and accepts connection requests. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @details Pop-up is shown automatically when a RFCOMM connection is requested. + * bt_socket_connection_state_changed_cb() will be called with + * #BT_SOCKET_CONNECTED if you click "yes" and connection is finished successfully. + * @param[in] socket_fd The file descriptor of socket on which start to listen + * @param[in] max_pending_connections The maximum number of pending connections + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The socket must be created with bt_socket_create_rfcomm(). + * @post If callback function bt_socket_connection_state_changed_cb() is set, + * then bt_socket_connection_state_changed_cb() will be called when the remote Bluetooth device is connected. + * @see bt_socket_create_rfcomm() + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_listen_and_accept_rfcomm(int socket_fd, int max_pending_connections); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Starts listening on passed rfcomm socket. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @details bt_socket_connection_requested_cb() will be called when a RFCOMM connection is requested. + * + * @param[in] socket_fd The file descriptor socket on which start to listen + * @param[in] max_pending_connections The number of pending connections + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The socket must be created with bt_socket_create_rfcomm(). + * @post This function invokes bt_socket_connection_state_changed_cb(). + * + * @see bt_socket_create_rfcomm() + * @see bt_socket_set_connection_requested_cb() + * @see bt_socket_unset_connection_requested_cb() + * @see bt_socket_connection_requested_cb() + */ +int bt_socket_listen(int socket_fd, int max_pending_connections); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Accepts a connection request. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] requested_socket_fd The file descriptor of socket on which a connection is requested + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The connection is requested by bt_socket_connection_requested_cb(). + * @see bt_socket_create_rfcomm() + * @see bt_socket_connection_requested_cb() + * @see bt_socket_listen() + * @see bt_socket_reject() +*/ +int bt_socket_accept(int requested_socket_fd); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Rejects a connection request. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] socket_fd The file descriptor of socket on which a connection is requested + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The connection is requested by bt_socket_connection_requested_cb(). + * @see bt_socket_create_rfcomm() + * @see bt_socket_connection_requested_cb() + * @see bt_socket_listen() + * @see bt_socket_accept() + */ +int bt_socket_reject(int socket_fd); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Connects to a specific RFCOMM based service on a remote Bluetooth device UUID, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks A connection can be disconnected by bt_socket_disconnect_rfcomm(). + * + * @param[in] remote_address The address of the remote Bluetooth device + * @param[in] service_uuid The UUID of service provided by the remote Bluetooth device + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The remote device must be discoverable with bt_adapter_start_device_discovery(). + * @pre The bond with the remote device must be created with bt_device_create_bond(). + * @post This function invokes bt_socket_connection_state_changed_cb(). + * + * @see bt_device_create_bond() + * @see bt_adapter_start_device_discovery() + * @see bt_device_start_service_search() + * @see bt_socket_disconnect_rfcomm() + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_connect_rfcomm(const char *remote_address, const char *service_uuid); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Disconnects the RFCOMM connection with the given file descriptor of conneted socket. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] socket_fd The file descriptor of socket to close which was received using bt_socket_connection_state_changed_cb(). + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The connection must be established. + * + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_disconnect_rfcomm(int socket_fd); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Sends data to the connected device. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remark The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. + * + * @param[in] socket_fd The file descriptor of connected socket which was received using bt_socket_connection_state_changed_cb() + * @param[in] data The data to be sent + * @param[in] length The length of data to be sent + * + * @return the number of bytes written (zero indicates nothing was written). + * @retval On error, -1 is returned, and errno is set appropriately. See write 2 man page. + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @exception BT_ERROR_NOT_INITIALIZED Not initialized + * @exception BT_ERROR_PERMISSION_DENIED Permission denied + * @exception BT_ERROR_AGAIN Resource temporarily unavailable + * + * @pre The connection must be established. + * + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_send_data(int socket_fd, const char *data, int length); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Register a callback function that will be invoked when you receive data. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_socket_data_received_cb() will be invoked. + * @see bt_initialize() + * @see bt_socket_data_received_cb() + * @see bt_socket_set_data_received_cb() + * @see bt_socket_unset_data_received_cb() + */ +int bt_socket_set_data_received_cb(bt_socket_data_received_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_socket_data_received_cb() + * @see bt_socket_set_data_received_cb() + */ +int bt_socket_unset_data_received_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Register a callback function that will be invoked when a RFCOMM connection is requested. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post If you listen a socket by bt_socket_listen(), bt_socket_connection_requested_cb() will be invoked. + * @see bt_initialize() + * @see bt_socket_unset_connection_requested_cb() + */ +int bt_socket_set_connection_requested_cb(bt_socket_connection_requested_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_socket_set_connection_requested_cb() + * @see bt_socket_connection_requested_cb() + */ +int bt_socket_unset_connection_requested_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Register a callback function that will be invoked when the connection state changes. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_socket_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +int bt_socket_set_connection_state_changed_cb(bt_socket_connection_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_socket_connection_state_changed_cb() + * @see bt_socket_set_connection_state_changed_cb() + */ +int bt_socket_unset_connection_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Initializes the Bluetooth OPP server requested by bt_opp_server_push_requested_cb(). + * @since_tizen 2.3 + * @details The popup appears when an OPP connection is requested from a remote device. + * If you accept the request, then connection will be established and bt_opp_server_push_requested_cb() will be called. + * At that time, you can call either bt_opp_server_accept() or bt_opp_server_reject(). + * @remarks This function must be called to start Bluetooth OPP server. You must free all resources of the Bluetooth service + * by calling bt_opp_server_deinitialize() if Bluetooth OPP service is no longer needed. + * @param[in] destination The destination path + * @param[in] push_requested_cb The callback called when a push is requested + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_server_push_requested_cb() + * @see bt_opp_server_deinitialize() + * @see bt_opp_server_accept() + * @see bt_opp_server_reject() + */ +int bt_opp_server_initialize(const char *destination, bt_opp_server_push_requested_cb push_requested_cb, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Initializes the Bluetooth OPP server requested by bt_opp_server_connection_requested_cb(). + * @since_tizen 2.3 + * @details No popup appears when an OPP connection is requested from a remote device. + * Instead, @a connection_requested_cb() will be called. + * At that time, you can call either bt_opp_server_accept() or bt_opp_server_reject(). + * @remarks This function must be called to start Bluetooth OPP server. \n + * You must free all resources of the Bluetooth service by calling bt_opp_server_deinitialize() if Bluetooth OPP service is no longer needed. + * @param[in] destination The destination path + * @param[in] connection_requested_cb The callback called when an OPP connection is requested + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_server_connection_requested_cb() + * @see bt_opp_server_deinitialize() + * @see bt_opp_server_accept_connection() + * @see bt_opp_server_reject_connection() + */ +int bt_opp_server_initialize_by_connection_request(const char *destination, bt_opp_server_connection_requested_cb connection_requested_cb, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Denitializes the Bluetooth OPP server. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_server_initialize() + * @see bt_opp_server_deinitialize() + */ +int bt_opp_server_deinitialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Accepts the push request from the remote device. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks If you initialize OPP server by bt_opp_server_initialize_by_connection_request(), then name is ignored. + * You can cancel the pushes by bt_opp_server_cancel_transfer() with transfer_id. + * @param[in] progress_cb The callback called when a file is being transfered + * @param[in] finished_cb The callback called when a transfer is finished + * @param[in] name The name to store. This can be NULL if you initialize OPP server by bt_opp_server_initialize_by_connection_request(). + * @param[in] user_data The user data to be passed to the callback function + * @param[out] transfer_id The ID of transfer + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_server_reject() + */ +int bt_opp_server_accept(bt_opp_server_transfer_progress_cb progress_cb, bt_opp_server_transfer_finished_cb finished_cb, const char *name, + void *user_data, int *transfer_id); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Rejects the push request from the remote device. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_server_accept() + */ +int bt_opp_server_reject(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Cancels the transfer. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] transfer_id The ID of transfer + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_server_accept_connection() + * @see bt_opp_server_accept() + */ +int bt_opp_server_cancel_transfer(int transfer_id); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Sets the destination path of file to be pushed. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] destination The destination path of file to be pushed + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_server_initialize() + */ +int bt_opp_server_set_destination(const char *destination); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Initializes the Bluetooth OPP client. + * @since_tizen 2.3 + * @remarks This function must be called before Bluetooth OPP client starts. \n + * You must free all resources of the Bluetooth service by calling bt_opp_client_deinitialize() + * if Bluetooth OPP service is no longer needed. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_client_deinitialize() + */ +int bt_opp_client_initialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Denitializes the Bluetooth OPP client. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_client_initialize() + */ +int bt_opp_client_deinitialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Adds file to be pushed. + * @since_tizen 2.3 + * @param[in] file The path of file to be pushed + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_client_clear_files() + * @see bt_opp_client_push_files() + */ +int bt_opp_client_add_file(const char *file); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Adds file to be pushed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @see bt_opp_client_add_file() + * @see bt_opp_client_push_files() + */ +int bt_opp_client_clear_files(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Pushes the file to the remote device, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @details At first, bt_opp_client_push_responded_cb() will be called when OPP server responds to the push request. + * After connection is established, bt_opp_client_push_progress_cb() will be called repeatedly until a file is tranfered completely. + * If you send several files, then bt_opp_client_push_progress_cb() with another file will be called repeatedly until the file is tranfered completely. + * bt_opp_client_push_finished_cb() will be called when the push request is finished. + * @param[in] remote_address The remote address + * @param[in] responded_cb The callback called when OPP server responds to the push request + * @param[in] progress_cb The callback called when each file is being transfered + * @param[in] finished_cb The callback called when the push request is finished + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_NOW_IN_PROGRESS Operation now in progress + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_opp_client_initialize() + * @see bt_opp_client_cancel_push + */ +int bt_opp_client_push_files(const char *remote_address, bt_opp_client_push_responded_cb responded_cb, + bt_opp_client_push_progress_cb progress_cb, bt_opp_client_push_finished_cb finished_cb, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Cancels the push request in progress, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre bt_opp_client_push_files() must be called. + * @post bt_opp_client_push_finished_cb() will be invoked with result #BT_ERROR_CANCELLED, + * which is a parameter of bt_opp_client_push_files(). + * @see bt_opp_client_initialize() + * @see bt_opp_client_push_files() + */ +int bt_opp_client_cancel_push(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HID_MODULE + * @brief Initializes the Bluetooth HID(Human Interface Device) Host. + * @since_tizen 2.3 + * @remarks This function must be called before Bluetooth HID Host starts. \n + * You must free all resources of the Bluetooth service by calling bt_hid_host_deinitialize() + * if Bluetooth HID Host service is no longer needed. + * @param[in] connection_cb The callback called when the connection state is changed + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_hid_host_deinitialize() + */ +int bt_hid_host_initialize(bt_hid_host_connection_state_changed_cb connection_cb, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HID_MODULE + * @brief Deinitializes the Bluetooth HID(Human Interface Device) Host. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The Bluetooth HID service must be initialized with bt_hid_host_initialize(). + * @see bt_hid_host_initialize() + */ +int bt_hid_host_deinitialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HID_MODULE + * @brief Connects the remote device with the HID(Human Interface Device) service, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] remote_address The remote address + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The local device must be bonded with the remote device by bt_device_create_bond(). + * @pre The Bluetooth HID service must be initialized with bt_hid_host_initialize(). + * @post bt_hid_host_connection_state_changed_cb() will be invoked. + * @see bt_hid_host_disconnect() + * @see bt_hid_host_connection_state_changed_cb() + */ +int bt_hid_host_connect(const char *remote_address); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HID_MODULE + * @brief Disconnects the remote device with the HID(Human Interface Device) service, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] remote_address The remote address + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected by bt_hid_host_connect(). + * @post bt_hid_host_connection_state_changed_cb() will be invoked. + * @see bt_hid_host_connect() + * @see bt_hid_host_connection_state_changed_cb() + */ +int bt_hid_host_disconnect(const char *remote_address); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Initializes the Bluetooth profiles related with audio. + * @since_tizen 2.3 + * @remarks This function must be called before Bluetooth profiles related with audio starts. \n + * You must free all resources of the this service by calling bt_audio_deinitialize() + * if Bluetooth profiles related with audio service is no longer needed. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_audio_deinitialize() + */ +int bt_audio_initialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Deinitializes the Bluetooth profiles related with audio. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + */ +int bt_audio_deinitialize(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Connects the remote device with the given audio profile, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @details If you input type as #BT_AUDIO_PROFILE_TYPE_ALL and connection request succeeds, then bt_audio_connection_state_changed_cb() will be called twice + * when #BT_AUDIO_PROFILE_TYPE_HSP_HFP is connected and #BT_AUDIO_PROFILE_TYPE_A2DP is connected. + * @param[in] remote_address The remote address + * @param[in] type The type of audio profile + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @pre The local device must be bonded with the remote device by bt_device_create_bond(). + * @post bt_audio_connection_state_changed_cb() will be invoked. + * @see bt_audio_disconnect() + * @see bt_audio_connection_state_changed_cb() + */ +int bt_audio_connect(const char *remote_address, bt_audio_profile_type_e type); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Disconnects the remote device with the given audio profile, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @details If you input type as #BT_AUDIO_PROFILE_TYPE_ALL and disconnection request succeeds, then bt_audio_connection_state_changed_cb() will be called twice + * when #BT_AUDIO_PROFILE_TYPE_HSP_HFP is disconnected and #BT_AUDIO_PROFILE_TYPE_A2DP is disconnected. + * @param[in] remote_address The remote address + * @param[in] type The type of audio profile + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The remote device must be connected by bt_audio_connect(). + * @post bt_audio_connection_state_changed_cb() will be invoked. + * @see bt_audio_connect() + * @see bt_audio_connection_state_changed_cb() + */ +int bt_audio_disconnect(const char *remote_address, bt_audio_profile_type_e type); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Registers a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_audio_connection_state_changed_cb() + * @see bt_panu_unset_connection_state_changed_cb() + */ +int bt_audio_set_connection_state_changed_cb(bt_audio_connection_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Unregisters a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_audio_connection_state_changed_cb() + * @see bt_audio_set_connection_state_changed_cb() + */ +int bt_audio_unset_connection_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Opens a SCO(Synchronous Connection Oriented link) to connected remote device, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_ALREADY_DONE Operation is already done + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio device must be connected with bt_audio_connect(). + * @post bt_ag_sco_state_changed_cb() will be invoked. + * @see bt_ag_close_sco() + * @see bt_ag_sco_state_changed_cb() + * @see bt_audio_connect() + */ +int bt_ag_open_sco(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Closes an opened SCO(Synchronous Connection Oriented link), asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The SCO must be opened with bt_ag_open_sco(). + * @post bt_ag_sco_state_changed_cb() will be invoked. + * @see bt_ag_open_sco() + * @see bt_ag_sco_state_changed_cb() + */ +int bt_ag_close_sco(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Checks whether an opened SCO(Synchronous Connection Oriented link) exists or not. + * @since_tizen 2.3 + * @param[out] opened The SCO status: (@c true = opened, @c false = not opened) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_ag_open_sco() + * @see bt_ag_close_sco() + */ +int bt_ag_is_sco_opened(bool *opened); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when the SCO(Synchronous Connection Oriented link) state is changed. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_sco_state_changed_cb() + * @see bt_ag_unset_sco_state_changed_cb() + */ +int bt_ag_set_sco_state_changed_cb(bt_ag_sco_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when the SCO(Synchronous Connection Oriented link) state is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_sco_state_changed_cb() + * @see bt_ag_set_sco_state_changed_cb() + */ +int bt_ag_unset_sco_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Notifies the call event to the remote bluetooth device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @remarks Before notifying #BT_AG_CALL_EVENT_ANSWERED or #BT_AG_CALL_EVENT_DIALING, you should open SCO(Synchronous Connection Oriented link) + * if Bluetooth Hands-Free need SCO connection. + * @param[in] event The call event + * @param[in] call_id The call ID + * @param[in] phone_number The phone number. You must set this value in case of #BT_AG_CALL_EVENT_DIALING and #BT_AG_CALL_EVENT_INCOMING. + * In other cases, this value can be NULL. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio device must be connected with bt_audio_connect(). + * @see bt_audio_connect() + */ +int bt_ag_notify_call_event(bt_ag_call_event_e event, unsigned int call_id, const char *phone_number); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Notifies the call list to the remote bluetooth device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] list The call list + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio device must be connected with bt_audio_connect(). + * @see bt_audio_connect() + */ +int bt_ag_notify_call_list(bt_call_list_h list); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Notifies the state of voice recognition. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] state The state of voice recognition: (@c true = enabled, @c false = disabled) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio device must be connected with bt_audio_connect(). + * @see bt_audio_connect() + */ +int bt_ag_notify_voice_recognition_state(bool state); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when a call handling event happened from Hands-Free. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_call_handling_event_cb() + * @see bt_ag_unset_call_handling_event_cb() + */ +int bt_ag_set_call_handling_event_cb(bt_ag_call_handling_event_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when a call handling event happened from Hands-Free. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_call_handling_event_cb() + * @see bt_ag_set_call_handling_event_cb() + */ +int bt_ag_unset_call_handling_event_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when a multi call handling event happened from Hands-Free. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_multi_call_handling_event_cb() + * @see bt_ag_unset_multi_call_handling_event_cb() + */ +int bt_ag_set_multi_call_handling_event_cb(bt_ag_multi_call_handling_event_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when a multi call handling event happened from Hands-Free. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_multi_call_handling_event_cb() + * @see bt_ag_set_multi_call_handling_event_cb() + */ +int bt_ag_unset_multi_call_handling_event_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when a DTMF(Dual Tone Multi Frequency) is transmitted from Hands-Free. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_dtmf_transmitted_cb() + * @see bt_ag_unset_dtmf_transmitted_cb() + */ +int bt_ag_set_dtmf_transmitted_cb(bt_ag_dtmf_transmitted_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when a DTMF(Dual Tone Multi Frequency) is transmitted from Hands-Free. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_dtmf_transmitted_cb() + * @see bt_ag_set_dtmf_transmitted_cb() + */ +int bt_ag_unset_dtmf_transmitted_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Notifies the speaker gain to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @details This function sends a signal to the remote device. This signal has the gain value. + * @a gain is represented on a scale from 0 to 15. This value is absolute value relating to a particular volume level. + * When the speaker gain of remote device is changed to the requested gain, bt_audio_speaker_gain_changed_cb() will be called. + * @param[in] gain The gain of speaker (0 ~ 15) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The remote device is connected by bt_audio_connect() with #BT_AUDIO_PROFILE_TYPE_HSP_HFP service. + * @see bt_ag_get_speaker_gain() + * @see bt_ag_set_speaker_gain_changed_cb() + * @see bt_ag_unset_speaker_gain_changed_cb() + */ +int bt_ag_notify_speaker_gain(int gain); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Gets the current speaker gain of the remote device. + * @since_tizen 2.3 + * @details This function gets the value of speaker gain of the remote device. + * @a gain is represented on a scale from 0 to 15. This value is absolute value relating to a particular volume level. + * @param[out] gain The gain of speaker (0 ~ 15) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The remote device is connected by bt_audio_connect() with #BT_AUDIO_PROFILE_TYPE_HSP_HFP service. + * @see bt_ag_notify_speaker_gain() + * @see bt_ag_set_speaker_gain_changed_cb() + * @see bt_ag_unset_speaker_gain_changed_cb() + */ +int bt_ag_get_speaker_gain(int *gain); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Checks whether the remoted device enables NREC(Noise Reduction and Echo Canceling) or not. + * @since_tizen 2.3 + * @param[out] enabled The NREC status: (@c true = enabled, @c false = not enabled) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The remote device is connected by bt_audio_connect() with #BT_AUDIO_PROFILE_TYPE_HSP_HFP service. + * @see bt_audio_connect() + */ +int bt_ag_is_nrec_enabled(bool *enabled); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when the speaker gain of the remote device is changed. + * @since_tizen 2.3 + * @details This function let you know the change of the speaker gain of the remote device. + * @a gain is represented on a scale from 0 to 15. This value is absolute value relating to a particular volume level. + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_unset_speaker_gain_changed_cb() + */ +int bt_ag_set_speaker_gain_changed_cb(bt_ag_speaker_gain_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when the speaker gain of the remote device is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_set_speaker_gain_changed_cb() + */ +int bt_ag_unset_speaker_gain_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when the microphone gain of the remote device is changed. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_unset_microphone_gain_changed_cb() + */ +int bt_ag_set_microphone_gain_changed_cb(bt_ag_microphone_gain_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when the microphone gain of the remote device is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_SUPPORTED Not supported + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_set_microphone_gain_changed_cb() + */ +int bt_ag_unset_microphone_gain_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_CALL_MODULE + * @brief Creates a handle of call list. + * @since_tizen 2.3 + * @param[out] list The handle of call list + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_call_list_destroy() + */ +int bt_call_list_create(bt_call_list_h *list); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_CALL_MODULE + * @brief Destroys the handle of call list. + * @since_tizen 2.3 + * @param[in] list The handle of call list + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @see bt_call_list_create() + */ +int bt_call_list_destroy(bt_call_list_h list); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_CALL_MODULE + * @brief Resets the handle of call list. + * @since_tizen 2.3 + * @param[in] list The handle of call list + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @see bt_call_list_create() + */ +int bt_call_list_reset(bt_call_list_h list); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_CALL_MODULE + * @brief Adds a call to the handle of call list. + * @since_tizen 2.3 + * @param[in] list The handle of call list + * @param[in] call_id The call ID + * @param[in] state The state of audio gate call + * @param[in] phone_number The phone number. You must set this value in case of #BT_AG_CALL_EVENT_DIALING and #BT_AG_CALL_EVENT_INCOMING. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @see bt_call_list_create() + */ +int bt_call_list_add(bt_call_list_h list, unsigned int call_id, bt_ag_call_state_e state, const char *phone_number); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Initializes the Bluetooth AVRCP(Audio/Video Remote Control Profile) service. + * @since_tizen 2.3 + * @remarks This function must be called before Bluetooth AVRCP service. \n + * You must free all resources of the this service by calling bt_avrcp_target_deinitialize() + * if Bluetooth AVRCP service is no longer needed. + * @param[in] callback The callback function called when the connection state is changed + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_target_deinitialize() + */ +int bt_avrcp_target_initialize(bt_avrcp_target_connection_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Deinitializes the Bluetooth AVRCP(Audio/Video Remote Control Profile) service. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth audio service must be initialized with bt_avrcp_target_initialize(). + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_deinitialize(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the equalize state to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] state The state of equalizer + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_equalizer_state(bt_avrcp_equalizer_state_e state); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the repeat mode to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] mode The repeat mode + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_repeat_mode(bt_avrcp_repeat_mode_e mode); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the shuffle mode to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] mode The repeat mode + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_shuffle_mode(bt_avrcp_shuffle_mode_e mode); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the scan mode to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] mode The scan mode + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_scan_mode(bt_avrcp_scan_mode_e mode); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the player state to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] state The player state + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_player_state(bt_avrcp_player_state_e state); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the current position of song to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] position The current position in milliseconds + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_position(unsigned int position); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Notifies the track to the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] title The title of track + * @param[in] artist The artist of track + * @param[in] album The album of track + * @param[in] genre The genre of track + * @param[in] track_num The track number + * @param[in] total_tracks The number of all tracks + * @param[in] duration The duration of track in milliseconds + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_avrcp_target_connection_state_changed_cb() + * @see bt_avrcp_target_initialize() + */ +int bt_avrcp_target_notify_track(const char *title, const char *artist, const char *album, const char *genre, unsigned int track_num, unsigned int total_tracks, unsigned int duration); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Registers a callback function that will be invoked when the equalizer state is changed by the remote control device. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_unset_equalizer_state_changed_cb() + */ +int bt_avrcp_set_equalizer_state_changed_cb(bt_avrcp_equalizer_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Unregisters a callback function that will be invoked when the equalizer state is changed by the remote control device. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_set_equalizer_state_changed_cb() + */ +int bt_avrcp_unset_equalizer_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Registers a callback function that will be invoked when the repeat mode is changed by the remote control device. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_unset_repeat_mode_changed_cb() + */ +int bt_avrcp_set_repeat_mode_changed_cb(bt_avrcp_repeat_mode_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Unregisters a callback function that will be invoked when the repeat mode is changed by the remote control device. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_set_repeat_mode_changed_cb() + */ +int bt_avrcp_unset_repeat_mode_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Registers a callback function that will be invoked when the shuffle mode is changed by the remote control device. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_unset_shuffle_mode_changed_cb() + */ +int bt_avrcp_set_shuffle_mode_changed_cb(bt_avrcp_shuffle_mode_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Unregisters a callback function that will be invoked when the shuffle mode is changed by the remote control device. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_set_shuffle_mode_changed_cb() + */ +int bt_avrcp_unset_shuffle_mode_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Registers a callback function that will be invoked when the scan mode is changed by the remote control device. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_unset_scan_mode_changed_cb() + */ +int bt_avrcp_set_scan_mode_changed_cb(bt_avrcp_scan_mode_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Unregisters a callback function that will be invoked when the scan mode is changed by the remote control device. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @see bt_initialize() + * @see bt_avrcp_set_scan_mode_changed_cb() + */ +int bt_avrcp_unset_scan_mode_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Registers an application that acts as the @a Sink role of HDP(Health Device Profile). + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks The @a app_id must be released with free() by you. + * @param[in] data_type The data type of MDEP. This value is defined in ISO/IEEE 11073-20601 spec. + * For example, pulse oximeter is 0x1004 and blood pressure monitor is 0x1007. + * @param[out] app_id The ID of application + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_hdp_deactivate_sink() + */ +int bt_hdp_register_sink_app(unsigned short data_type, char **app_id); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Unregisters the given application that acts as the @a Sink role of HDP(Health Device Profile). + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] app_id The ID of application + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @see bt_hdp_register_sink_app() + */ +int bt_hdp_unregister_sink_app(const char *app_id); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Connects the remote device which acts as @a Source role, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] remote_address The remote address + * @param[in] app_id The ID of application + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Sink role of HDP must be registered with bt_hdp_register_sink_app(). + * @pre The local device must be bonded with the remote device by bt_device_create_bond(). + * @post bt_hdp_connected_cb() will be invoked. + * @see bt_hdp_disconnect() + * @see bt_hdp_set_connection_state_changed_cb() + * @see bt_hdp_unset_connection_state_changed_cb() + */ +int bt_hdp_connect_to_source(const char *remote_address, const char *app_id); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Disconnects the remote device, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] remote_address The remote address + * @param[in] channel The connected data channel + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @post bt_hdp_disconnected_cb() will be invoked. + * @see bt_hdp_set_connection_state_changed_cb() + * @see bt_hdp_unset_connection_state_changed_cb() + */ +int bt_hdp_disconnect(const char *remote_address, unsigned int channel); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Sends the data to the remote device. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] channel The connected data channel + * @param[in] data The data to send + * @param[in] size The size of data to send (byte) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected. + * @see bt_hdp_data_received_cb() + * @see bt_hdp_set_data_received_cb() + * @see bt_hdp_unset_data_received_cb() + */ +int bt_hdp_send_data(unsigned int channel, const char *data, unsigned int size); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Registers a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * @param[in] connected_cb The callback function called when a connection is established + * @param[in] disconnected_cb The callback function called when a connection is disconnected + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_hdp_unset_connection_state_changed_cb() + */ +int bt_hdp_set_connection_state_changed_cb(bt_hdp_connected_cb connected_cb, bt_hdp_disconnected_cb disconnected_cb, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Unregisters a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_hdp_set_connection_state_changed_cb() + */ +int bt_hdp_unset_connection_state_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Registers a callback function that will be invoked when you receive the data. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_hdp_unset_data_received_cb() + */ +int bt_hdp_set_data_received_cb(bt_hdp_data_received_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Unregisters a callback function that will be invoked when you receive the data. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_hdp_set_data_received_cb() + */ +int bt_hdp_unset_data_received_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Gets the primary services of GATT(Generic Attribute Profile). + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] remote_address The address of the remote device + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post @a callback will be called if there are primary services. + * @see bt_gatt_primary_service_cb() + */ +int bt_gatt_foreach_primary_services(const char *remote_address, bt_gatt_primary_service_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Discovers the characteristics in service, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] service The attribute handle of service + * @param[in] callback The result callback + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post @a callback will be called. + * @see bt_gatt_characteristics_discovered_cb() + */ +int bt_gatt_discover_characteristics(bt_gatt_attribute_h service, bt_gatt_characteristics_discovered_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Gets the UUID of service. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks @a uuid must be released with free() by you. + * @param[in] service The attribute handle of service + * @param[out] uuid The UUID of service + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + */ +int bt_gatt_get_service_uuid(bt_gatt_attribute_h service, char **uuid); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Gets the included services in service. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] service The attribute handle of service + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post @a callback will be called if there are included services. + * @see bt_gatt_included_service_cb() + */ +int bt_gatt_foreach_included_services(bt_gatt_attribute_h service, bt_gatt_included_service_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Registers a callback function that will be invoked when a characteristic value is changed. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_gatt_unset_characteristic_changed_cb() + */ +int bt_gatt_set_characteristic_changed_cb(bt_gatt_characteristic_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Unregisters a callback function that will be invoked when a characteristic is changed. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_gatt_set_characteristic_changed_cb() + */ +int bt_gatt_unset_characteristic_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Watches all the characteristic value changes of the service + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] service The attribute handle of service + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_gatt_unset_characteristic_changed_cb() + */ +int bt_gatt_watch_characteristic_changes(bt_gatt_attribute_h service); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Remove watching of all the characteristic value changes of the service + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] service The attribute handle of service + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_gatt_set_characteristic_changed_cb() + */ +int bt_gatt_unwatch_characteristic_changes(bt_gatt_attribute_h service); + + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Gets the characteristic declaration. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @remarks @a uuid and @a value must be released with free() by you. + * @param[in] characteristic The attribute handle of characteristic + * @param[out] uuid The UUID of service + * @param[out] value The value of characteristic (byte array) + * @param[out] value_length The length of value + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_gatt_set_characteristic_value() + */ +int bt_gatt_get_characteristic_declaration(bt_gatt_attribute_h characteristic, char **uuid, unsigned char **value, int *value_length); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Sets the value of characteristic. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] characteristic The attribute handle of characteristic + * @param[in] value The value of characteristic (byte array) + * @param[in] value_length The length of value + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_gatt_get_characteristic_declaration() + */ +int bt_gatt_set_characteristic_value(bt_gatt_attribute_h characteristic, const unsigned char *value, int value_length); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Sets the value of characteristic request. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] characteristic The attribute handle of characteristic + * @param[in] value The value of characteristic (byte array) + * @param[in] value_length The length of value + * @param[in] callback The result callback + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_gatt_get_characteristic_declaration() + */ +int bt_gatt_set_characteristic_value_request(bt_gatt_attribute_h characteristic, const unsigned char *value, + int value_length, bt_gatt_characteristic_write_cb callback); + +/** +* @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE +* @brief Clones the attribute handle. +* @since_tizen 2.3 +* @remarks @a clone must be released with bt_gatt_destroy_attribute_handle(). +* @param[out] clone The cloned attribute handle +* @param[in] origin The origin attribute handle +* @return 0 on success, otherwise negative error value. +* @retval #BT_ERROR_NONE Successful +* @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter +* @retval #BT_ERROR_OUT_OF_MEMORY Out of memory +* @see bt_gatt_destroy_attribute_handle() +*/ +int bt_gatt_clone_attribute_handle(bt_gatt_attribute_h* clone, bt_gatt_attribute_h origin); + +/** +* @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE +* @brief Destroys the attribute handle. +* @since_tizen 2.3 +* @param[in] handle The attribute handle +* @return 0 on success, otherwise negative error value. +* @retval #BT_ERROR_NONE Successful +* @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter +* @see bt_gatt_clone_attribute_handle() +*/ +int bt_gatt_destroy_attribute_handle(bt_gatt_attribute_h handle); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Reads the value of characteristic from remote device + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] char_handle The attribute handle of characteristic + * @param[in] callback The result callback + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_gatt_get_characteristic_declaration() + */ +int bt_gatt_read_characteristic_value(bt_gatt_attribute_h char_handle, + bt_gatt_characteristic_read_cb callback); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Discovers the characteristic descriptors of a characteristic within its definition, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] characteristic_handle The attribute handle of characteristic + * @param[in] callback The result callback + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post @a callback will be called. + * @see bt_gatt_characteristic_descriptor_discovered_cb() + */ +int bt_gatt_discover_characteristic_descriptor(bt_gatt_attribute_h characteristic_handle, + bt_gatt_characteristic_descriptor_discovered_cb callback, + void *user_data); +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Sets the value of characteristic descriptor request. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * @param[in] characteristic The attribute handle of characteristic + * @param[in] value The value of characteristic (byte array), desc handle, desc value + * @param[in] value_length The length of value + * @param[in] callback The result callback + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_gatt_get_characteristic_declaration() + */ +int bt_gatt_set_characteristic_desc_value_request(bt_gatt_attribute_h characteristic, + const unsigned char *value, int value_length, + bt_gatt_characteristic_write_cb callback); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Connect to a specific LE based service on a remote bluetooth dievice address, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @remarks A connection can be disconnected by bt_gatt_disconnect(). + * + * @param[in] address The address of the remote Bluetooth device. + * @param[in] auto_connect The flag of the auto connection. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid paramater + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @pre The remote device must support le connection. + * @post This function invokes bt_gatt_connection_state_changed_cb(). + * + * @see bt_initialize() + * @see bt_gatt_disconnect() + * @see bt_gatt_set_connection_state_changed_cb() + * @see bt_gatt_unset_connection_state_changed_cb() + * @see bt_gatt_connection_state_changed_cb() + */ +int bt_gatt_connect(const char *address, bool auto_connect); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Disconnect to LE connection with the given remote Bluetooth dievice address, asynchronously. + * @since_tizen 2.3 + * @privlevel public + * @privilege %http://tizen.org/privilege/bluetooth + * + * @param[in] address The address of the remote Bluetooth device + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_INVALID_PARAMETER Invalid paramater + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The connection must be established. + * @post This function invokes bt_gatt_connection_state_changed_cb(). + * + * @see bt_initialize() + * @see bt_gatt_connect() + * @see bt_gatt_set_connection_state_changed_cb() + * @see bt_gatt_unset_connection_state_changed_cb() + * @see bt_gatt_connection_state_changed_cb() + */ +int bt_gatt_disconnect(const char *address); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Registers a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to register. + * @param[in] user_data The user data to be passed to the callback function. + * + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid paramater + * + * @see bt_gatt_connect() + * @see bt_gatt_disconnect() + * @see bt_gatt_unset_connection_state_changed_cb() + */ +int bt_gatt_set_connection_state_changed_cb(bt_gatt_connection_state_changed_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Unregisters a callback function that will be invoked when the connection state is changed. + * @since_tizen 2.3 + * + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @see bt_gatt_connect() + * @see bt_gatt_disconnect() + * @see bt_gatt_connection_state_changed_cb() + */ +int bt_gatt_unset_connection_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Initializes the Gatt Service. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int _bt_gatt_init_service(void); + + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief DeInitializes the Gatt Service. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + * @see _bt_gatt_init_service(void) + */ +int _bt_gatt_deinit_service(void); + + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Adds Gatt Service to the service interface. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] svc_uuid Gatt service uuid. + * @param[out] svc_path Object path of the GATT service. + * @remarks svc_path must be released with free() by you. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int bt_gatt_add_service(const char *svc_uuid, + char **svc_path); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Deletes a Gatt Service from the Gatt Server Database. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] svc_path Service path of the gatt service to remove. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int bt_gatt_remove_service(const char *svc_path); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Adds Gatt characteristic to the Characteristics interface. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] char_uuid Gatt characteristic uuid. + * @param[in] char_value Gatt characteristic value. + * @param[in] value_length Caracteristic value length. + * @param[in] char_flags Characteristic flags. + * @param[in] flags_length Caracteristic flags length. + * @param[in] svc_path service path to which this characteristic belongs to. + * @param[out] char_path characteristic path registered on the interface. + * @remarks char_path must be released with free() by you. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int bt_gatt_add_characteristic(const char *char_uuid, + const char *char_value, int value_length, + const char *char_flags[], int flags_length, + const char *svc_path, char **char_path); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Adds Gatt descriptor to the descriptor interface. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] desc_uuid Gatt descriptor uuid. + * @param[in] desc_value Gatt descriptor value. + * @param[in] desc_length Gatt descriptor value. + * @param[in] permissions Permissions for the descriptor. + * @param[in] char_path Characteristic path to which this descriptor should belong to. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int bt_gatt_add_descriptor(const char *desc_uuid, + const char *desc_value, int value_length, + const char *permissions, const char *char_path, + char **desc_path); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Registers the given service path (including characteristics and descriptor) with the Bluez. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] svc_path Gatt service path obtained from the add_service. + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre bt_gatt_add_service, bt_gatt_add_characteristic and bt_gatt_add_descriptor + * must be called before calling bt_gatt_register_service + * + * @see bt_adapter_enable() + * @see bt_gatt_add_service() + * @see bt_gatt_add_characteristic() + * @see bt_gatt_add_descriptor() + */ +int bt_gatt_register_service(const char *svc_path, + bt_gatt_remote_characteristic_write_cb callback, + void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Updates the existing characteristic value. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @param[in] char_path characteristic path registered on the interface. + * @param[in] char_value Gatt characteristic value. + * @param[in] value_length Characteristic value length. + * @param[in] address Remote device address, for which + * Notification/Indication need to be sent. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @see bt_adapter_enable() + */ +int bt_gatt_update_characteristic(const char *char_path, + const char *char_value, int value_length, + const char *address); +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Delete Gatt Services from the Gatt Server Database. + * @since_tizen 2.3 + * @privlevel platform + * @privilege http://tizen.org/privilege/bluetooth.admin + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post @a callback will be called. + * @see bt_adapter_enable() + */ +int bt_gatt_delete_services(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Activates the NAP(Network Access Point). + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_ALREADY_DONE Operation is already done + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED + * @see bt_nap_deactivate() + */ +int bt_nap_activate(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Deactivates the NAP(Network Access Point). + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_ALREADY_DONE Operation is already done + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth NAP service must be activated with bt_nap_activate(). + * @see bt_nap_activate() + */ +int bt_nap_deactivate(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Disconnects the all PANUs(Personal Area Networking User) which are connected to you. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth NAP service must be activated with bt_nap_activate(). + * @see bt_nap_activate() + */ +int bt_nap_disconnect_all(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Disconnects the specified PANU(Personal Area Networking User) which is connected to you. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] remote_address The remote address + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth NAP service must be activated with bt_nap_activate(). + * @see bt_nap_activate() + */ +int bt_nap_disconnect(const char *remote_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Registers a callback function that will be invoked when the connection state changes. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_nap_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_nap_connection_state_changed_cb() + * @see bt_nap_unset_connection_state_changed_cb() + */ +int bt_nap_set_connection_state_changed_cb(bt_nap_connection_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Unregisters a callback function that will be invoked when the connection state changes. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_nap_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_nap_connection_state_changed_cb() + * @see bt_nap_set_connection_state_changed_cb() + */ +int bt_nap_unset_connection_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Registers a callback function that will be invoked when the connection state changes. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_nap_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_panu_connection_state_changed_cb() + * @see bt_panu_unset_connection_state_changed_cb() + */ +int bt_panu_set_connection_state_changed_cb(bt_panu_connection_state_changed_cb callback, void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Unregisters a callback function that will be invoked when the connection state changes. + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_nap_connection_state_changed_cb() will be invoked. + * @see bt_initialize() + * @see bt_panu_connection_state_changed_cb() + * @see bt_panu_set_connection_state_changed_cb() + */ +int bt_panu_unset_connection_state_changed_cb(void); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Connects the remote device with the PAN(Personal Area Networking) service, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] remote_address The remote address + * @param[in] type The type of PAN service + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The local device must be bonded with the remote device by bt_device_create_bond(). + * @post bt_panu_connection_state_changed_cb() will be invoked. + * @see bt_panu_disconnect() + * @see bt_panu_connection_state_changed_cb() + */ +int bt_panu_connect(const char *remote_address, bt_panu_service_type_e type); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Disconnects the remote device with the PAN(Personal Area Networking) service, asynchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] remote_address The remote address + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OUT_OF_MEMORY Out of memory + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The remote device must be connected by bt_panu_connect(). + * @post bt_panu_connection_state_changed_cb() will be invoked. + * @see bt_panu_connect() + * @see bt_panu_connection_state_changed_cb() + */ +int bt_panu_disconnect(const char *remote_address); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief update LE connection. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_PERMISSION_DENIED Permission denied + * @pre The Bluetooth service must be initialized by bt_initialize(). + * @pre The remote device must be connected with bt_gatt_connect(). + */ +int bt_device_le_conn_update(const char *device_address, + const bt_le_conn_update_s *parameters); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __TIZEN_NETWORK_BLUETOOTH_H__ diff --git a/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_private.h b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_private.h new file mode 100644 index 0000000..dbb8e44 --- /dev/null +++ b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_private.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + + +#ifndef __TIZEN_NETWORK_BLUETOOTH_PRIVATE_H__ +#define __TIZEN_NETWORK_BLUETOOTH_PRIVATE_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include "bluetooth.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "CAPI_NETWORK_BLUETOOTH" + +#define BT_INFO(fmt, args...) SLOGI(fmt, ##args) +#define BT_DBG(fmt, args...) SLOGD(fmt, ##args) +#define BT_ERR(fmt, args...) SLOGE(fmt, ##args) + +#define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" + +/** + * @internal + * @brief Bluetooth callback. + */ +typedef enum +{ + BT_EVENT_STATE_CHANGED = 0x00, /**< Adapter state is changed */ + BT_EVENT_LE_STATE_CHANGED, /**< Adapter le state is changed */ + BT_EVENT_NAME_CHANGED, /**< Adapter name is changed */ + BT_EVENT_VISIBILITY_MODE_CHANGED, /**< Adapter visibility mode is changed */ + BT_EVENT_VISIBILITY_DURATION_CHANGED, /**< Adapter visibility duration is changed */ + BT_EVENT_DEVICE_DISCOVERY_STATE_CHANGED, /**< Device discovery state is changed */ + BT_EVENT_LE_DEVICE_DISCOVERY_STATE_CHANGED, /**< LE Device discovery state is changed */ + BT_EVENT_BOND_CREATED, /**< A bond is created */ + BT_EVENT_BOND_DESTROYED, /**< A bond is destroyed */ + BT_EVENT_AUTHORIZATION_CHANGED, /**< Authorization is changed */ + BT_EVENT_SERVICE_SEARCHED, /**< Service search finish */ + BT_EVENT_DATA_RECEIVED, /**< Data is received */ + BT_EVENT_CONNECTION_STATE_CHANGED, /**< Connection state is changed */ + BT_EVENT_RFCOMM_CONNECTION_REQUESTED, /**< RFCOMM connection is requested */ + BT_EVENT_OPP_CONNECTION_REQUESTED, /**< OPP connection is requested */ + BT_EVENT_OPP_PUSH_REQUESTED, /**< OPP push is requested */ + BT_EVENT_OPP_SERVER_TRANSFER_PROGRESS, /**< OPP transfer progress */ + BT_EVENT_OPP_SERVER_TRANSFER_FINISHED, /**< OPP transfer is completed */ + BT_EVENT_OPP_CLIENT_PUSH_RESPONSED, /**< OPP client connection is reponsed */ + BT_EVENT_OPP_CLIENT_PUSH_PROGRESS, /**< OPP client push progress */ + BT_EVENT_OPP_CLIENT_PUSH_FINISHED, /**< OPP client push is finished */ + BT_EVENT_PAN_CONNECTION_STATE_CHANGED, /**< PAN connection change */ + BT_EVENT_NAP_CONNECTION_STATE_CHANGED, /**< NAP connection change */ + BT_EVENT_HDP_CONNECTED, /**< HDP connection change */ + BT_EVENT_HDP_DISCONNECTED, /**< HDP disconnection change */ + BT_EVENT_HDP_DATA_RECEIVED, /**< HDP Data receive Callabck */ + BT_EVENT_AUDIO_CONNECTION_STATUS, /**< Audio Connection change callback */ + BT_EVENT_AG_SCO_CONNECTION_STATUS, /**< Audio - AG SCO Connection state change callback */ + BT_EVENT_AG_CALL_HANDLING_EVENT, /**< Audio - AG call event callback */ + BT_EVENT_AG_MULTI_CALL_HANDLING_EVENT, /**< Audio - AG 3-way call event callback */ + BT_EVENT_AG_DTMF_TRANSMITTED, /**< Audio - DTMF tone sending request */ + BT_EVENT_AG_MICROPHONE_GAIN_CHANGE, /**< Audio Microphone change callback */ + BT_EVENT_AG_SPEAKER_GAIN_CHANGE, /**< Audio Speaker gain change callback */ + BT_EVENT_AG_VENDOR_CMD, /**< Audio - XSAT Vendor cmd */ + BT_EVENT_AVRCP_CONNECTION_STATUS, /**< AVRCP connection change callback */ + BT_EVENT_AVRCP_EQUALIZER_STATE_CHANGED, /**< AVRCP equalizer state change callback */ + BT_EVENT_AVRCP_REPEAT_MODE_CHANGED, /**< AVRCP repeat mode change callback */ + BT_EVENT_AVRCP_SHUFFLE_MODE_CHANGED, /**< AVRCP equalizer mode change callback */ + BT_EVENT_AVRCP_SCAN_MODE_CHANGED, /**< AVRCP scan mode change callback */ + BT_EVENT_HID_CONNECTION_STATUS, /**< HID connection status callback */ + BT_EVENT_DEVICE_CONNECTION_STATUS, /**< Device connection status callback */ + BT_EVENT_GATT_CONNECTION_STATUS, /** < GATT connection status callback */ + BT_EVENT_GATT_PRIM_SVC_DISCOVERED, /**< GATT Primary Service discovered callback */ + BT_EVENT_GATT_CHARACTERISTIC_DISCOVERED, /**< GATT characteristic discovered callback */ + BT_EVENT_GATT_CHARACTERISTIC_DESCRIPTOR_DISCOVERED, /**< GATT characteristic descriptor discovered callback */ + BT_EVENT_GATT_VALUE_CHANGED, /**< GATT characteristic value changed callback */ + BT_EVENT_GATT_READ_CHARACTERISTIC, /**< GATT characteristic value read callback */ + BT_EVENT_GATT_WRITE_CHARACTERISTIC, /**< GATT characteristic value write callback */ + BT_EVENT_GATT_SERVER_ON_WRITE_CHAR, /**< GATT characteristic value write callback */ + BT_EVENT_ADVERTISING_STATE_CHANGED, /**< Advertising state changed callback */ + BT_EVENT_MANUFACTURER_DATA_CHANGED, /**< Manufacturer data changed callback */ + BT_EVENT_CONNECTABLE_CHANGED_EVENT, /**< Adapter connectable changed callback */ + BT_EVENT_RSSI_ENABLED_EVENT, /**< RSSI Enabled callback */ + BT_EVENT_RSSI_ALERT_EVENT, /**< RSSI Alert callback */ + BT_EVENT_GET_RSSI_EVENT, /**< Get RSSI Strength callback */ +#ifdef TIZEN_WEARABLE + BT_EVENT_PBAP_CONNECTION_STATUS, /**< PBAP connection status callback */ + BT_EVENT_PBAP_PHONEBOOK_SIZE, /**< PBAP Phonebook Size status callback */ + BT_EVENT_PBAP_PHONEBOOK_PULL, /**< PBAP Phonebook Pull status callback */ + BT_EVENT_PBAP_VCARD_LIST, /**< PBAP vCard List status callback */ + BT_EVENT_PBAP_VCARD_PULL, /**< PBAP vCard Pull status callback */ + BT_EVENT_PBAP_PHONEBOOK_SEARCH, /**< PBAP Phonebook Search status callback */ + BT_EVENT_HF_SCO_CONNECTION_STATUS, /**< Audio - HF SCO Connection state change callback */ + BT_EVENT_HF_SPEAKER_GAIN_CHANGE, /**< Audio - HF Speaker gain change callback */ + BT_EVENT_HF_CALL_HANDLING_EVENT, /**< Audio - HF call event callback */ + BT_EVENT_HF_VENDOR_DEP_CMD_EVENT, /**< Audio - HF Vendor Command callback */ + BT_EVENT_HF_MULTI_CALL_HANDLING_EVENT, /**< Audio - HF 3-way call event callback */ +#endif +} bt_event_e; + +/** + * @internal + */ +typedef struct { + int handle; + + bt_adapter_le_advertising_state_changed_cb cb; + void *cb_data; + + bt_adapter_le_advertising_params_s adv_params; + + unsigned int adv_data_len; + char *adv_data; + + unsigned int scan_rsp_data_len; + char *scan_rsp_data; + + void *user_data; +} bt_advertiser_s; + +/** + * @internal + */ +typedef struct bt_event_sig_event_slot_s +{ + int event_type; + const void *callback; + void *user_data; +} bt_event_sig_event_slot_s; + + +#define BT_CHECK_INPUT_PARAMETER(arg) \ + if (arg == NULL) \ + { \ + LOGE("[%s] INVALID_PARAMETER(0x%08x)", __FUNCTION__, BT_ERROR_INVALID_PARAMETER); \ + return BT_ERROR_INVALID_PARAMETER; \ + } + +/** + * @internal + * @brief Check the initialzating status + */ +int _bt_check_init_status(void); + +#define BT_CHECK_INIT_STATUS() \ + if (_bt_check_init_status() == BT_ERROR_NOT_INITIALIZED) \ + { \ + LOGE("[%s] NOT_INITIALIZED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_INITIALIZED); \ + return BT_ERROR_NOT_INITIALIZED; \ + } + +/** + * @internal + * @brief Initialize Bluetooth LE adapter + */ +int _bt_le_adapter_init(void); + +/** + * @internal + * @brief Deinitialize Bluetooth LE adapter + */ +int _bt_le_adapter_deinit(void); + +/** + * @internal + * @brief Set the event callback. + */ +void _bt_set_cb(int events, void *callback, void *user_data); + +/** + * @internal + * @brief Unset the event callback. + */ +void _bt_unset_cb(int events); + +/** + * @internal + * @brief Check if the event callback exist or not. + */ +bool _bt_check_cb(int events); + +/** + * @internal + * @brief Convert Bluetooth F/W error codes to capi Bluetooth error codes. + */ +int _bt_get_error_code(int origin_error); + + +/** + * @internal + * @brief Convert Bluetooth F/W bluetooth_device_info_t to capi bt_device_info_s. + */ +int _bt_get_bt_device_info_s(bt_device_info_s **dest_dev, bluetooth_device_info_t *source_dev); + + +/** + * @internal + * @brief Free bt_device_info_s. + */ +void _bt_free_bt_device_info_s(bt_device_info_s *device_info); + +/** + * @internal + * @brief Convert Bluetooth F/W bluetooth_device_address_t to string. + */ +int _bt_convert_address_to_string(char **addr_str, bluetooth_device_address_t *addr_hex); + + +/** + * @internal + * @brief Convert string to Bluetooth F/W bluetooth_device_address_t. + */ +void _bt_convert_address_to_hex(bluetooth_device_address_t *addr_hex, const char *addr_str); + + +/** + * @internal + * @brief Convert error code to string. + */ +char* _bt_convert_error_to_string(int error); + +/** + * @internal + * @brief Convert the visibility mode + */ +bt_adapter_visibility_mode_e _bt_get_bt_visibility_mode_e(bluetooth_discoverable_mode_t mode); + +/** + * @internal + * @brief Since the Audio call back and event proxy call backs have different prototype it is wrapper function. + */ +void _bt_audio_event_proxy(int event, bt_audio_event_param_t *param, void *user_data); + +#ifdef TIZEN_WEARABLE +/** + * @internal + * @brief Since the HF call back and event proxy call backs have different prototype it is wrapper function. + */ +void _bt_hf_event_proxy(int event, bt_hf_event_param_t *param, void *user_data); +#endif + +/** + * @internal + * @brief Since the Telephony call back and event proxy call backs have different prototype it is wrapper function. + */ +void _bt_telephony_event_proxy(int event, telephony_event_param_t *param, void *user_data); + +/** + * @internal + * @brief Since the AVRCP call back and event proxy call backs have different prototype it is wrapper function. + */ +void _bt_avrcp_event_proxy(int event, media_event_param_t *param, void *user_data); + +/** + * @internal + * @brief Since the HID call back and event proxy call backs have different prototype it is wrapper function. + */ +void _bt_hid_event_proxy(int event, hid_event_param_t *param, void *user_data); + + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_NETWORK_BLUETOOTH_PRIVATE_H__ */ diff --git a/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_type.h b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_type.h new file mode 100644 index 0000000..95d195d --- /dev/null +++ b/resource/csdk/connectivity/lib/tizen/ble/inc/bluetooth_type.h @@ -0,0 +1,1495 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + + +#ifndef __TIZEN_NETWORK_BLUETOOTH_TYPE_H__ +#define __TIZEN_NETWORK_BLUETOOTH_TYPE_H__ + + #ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** + * @file bluetooth_type.h + * @brief API to control the Bluetooth adapter, devices and communications. + * @ingroup CAPI_NETWORK_BLUETOOTH_TYPE_MODULE + */ + + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_MODULE + * @brief Enumerations of Bluetooth error codes. + */ +typedef enum +{ + BT_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful*/ + BT_ERROR_CANCELLED = TIZEN_ERROR_CANCELED, /**< Operation cancelled */ + BT_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + BT_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + BT_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY, /**< Device or resource busy */ + BT_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< Timeout error */ + BT_ERROR_NOW_IN_PROGRESS = TIZEN_ERROR_NOW_IN_PROGRESS, /**< Operation now in progress */ + BT_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, + BT_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + BT_ERROR_QUOTA_EXCEEDED = TIZEN_ERROR_QUOTA_EXCEEDED, /**< Quota exceeded */ + BT_ERROR_NOT_INITIALIZED = TIZEN_ERROR_BLUETOOTH|0x0101, /**< Local adapter not initialized */ + BT_ERROR_NOT_ENABLED = TIZEN_ERROR_BLUETOOTH|0x0102, /**< Local adapter not enabled */ + BT_ERROR_ALREADY_DONE = TIZEN_ERROR_BLUETOOTH|0x0103, /**< Operation already done */ + BT_ERROR_OPERATION_FAILED = TIZEN_ERROR_BLUETOOTH|0x0104, /**< Operation failed */ + BT_ERROR_NOT_IN_PROGRESS = TIZEN_ERROR_BLUETOOTH|0x0105, /**< Operation not in progress */ + BT_ERROR_REMOTE_DEVICE_NOT_BONDED = TIZEN_ERROR_BLUETOOTH|0x0106, /**< Remote device not bonded */ + BT_ERROR_AUTH_REJECTED = TIZEN_ERROR_BLUETOOTH|0x0107, /**< Authentication rejected */ + BT_ERROR_AUTH_FAILED = TIZEN_ERROR_BLUETOOTH|0x0108, /**< Authentication failed */ + BT_ERROR_REMOTE_DEVICE_NOT_FOUND = TIZEN_ERROR_BLUETOOTH|0x0109, /**< Remote device not found */ + BT_ERROR_SERVICE_SEARCH_FAILED = TIZEN_ERROR_BLUETOOTH|0x010A, /**< Service search failed */ + BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED = TIZEN_ERROR_BLUETOOTH|0x010B, /**< Remote device is not connected */ + BT_ERROR_AGAIN = TIZEN_ERROR_BLUETOOTH|0x010C, /**< Resource temporarily unavailable */ + BT_ERROR_SERVICE_NOT_FOUND = TIZEN_ERROR_BLUETOOTH|0x010D, /**< Service Not Found */ +} bt_error_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enumerations of the Bluetooth adapter state. + */ +typedef enum +{ + BT_ADAPTER_DISABLED = 0x00, /**< Bluetooth adapter is disabled */ + BT_ADAPTER_ENABLED, /**< Bluetooth adapter is enabled */ +} bt_adapter_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth adapter le state. + */ +typedef enum +{ + BT_ADAPTER_LE_DISABLED = 0x00, /**< Bluetooth le is disabled */ + BT_ADAPTER_LE_ENABLED, /**< Bluetooth le is enabled */ +} bt_adapter_le_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enumerations of the Bluetooth visibility mode. + */ +typedef enum +{ + BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE = 0x00, /**< Other devices cannot find your device via discovery */ + BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, /**< Discoverable mode */ + BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE, /**< Discoverable mode with time limit. After specific period, + it is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE.*/ +} bt_adapter_visibility_mode_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Enumerations of the discovery state of Bluetooth device. + * + */ +typedef enum +{ + BT_ADAPTER_DEVICE_DISCOVERY_STARTED, /**< Device discovery is started */ + BT_ADAPTER_DEVICE_DISCOVERY_FINISHED, /**< Device discovery is finished */ + BT_ADAPTER_DEVICE_DISCOVERY_FOUND, /**< The remote Bluetooth device is found */ +} bt_adapter_device_discovery_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the discovery state of Bluetooth LE device. + * + */ +typedef enum +{ + BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED, /**< LE device discovery is started */ + BT_ADAPTER_LE_DEVICE_DISCOVERY_FINISHED, /**< LE device discovery is finished */ + BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND, /**< The remote Bluetooth LE device is found */ +} bt_adapter_le_device_discovery_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth advertising state. + */ +typedef enum { + BT_ADAPTER_LE_ADVERTISING_STOPPED = 0x00, /**< Bluetooth advertising is stopped */ + BT_ADAPTER_LE_ADVERTISING_STARTED, /**< Bluetooth advertising is started */ +} bt_adapter_le_advertising_state_e; + + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth advertising filter policy. + */ +typedef enum { + BT_ADAPTER_LE_ADVERTISING_FILTER_DEFAULT = 0x00, /**< White list is not in use */ + BT_ADAPTER_LE_ADVERTISING_FILTER_ALLOW_SCAN_WL = 0x01, /**< Allow the scan + request that in the White list */ + BT_ADAPTER_LE_ADVERTISING_FILTER_ALLOW_CONN_WL = 0x02, /**< Allow the connectoin + request that in the White list */ + BT_ADAPTER_LE_ADVERTISING_FILTER_ALLOW_SCAN_CONN_WL = 0x03, /**< Allow the + scan and connectoin request that in the White list */ +} bt_adapter_le_advertising_filter_policy_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth advertising type. + */ +typedef enum { + BT_ADAPTER_LE_ADVERTISING_CONNECTABLE = 0x00, /**< Connectable undirected advertising (ADV_IND) */ + BT_ADAPTER_LE_ADVERTISING_CONNECTABLE_DIRECT_HIGH = 0x01, /**< Connectable high duty cycle directed advertising (ADV_DIRECT_IND) */ + BT_ADAPTER_LE_ADVERTISING_SCANNABLE = 0x02, /**< Scannable undirected advertising (ADV_SCAN_IND) */ + BT_ADAPTER_LE_ADVERTISING_NON_CONNECTABLE = 0x03, /**< Non connectable undirected advertising (ADV_NONCOND_IND) */ + BT_ADAPTER_LE_ADVERTISING_CONNECTABLE_DIRECT_LOW = 0x04, /**< Connectable low duty cycle directed advertising (ADV_DIRECT_IND) */ +} bt_adapter_le_advertising_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth LE packet type. + */ +typedef enum { + BT_ADAPTER_LE_PACKET_ADVERTISING, /**< Advertising packet */ + BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, /**< Sacn response packet */ +} bt_adapter_le_packet_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth LE data type + * that can be included in LE packets. + */ +typedef enum { + BT_ADAPTER_LE_PACKET_DATA_COMP_LIST_16_BIT_SERVICE_CLASS_UUIDS = 0x03, /**< 16 bit UUID */ + BT_ADAPTER_LE_PACKET_DATA_MANUFACTURER_SPECIFIC_DATA = 0xff, /**< Manufacturer data */ +} bt_adapter_le_packet_data_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of device disconnect reason. + */ +typedef enum +{ + BT_DEVICE_DISCONNECT_REASON_UNKNOWN, /**< Disconnected by unknown reason */ + BT_DEVICE_DISCONNECT_REASON_TIMEOUT, /**< Disconnected by timeout */ + BT_DEVICE_DISCONNECT_REASON_LOCAL_HOST, /**< Disconnected by local host */ + BT_DEVICE_DISCONNECT_REASON_REMOTE, /**< Disconnected by remote */ +} bt_device_disconnect_reason_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of connection link type. + */ +typedef enum +{ + BT_DEVICE_CONNECTION_LINK_BREDR, /**< BR/EDR link */ + BT_DEVICE_CONNECTION_LINK_LE, /**< LE link */ + BT_DEVICE_CONNECTION_LINK_DEFAULT = 0xFF, /**< The connection type defualt */ +} bt_device_connection_link_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of device authorization state. + */ +typedef enum +{ + BT_DEVICE_AUTHORIZED, /**< The remote Bluetooth device is authorized */ + BT_DEVICE_UNAUTHORIZED, /**< The remote Bluetooth device is unauthorized */ +} bt_device_authorization_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of Bluetooth profile. + */ +typedef enum +{ + BT_PROFILE_RFCOMM = 0x01, /**< RFCOMM Profile */ + BT_PROFILE_A2DP = 0x02, /**< Advanced Audio Distribution Profile */ + BT_PROFILE_HSP = 0x04, /**< Headset Profile */ + BT_PROFILE_HID = 0x08, /**< Human Interface Device Profile */ + BT_PROFILE_NAP = 0x10, /**< Network Access Point Profile */ + BT_PROFILE_AG = 0x20, /**< Audio Gateway Profile */ + BT_PROFILE_GATT = 0x40, /**< Generic Attribute Profile */ + BT_PROFILE_NAP_SERVER = 0x80, /**< NAP server Profile */ +} bt_profile_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of device address type. + */ +typedef enum +{ + BT_DEVICE_PUBLIC_ADDRESS = 0x00, /**< Public address */ + BT_DEVICE_RANDOM_ADDRESS, /**< Random address */ +} bt_device_address_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of service class. + */ +typedef enum { + BT_SC_NONE = 0, /**< No service class */ + BT_SC_RES_SERVICE_MASK = 0x00000001, /**< RES service class */ + BT_SC_SPP_SERVICE_MASK = 0x00000002, /**< SPP service class */ + BT_SC_DUN_SERVICE_MASK = 0x00000004, /**< DUN service class */ + BT_SC_FAX_SERVICE_MASK = 0x00000008, /**< FAX service class */ + BT_SC_LAP_SERVICE_MASK = 0x00000010, /**< LAP service class */ + BT_SC_HSP_SERVICE_MASK = 0x00000020, /**< HSP service class */ + BT_SC_HFP_SERVICE_MASK = 0x00000040, /**< HFP service class */ + BT_SC_OPP_SERVICE_MASK = 0x00000080, /**< OPP service class */ + BT_SC_FTP_SERVICE_MASK = 0x00000100, /**< FTP service class */ + BT_SC_CTP_SERVICE_MASK = 0x00000200, /**< CTP service class */ + BT_SC_ICP_SERVICE_MASK = 0x00000400, /**< ICP service class */ + BT_SC_SYNC_SERVICE_MASK = 0x00000800, /**< SYNC service class */ + BT_SC_BPP_SERVICE_MASK = 0x00001000, /**< BPP service class */ + BT_SC_BIP_SERVICE_MASK = 0x00002000, /**< BIP service class */ + BT_SC_PANU_SERVICE_MASK = 0x00004000, /**< PANU service class */ + BT_SC_NAP_SERVICE_MASK = 0x00008000, /**< NAP service class */ + BT_SC_GN_SERVICE_MASK = 0x00010000, /**< GN service class */ + BT_SC_SAP_SERVICE_MASK = 0x00020000, /**< SAP service class */ + BT_SC_A2DP_SERVICE_MASK = 0x00040000, /**< A2DP service class */ + BT_SC_AVRCP_SERVICE_MASK = 0x00080000, /**< AVRCP service class */ + BT_SC_PBAP_SERVICE_MASK = 0x00100000, /**< PBAP service class */ + BT_SC_HID_SERVICE_MASK = 0x00200000, /**< HID service class */ + BT_SC_ALL_SERVICE_MASK = 0x00FFFFFF, /**< ALL service class */ + BT_SC_MAX /**< MAX service class */ +} bt_service_class_t; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of major service class. + */ +typedef enum +{ + BT_MAJOR_SERVICE_CLASS_LIMITED_DISCOVERABLE_MODE = 0x002000, /**< Limited discoverable mode */ + BT_MAJOR_SERVICE_CLASS_POSITIONING = 0x010000, /**< Positioning class */ + BT_MAJOR_SERVICE_CLASS_NETWORKING = 0x020000, /**< Networking class */ + BT_MAJOR_SERVICE_CLASS_RENDERING = 0x040000, /**< Rendering class */ + BT_MAJOR_SERVICE_CLASS_CAPTURING = 0x080000, /**< Capturing class */ + BT_MAJOR_SERVICE_CLASS_OBJECT_TRANSFER = 0x100000, /**< Object transferring class */ + BT_MAJOR_SERVICE_CLASS_AUDIO = 0x200000, /**< Audio class*/ + BT_MAJOR_SERVICE_CLASS_TELEPHONY = 0x400000, /**< Telephony class */ + BT_MAJOR_SERVICE_CLASS_INFORMATION = 0x800000, /**< Information class */ +} bt_major_service_class_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of major device class. + */ +typedef enum +{ + BT_MAJOR_DEVICE_CLASS_MISC = 0x00, /**< Miscellaneous major device class*/ + BT_MAJOR_DEVICE_CLASS_COMPUTER = 0x01, /**< Computer major device class */ + BT_MAJOR_DEVICE_CLASS_PHONE = 0x02, /**< Phone major device class */ + BT_MAJOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT = 0x03, /**< LAN/Network access point major device class */ + BT_MAJOR_DEVICE_CLASS_AUDIO_VIDEO = 0x04, /**< Audio/Video major device class */ + BT_MAJOR_DEVICE_CLASS_PERIPHERAL = 0x05, /**< Peripheral major device class */ + BT_MAJOR_DEVICE_CLASS_IMAGING = 0x06, /**< Imaging major device class */ + BT_MAJOR_DEVICE_CLASS_WEARABLE = 0x07, /**< Wearable device class */ + BT_MAJOR_DEVICE_CLASS_TOY = 0x08, /**< Toy device class */ + BT_MAJOR_DEVICE_CLASS_HEALTH = 0x09, /**< Health device class */ + BT_MAJOR_DEVICE_CLASS_UNCATEGORIZED = 0x1F, /**< Uncategorized major device class */ +} bt_major_device_class_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of minor device class. + */ +typedef enum +{ + BT_MINOR_DEVICE_CLASS_COMPUTER_UNCATEGORIZED = 0x00, /**< Uncategorized minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_DESKTOP_WORKSTATION = 0x04, /**< Desktop workstation minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_SERVER_CLASS = 0x08, /**< Server minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_LAPTOP = 0x0C, /**< Laptop minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_HANDHELD_PC_OR_PDA = 0x10, /**< Handheld PC/PDA minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_PALM_SIZED_PC_OR_PDA = 0x14, /**< Palm sized PC/PDA minor device class of computer */ + BT_MINOR_DEVICE_CLASS_COMPUTER_WEARABLE_COMPUTER = 0x18, /**< Wearable(watch sized) minor device class of computer */ + + BT_MINOR_DEVICE_CLASS_PHONE_UNCATEGORIZED = 0x00, /**< Uncategorized minor device class of phone */ + BT_MINOR_DEVICE_CLASS_PHONE_CELLULAR = 0x04, /**< Cellular minor device class of phone */ + BT_MINOR_DEVICE_CLASS_PHONE_CORDLESS = 0x08, /**< Cordless minor device class of phone */ + BT_MINOR_DEVICE_CLASS_PHONE_SMART_PHONE = 0x0C, /**< Smart phone minor device class of phone */ + BT_MINOR_DEVICE_CLASS_PHONE_WIRED_MODEM_OR_VOICE_GATEWAY = 0x10, /**< Wired modem or voice gateway minor device class of phone */ + BT_MINOR_DEVICE_CLASS_PHONE_COMMON_ISDN_ACCESS = 0x14, /**< Common ISDN minor device class of phone */ + + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_FULLY_AVAILABLE = 0x04, /**< Fully available minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_1_TO_17_PERCENT_UTILIZED = 0x20, /**< 1-17% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_17_TO_33_PERCENT_UTILIZED = 0x40, /**< 17-33% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_33_TO_50_PERCENT_UTILIZED = 0x60, /**< 33-50% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_50_to_67_PERCENT_UTILIZED = 0x80, /**< 50-67% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_67_TO_83_PERCENT_UTILIZED = 0xA0, /**< 67-83% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_83_TO_99_PERCENT_UTILIZED = 0xC0, /**< 83-99% utilized minor device class of LAN/Network access point */ + BT_MINOR_DEVICE_CLASS_LAN_NETWORK_ACCESS_POINT_NO_SERVICE_AVAILABLE = 0xE0, /**< No service available minor device class of LAN/Network access point */ + + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_UNCATEGORIZED = 0x00, /**< Uncategorized minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_WEARABLE_HEADSET = 0x04, /**< Wearable headset minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_HANDS_FREE = 0x08, /**< Hands-free minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_MICROPHONE = 0x10, /**< Microphone minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_LOUDSPEAKER = 0x14, /**< Loudspeaker minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_HEADPHONES = 0x18, /**< Headphones minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_PORTABLE_AUDIO = 0x1C, /**< Portable audio minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_CAR_AUDIO = 0x20, /**< Car audio minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_SET_TOP_BOX = 0x24, /**< Set-top box minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_HIFI_AUDIO_DEVICE = 0x28, /**< Hifi audio minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_VCR = 0x2C, /**< VCR minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_VIDEO_CAMERA = 0x30, /**< Video camera minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_CAMCORDER = 0x34, /**< Camcorder minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_VIDEO_MONITOR = 0x38, /**< Video monitor minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_VIDEO_DISPLAY_LOUDSPEAKER = 0x3C, /**< Video display and loudspeaker minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_VIDEO_CONFERENCING = 0x40, /**< Video conferencing minor device class of audio/video */ + BT_MINOR_DEVICE_CLASS_AUDIO_VIDEO_GAMING_TOY = 0x48, /**< Gaming/toy minor device class of audio/video */ + + BT_MINOR_DEVICE_CLASS_PERIPHERA_UNCATEGORIZED = 0x00, /**< Uncategorized minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_KEY_BOARD = 0x40, /**< Key board minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_POINTING_DEVICE = 0x80, /**< Pointing device minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_COMBO_KEYBOARD_POINTING_DEVICE = 0xC0, /**< Combo keyboard or pointing device minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_JOYSTICK = 0x04, /**< Joystick minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_GAME_PAD = 0x08, /**< Game pad minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_REMOTE_CONTROL = 0x0C, /**< Remote control minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_SENSING_DEVICE = 0x10, /**< Sensing device minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_DIGITIZER_TABLET = 0x14, /**< Digitizer minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_CARD_READER = 0x18, /**< Card reader minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_DIGITAL_PEN = 0x1C, /**< Digital pen minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_HANDHELD_SCANNER = 0x20, /**< Handheld scanner minor device class of peripheral */ + BT_MINOR_DEVICE_CLASS_PERIPHERAL_HANDHELD_GESTURAL_INPUT_DEVICE = 0x24, /**< Handheld gestural input device minor device class of peripheral */ + + BT_MINOR_DEVICE_CLASS_IMAGING_DISPLAY = 0x10, /**< Display minor device class of imaging */ + BT_MINOR_DEVICE_CLASS_IMAGING_CAMERA = 0x20, /**< Camera minor device class of imaging */ + BT_MINOR_DEVICE_CLASS_IMAGING_SCANNER = 0x40, /**< Scanner minor device class of imaging */ + BT_MINOR_DEVICE_CLASS_IMAGING_PRINTER = 0x80, /**< Printer minor device class of imaging */ + + BT_MINOR_DEVICE_CLASS_WEARABLE_WRIST_WATCH = 0x04, /**< Wrist watch minor device class of wearable */ + BT_MINOR_DEVICE_CLASS_WEARABLE_PAGER = 0x08, /**< Pager minor device class of wearable */ + BT_MINOR_DEVICE_CLASS_WEARABLE_JACKET = 0x0C, /**< Jacket minor device class of wearable */ + BT_MINOR_DEVICE_CLASS_WEARABLE_HELMET = 0x10, /**< Helmet minor device class of wearable */ + BT_MINOR_DEVICE_CLASS_WEARABLE_GLASSES = 0x14, /**< Glasses minor device class of wearable */ + + BT_MINOR_DEVICE_CLASS_TOY_ROBOT = 0x04, /**< Robot minor device class of toy */ + BT_MINOR_DEVICE_CLASS_TOY_VEHICLE = 0x08, /**< Vehicle minor device class of toy */ + BT_MINOR_DEVICE_CLASS_TOY_DOLL_ACTION = 0x0C, /**< Doll/Action minor device class of toy */ + BT_MINOR_DEVICE_CLASS_TOY_CONTROLLER = 0x10, /**< Controller minor device class of toy */ + BT_MINOR_DEVICE_CLASS_TOY_GAME = 0x14, /**< Game minor device class of toy */ + + BT_MINOR_DEVICE_CLASS_HEALTH_UNCATEGORIZED = 0x00, /**< Uncategorized minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_BLOOD_PRESSURE_MONITOR = 0x04, /**< Blood pressure monitor minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_THERMOMETER = 0x08, /**< Thermometer minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_WEIGHING_SCALE = 0x0C, /**< Weighing scale minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_GLUCOSE_METER = 0x10, /**< Glucose minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_PULSE_OXIMETER = 0x14, /**< Pulse oximeter minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_HEART_PULSE_RATE_MONITOR = 0x18, /**< Heart/Pulse rate monitor minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_DATA_DISPLAY = 0x1C, /**< Health data display minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_STEP_COUNTER = 0x20, /**< Step counter minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_BODY_COMPOSITION_ANALYZER = 0x24, /**< Body composition analyzer minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_PEAK_FLOW_MONITOR = 0x28, /**< Peak flow monitor minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_MEDICATION_MONITOR = 0x2C, /**< Medication monitor minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_KNEE_PROSTHESIS = 0x30, /**< Knee prosthesis minor device class of health */ + BT_MINOR_DEVICE_CLASS_HEALTH_ANKLE_PROSTHESIS = 0x34, /**< Ankle prosthesis minor device class of health */ +} bt_minor_device_class_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enumerations of gap appearance type. + */ +typedef enum +{ + BT_APPEARANCE_TYPE_UNKNOWN = 0x00, /**< Unknown appearance type */ + BT_APPEARANCE_TYPE_GENERIC_PHONE = 0x40, /**< Generic Phone type - Generic category */ + BT_APPEARANCE_TYPE_GENERIC_COMPUTER = 0x80, /**< Generic Computer type - Generic category */ + BT_APPEARANCE_TYPE_GENERIC_WATCH = 0xC0, /**< Generic Watch type - Generic category */ +} bt_appearance_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Enumerations of connected Bluetooth device event role. + */ +typedef enum +{ + BT_SOCKET_UNKNOWN = 0x00, /**< Unknown role*/ + BT_SOCKET_SERVER , /**< Server role*/ + BT_SOCKET_CLIENT, /**< Client role*/ +} bt_socket_role_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Enumerations of Bluetooth socket connection state. + */ +typedef enum +{ + BT_SOCKET_CONNECTED, /**< RFCOMM is connected */ + BT_SOCKET_DISCONNECTED, /**< RFCOMM is disconnected */ +} bt_socket_connection_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Enumerations for the types of profiles related with audio + */ +typedef enum { + BT_AUDIO_PROFILE_TYPE_ALL = 0, /**< All supported profiles related with audio */ + BT_AUDIO_PROFILE_TYPE_HSP_HFP, /**< HSP(Headset Profile) and HFP(Hands-Free Profile) */ + BT_AUDIO_PROFILE_TYPE_A2DP, /**< A2DP(Advanced Audio Distribution Profile) */ + BT_AUDIO_PROFILE_TYPE_AG, /**< AG(Audio Gateway) */ +} bt_audio_profile_type_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Enumerations for the call handling event + */ +typedef enum { + BT_AG_CALL_HANDLING_EVENT_ANSWER = 0x00, /**< Request to answer an incoming call */ + BT_AG_CALL_HANDLING_EVENT_RELEASE, /**< Request to release a call */ + BT_AG_CALL_HANDLING_EVENT_REJECT, /**< Request to reject an incoming call */ +} bt_ag_call_handling_event_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Enumerations for the multi call handling event + */ +typedef enum { + BT_AG_MULTI_CALL_HANDLING_EVENT_RELEASE_HELD_CALLS = 0x00, /**< Request to release held calls */ + BT_AG_MULTI_CALL_HANDLING_EVENT_RELEASE_ACTIVE_CALLS, /**< Request to release active calls */ + BT_AG_MULTI_CALL_HANDLING_EVENT_ACTIVATE_HELD_CALL, /**< Request to put active calls into hold state and activate another (held or waiting) call */ + BT_AG_MULTI_CALL_HANDLING_EVENT_MERGE_CALLS, /**< Request to add a held call to the conversation */ + BT_AG_MULTI_CALL_HANDLING_EVENT_EXPLICIT_CALL_TRANSFER, /**< Request to let a user who has two calls to connect these two calls together and release its connections to both other parties */ +} bt_ag_multi_call_handling_event_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Enumerations for the call state + */ +typedef enum { + BT_AG_CALL_EVENT_IDLE = 0x00, /**< Idle */ + BT_AG_CALL_EVENT_ANSWERED, /**< Answered */ + BT_AG_CALL_EVENT_HELD, /**< Held */ + BT_AG_CALL_EVENT_RETRIEVED, /**< Retrieved */ + BT_AG_CALL_EVENT_DIALING, /**< Dialing */ + BT_AG_CALL_EVENT_ALERTING, /**< Alerting */ + BT_AG_CALL_EVENT_INCOMING, /**< Incoming */ +} bt_ag_call_event_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Enumerations for the call state + */ +typedef enum { + BT_AG_CALL_STATE_IDLE = 0x00, /**< Idle state */ + BT_AG_CALL_STATE_ACTIVE, /**< Active state */ + BT_AG_CALL_STATE_HELD, /**< Held state */ + BT_AG_CALL_STATE_DIALING, /**< Dialing state */ + BT_AG_CALL_STATE_ALERTING, /**< Alerting state */ + BT_AG_CALL_STATE_INCOMING, /**< Incoming state */ + BT_AG_CALL_STATE_WAITING, /**< Waiting for connected indication event after answering an incoming call*/ +} bt_ag_call_state_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Enumerations for the equalizer state + */ +typedef enum { + BT_AVRCP_EQUALIZER_STATE_OFF = 0x01, /**< Equalizer Off */ + BT_AVRCP_EQUALIZER_STATE_ON, /**< Equalizer On */ +} bt_avrcp_equalizer_state_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Enumerations for the repeat mode + */ +typedef enum { + BT_AVRCP_REPEAT_MODE_OFF = 0x01, /**< Repeat Off */ + BT_AVRCP_REPEAT_MODE_SINGLE_TRACK, /**< Single track repeat */ + BT_AVRCP_REPEAT_MODE_ALL_TRACK, /**< All track repeat */ + BT_AVRCP_REPEAT_MODE_GROUP, /**< Group repeat */ +} bt_avrcp_repeat_mode_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Enumerations for the shuffle mode + */ +typedef enum { + BT_AVRCP_SHUFFLE_MODE_OFF = 0x01, /**< Shuffle Off */ + BT_AVRCP_SHUFFLE_MODE_ALL_TRACK, /**< All tracks shuffle */ + BT_AVRCP_SHUFFLE_MODE_GROUP, /**< Group shuffle */ +} bt_avrcp_shuffle_mode_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Enumerations for the scan mode + */ +typedef enum { + BT_AVRCP_SCAN_MODE_OFF = 0x01, /**< Scan Off */ + BT_AVRCP_SCAN_MODE_ALL_TRACK, /**< All tracks scan */ + BT_AVRCP_SCAN_MODE_GROUP, /**< Group scan */ +} bt_avrcp_scan_mode_e; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Enumerations for the player state + */ +typedef enum { + BT_AVRCP_PLAYER_STATE_STOPPED = 0x00, /**< Stopped */ + BT_AVRCP_PLAYER_STATE_PLAYING, /**< Playing */ + BT_AVRCP_PLAYER_STATE_PAUSED, /**< Paused */ + BT_AVRCP_PLAYER_STATE_FORWARD_SEEK, /**< Seek Forward */ + BT_AVRCP_PLAYER_STATE_REWIND_SEEK, /**< Seek Rewind */ +} bt_avrcp_player_state_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Enumerations for the data channel type + */ +typedef enum { + BT_HDP_CHANNEL_TYPE_RELIABLE = 0x01, /**< Reliable Data Channel */ + BT_HDP_CHANNEL_TYPE_STREAMING, /**< Streaming Data Channel */ +} bt_hdp_channel_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Enumerations for the types of PAN(Personal Area Networking) service + */ +typedef enum { + BT_PANU_SERVICE_TYPE_NAP = 0, /**< Network Access Point */ +} bt_panu_service_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief The handle to control Bluetooth LE advertising + */ +typedef void* bt_advertiser_h; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief The attribute handle of GATT(Generic Attribute Profile) + */ +typedef void* bt_gatt_attribute_h; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief The handle of calls state + */ +typedef void* bt_call_list_h; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Class structure of device and service. + * + * @see #bt_device_info_s + * @see #bt_adapter_device_discovery_info_s + * @see bt_device_bond_created_cb() + * @see bt_adapter_device_discovery_state_changed_cb() + */ +typedef struct +{ + bt_major_device_class_e major_device_class; /**< Major device class. */ + bt_minor_device_class_e minor_device_class; /**< Minor device class. */ + int major_service_class_mask; /**< Major service class mask. + This value can be a combination of #bt_major_service_class_e like #BT_MAJOR_SERVICE_CLASS_RENDERING | #BT_MAJOR_SERVICE_CLASS_AUDIO */ +} bt_class_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Structure of device discovery information. + * + * @see #bt_class_s + * @see bt_adapter_device_discovery_state_changed_cb() + */ +typedef struct +{ + char *remote_address; /**< The address of remote device */ + char *remote_name; /**< The name of remote device */ + bt_class_s bt_class; /**< The Bluetooth classes */ + int rssi; /**< The strength indicator of received signal */ + bool is_bonded; /**< The bonding state */ + char **service_uuid; /**< The UUID list of service */ + int service_count; /**< The number of services */ + bt_appearance_type_e appearance; /**< The Bluetooth appearance */ + int manufacturer_data_len; /**< manufacturer specific data length */ + char *manufacturer_data; /**< manufacturer specific data */ +} bt_adapter_device_discovery_info_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Structure of le device discovery information. + * + * @see #bt_class_s + * @see bt_adapter_le_device_discovery_state_changed_cb() + */ +typedef struct +{ + char *remote_address; /**< The address of remote device */ + int address_type; /**< The address type of remote device */ + int rssi; /**< The strength indicator of received signal */ + char **service_uuid; /**< The UUID list of service */ + int service_count; /**< The number of services */ + int adv_data_len; /**< advertising indication data length */ + char *adv_data; /**< advertising indication data */ + int scan_data_len; /**< scan response data length */ + char *scan_data; /**< scan response data */ +} bt_adapter_le_device_discovery_info_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Structure of advertising parameters + * + * @see #bt_class_s + * @see bt_adapter_le_advertising_state_changed_cb() + * @see bt_adapter_le_start_advertising() + */ +typedef struct { + float interval_min; /**< Minimum advertising interval for non-directed advertising. + A multiple of 0.625ms is only allowed (Time range : 20ms to 10.24sec). */ + float interval_max; /**< Maximum advertising interval for non-directed advertising. + A multiple of 0.625ms is only allowed (Time range : 20ms to 10.24sec). */ + char filter_policy; /* Advertising filter policy */ + char type; /* Advertising type */ +} bt_adapter_le_advertising_params_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Device information structure used for identifying pear device. + * + * @see #bt_class_s + * @see bt_device_bond_created_cb() + */ +typedef struct +{ + char *remote_address; /**< The address of remote device */ + char *remote_name; /**< The name of remote device */ + bt_class_s bt_class; /**< The Bluetooth classes */ + char **service_uuid; /**< The UUID list of service */ + int service_count; /**< The number of services */ + bool is_bonded; /**< The bonding state */ + bool is_connected; /**< The connection state */ + bool is_authorized; /**< The authorization state */ + int manufacturer_data_len; /**< manufacturer specific data length */ + char *manufacturer_data; /**< manufacturer specific data */ +} bt_device_info_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Service Discovery Protocol (SDP) data structure. + * + * @details This protocol is used for discovering available services or pear device, + * and finding one to connect with. + * + * @see bt_device_service_searched_cb() + */ +typedef struct +{ + char *remote_address; /**< The address of remote device */ + char **service_uuid; /**< The UUID list of service */ + int service_count; /**< The number of services. */ +} bt_device_sdp_info_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Device connection information structure. + * + * @see bt_device_connection_state_changed_cb() + */ +typedef struct +{ + char *remote_address; /**< The address of remote device */ + bt_device_connection_link_type_e link; /**< Link type */ + bt_device_disconnect_reason_e disconn_reason; /**< Disconnection reason */ +} bt_device_connection_info_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Device LE connection update structure. + * + * @see bt_device_le_conn_update() + */ +typedef struct +{ + unsigned int interval_min; /**< Minimum value for the connection event interval (msec) */ + unsigned int interval_max; /**< Maximum value for the connection event interval (msec) */ + unsigned int latency; /**< Slave latency (msec) */ + unsigned int time_out; /**< Supervision timeout (msec) */ +} bt_le_conn_update_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * + * @brief Rfcomm connection data used for exchanging data between Bluetooth devices. + * + * @see bt_socket_connection_state_changed_cb() + */ +typedef struct +{ + int socket_fd; /**< The file descriptor of connected socket */ + int server_fd; /**< The file descriptor of the server socket or -1 for client connection */ + bt_socket_role_e local_role; /**< The local device role in this connection */ + char *remote_address; /**< The remote device address */ + char *service_uuid; /**< The service UUId */ +} bt_socket_connection_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * + * @brief Structure of RFCOMM received data. + * + * @remarks User can use standard linux functions for reading/writing + * data from/to sockets. + * + * @see bt_socket_data_received_cb() + */ +typedef struct +{ + int socket_fd; /**< The socket fd */ + int data_size; /**< The length of the received data */ + char *data; /**< The received data */ +} bt_socket_received_data_s; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when the Bluetooth adapter state changes. + * @param[in] result The result of the adapter state changing + * @param[in] adapter_state The adapter state to be changed + * @param[in] user_data The user data passed from the callback registration function + * @see bt_adapter_set_state_changed_cb() + * @see bt_adapter_unset_state_changed_cb() + */ +typedef void (*bt_adapter_state_changed_cb)(int result, bt_adapter_state_e adapter_state, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when adapter name changes. + * @param[in] device_name The name of the Bluetooth device to be changed + * @param[in] user_data The user data passed from the callback registration function + * @pre This function will be invoked when the name of Bluetooth adapter changes + * if you register this callback using bt_adapter_set_name_changed_cb(). + * @see bt_adapter_set_name() + * @see bt_adapter_set_name_changed_cb() + * @see bt_adapter_unset_name_changed_cb() + */ +typedef void (*bt_adapter_name_changed_cb)(char *device_name, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when the visibility mode changes. + * @param[in] result The result of the visibility mode changing + * @param[in] visibility_mode The visibility mode to be changed + * @param[in] user_data The user data passed from the callback registration function + * + * @pre This function will be invoked when the visibility of Bluetooth adapter changes + * if you register this callback using bt_adapter_set_visibility_mode_changed_cb(). + * + * @see bt_adapter_set_visibility_mode_changed_cb() + * @see bt_adapter_unset_visibility_mode_changed_cb() + */ +typedef void (*bt_adapter_visibility_mode_changed_cb) + (int result, bt_adapter_visibility_mode_e visibility_mode, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called every second until the visibility mode is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE. + * @remarks This callback function is called only if visibility mode is #BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE. + * @param[in] duration The duration until the visibility mode is changed to #BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE (in seconds) + * @param[in] user_data The user data passed from the callback registration function + * @pre This function will be invoked if you register this callback using bt_adapter_set_visibility_duration_changed_cb(). + * @see bt_adapter_set_visibility_duration_changed_cb() + * @see bt_adapter_unset_visibility_duration_changed_cb() + */ +typedef void (*bt_adapter_visibility_duration_changed_cb)(int duration, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when the state of device discovery changes. + * + * @remarks If \a discovery_state is #BT_ADAPTER_DEVICE_DISCOVERY_FOUND, + * then you can get some information, such as remote device address, remote device name, rssi, and bonding state. + * + * @param[in] result The result of the device discovery + * @param[in] discovery_state The discovery state to be changed + * @param[in] discovery_info The information of the discovered device \n + * If \a discovery_state is #BT_ADAPTER_DEVICE_DISCOVERY_STARTED or + * #BT_ADAPTER_DEVICE_DISCOVERY_FINISHED, then \a discovery_info is NULL. + * @param[in] user_data The user data passed from the callback registration function + * + * @pre Either bt_adapter_start_device_discovery() or bt_adapter_stop_device_discovery() will invoke this function + * if you register this callback using bt_adapter_set_device_discovery_state_changed_cb(). + * + * @see bt_adapter_start_device_discovery() + * @see bt_adapter_stop_device_discovery() + * @see bt_adapter_set_device_discovery_state_changed_cb() + * @see bt_adapter_unset_device_discovery_state_changed_cb() + * + */ +typedef void (*bt_adapter_device_discovery_state_changed_cb) + (int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when you get bonded devices repeatedly. + * + * @param[in] device_info The bonded device information + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * \n @c false to break out of the loop. + * @pre bt_adapter_foreach_bonded_device() will invoke this function. + * + * @see bt_adapter_foreach_bonded_device() + * + */ +typedef bool (*bt_adapter_bonded_device_cb)(bt_device_info_s *device_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when the connectable state changes. + * @param[in] result The result of the connectable state changing + * @param[in] connectable The connectable to be changed + * @param[in] user_data The user data passed from the callback registration function + * + * @pre This function will be invoked when the connectable state of local Bluetooth adapter changes + * if you register this callback using bt_adapter_set_connectable_changed_cb(). + * + * @see bt_adapter_set_connectable() + * @see bt_adapter_set_connectable_changed_cb() + * @see bt_adapter_unset_connectable_changed_cb() + */ +typedef void (*bt_adapter_connectable_changed_cb) + (int result, bool connectable, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Called when the state of LE device discovery changes. + * + * @remarks If \a discovery_state is #BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND, + * then you can get some information, such as remote LE device address, remote device name, rssi, and bonding state. + * + * @param[in] result The result of the LE device discovery + * @param[in] discovery_state The discovery state to be changed + * @param[in] discovery_info The information of the discovered LE device \n + * If \a discovery_state is #BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED or + * #BT_ADAPTER_LE_DEVICE_DISCOVERY_FINISHED, then \a discovery_info is NULL. + * @param[in] user_data The user data passed from the callback registration function + * + * @pre Either bt_adapter_start_device_discovery() or bt_adapter_stop_device_discovery() will invoke this function + * if you register this callback using bt_adapter_set_device_discovery_state_changed_cb(). + * + * @see bt_adapter_le_start_device_discovery() + * @see bt_adapter_le_stop_device_discovery() + * @see bt_adapter_le_set_device_discovery_state_changed_cb() + * @see bt_adapter_le_unset_device_discovery_state_changed_cb() + * + */ +typedef void (*bt_adapter_le_device_discovery_state_changed_cb) + (int result, bt_adapter_le_device_discovery_state_e discovery_state, bt_adapter_le_device_discovery_info_s *discovery_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Called when the state of advertiser changes. + * + * @param[out] result The result of the requested state change of advertiser + * @param[out] advertiser The handle of the state changed advertiser + * @param[out] adv_state The advertiser state to be changed + * @param[out] user_data The user data passed from the start function + * + * @see bt_adapter_le_start_advertiser() + * @see bt_adapter_le_stop_advertiser() + */ +typedef void (*bt_adapter_le_advertising_state_changed_cb)(int result, + bt_advertiser_h advertiser, bt_adapter_le_advertising_state_e adv_state, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Called when the Bluetooth adapter le state changes. + * @param[in] result The result of the adapter state changing + * @param[in] adapter_le_state The adapter le state to be changed + * @param[in] user_data The user data passed from the callback registration function + * @pre Either bt_adapter_le_enable() or bt_adapter_le_disable() will invoke this callback if you register this callback using bt_adapter_le_set_state_changed_cb(). + * @see bt_adapter_le_enable() + * @see bt_adapter_le_disable() + * @see bt_adapter_le_set_state_changed_cb() + * @see bt_adapter_le_unset_state_changed_cb() + */ +typedef void (*bt_adapter_le_state_changed_cb)(int result, bt_adapter_le_state_e adapter_le_state, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when the process of creating bond finishes. + * @remarks If the remote user does not respond within 60 seconds, a time out will happen with #BT_ERROR_TIMED_OUT result code.\n + * If bt_device_cancel_bonding() is called and it returns #BT_ERROR_NONE, then this callback function will be called + * with #BT_ERROR_CANCELLED result. \n + * If creating a bond succeeds but service search fails, then this callback will be called with #BT_ERROR_SERVICE_SEARCH_FAILED. + * In this case, you should try service search again by bt_device_start_service_search() to get the supported service list. + * + * @param[in] result The result of the bonding device + * @param[in] device_info The device information which you creates bond with + * @param[in] user_data The user data passed from the callback registration function + * + * @pre Either bt_device_create_bond() will invoke this function + * if you register this callback using bt_device_set_bond_created_cb(). + * + * @see bt_device_create_bond() + * @see bt_device_cancel_bonding() + * @see bt_device_set_bond_created_cb() + * @see bt_device_unset_bond_created_cb() + */ +typedef void (*bt_device_bond_created_cb)(int result, bt_device_info_s *device_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when you get connected profiles repeatedly. + * @param[in] profile The connected Bluetooth profile + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * \n @c false to break out of the loop. + * @pre bt_device_foreach_connected_profiles() will invoke this function. + * @see bt_device_foreach_connected_profiles() + */ +typedef bool (*bt_device_connected_profile)(bt_profile_e profile, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when the bond destroys. + * @param[in] result The result that a bond is destroyed + * @param[in] remote_address The address of the remote Bluetooth device to destroy bond with + * @param[in] user_data The user data passed from the callback registration function + * @pre bt_device_destroy_bond() will invoke this function + * if you register this callback using bt_device_set_bond_destroyed_cb(). + * + * @see bt_device_destroy_bond() + * @see bt_device_set_bond_destroyed_cb() + * @see bt_device_unset_bond_destroyed_cb() + */ +typedef void (*bt_device_bond_destroyed_cb)(int result, char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when the authorization of device changes. + * @param[in] authorization The authorization of device + * @param[in] remote_address The address of the remote Bluetooth device which is (un)authorized + * @param[in] user_data The user data passed from the callback registration function + * @pre bt_device_set_authorization() will invoke this function if you register this callback using bt_device_set_authorization_changed_cb(). + * + * @see bt_device_set_authorization() + * @see #bt_device_set_authorization_changed_cb() + * @see #bt_device_unset_authorization_changed_cb() + */ +typedef void (*bt_device_authorization_changed_cb) + (bt_device_authorization_e authorization, char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when the process of service search finishes. + * @remark If bt_device_cancel_service_search() is called and it returns #BT_ERROR_NONE, + * then this callback function will be called with #BT_ERROR_CANCELLED result. + * + * @param[in] result The result of the service searching + * @param[in] sdp_info The structure of service lists found on a device + * @param[in] user_data The user data passed from the callback registration function + * @pre Either bt_device_start_service_search() will invoke this function + * if you register this callback using bt_device_set_service_searched_cb(). + * + * @see bt_device_start_service_search() + * @see bt_device_cancel_service_search() + * @see bt_device_set_service_searched_cb() + * @see bt_device_unset_service_searched_cb() + * + */ +typedef void (*bt_device_service_searched_cb)(int result, bt_device_sdp_info_s *sdp_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when the connection state is changed. + * @param[in] connected The connection status: (@c true = connected, @c false = disconnected) + * @param[in] conn_info The connection information + * @param[in] user_data The user data passed from the callback registration function + * @see bt_device_set_connection_state_changed_cb() + * @see bt_device_unset_connection_state_changed_cb() + */ +typedef void (*bt_device_connection_state_changed_cb)(bool connected, bt_device_connection_info_s *conn_info, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Called when you receive data. + * + * @param[in] data The received data from the remote device + * @param[in] user_data The user data passed from the callback registration function + * + * @pre When the connected remote Bluetooth device invokes bt_socket_send_data(), + * this function will be invoked if you register this function using bt_socket_set_data_received_cb(). + * + * @see bt_socket_set_data_received_cb() + * @see bt_socket_unset_data_received_cb() + * @see bt_socket_send_data() + */ +typedef void (*bt_socket_data_received_cb)(bt_socket_received_data_s *data, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Called when the socket connection state changes. + * @param[in] result The result of connection state changing + * @param[in] connection_state The connection state + * @param[in] connection The connection information which is established or disconnected + * @param[in] user_data The user data passed from the callback registration function + * @pre Either bt_socket_connect_rfcomm() will invoke this function. + * In addtion, bt_socket_connection_state_changed_cb() will be invoked when the socket connection state is changed. + * @see bt_socket_listen_and_accept_rfcomm() + * @see bt_socket_connect_rfcomm() + * @see bt_socket_set_connection_state_changed_cb() + * @see bt_socket_unset_connection_state_changed_cb() + */ +typedef void (*bt_socket_connection_state_changed_cb) + (int result, bt_socket_connection_state_e connection_state, bt_socket_connection_s *connection, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_SOCKET_MODULE + * @brief Called when a RFCOMM connection is requested. + * @details You must call bt_socket_accept() if you want to accept. Otherwise, you must call bt_socket_reject(). + * @param[in] socket_fd The file descriptor of socket on which a connection is requested + * @param[in] remote_address The address of remote device + * @param[in] user_data The user data passed from the callback registration function + * @pre If you register this callback function by bt_socket_set_connection_requested_cb() and listen a socket by bt_socket_listen(), + * bt_socket_connection_requested_cb() will be invoked. + * @see bt_socket_listen() + * @see bt_socket_accept() + * @see bt_socket_reject() + */ +typedef void (*bt_socket_connection_requested_cb) (int socket_fd, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Called when the push is requested. + * @details You must call bt_opp_server_accept() if you want to accept. + * Otherwise, you must call bt_opp_server_reject(). + * @param[in] file The path of file to be pushed + * @param[in] size The file size (bytes) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_opp_server_initialize() + */ +typedef void (*bt_opp_server_push_requested_cb)(const char *file, int size, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Called when an OPP connection is requested. + * @details You must call bt_opp_server_accept_connection() if you want to accept. + * Otherwise, you must call bt_opp_server_reject_connection(). + * @param[in] remote_address The address of remote device + * @param[in] user_data The user data passed from the callback registration function + * @see bt_opp_server_initialize() + * @see bt_opp_server_accept_connection() + * @see bt_opp_server_reject_connection() + */ +typedef void (*bt_opp_server_connection_requested_cb)(const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Called when a file is being transfered. + * @param[in] file The path of file to be pushed + * @param[in] size The file size (bytes) + * @param[in] percent The progress in percentage (1 ~ 100) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_opp_server_accept() + * @see bt_opp_server_accept_connection() + */ +typedef void (*bt_opp_server_transfer_progress_cb) (const char *file, long long size, int percent, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_SERVER_MODULE + * @brief Called when a transfer is finished. + * @param[in] error_code The result of push + * @param[in] file The path of file to be pushed + * @param[in] size The file size (bytes) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_opp_server_accept() + * @see bt_opp_server_accept_connection() + */ +typedef void (*bt_opp_server_transfer_finished_cb) (int result, const char *file, long long size, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Called when OPP server responds to the push request. + * @param[in] result The result of OPP server response + * @param[in] remote_address The remote address + * @param[in] user_data The user data passed from the callback registration function + * @pre bt_opp_client_push_files() will invoke this function. + * @see bt_opp_client_push_files() + */ +typedef void (*bt_opp_client_push_responded_cb)(int result, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Called when each file is being transfered. + * @param[in] file The path of file to be pushed + * @param[in] size The file size (bytes) + * @param[in] percent The progress in percentage (1 ~ 100). 100 means that a file is transfered completely. + * @param[in] user_data The user data passed from the callback registration function + * @pre bt_opp_client_push_files() will invoke this function. + * @see bt_opp_client_push_files() + */ +typedef void (*bt_opp_client_push_progress_cb)(const char *file, long long size, int percent, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_OPP_CLIENT_MODULE + * @brief Called when the push request is finished. + * @param[in] result The result of the push request + * @param[in] remote_address The remote address + * @param[in] user_data The user data passed from the callback registration function + * @see bt_opp_client_push_files() + */ +typedef void (*bt_opp_client_push_finished_cb)(int result, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_MODULE + * @brief Called when the connection state is changed. + * @details This callback is called when the connection state is changed. + * When you call bt_audio_connect() or bt_audio_disconnect(), this callback is also called with error result even though these functions fail. + * @param[in] result The result of changing the connection state + * @param[in] connected The state to be changed. @a true means connected state, Otherwise, @a false. + * @param[in] remote_address The remote address + * @param[in] type The type of audio profile except #BT_AUDIO_PROFILE_TYPE_ALL + * @param[in] user_data The user data passed from the callback registration function + * @see bt_audio_set_connection_state_changed_cb() + * @see bt_audio_unset_connection_state_changed_cb() + */ +typedef void (*bt_audio_connection_state_changed_cb) (int result, bool connected, const char *remote_address, bt_audio_profile_type_e type, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when the SCO(Synchronous Connection Oriented link) state is changed. + * @details This callback is called when the SCO state is changed. + * When you call bt_ag_open_sco() or bt_ag_close_sco(), this callback is also called with error result even though these functions failed. + * @param[in] result The result of changing the connection state + * @param[in] opened The state to be changed: (@c true = opened, @c false = not opened) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_sco_state_changed_cb() + * @see bt_ag_unset_sco_state_changed_cb() + * @see bt_ag_open_sco() + * @see bt_ag_close_sco() + */ +typedef void (*bt_ag_sco_state_changed_cb) (int result, bool opened, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when a call handling event happened from Hands-Free. + * @param[in] event The call handling event happened from Hands-Free + * @param[in] call_id The call ID + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_call_handling_event_cb() + * @see bt_ag_unset_call_handling_event_cb() + */ +typedef void (*bt_ag_call_handling_event_cb) (bt_ag_call_handling_event_e event, unsigned int call_id, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when a multi call handling event happened from Hands-Free. + * @param[in] event The call handling event happened from Hands-Free + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_multi_call_handling_event_cb() + * @see bt_ag_unset_multi_call_handling_event_cb() + */ +typedef void (*bt_ag_multi_call_handling_event_cb) (bt_ag_multi_call_handling_event_e event, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when a DTMF(Dual Tone Multi Frequency) is transmitted from Hands-Free. + * @param[in] dtmf The DTMF transmitted from Hands-Free + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_dtmf_transmitted_cb() + * @see bt_ag_unset_dtmf_transmitted_cb() + */ +typedef void (*bt_ag_dtmf_transmitted_cb) (const char *dtmf, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when the speaker gain of the remote device is changed. + * @param[in] gain The gain of speaker (0 ~ 15) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_speaker_gain_changed_cb() + * @see bt_ag_unset_speaker_gain_changed_cb() + */ +typedef void (*bt_ag_speaker_gain_changed_cb) (int gain, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when the microphone gain of the remote device is changed. + * @param[in] gain The gain of microphone (0 ~ 15) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_microphone_gain_changed_cb() + * @see bt_ag_unset_microphone_gain_changed_cb() + */ +typedef void (*bt_ag_microphone_gain_changed_cb) (int gain, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Called when the connection state is changed. + * @param[in] connected The state to be changed. @a true means connected state, Otherwise, @a false. + * @param[in] remote_address The remote address + * @param[in] user_data The user data passed from the callback registration function + * @see bt_avrcp_target_initialize() + * @see bt_avrcp_target_deinitialize() + */ +typedef void (*bt_avrcp_target_connection_state_changed_cb) (bool connected, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Called when the equalizer state is changed by the remote control device. + * @param[in] equalizer The equalizer state + * @param[in] user_data The user data passed from the callback registration function + * @see bt_avrcp_set_equalizer_state_changed_cb() + * @see bt_avrcp_unset_equalizer_state_changed_cb() + */ +typedef void (*bt_avrcp_equalizer_state_changed_cb) (bt_avrcp_equalizer_state_e equalizer, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Called when the repeat mode is changed by the remote control device. + * @param[in] repeat The repeat mode + * @param[in] user_data The user data passed from the callback registration function + * @see bt_avrcp_set_repeat_mode_changed_cb() + * @see bt_avrcp_unset_repeat_mode_changed_cb() + */ +typedef void (*bt_avrcp_repeat_mode_changed_cb) (bt_avrcp_repeat_mode_e repeat, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Called when the shuffle mode is changed by the remote control device. + * @param[in] shuffle The shuffle mode + * @param[in] user_data The user data passed from the callback registration function + * @see bt_avrcp_set_shuffle_mode_changed_cb() + * @see bt_avrcp_unset_shuffle_mode_changed_cb() + */ +typedef void (*bt_avrcp_shuffle_mode_changed_cb) (bt_avrcp_shuffle_mode_e shuffle, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AVRCP_MODULE + * @brief Called when the scan mode is changed by the remote control device. + * @param[in] shuffle The shuffle mode + * @param[in] user_data The user data passed from the callback registration function + * @see bt_avrcp_set_scan_mode_changed_cb() + * @see bt_avrcp_unset_scan_mode_changed_cb() + */ +typedef void (*bt_avrcp_scan_mode_changed_cb) (bt_avrcp_scan_mode_e scan, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HID_MODULE + * @brief Called when the connection state is changed. + * @details This callback is called when the connection state is changed. + * When you call bt_hid_host_connect() or bt_hid_host_disconnect(), this callback is also called with error result even though these functions fail. + * @param[in] result The result of changing the connection state + * @param[in] connected The state to be changed. @a true means connected state, Otherwise, @a false. + * @param[in] remote_address The remote address + * @param[in] user_data The user data passed from the callback registration function + * @see bt_hid_host_connect() + * @see bt_hid_host_disconnect() + */ +typedef void (*bt_hid_host_connection_state_changed_cb) (int result, bool connected, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Called when the connection is established. + * @param[in] result The result of connecting to the remote device + * @param[in] remote_address The address of connected remote device + * @param[in] app_id The ID of application + * @param[in] type The type of HDP(Health Device Profile) channel + * @param[in] channel The connected data channel + * @param[in] user_data The user data passed from the callback registration function + * @see bt_hdp_disconnected_cb + * @see bt_hdp_set_connection_state_changed_cb() + * @see bt_hdp_unset_connection_state_changed_cb() + */ +typedef void (*bt_hdp_connected_cb) (int result, const char *remote_address, const char *app_id, + bt_hdp_channel_type_e type, unsigned int channel, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Called when the connection is disconnected. + * @param[in] result The result of disconnecting from the remote device + * @param[in] remote_address The address of disconnected remote device + * @param[in] channel The connected data channel + * @param[in] user_data The user data passed from the callback registration function + * @see bt_hdp_connected_cb + * @see bt_hdp_set_connection_state_changed_cb() + * @see bt_hdp_unset_connection_state_changed_cb() + */ +typedef void (*bt_hdp_disconnected_cb) (int result, const char *remote_address, unsigned int channel, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_HDP_MODULE + * @brief Called when the you receive the data. + * @param[in] channel The connected data channel + * @param[in] data The received data + * @param[in] size The size of received data (byte) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_hdp_set_data_received_cb() + * @see bt_hdp_unset_data_received_cb() + */ +typedef void (*bt_hdp_data_received_cb) (unsigned int channel, const char *data, unsigned int size, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when you get the primary services repeatedly. + * @param[in] service The attribute handle of service + * @param[in] index The index of a service, starts from 0 + * @param[in] total The total number of services + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * \n @c false to break out of the loop. + * @pre bt_gatt_foreach_primary_services() will invoke this function. + * @see bt_gatt_foreach_primary_services() + */ +typedef bool (*bt_gatt_primary_service_cb) (bt_gatt_attribute_h service, int index, int total, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called after the characteristics are discovered by bt_gatt_discover_characteristics(). + * @remarks If bt_gatt_discover_characteristics() failed, then this callback function is called only once with 0 totla and NULL characteristic_handle. + * @param[in] result The result of discovering + * @param[in] index The index of characteristics in a service, starts from 0 + * @param[in] total The total number of characteristics in a service + * @param[in] characteristic The attribute handle of characteristic + * @param[in] user_data The user data passed from the request function + * @return @c true to continue with the next iteration of the loop, + * \n @c false to break out of the loop. + * @pre bt_gatt_discover_characteristics() will invoke this callback. + * @see bt_gatt_discover_characteristics() + */ +typedef bool (*bt_gatt_characteristics_discovered_cb) (int result, int index, int total, bt_gatt_attribute_h characteristic, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when you get the included services repeatedly. + * @param[in] service The attribute handle of service + * @param[in] user_data The user data passed from the foreach function + * @return @c true to continue with the next iteration of the loop, + * \n @c false to break out of the loop. + * @pre bt_gatt_foreach_included_services() will invoke this function. + * @see bt_gatt_foreach_included_services() + */ +typedef bool (*bt_gatt_included_service_cb) (bt_gatt_attribute_h service, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when a characteristic in service is changed. + * @param[in] characteristic The attribute handle of characteristic + * @param[in] value The value of characteristic (byte array) + * @param[in] value_length The length of value + * @param[in] user_data The user data passed from the callback registration function + * @see bt_gatt_set_characteristic_changed_cb() + * @see bt_gatt_unset_characteristic_changed_cb() + */ +typedef void (*bt_gatt_characteristic_changed_cb) (bt_gatt_attribute_h characteristic, unsigned char *value, int value_length, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when a characteristic value is written. + * @see bt_gatt_set_characteristic_value() + */ +typedef void (*bt_gatt_characteristic_write_cb) (int result, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when a characteristic value is read. + * @param[in] value The value of characteristic (byte array) + * @param[in] value_length The length of value + * @param[in] user_data The user data passed from the foreach function + * @see bt_gatt_read_characteristic_value() + */ +typedef void (*bt_gatt_characteristic_read_cb) (unsigned char *value, + int value_length, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called after the characteristics descriptors are discovered by bt_gatt_discover_characteristic_descriptor(). + * @param[in] result The result of discovering + * @param[in] characteristic_format The format of the information data. + * characteristic_format = 0x01 indicates UUIDs are 16-bits + * characteristic_format = 0x02 indicates UUIDs are 128-bits + * @param[in] total The total number of elements in characteristic_descriptor + * @param[in] characteristic descriptor The attribute handle and the UUID of characteristic descriptor + * @param[in] characteristic The attribute handle and the UUID of characteristic + * @param[in] user_data The user data passed from the request function + * @see bt_gatt_discover_characteristic_descriptor() + */ +typedef void (*bt_gatt_characteristic_descriptor_discovered_cb) (int result, + unsigned char characteristic_format, int total, + bt_gatt_attribute_h characteristic_descriptor, + bt_gatt_attribute_h characteristic, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when the connection state is changed. + * @details This callback is called when the connection state is changed. + * When you called bt_gatt_connect() or bt_gatt_disconnect(), this callback is also called with error result even though these functions fail. + * + * @param[in] result The result of changing the connection state. + * @param[in] connected The state to be changed, @a true means connected state, Otherwise, @a false. + * @param[in] remote_address The remote_address + * @param[in] user_data The user data passed from the callback registration function. + * + * @see bt_gatt_connect() + * @see bt_gatt_disconnect() + * @see bt_gatt_set_connection_state_changed_cb() + * @see bt_gatt_unset_connection_state_changed_cb() + */ +typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected, const char *remote_address, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_MODULE + * @brief Called when the remote devices writes a characteristic to the server db. + * @details This callback is called when the remote client device writes a characteristics + * to the server attribute database. + * + * @param[in] char_path Characteristic path for which the value is writtten. + * @param[in] char_value The characteristic value + * @param[in] value_length The length of the characteristic value written. + * @param[in] remote_address remote client device bd address. + * + * @see bt_gatt_connect() + */ +typedef void (*bt_gatt_remote_characteristic_write_cb) (char *char_path, + unsigned char* char_value, int value_length, + const char *remote_address, + void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_NAP_MODULE + * @brief Called when the connection state is changed. + * @param[in] connected Indicates whether a client is connected or disconnected + * @param[in] remote_address The remote address + * @param[in] interface_name The interface name. For example, bnep0, bnep1. + * @param[in] user_data The user data passed from the callback registration function + * @see bt_nap_set_connection_state_changed_cb() + * @see bt_nap_unset_connection_state_changed_cb() + */ +typedef void (*bt_nap_connection_state_changed_cb) (bool connected, const char *remote_address, const char *interface_name, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_PAN_PANU_MODULE + * @brief Called when the connection state is changed. + * @details This callback is called when the connection state is changed. + * When you call bt_panu_connect() or bt_panu_disconnect(), this callback is also called with error result even though these functions fail. + * @param[in] result The result of changing the connection state + * @param[in] connected The state to be changed. @a true means connected state, Otherwise, @a false. + * @param[in] remote_address The remote address + * @param[in] type The type of PAN service + * @param[in] user_data The user data passed from the callback registration function + * @see bt_nap_set_connection_state_changed_cb() + * @see bt_nap_unset_connection_state_changed_cb() + */ +typedef void (*bt_panu_connection_state_changed_cb) (int result, bool connected, const char *remote_address, bt_panu_service_type_e type, void *user_data); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __TIZEN_NETWORK_BLUETOOTH_TYPE_H__ diff --git a/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_product.h b/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_product.h new file mode 100644 index 0000000..74f2b55 --- /dev/null +++ b/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_product.h @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file + * + * + */ + +#ifndef __TIZEN_NETWORK_BLUETOOTH_PRODUCT_H__ +#define __TIZEN_NETWORK_BLUETOOTH_PRODUCT_H__ + +#include "bluetooth_type.h" +#include "bluetooth_type_product.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Sets the manufacturer data of local Bluetooth adapter. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] data The manufacturer specific data of the Bluetooth device. + * @param[in] len The length of @a data.Maximaum length is 240 bytes. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @post bt_adapter_manufacturer_data_changed_cb() will be invoked + * if this function returns #BT_ERROR_NONE. + * + * @see bt_adapter_manufacturer_data_changed_cb + * @see bt_adapter_set_manufacturer_data_changed_cb() + * @see bt_adapter_unset_manufacturer_data_changed_cb() + */ +int bt_adapter_set_manufacturer_data(char *data, int len); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Registers a callback function to be invoked + * when the manufacturer data of Bluetooth adapter changes. + * @since_tizen 2.3 + * + * @param[in] callback The callback function to invoke + * @param[in] user_data The user data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @post bt_adapter_manufacturer_data_changed_cb() will be invoked. + * + * @see bt_initialize() + * @see bt_adapter_unset_manufacturer_data_changed_cb() + */ +int bt_adapter_set_manufacturer_data_changed_cb( + bt_adapter_manufacturer_data_changed_cb callback, + void *user_data); + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Unregisters the callback function. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * + * @pre The Bluetooth service must be initialized with bt_initialize(). + * + * @see bt_initialize() + * @see bt_adapter_set_manufacturer_data_changed_cb() + */ +int bt_adapter_unset_manufacturer_data_changed_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Sets the scan interval and widow, synchronously. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] scan_params The parameters of le scanning \n + * If NULL is passed, default values which are defined in driver / controller are used. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_ENABLED Adapter is not enabled + * @retval #BT_ERROR_INVALID_PARAM Parameter is invalid + * @pre The state of local Bluetooth must be #BT_ADAPTER_ENABLED. + * @pre The Bluetooth service must be initialized with bt_initialize(). + * @see bt_initialize() + */ +int bt_adapter_le_set_scan_parameter(bt_adapter_le_scan_params_s *scan_params); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Enables RSSI monitoring and sets threshold for LE/ACL link present with the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] remote_address The address of the remote Bluetooth device for which RSSI is to be monitored + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] low_threshold Lower threshold value for the LE Link in dBm. + * @param[in] in_range_threshold In-Range threshold value for the LE Link in dBm. + * @param[in] cb_enable Callback to be called when RSSI monitoring is enabled. + * @param[in] user_data_enable Data to be passed to RSSI enable callback. + * @param[in] cb_alert Callback to receive RSSI Alert values. + * @param[in] user_data_alert Data to be passed to RSSI Alert callback. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @remarks High Threshold value is set to 127. + * + * @see bt_device_unset_rssi_alert_cb() + * @see bt_device_disable_rssi_monitor() + */ +int bt_device_enable_rssi_monitor(const char *remote_address, + bt_device_connection_link_type_e link_type, + int low_threshold, int in_range_threshold, + bt_rssi_monitor_enabled_cb cb_enable, void *user_data_enable, + bt_rssi_alert_cb cb_alert, void *user_data_alert); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Disables RSSI monitoring for LE/ACL link present with the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] remote_address The address of the remote Bluetooth device for which RSSI monitoring is to be disabled + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] cb_disable Callback to be called when RSSI monitoring is disabled. + * @param[in] user_data_enable Data to be passed to RSSI enable callback. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @remarks Low Threshold, In-range Threshold and High Threshold value are set to 0 to disable RSSI monitoring. + * @remarks This also calls bt_device_unset_rssi_alert_cb() + * + * @see bt_device_unset_rssi_alert_cb() + * @see bt_device_enable_rssi_monitor() + */ +int bt_device_disable_rssi_monitor(const char *remote_address, + bt_device_connection_link_type_e link_type, + bt_rssi_monitor_enabled_cb cb_disable, void *user_data_disable); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Get Raw RSSI for LE link present with the remote device. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * + * @param[in] remote_address The address of the remote Bluetooth device for which RSSI is to be monitored + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] callback Callback to receive Raw RSSI values. + * @param[in] user_data Data to be passed to Raw RSSI callback. + * + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_RESOURCE_BUSY Device or resource busy + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * + * @see bt_device_le_unset_rssi_strength_cb() + */ +int bt_device_get_rssi_strength(const char *remote_address, + bt_device_connection_link_type_e link_type, + bt_rssi_strength_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Unset the callback to receive RSSI Alert values. + * @since_tizen 2.3 + * + * @return 0 on success, otherwise a negative error value. + * + * @see bt_device_le_enable_rssi() + */ +int bt_device_unset_rssi_alert_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Notifies the XSAT vendor command to the remote. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] state The XSAT vendor dependent command string. Ex: "AT+SAT= 00,TY,WA" + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_BONDED Remote device is not bonded + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @retval #BT_ERROR_OPERATION_FAILED Operation failed + * @pre The Bluetooth audio device must be connected with bt_audio_connect(). + * @see bt_audio_connect() + */ +int bt_ag_notify_vendor_cmd(const char *command); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Registers a callback function that will be invoked when a XSATvendor AT command is transmitted from Hands-Free. + * @since_tizen 2.3 + * @param[in] callback The callback function to register + * @param[in] user_data The user data to be passed to the callback function + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_vendor_cmd_cb() + * @see bt_ag_unset_vendor_cmd_cb() + */ +int bt_ag_set_vendor_cmd_cb(bt_ag_vendor_cmd_cb callback, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Unregisters a callback function that will be invoked when a XSATvendor AT command is transmitted from Hands-Free + * @since_tizen 2.3 + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @pre The Bluetooth audio service must be initialized with bt_audio_initialize(). + * @see bt_audio_initialize() + * @see bt_ag_vendor_cmd_cb() + * @see bt_ag_set_vendor_cmd_cb() + */ +int bt_ag_unset_vendor_cmd_cb(void); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Checks whether the remoted device is wbs (Wide Band Speech) mode or not. + * @since_tizen 2.3 + * @param[out] wbs_mode The wbs status: (@c true = wide band speech, @c false = narrow band speech) + * @return 0 on success, otherwise a negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_NOT_INITIALIZED Not initialized + * @retval #BT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #BT_ERROR_NOT_ENABLED Not enabled + * @retval #BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED Remote device is not connected + * @pre The remote device is connected by bt_audio_connect() with #BT_AUDIO_PROFILE_TYPE_HSP_HFP service. + * @see bt_audio_connect() + */ +int bt_ag_is_wbs_mode(bool *wbs_mode); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_A2DP_MODULE + * @brief Sets copy protection. streaming application that needs to have the copy protection for the streaming data, shall invoke this API. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://tizen.org/privilege/bluetooth.admin + * @param[in] status - TRUE/FALSE + * @return 0 on success, otherwise negative error value. + * @retval #BT_ERROR_NONE Successful + * @retval #BT_ERROR_OPERATION_FAILED on failure + */ +int bt_a2dp_set_content_protection(bool status); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __TIZEN_NETWORK_BLUETOOTH_PRODUCT_H__ diff --git a/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_type_product.h b/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_type_product.h new file mode 100644 index 0000000..999b847 --- /dev/null +++ b/resource/csdk/connectivity/lib/tizen/ble/inc/mobile/bluetooth_type_product.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file + * + * + */ + +#ifndef __TIZEN_NETWORK_BLUETOOTH_TYPE_PRODUCT_H__ +#define __TIZEN_NETWORK_BLUETOOTH_TYPE_PRODUCT_H__ + + #ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Enumerations of the Bluetooth adapter le scan type. + */ +typedef enum +{ + BT_ADAPTER_LE_PASSIVE_SCAN = 0x00, + BT_ADAPTER_LE_ACTIVE_SCAN +} bt_adapter_le_scan_type_e; + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_LE_MODULE + * @brief Structure of le scan parameters + * + * @see bt_adapter_le_set_scan_parameter() + * @see bt_adapter_le_start_device_discovery() + */ +typedef struct { + bt_adapter_le_scan_type_e type; /**< LE scan type */ + float interval; /**< LE scan interval */ + float window; /**< LE scan window */ +} bt_adapter_le_scan_params_s; + +/** + * @internal + * @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE + * @brief Called when the manufacturer dat changes. + * @param[in] data The manufacurer data of the Bluetooth device to be changed + * @param[in] len The length of @a data + * @param[in] user_data The user data passed from the callback registration function + * @pre This function will be invoked when the manufacturer data of Bluetooth adapter changes + * if callback is registered using bt_adapter_set_manufacturer_data_changed_cb(). + * @see bt_adapter_set_manufacturer_data() + * @see bt_adapter_set_manufacturer_data_changed_cb() + * @see bt_adapter_unset_manufacturer_data_changed_cb() + */ +typedef void (*bt_adapter_manufacturer_data_changed_cb) (char *data, + int len, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when RSSI monitoring is enabled. + * @param[in] remote_address Remote Device address + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] rssi_enabled RSSI monitoring status (@c 1 = enabled, @c 0 = disabled) + * @param[in] user_data The user data passed from the callback registration function + * @see bt_device_enable_rssi_monitor() + * @see bt_device_disable_rssi_monitor() + */ +typedef void (*bt_rssi_monitor_enabled_cb)(const char *remote_address, + bt_device_connection_link_type_e link_type, + int rssi_enabled, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when RSSI Alert is received. + * @param[in] remote_address Remote Device address + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] rssi_alert_type RSSI Alert type (@c 1 = High Alert (In-Range Alert), @c 2 = Low Alert) + * @param[in] rssi_alert_dbm RSSI Alert signal strength value + * @param[in] user_data The user data passed from the callback registration function + * @see bt_device_enable_rssi_monitor() + * @see bt_device_disable_rssi_monitor() + */ +typedef void (*bt_rssi_alert_cb)(char *bt_address, + bt_device_connection_link_type_e link_type, + int rssi_alert_type, int rssi_alert_dbm, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_DEVICE_MODULE + * @brief Called when Raw RSSI signal strength is received. + * @param[in] remote_address Remote Device address + * @param[in] link_type Link type for the connection (@c 0 = BR/EDR link, @c 1 = LE link). + * @param[in] rssi_dbm Raw RSSI signal strength value + * @param[in] user_data The user data passed from the callback registration function + * @see bt_device_get_rssi_strength() + */ +typedef void (*bt_rssi_strength_cb)(char *bt_address, + bt_device_connection_link_type_e link_type, + int rssi_dbm, void *user_data); + +/** + * @ingroup CAPI_NETWORK_BLUETOOTH_AUDIO_AG_MODULE + * @brief Called when a XSAT vendor command is transmitted from Hands-Free. + * @param[in] command The XSAT vendor command transmitted from Hands-Free + * @param[in] user_data The user data passed from the callback registration function + * @see bt_ag_set_vendor_cmd_cb() + * @see bt_ag_unset_vendor_cmd_cb() + */ +typedef void (*bt_ag_vendor_cmd_cb) (char *command, void *user_data); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // __TIZEN_NETWORK_BLUETOOTH_TYPE_PRODUCT_H__ diff --git a/resource/csdk/connectivity/samples/android/SConscript b/resource/csdk/connectivity/samples/android/SConscript new file mode 100644 index 0000000..e3a4f18 --- /dev/null +++ b/resource/csdk/connectivity/samples/android/SConscript @@ -0,0 +1,51 @@ +## +# Building sample application +## + +Import('env') + +app_env = env.Clone() + +ca_os = app_env.get('TARGET_OS') +ca_transport = app_env.get('TARGET_TRANSPORT') +secured = app_env.get('SECURED') + +root_dir = './../../' +main_dir = Dir('.').srcnode().abspath +jni_dir = main_dir + '/sample_serivce/android/jni' +env.PrependUnique(CPPPATH = ['jni_dir']) +app_env.PrependUnique(CPPDEFINES = ['__ANDROID__']) + +##################################################################### +# Source files and Target(s) +###################################################################### + +print"Reading ca script %s"%ca_transport + +app_env.AppendUnique(CPPPATH = [root_dir + '/api/']) + +print "Reading sample application build script" + +build_dir = app_env.get('BUILD_DIR') +secured = app_env.get('SECURED') + +print "Sample secured flag is %s" % secured + +sample_dir = 'sample_service/jni/' +sample_src = [sample_dir + 'ResourceModel.c',] + +print " sample src %s" % sample_src + +app_env.AppendUnique(LIBPATH = [app_env.get('BUILD_DIR'), '.',]) +app_env.AppendUnique(CPPPATH = ['lib/android']) +app_env.PrependUnique(LIBS = ['connectivity_abstraction']) + + +if secured == '1': + app_env.AppendUnique(CPPPATH = [root_dir + 'external/inc/']) + app_env.PrependUnique(CPPDEFINES = ['__WITH_DTLS__']) + +libRMInterface = app_env.SharedLibrary('RMInterface', sample_src, OBJPREFIX='libRMInterface_') +app_env.InstallTarget(libRMInterface, 'RMInterface') + + diff --git a/resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml b/resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml new file mode 100644 index 0000000..91fcef9 --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk b/resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk new file mode 100644 index 0000000..55ac16d --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk @@ -0,0 +1,27 @@ +APP_PATH := $(call my-dir) +#specify project root path here wrt make file directory +PROJECT_ROOT_PATH = ../../.. + +include $(CLEAR_VARS) +LOCAL_PATH := $(APP_PATH) +LOCAL_MODULE := CAInterface +LOCAL_STATIC_LIBRARIES = CA +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_PATH := $(APP_PATH) +LOCAL_MODULE := RMInterface +LOCAL_SRC_FILES := ResourceModel.c +LOCAL_STATIC_LIBRARIES := CA +LOCAL_LDLIBS := -llog +LOCAL_C_INCLUDES := ../../../api +include $(BUILD_SHARED_LIBRARY) + +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +#Build CACommon CACoap CA +include $(CLEAR_VARS) +PROJECT_ROOT_PATH = ../../.. +CA_LIB_PATH = $(PROJECT_ROOT_PATH)/build/android +include $(CA_LIB_PATH)/jni/Android.mk +#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk b/resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk new file mode 100644 index 0000000..a0e5d81 --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk @@ -0,0 +1,6 @@ +APP_STL := gnustl_shared + +APP_PLATFORM = android-21 +APP_CPPFLAGS += -fexceptions +APP_CPPFLAGS += -frtti +APP_CFLAGS = -Wno-error=format-security diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c b/resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c new file mode 100644 index 0000000..acca05d --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c @@ -0,0 +1,1322 @@ +#include +#include +#include +#include +#include +#include + +#include "cainterface.h" +#include "cacommon.h" + +#include "org_iotivity_service_RMInterface.h" + +#define LOG_TAG "JNI_INTERFACE_SAMPLE" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +/** + * @def RS_IDENTITY + * @brief + */ +#define IDENTITY ("1111111111111111") +/* @def RS_CLIENT_PSK + * @brief + */ +#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA") + +#define PORT_LENGTH 5 +#define SECURE_DEFAULT_PORT 5684 +#define RESOURCE_URI_LENGTH 14 +#define OPTION_INFO_LENGTH 1024 +#define NETWORK_INFO_LENGTH 1024 + +uint16_t g_localSecurePort = SECURE_DEFAULT_PORT; + +void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo); +void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo); +void get_resource_uri(const char *URI, char *resourceURI, uint32_t length); +uint32_t get_secure_information(CAPayload_t payLoad); +CAResult_t get_network_type(uint32_t selectedNetwork); +void callback(char *subject, char *receivedData); +CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo); + +CATransportType_t g_selectedNwType = CA_IPV4; +static CAToken_t g_lastRequestToken = NULL; +static uint8_t g_lastRequestTokenLength; + +static const char SECURE_COAPS_PREFIX[] = "coaps://"; + +static const char SECURE_INFO_DATA[] + = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"]," + "\"if\":[\"oic.if.baseline\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}"; +static const char NORMAL_INFO_DATA[] + = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"]," + "\"if\":[\"oic.if.baseline\"],\"obs\":1}}]}"; + + +static jobject g_responseListenerObject = NULL; +static JavaVM *g_jvm; + +static CARemoteEndpoint_t *g_clientEndpoint = NULL; +static CAToken_t g_clientToken; +static uint8_t g_clientTokenLength = NULL; + +static uint16_t g_clientMsgId; +static char *g_remoteAddress = NULL; + +// init +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_setNativeResponseListener(JNIEnv *env, jobject obj, + jobject listener) +{ + LOGI("setNativeResponseListener"); + g_responseListenerObject = (*env)->NewGlobalRef(env, obj); +} + +#ifdef __WITH_DTLS__ +static CADtlsPskCredsBlob_t *pskCredsBlob = NULL; + +void clearDtlsCredentialInfo() +{ + LOGI("clearDtlsCredentialInfo IN"); + if (pskCredsBlob) + { + // Initialize sensitive data to zeroes before freeing. + if (NULL != pskCredsBlob->creds) + { + memset(pskCredsBlob->creds, 0, sizeof(OCDtlsPskCreds)*(pskCredsBlob->num)); + free(pskCredsBlob->creds); + } + + memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t)); + free(pskCredsBlob); + pskCredsBlob = NULL; + } + LOGI("clearDtlsCredentialInfo OUT"); +} + +// Internal API. Invoked by OC stack to retrieve credentials from this module +void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo) +{ + LOGI("CAGetDtlsPskCredentials IN"); + *credInfo = (CADtlsPskCredsBlob_t *) malloc(sizeof(CADtlsPskCredsBlob_t)); + if (NULL == *credInfo) + { + LOGE("Failed to allocate credential blob."); + return; + } + + int16_t credLen = sizeof(OCDtlsPskCreds) * (pskCredsBlob->num); + (*credInfo)->creds = (OCDtlsPskCreds *) malloc(credLen); + if (NULL == (*credInfo)->creds) + { + LOGE("Failed to allocate crentials."); + free(*credInfo); + *credInfo = NULL; + return; + } + + memcpy((*credInfo)->identity, pskCredsBlob->identity, DTLS_PSK_ID_LEN); + (*credInfo)->num = pskCredsBlob->num; + memcpy((*credInfo)->creds, pskCredsBlob->creds, credLen); + + LOGI("CAGetDtlsPskCredentials OUT"); +} + +CAResult_t SetCredentials() +{ + LOGI("SetCredentials IN"); + pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t)); + if (NULL == pskCredsBlob) + { + LOGE("Memory allocation failed!"); + return CA_MEMORY_ALLOC_FAILED; + } + memcpy(pskCredsBlob->identity, IDENTITY, DTLS_PSK_ID_LEN); + + pskCredsBlob->num = 1; + + pskCredsBlob->creds = (OCDtlsPskCreds *)malloc(sizeof(OCDtlsPskCreds) *(pskCredsBlob->num)); + if (NULL == pskCredsBlob->creds) + { + LOGE("Memory allocation failed!"); + return CA_MEMORY_ALLOC_FAILED; + } + memcpy(pskCredsBlob->creds[0].id, IDENTITY, DTLS_PSK_ID_LEN); + memcpy(pskCredsBlob->creds[0].psk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN); + + LOGI("SetCredentials OUT"); + return CA_STATUS_OK; +} +#endif + +JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved) +{ + LOGI("JNI_OnLoad"); + + JNIEnv* env; + if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6)) + { + return -1; + } + g_jvm = jvm; /* cache the JavaVM pointer */ + + CANativeJNISetJavaVM(g_jvm); + + return JNI_VERSION_1_6; +} + +void JNI_OnUnload(JavaVM *jvm, void *reserved) +{ + LOGI("JNI_OnUnload"); + + JNIEnv* env; + if (JNI_OK != (*jvm)->GetEnv(jvm, (void**) &env, JNI_VERSION_1_6)) + { + return; + } + g_jvm = 0; + return; +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMInitialize(JNIEnv *env, jobject obj, jobject context) +{ + LOGI("RMInitialize"); + + //Currently set context for Android Platform + CANativeJNISetContext(env, context); + + CAResult_t res = CAInitialize(); + + if (CA_STATUS_OK != res) + { + LOGE("Could not Initialize"); + } + +#ifdef __WITH_DTLS__ + if (CA_STATUS_OK != SetCredentials()) + { + LOGE("SetCredentials failed"); + return; + } + + res = CARegisterDTLSCredentialsHandler(CAGetDtlsPskCredentials); + if(CA_STATUS_OK != res) + { + LOGE("Set credential handler fail"); + return; + } +#endif +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj) +{ + LOGI("RMTerminate"); + CADestroyToken(g_lastRequestToken); + CATerminate(); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env, jobject obj) +{ + LOGI("RMStartListeningServer"); + + if (CA_STATUS_OK != CAStartListeningServer()) + { + LOGE("Could not start Listening server"); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env, jobject obj) +{ + LOGI("RMStartDiscoveryServer"); + + if (CA_STATUS_OK != CAStartDiscoveryServer()) + { + LOGE("Could not start discovery server"); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMRegisterHandler(JNIEnv *env, jobject obj) +{ + LOGI("RMRegisterHandler"); + + CARegisterHandler(request_handler, response_handler); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj, jstring uri) +{ + // create token + CAToken_t token = NULL; + uint8_t tokenLength = CA_MAX_TOKEN_LEN; + + CAResult_t res = CAGenerateToken(&token, tokenLength); + if ((CA_STATUS_OK != res) || (!token)) + { + LOGE("token generate error!!"); + return; + } + + printf("Generated token %s\n", token); + + const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); + LOGI("RMFindResource - %s", strUri); + + res = CAFindResource((const CAURI_t) strUri, token, tokenLength); + + //ReleseStringUTFCharss for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); + + if (CA_STATUS_OK != res) + { + LOGE("Could not find resource"); + //destroy token + CADestroyToken(token); + } + else + { + LOGI("find resource to %s URI", strUri); + CADestroyToken(g_lastRequestToken); + g_lastRequestToken = token; + g_lastRequestTokenLength = tokenLength; + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj, jstring uri, + jstring payload, jint selectedNetwork, + jint isSecured, jint msgType) +{ + LOGI("selectedNetwork - %d", selectedNetwork); + CAResult_t res = get_network_type(selectedNetwork); + if (CA_STATUS_OK != res) + { + return; + } + + const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); + LOGI("RMSendRequest - %s", strUri); + + //create remote endpoint + CARemoteEndpoint_t* endpoint = NULL; + res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint); + + //ReleaseStringUTFChars for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); + + if (CA_STATUS_OK != res) + { + LOGE("Could not create remote end point"); + return; + } + + CAMessageType_t messageType = msgType; + + // create token + CAToken_t token = NULL; + uint8_t tokenLength = CA_MAX_TOKEN_LEN; + + res = CAGenerateToken(&token, tokenLength); + if ((CA_STATUS_OK != res) || (!token)) + { + LOGE("token generate error!!"); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + return; + } + + char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 }; + + get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH); + + CAInfo_t requestData = { 0 }; + requestData.token = token; + requestData.tokenLength = tokenLength; + + if (1 == isSecured) + { + uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI); + requestData.payload = (CAPayload_t) malloc(length); + if (NULL == requestData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + return; + } + snprintf(requestData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort); + } + else + { + uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI); + requestData.payload = (CAPayload_t) malloc(length); + if (NULL == requestData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + return; + } + snprintf(requestData.payload, length, NORMAL_INFO_DATA, resourceURI); + } + + requestData.type = messageType; + + CARequestInfo_t requestInfo = { 0 }; + requestInfo.method = CA_GET; + requestInfo.info = requestData; + + // send request + if (CA_STATUS_OK != CASendRequest(endpoint, &requestInfo)) + { + LOGE("Could not send request"); + } + + // destroy token + CADestroyToken(token); + + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + + free(requestData.payload); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMSendReqestToAll(JNIEnv *env, jobject obj, jstring uri, + jint selectedNetwork) +{ + LOGI("selectedNetwork - %d", selectedNetwork); + CAResult_t res = get_network_type(selectedNetwork); + if (CA_STATUS_OK != res) + { + return; + } + + const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); + LOGI("RMSendReqestToAll - %s", strUri); + + // create remote endpoint + CARemoteEndpoint_t *endpoint = NULL; + res = CACreateRemoteEndpoint((const CAURI_t) strUri, g_selectedNwType, &endpoint); + + //ReleaseStringUTFChars for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); + + if (CA_STATUS_OK != res) + { + LOGE("create remote endpoint error, error code: %d", res); + return; + } + + CAGroupEndpoint_t *group = (CAGroupEndpoint_t *) malloc(sizeof(CAGroupEndpoint_t)); + if (NULL == group) + { + LOGE("Memory allocation failed!"); + CADestroyRemoteEndpoint(endpoint); + return; + } + group->transportType = endpoint->transportType; + group->resourceUri = endpoint->resourceUri; + + // create token + CAToken_t token = NULL; + uint8_t tokenLength = CA_MAX_TOKEN_LEN; + + res = CAGenerateToken(&token, tokenLength); + if ((CA_STATUS_OK != res) || (!token)) + { + LOGE("token generate error!!"); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + free(group); + return; + } + + LOGI("generated token %s", token); + + CAInfo_t requestData = { 0 }; + requestData.token = token; + requestData.tokenLength = tokenLength; + requestData.payload = "Temp Json Payload"; + requestData.type = CA_MSG_NONCONFIRM; + + CARequestInfo_t requestInfo = { 0 }; + requestInfo.method = CA_GET; + requestInfo.info = requestData; + + // send request to all + res = CASendRequestToAll(group, &requestInfo); + if (CA_STATUS_OK != res) + { + LOGE("Could not send request to all"); + //destroy token + CADestroyToken(token); + } + else + { + CADestroyToken(g_lastRequestToken); + g_lastRequestToken = token; + g_lastRequestTokenLength = tokenLength; + } + + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + free(group); + +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj, + jint selectedNetwork, + jint isSecured, jint msgType, + jint responseValue) +{ + LOGI("RMSendResponse"); + + LOGI("selectedNetwork - %d", selectedNetwork); + + CAResult_t res = get_network_type(selectedNetwork); + if (CA_STATUS_OK != res) + { + LOGE("Not supported network type"); + return; + } + + if (NULL == g_clientEndpoint) + { + LOGE("No Request received"); + return; + } + + CAMessageType_t messageType = msgType; + + CAInfo_t responseData = { 0 }; + responseData.type = messageType; + responseData.messageId = g_clientMsgId; + + CAResponseInfo_t responseInfo = { 0 }; + + if (msgType != CA_MSG_RESET) + { + responseData.token = g_clientToken; + responseData.tokenLength = g_clientTokenLength; + responseInfo.result = responseValue; + + if (1 == isSecured) + { + uint32_t length = strlen(SECURE_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1; + responseData.payload = (CAPayload_t) malloc(length); + sprintf(responseData.payload, SECURE_INFO_DATA, g_clientEndpoint->resourceUri, + g_localSecurePort); + } + else + { + uint32_t length = strlen(NORMAL_INFO_DATA) + strlen(g_clientEndpoint->resourceUri) + 1; + responseData.payload = (CAPayload_t) malloc(length); + sprintf(responseData.payload, NORMAL_INFO_DATA, g_clientEndpoint->resourceUri); + } + } + //msgType is RESET + else + { + responseInfo.result = CA_EMPTY; + } + + responseInfo.info = responseData; + + // send response + res = CASendResponse(g_clientEndpoint, &responseInfo); + if (CA_STATUS_OK != res) + { + LOGE("Could not send response"); + } + + // destroy token + CADestroyToken(g_clientToken); + g_clientToken = NULL; + g_clientTokenLength = 0; + + // destroy remote endpoint + CADestroyRemoteEndpoint(g_clientEndpoint); + g_clientEndpoint = NULL; +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMAdvertiseResource(JNIEnv *env, jobject obj, jstring uri) +{ + LOGI("RMAdvertiseResource"); + + uint32_t optionNum = 2; + + CAHeaderOption_t *headerOpt = (CAHeaderOption_t*) calloc(1, + sizeof(CAHeaderOption_t) * optionNum); + if (NULL == headerOpt) + { + LOGE("Memory allocation failed!"); + return; + } + + char* tmpOptionData1 = "Hello"; + headerOpt[0].optionID = 3000; + memcpy(headerOpt[0].optionData, tmpOptionData1, strlen(tmpOptionData1)); + headerOpt[0].optionLength = (uint16_t) strlen(tmpOptionData1); + + char* tmpOptionData2 = "World"; + headerOpt[1].optionID = 3001; + memcpy(headerOpt[1].optionData, tmpOptionData2, strlen(tmpOptionData2)); + headerOpt[1].optionLength = (uint16_t) strlen(tmpOptionData2); + + // create token + CAToken_t token = NULL; + uint8_t tokenLength = CA_MAX_TOKEN_LEN; + + CAResult_t res = CAGenerateToken(&token, tokenLength); + if ((CA_STATUS_OK != res) || (!token)) + { + LOGE("token generate error!"); + free(headerOpt); + return; + } + + const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); + + res = CAAdvertiseResource((const CAURI_t) strUri, token, tokenLength, + headerOpt, (uint8_t) optionNum); + if (CA_STATUS_OK != res) + { + LOGE("Could not start advertise resource"); + CADestroyToken(token); + } + else + { + CADestroyToken(g_lastRequestToken); + g_lastRequestToken = token; + g_lastRequestTokenLength = tokenLength; + } + + free(headerOpt); + + //ReleaseStringUTFChars for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env, jobject obj, jstring uri, + jstring payload, jint selectedNetwork, + jint isSecured, jint msgType, + jint responseValue) +{ + LOGI("selectedNetwork - %d", selectedNetwork); + + CAResult_t res = get_network_type(selectedNetwork); + if (CA_STATUS_OK != res) + { + LOGE("Not supported network type"); + return; + } + + const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL); + LOGI("RMSendNotification - %s", strUri); + + //create remote endpoint + CARemoteEndpoint_t* endpoint = NULL; + if (CA_STATUS_OK != CACreateRemoteEndpoint((const CAURI_t) strUri, + g_selectedNwType, &endpoint)) + { + //ReleaseStringUTFChars for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); + LOGE("Could not create remote end point"); + return; + } + + char resourceURI[RESOURCE_URI_LENGTH + 1] = { 0 }; + get_resource_uri((const CAURI_t) strUri, resourceURI, RESOURCE_URI_LENGTH); + + //ReleaseStringUTFChars for strUri + (*env)->ReleaseStringUTFChars(env, uri, strUri); + + CAMessageType_t messageType = msgType; + + // create token + CAToken_t token = NULL; + uint8_t tokenLength = CA_MAX_TOKEN_LEN; + + res = CAGenerateToken(&token, tokenLength); + if ((CA_STATUS_OK != res) || (!token)) + { + LOGE("token generate error!"); + CADestroyRemoteEndpoint(endpoint); + return; + } + + CAInfo_t responseData = { 0 }; + responseData.token = token; + responseData.tokenLength = tokenLength; + + if (1 == isSecured) + { + uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(resourceURI); + responseData.payload = (CAPayload_t) malloc(length); + if (NULL == responseData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + return; + } + snprintf(responseData.payload, length, SECURE_INFO_DATA, resourceURI, g_localSecurePort); + } + else + { + uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(resourceURI); + responseData.payload = (CAPayload_t) malloc(length); + if (NULL == responseData.payload) + { + LOGE("Memory allocation failed!"); + // destroy token + CADestroyToken(token); + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + return; + } + snprintf(responseData.payload, length, NORMAL_INFO_DATA, resourceURI); + } + + responseData.type = messageType; + + CAResponseInfo_t responseInfo = { 0 }; + responseInfo.result = responseValue; + responseInfo.info = responseData; + + // send notification + if (CA_STATUS_OK != CASendNotification(endpoint, &responseInfo)) + { + LOGE("Could not send notification"); + } + + LOGI("Send Notification"); + + // destroy token + CADestroyToken(token); + + // destroy remote endpoint + CADestroyRemoteEndpoint(endpoint); + + free(responseData.payload); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj, jint networkType) +{ + LOGI("RMSelectNetwork Type : %d", networkType); + + if (CA_STATUS_OK != CASelectNetwork(networkType)) + { + LOGE("Could not select network"); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMUnSelectNetwork(JNIEnv *env, jobject obj, jint networkType) +{ + LOGI("RMUnSelectNetwork Type : %d", networkType); + + if (CA_STATUS_OK != CAUnSelectNetwork(networkType)) + { + LOGE("Could not unselect network"); + } +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation(JNIEnv *env, jobject obj) +{ + LOGI("RMGetNetworkInfomation"); + + CALocalConnectivity_t *tempInfo = NULL; + uint32_t tempSize = 0; + + CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize); + if (CA_STATUS_OK != res) + { + LOGE("Could not start get network information"); + OICFree(tempInfo); + return; + } + + LOGI("################## Network Information #######################"); + callback("######## Network Information", "#######"); + LOGI("Network info total size is %d", tempSize); + + uint32_t index; + for (index = 0; index < tempSize; index++) + { + res = get_remote_address(tempInfo[index].type, tempInfo[index].addressInfo); + if (CA_STATUS_OK != res) + { + OICFree(tempInfo); + return; + } + if (NULL != g_responseListenerObject) + { + char networkInfo[NETWORK_INFO_LENGTH]; + LOGI("Type: %d", tempInfo[index].type); + sprintf(networkInfo, "%d",tempInfo[index].type); + callback("Type :", networkInfo); + if (CA_IPV4 == tempInfo[index].type) + { + LOGI("Port: %d", tempInfo[index].addressInfo.IP.port); + sprintf(networkInfo, "%d",tempInfo[index].addressInfo.IP.port); + callback("Port: ", networkInfo); + } + LOGI("Secured: %d", tempInfo[index].isSecured); + LOGI("Address: %s", g_remoteAddress); + callback("Address: ", g_remoteAddress); + free(g_remoteAddress); + } + if (true == tempInfo[index].isSecured) + { + g_localSecurePort = tempInfo[index].addressInfo.IP.port; + } + } + + // free + OICFree(tempInfo); + + LOGI("##############################################################"); +} + +JNIEXPORT void JNICALL +Java_org_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env, jobject obj) +{ + LOGI("RMHandleRequestResponse"); + + if (CA_STATUS_OK != CAHandleRequestResponse()) + { + LOGE("Could not handle request and response"); + } +} + +void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo) +{ + + if (!object) + { + LOGE("Remote endpoint is NULL!"); + return; + } + + if (!requestInfo) + { + LOGE("Request info is NULL!"); + return; + } + + if ((NULL != g_lastRequestToken) && (NULL != requestInfo->info.token) && + (strncmp(g_lastRequestToken, requestInfo->info.token, + requestInfo->info.tokenLength) == 0)) + { + LOGI("token is same. received request of it's own. skip.. "); + return; + } + + CAResult_t res = get_remote_address(object->transportType, object->addressInfo); + if (CA_STATUS_OK != res) + { + return; + } + + LOGI("##########received request from remote device #############"); + if (object->resourceUri) + { + LOGI("Uri: %s", object->resourceUri); + } + LOGI("Remote Address: %s", g_remoteAddress); + LOGI("Data: %s", requestInfo->info.payload); + LOGI("Token: %s", requestInfo->info.token); + LOGI("Code: %d", requestInfo->method); + LOGI("MessageType: %d", requestInfo->info.type); + + if (NULL != g_responseListenerObject) + { + callback("received request from remote device", "#######"); + char *cloneUri = NULL; + uint32_t len = 0; + + if (NULL != object->resourceUri) + { + len = strlen(object->resourceUri); + cloneUri = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == cloneUri) + { + LOGE("cloneUri Out of memory"); + free(g_remoteAddress); + return; + } + + memcpy(cloneUri, object->resourceUri, len + 1); + callback("Uri: ", cloneUri); + } + + len = strlen(g_remoteAddress); + char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == cloneRemoteAddress) + { + LOGE("cloneRemoteAddress Out of memory"); + free(g_remoteAddress); + free(cloneUri); + return; + } + + memcpy(cloneRemoteAddress, g_remoteAddress, len + 1); + + callback("Remote Address: ", cloneRemoteAddress); + free(cloneRemoteAddress); + free(g_remoteAddress); + + //clone g_clientEndpoint + g_clientEndpoint = (CARemoteEndpoint_t *) malloc(sizeof(CARemoteEndpoint_t)); + if (NULL == g_clientEndpoint) + { + LOGE("g_clientEndpoint Out of memory"); + free(cloneUri); + return; + } + memcpy(g_clientEndpoint, object, sizeof(CARemoteEndpoint_t)); + + if (NULL != cloneUri) + { + len = strlen(cloneUri); + g_clientEndpoint->resourceUri = (char *) malloc(sizeof(char) * (len + 1)); + if (NULL == g_clientEndpoint) + { + LOGE("g_clientEndpoint->resourceUri Out of memory"); + free(g_clientEndpoint); + free(cloneUri); + return; + } + memcpy(g_clientEndpoint->resourceUri, cloneUri, len + 1); + free(cloneUri); + } + //clone g_clientToken + len = requestInfo->info.tokenLength; + + g_clientToken = (char *) malloc(sizeof(char) * len); + if (NULL == g_clientToken) + { + LOGE("g_clientToken Out of memory"); + free(g_clientEndpoint->resourceUri); + free(g_clientEndpoint); + return; + } + + if (NULL != requestInfo->info.token) + { + memcpy(g_clientToken, requestInfo->info.token, len); + g_clientTokenLength = len; + + } + + //clone g_clientMsgId + g_clientMsgId = requestInfo->info.messageId; + + if (NULL != requestInfo->info.payload) + { + len = strlen(requestInfo->info.payload); + char *clonePayload = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == clonePayload) + { + LOGE("clonePayload Out of memory"); + free(g_clientEndpoint->resourceUri); + free(g_clientEndpoint); + return; + } + + memcpy(clonePayload, requestInfo->info.payload, len + 1); + + callback("Data: ", clonePayload); + free(clonePayload); + } + } + + if (requestInfo->info.options) + { + uint32_t len = requestInfo->info.numOptions; + uint32_t i; + + LOGI("Option count: %d", requestInfo->info.numOptions); + + for (i = 0; i < len; i++) + { + LOGI("Option %d", i + 1); + LOGI("ID : %d", requestInfo->info.options[i].optionID); + LOGI("Data[%d]: %s", requestInfo->info.options[i].optionLength, + requestInfo->info.options[i].optionData); + + if (NULL != g_responseListenerObject) + { + char optionInfo[OPTION_INFO_LENGTH] = { 0, }; + sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1, + requestInfo->info.options[i].optionID, + requestInfo->info.options[i].optionLength); + + callback("Option info: ", optionInfo); + + uint32_t optionDataLen = strlen(requestInfo->info.options[i].optionData); + char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1)); + if (NULL == cloneOptionData) + { + LOGE("cloneOptionData Out of memory"); + free(g_clientEndpoint->resourceUri); + free(g_clientEndpoint); + return; + } + + memcpy(cloneOptionData, requestInfo->info.options[i].optionData, + optionDataLen + 1); + + callback("Option Data: ", cloneOptionData); + free(cloneOptionData); + } + } + } + LOGI("############################################################"); + + //Check if this has secure communication information + if (requestInfo->info.payload && CA_IPV4 == object->transportType) + { + uint32_t securePort = get_secure_information(requestInfo->info.payload); + if (0 < securePort) //Set the remote endpoint secure details and send response + { + LOGI("This is secure resource..."); + char *uri = NULL; + uint32_t length = 0; + + length = sizeof(SECURE_COAPS_PREFIX) - 1; //length of "coaps://" + // length of "ipaddress:port" + length += strlen(object->addressInfo.IP.ipAddress) + PORT_LENGTH; + length += strlen(object->resourceUri) + 1; + + uri = calloc(1, sizeof(char) * length); + if (!uri) + { + LOGE("Failed to create new uri"); + free(uri); + return; + } + sprintf(uri, "%s%s:%d/%s", SECURE_COAPS_PREFIX, object->addressInfo.IP.ipAddress, + securePort, object->resourceUri); + + CARemoteEndpoint_t *endpoint = NULL; + if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, object->transportType, &endpoint)) + { + LOGE("Failed to create duplicate of remote endpoint!"); + free(uri); + return; + } + endpoint->isSecured = true; + object = endpoint; + + free(uri); + } + } +} + +void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo) +{ + + CAResult_t res = get_remote_address(object->transportType, object->addressInfo); + if (CA_STATUS_OK != res) + { + return; + } + + LOGI("##########Received response from remote device #############"); + LOGI("Uri: %s", object->resourceUri); + LOGI("Remote Address: %s", g_remoteAddress); + LOGI("response result: %d", responseInfo->result); + LOGI("Data: %s", responseInfo->info.payload); + LOGI("Token: %s", responseInfo->info.token); + LOGI("MessageType: %d", responseInfo->info.type); + + if (NULL != g_responseListenerObject) + { + uint32_t len = 0; + + if (NULL != object->resourceUri) + { + len = strlen(object->resourceUri); + char *cloneUri = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == cloneUri) + { + LOGE("cloneUri Out of memory"); + free(g_remoteAddress); + return; + } + + memcpy(cloneUri, object->resourceUri, len + 1); + + callback("Uri: ", cloneUri); + free(cloneUri); + } + + len = strlen(g_remoteAddress); + char *cloneRemoteAddress = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == cloneRemoteAddress) + { + LOGE("cloneRemoteAddress Out of memory"); + free(g_remoteAddress); + return; + } + + memcpy(cloneRemoteAddress, g_remoteAddress, len + 1); + + callback("Remote Address: ", cloneRemoteAddress); + free(cloneRemoteAddress); + free(g_remoteAddress); + + if (NULL != responseInfo->info.payload) + { + len = strlen(responseInfo->info.payload); + char *clonePayload = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == clonePayload) + { + LOGE("clonePayload Out of memory"); + return; + } + + memcpy(clonePayload, responseInfo->info.payload, len + 1); + + callback("Data: ", clonePayload); + free(clonePayload); + } + } + + if (responseInfo->info.options) + { + uint32_t len = responseInfo->info.numOptions; + uint32_t i; + for (i = 0; i < len; i++) + { + LOGI("Option %d", i + 1); + LOGI("ID : %d", responseInfo->info.options[i].optionID); + LOGI("Data[%d]: %s", responseInfo->info.options[i].optionLength, + responseInfo->info.options[i].optionData); + + if (NULL != g_responseListenerObject) + { + char optionInfo[OPTION_INFO_LENGTH] = { 0, }; + sprintf(optionInfo, "Num[%d] - ID : %d, Option Length : %d", i + 1, + responseInfo->info.options[i].optionID, + responseInfo->info.options[i].optionLength); + + callback("Option info: ", optionInfo); + + uint32_t optionDataLen = strlen(responseInfo->info.options[i].optionData); + char *cloneOptionData = (char *) malloc(sizeof(char) * (optionDataLen + 1)); + if (NULL == cloneOptionData) + { + LOGE("cloneOptionData Out of memory"); + return; + } + memcpy(cloneOptionData, responseInfo->info.options[i].optionData, + optionDataLen + 1); + callback("Option Data: ", cloneOptionData); + free(cloneOptionData); + } + } + } + LOGI("############################################################"); + + //Check if this has secure communication information + if (responseInfo->info.payload && CA_IPV4 == object->transportType) + { + uint32_t securePort = get_secure_information(responseInfo->info.payload); + if (0 < securePort) //Set the remote endpoint secure details and send response + { + LOGI("This is secure resource..."); + } + } +} + +void get_resource_uri(const char *URI, char *resourceURI, uint32_t length) +{ + const char *startPos = URI; + const char *temp = NULL; + if (NULL != (temp = strstr(URI, "://"))) + { + startPos = strchr(temp + 3, '/'); + if (!startPos) + { + LOGE("Resource URI is missing"); + return; + } + } + + const char *endPos = strchr(startPos, '?'); + if (!endPos) + { + endPos = URI + strlen(URI); + } + --endPos; + + if (endPos - startPos <= length) + { + memcpy(resourceURI, startPos + 1, endPos - startPos); + } + + LOGI("URI: %s, ResourceURI: %s", URI, resourceURI); +} + +uint32_t get_secure_information(CAPayload_t payLoad) +{ + LOGI("entering get_secure_information"); + + if (!payLoad) + { + LOGE("Payload is NULL"); + return -1; + } + + const char *subString = NULL; + if (NULL == (subString = strstr(payLoad, "\"sec\":1"))) + { + LOGE("This is not secure resource"); + return -1; + } + + if (NULL == (subString = strstr(payLoad, "\"port\":"))) + { + LOGE("This secure resource does not have port information"); + return -1; + } + + const char *startPos = strstr(subString, ":"); + if (!startPos) + { + LOGE("Parsing failed !"); + return -1; + } + + const char *endPos = strstr(startPos, "}"); + if (!endPos) + { + LOGE("Parsing failed !"); + return -1; + } + + char portStr[6] = { 0 }; + memcpy(portStr, startPos + 1, (endPos - 1) - startPos); + + LOGI("secured port is: %s", portStr); + return atoi(portStr); +} + +CAResult_t get_network_type(uint32_t selectedNetwork) +{ + + uint32_t number = selectedNetwork; + + if (!(number & 0xf)) + { + return CA_NOT_SUPPORTED; + } + if (number & CA_IPV4) + { + g_selectedNwType = CA_IPV4; + return CA_STATUS_OK; + } + if (number & CA_EDR) + { + g_selectedNwType = CA_EDR; + return CA_STATUS_OK; + } + if (number & CA_LE) + { + g_selectedNwType = CA_LE; + return CA_STATUS_OK; + } + + return CA_NOT_SUPPORTED; +} + +void callback(char *subject, char *receivedData) +{ + JNIEnv* env = NULL; + uint32_t status = (*g_jvm)->GetEnv(g_jvm, (void **) &env, JNI_VERSION_1_6); + uint32_t res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); + + jclass cls = (*env)->GetObjectClass(env, g_responseListenerObject); + jmethodID mid = (*env)->GetMethodID(env, cls, "OnResponseReceived", + "(Ljava/lang/String;Ljava/lang/String;)V"); + + jstring jsubject = (*env)->NewStringUTF(env, (char*) subject); + jstring jreceivedData = (*env)->NewStringUTF(env, (char*) receivedData); + (*env)->CallVoidMethod(env, g_responseListenerObject, mid, jsubject, jreceivedData); + +} + +CAResult_t get_remote_address(CATransportType_t transportType, CAAddress_t addressInfo) +{ + + uint32_t len = 0; + if (CA_IPV4 == transportType) + { + len = strlen(addressInfo.IP.ipAddress); + g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == g_remoteAddress) + { + LOGE("g_remoteAddress Out of memory"); + return CA_MEMORY_ALLOC_FAILED; + } + + memcpy(g_remoteAddress, addressInfo.IP.ipAddress, len + 1); + } + + else if (CA_EDR == transportType) + { + len = strlen(addressInfo.BT.btMacAddress); + g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == g_remoteAddress) + { + LOGE("g_remoteAddress Out of memory"); + return CA_MEMORY_ALLOC_FAILED; + } + + memcpy(g_remoteAddress, addressInfo.BT.btMacAddress, len + 1); + } + + else if (CA_LE == transportType) + { + len = strlen(addressInfo.LE.leMacAddress); + g_remoteAddress = (char *) malloc(sizeof(char) * (len + 1)); + + if (NULL == g_remoteAddress) + { + LOGE("g_remoteAddress Out of memory"); + return CA_MEMORY_ALLOC_FAILED; + } + + memcpy(g_remoteAddress, addressInfo.LE.leMacAddress, len + 1); + } + + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h b/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h new file mode 100644 index 0000000..8c6b61f --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/jni/org_iotivity_service_RMInterface.h @@ -0,0 +1,134 @@ +#include +/* Header for class org_iotivity_service_RMInterface */ + +#ifndef _Included_org_iotivity_service_RMInterface +#define _Included_org_iotivity_service_RMInterface +#ifdef __cplusplus +extern "C" { +#endif +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_setNativeResponseListener + (JNIEnv *, jobject, jobject); +/* + * Class: org_iotivity_service_RMInterface + * Method: RMInitialize + * Signature: (Landroid/content/Context;)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMInitialize + (JNIEnv *, jobject, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMTerminate + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMTerminate + (JNIEnv *, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMStartListeningServer + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMStartListeningServer + (JNIEnv *, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMStartDiscoveryServer + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMStartDiscoveryServer + (JNIEnv *, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMRegisterHandler + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMRegisterHandler + (JNIEnv *, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMFindResource + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMFindResource + (JNIEnv *, jobject, jstring); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMSendRequest + * Signature: (Ljava/lang/String;Ljava/lang/String;III)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendRequest + (JNIEnv *, jobject, jstring, jstring, jint, jint, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMSendReqestToAll + * Signature: (Ljava/lang/String;I)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendReqestToAll + (JNIEnv *, jobject, jstring, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMSendResponse + * Signature: (IIII)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendResponse + (JNIEnv *, jobject, jint, jint, jint, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMAdvertiseResource + * Signature: (Ljava/lang/String)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMAdvertiseResource + (JNIEnv *, jobject, jstring); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMSendNotification + * Signature: (Ljava/lang/String;Ljava/lang/String;IIII)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSendNotification + (JNIEnv *, jobject, jstring, jstring, jint, jint, jint, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMSelectNetwork + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMSelectNetwork + (JNIEnv *, jobject, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMUnSelectNetwork + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMUnSelectNetwork + (JNIEnv *, jobject, jint); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMGetNetworkInfomation + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMGetNetworkInfomation + (JNIEnv *, jobject); + +/* + * Class: org_iotivity_service_RMInterface + * Method: RMHandleRequestResponse + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_service_RMInterface_RMHandleRequestResponse + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt b/resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt new file mode 100644 index 0000000..c1ff32f --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt @@ -0,0 +1,21 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + diff --git a/resource/csdk/connectivity/samples/android/sample_service/project.properties b/resource/csdk/connectivity/samples/android/sample_service/project.properties new file mode 100644 index 0000000..6e18427 --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-21 diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml b/resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml new file mode 100644 index 0000000..25ce793 --- /dev/null +++ b/resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +